Jump to content

boot c++ application

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
9 replies to this topic

#1
starsoheil

starsoheil

    Newbie

  • Members
  • PipPip
  • 13 posts
hello
please help me
i want programming a boot program .
i programming a application with c++ ( my compiler is : gcc - dev c++ 4.9)
my program need boot from system boot ( from a cd/dvd or HDD ) .
now i want boot from system and run this c++ application . i know assembly language .
please help me to write a program by assembly that boot from system and after booting successfully run my c++ application .
if you come an example for me , this is good .
thank full .

#2
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts
Let me get this straight...you want to create a bootloader program that will load your C++ program into memory and execute it? You've got problems.

1) C++ libraries relies on code that runs on top of a host operating system. You're going to be running below the operating system, so you can't use any of the libraries.
2) Caveat: Your compiler is going to link with system libraries and produce an operating system-specific executable format.

Pass GCC these options:
-nostdinc (ignore standard include paths)

Pass these options to LD:
-nostdlib (don't link with standard libraries)
-Ttext <starting address here> (specify the load address for the program)
--oformat binary (raw binary output)
-static (any libraries must be statically linked)

The bootloader program's load address must be 0x7C00 and must be less than either 446 bytes for hard drives, or 510 bytes for other media. You can specify any address you want for your main program, but make sure it's low so that you don't load it past the memory limit.

Things you need to watch out for:
- You won't have ANY memory allocation. No malloc(), new, or anything like that. You're going to have to write those yourself. The BIOS has memory allocation routines but I don't think those go over the 1MB memory limit imposed on 16-bit systems.
- You're going to have to write printf() and all that yourself. That means writing to memory-mapped locations or using BIOS routines to do that for you (but they're slow).
- No exception handling unless you do it yourself
- No STL, iostream, fstream, or any other C++ library stuff
- No C library either.
- No library support for file systems. You're going to have to use the BIOS, and typically those only support FAT*.
- You need to enable the A20 line or else you're restricted to one megabyte of memory. This requires assembly language, but since you know it it shouldn't be too much of a problem.

Edited by dargueta, 09 March 2010 - 10:43 AM.

sudo rm -rf /

#3
Ewe Loon

Ewe Loon

    Learning Programmer

  • Members
  • PipPipPip
  • 49 posts
If im not mistaken, the cpu is still in real mode during the boot sequence, meaning there is only 1meg of addressable space, which includes all the interrupt vectors, bios (kernal and video rom) , video memory is in there too,
of course your program can switch the processor into protected mode to access larger blocks of memory, how ever there will be no memory management routines to use

#4
starsoheil

starsoheil

    Newbie

  • Members
  • PipPip
  • 13 posts
dear dargueta
please write an example for me .
thank full

#5
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts

Quote

how ever there will be no memory management routines to use
I think you're still able to use BIOS routines. At least Bochs lets me, anyway. I've never been brave enough to test it on my own computer. :D

@Starsohell: Give me two weeks until I'm on spring break and I'll post something. Remind me, though, as I'm likely to forget.
sudo rm -rf /

#6
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts
Rolling Your Own Bootloader <-- in-depth tutorial

Here's my code. Mind you, I can't test it right now, so it may not work. I've tried to the best of my ability to ensure that it works. This is in NASM syntax, just so you know.


EDIT: This is wrong, see my next post for corrected and updated code.

Edited by dargueta, 10 March 2010 - 01:09 PM.
Removed faulty code (see my next post for fixed)

sudo rm -rf /

#7
starsoheil

starsoheil

    Newbie

  • Members
  • PipPip
  • 13 posts
hello
very thank you
you are best programmer .
this is my purpose .
i will testing this .
now , another question : you say "C++ libraries relies on code that runs on top of a host operating system" , i think your intention is : functions (such as createwindow()) is not working in boot , what do work this function in boot (16 bit system mode) ?

#8
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts
Nothing you didn't write will work. I edited my above post because I was slightly wrong. Anyway, I've finally written a bootloader that I've been able to test, and it works. (At least in Bochs, anyway.)

bits 16

org 7c00h

jmp     __start

[I]; This program does not load the kernel yet, I'm still working on that. All it does right now
; is enable A20 and deliberately hang.[/I]

msg_startup     db "Bootloader stub program starting up.",0dh,0ah,09h,"Enabling A20...",00h
msg_err_a20:    db "Failed to enable high memory.",0dh,0ah,00h
msg_err_nokrnl: db "No kernel found.",0dh,0ah,00h
msg_err_diskerr:db "Disk read error.",0dh,0ah,00h
msg_err_pmode:  db "Failed to switch to protected mode.",0dh,0ah,00h
msg_ok_a20:     db "Memory OK.",0dh,0ah,00h
msg_ok_startup: db 0dh,0ah,0dh,0ah,"Startup OK, deliberately hanging now.",0dh,0ah,00h

__start:
    [I]; set up stack and data segments[/I]
    cli
    mov     ax, 9000h
    mov     ss, ax
    mov     sp, 0ffffh
    push    cs
    pop     ds
    sti

    [I]; change video mode[/I]
    mov     ax, 0003h
    int     10h

    [I]; clear the screen[/I]
    mov     ax, 0600h
    mov     bh, 1fh
    xor     cx, cx
    mov     dx, 184fh
    int     10h

   [I] ; print startup loading message[/I]
    mov     si, msg_startup
    call    _print

    [I]; try to enable A20 using the BIOS[/I]
    mov     ax, 2401h
    int     15h

    [I]; if the carry flag is set high then we failed.[/I]
    jnc     .load_program

    [I]; okay, we failed. try another method.[/I]
    in      al, 92h
    or      al, 02h
    out     92h, al

   [I] ; check to see if A20 is enabled[/I]
    call    _check_a20
   [I] ; If we get carry then we failed again. Print error and hang.[/I]
    jnc     .load_program

   [I] ; print no memory error message[/I]
    mov     si, msg_err_a20
    call    _print

    [I].hang:[/I]
        cli
        hlt

    .load_program:
        [I]; this doesn't load the program. Put your loading code here.[/I]
        mov     si, msg_ok_a20
        call    _print
        mov     si, msg_ok_startup
        call    _print
        jmp     .hang

_print:
    mov     ah, 0eh
    mov     bx, 0007h

    ._printloop:

       [I] ; load the next char to print[/I]
        lodsb
       [I] ; test for end of string[/I]
        cmp     al, 00h
        je      .done_print
       [I] ; print character[/I]
        int     10h
        [I]; go on to next[/I]
        jmp     ._printloop

    .done_print:
    ret


[I]; FUNCTION TO CHECK WHETHER A20 IS ENABLED[/I]
_check_a20:
    [I];disable interrupts[/I]
    cli
    push    ds

   [I] ; ES = 0, DS = 0ffffh[/I]
    xor     ax, ax
    mov     es, ax
    not     ax
    mov     ds, ax

   [I] ; DI = 0500h, SI = 0510h[/I]
    mov     di, 0500h
    mov     si, 0510h

[I]    ; Note that because without A20 we're limited to 1 megabyte of memory, if
    ; A20 isn't enabled then high addresses will wrap around. Because of segmen-
    ; tation in 8086 mode, ES:[DI] and DS:[SI] (0000h:0500h and ffffh:0510h
    ; respectively) should map to the same memory address. So all we have to do
    ; is store a value to ES:[DI] and read it back from DS:[SI]. If we get the
    ; same value, then we're pretty much guaranteed that A20 isn't enabled. If
    ; we don't get the same value, then A20 is definitely on.[/I]

    cmpsw
    jne     .a20_ok

[I]    ; we got the same value back. If we write to one and get the same value
    ; in both then we've got A20 disabled.[/I]
    mov     WORD [ds:si], 0deadh
    cmp     WORD [es:di], 0deadh
    jne     .a20_ok

[I]    ; if we get here then A20 is definitely disabled. Set carry flag and exit.[/I]
    .a20_disabled:
        stc
        jmp     .exit

    .a20_ok:
[I]        ; if we get here then A20 is enabled. Clear the carry flag and exit.[/I]
        clc

    .exit:
        sti
        pop     ds
        ret

Edited by dargueta, 10 March 2010 - 01:08 PM.
Added code sample.

sudo rm -rf /

#9
starsoheil

starsoheil

    Newbie

  • Members
  • PipPip
  • 13 posts
hello thank you
in fact , i want to programming an simple Operating system .
my purpose is in Visopsys - Visual Operating System .
this OS programmed with GCC compiler . this OS use from all Library function .

#10
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts
You're using library functions? I can tell you right now, unless you've got a distro that's OS-independent or you've written it all yourself, it's not going to run.
sudo rm -rf /