Writing a custom OS kernel that can run a Turbo C DOS .exe after switching to protected mode

0

Im new to Assembly language, i want to call a .exe file from my assembly code after the MS DOS go to the protected mode (32 Bit)

code (boot.asm || boot.img):

bits 16
ORG 0x7c00

VIDEO_TEXT_ADDR     EQU 0xb8000 ; Hard code beginning of text video memory
ATTR_WHITE_ON_BLACK EQU 0x07    ; White on black attribute

CR                  EQU 0x0d    ; Carriage return
LF                  EQU 0x0a    ; Line feed

; Include a BPB (1.44MB floppy with FAT12) to be more comaptible with USB floppy media
%include "bpb.inc"

boot_start:
    xor ax, ax                  ; DS=SS=0. Real mode code below doesn't use ES
    mov ds, ax
    mov ss, ax                  ; Stack at 0x0000:0x7c00 below bootloader
    mov sp, 0x7c00
    cld                         ; Set string instructions to use forward movement

    mov si, boot_init_msg       ; Print boot initialization message
    call print_string_rm

    ; Fast method of enabling A20 may not work on all x86 BIOSes
    ; It is good enough for emulators and most modern BIOSes
    ; See: https://wiki.osdev.org/A20_Line
    cli                         ; Disable interrupts
    in al, 0x92
    or al, 2
    out 0x92, al                ; Enable A20 using Fast Method

    mov si, load_gdt_msg        ; Print loading GDT message
    call print_string_rm

    lgdt [gdtr]                 ; Load our GDT

    mov si, enter_pm_msg        ; Print protected mode message
    call print_string_rm

    mov eax, cr0
    or eax, 1
    mov cr0, eax                ; Set protected mode flag
    jmp CODE32_SEL:start32      ; FAR JMP to set CS

bits 32
start32:
    mov ax, DATA32_SEL          ; Setup the segment registers with data selector
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    mov esp, 0x9c000            ; Set the stack to grow down from area under
                                ;     EBDA/Video memory

    xor eax, eax                ; Clear EAX for the instructions below
    mov al, [0x450]             ; Byte at address 0x450 = last BIOS column position
    mov [cur_col], eax          ; Copy to current column
    mov al, [0x451]             ; Byte at address 0x451 = last BIOS row position
    mov [cur_row], eax          ; Copy to current row

    mov ax, [0x44a]             ; Word at address 0x44a = # of columns (screen width)
    mov [screen_width], eax     ; Copy to screen width

    mov eax, in_pm_msg          ; Print message we are in protected mode
    call print_string_pm        ; EAX = first parameter

end_loop:
    hlt
    jmp end_loop

; Function: set_cursor
;           set the hardware cursor position based on the
;           current column (cur_col) and current row (cur_row) coordinates
; See:      https://wiki.osdev.org/Text_Mode_Cursor#Moving_the_Cursor_2
;
; Inputs:   None
; Clobbers: EAX, ECX, EDX

set_cursor:
    mov ecx, [cur_row]          ; EAX = cur_row
    imul ecx, [screen_width]    ; ECX = cur_row * screen_width
    add ecx, [cur_col]          ; ECX = cur_row * screen_width + cur_col

    ; Send low byte of cursor position to video card
    mov edx, 0x3d4
    mov al, 0x0f
    out dx, al                  ; Output 0x0f to 0x3d4
    inc edx
    mov al, cl
    out dx, al                  ; Output lower byte of cursor pos to 0x3d5

    ; Send high byte of cursor position to video card
    dec edx
    mov al, 0x0e
    out dx, al                  ; Output 0x0e to 0x3d4
    inc edx
    mov al, ch
    out dx, al                  ; Output higher byte of cursor pos to 0x3d5

    ret

; Function: print_string_pm
;           Display a string to the console on display page 0 in protected mode.
;           Handles carriage return and line feed.
;           Doesn't handle tabs, backspace, wrapping and scrolling.
;
; Inputs:   EAX = Offset of address to print
; Clobbers: EAX, ECX, EDX

print_string_pm:
    push edi
    push esi
    push ebx
    mov esi, eax                ; Set ESI to beginning of string

    ; Assume base of text video memory is ALWAYS 0xb8000
    mov ebx, VIDEO_TEXT_ADDR    ; EBX = beginning of video memory

    mov eax, [cur_row]          ; EAX = cur_row
    mul dword [screen_width]    ; EAX = cur_row * screen_width
    mov edx, eax                ; EDX = copy of offset to beginning of line
    add eax, [cur_col]          ; EAX = cur_row * screen_width + cur_col
    lea edi, [ebx + eax * 2]    ; EDI = memory location of current screen cell

    mov ah, ATTR_WHITE_ON_BLACK ; Set attribute
    jmp .getch
.repeat:
    cmp al, CR                  ; Is the character a carriage return?
    jne .chk_lf                 ;     If not skip and check for line feed
    lea edi, [ebx + edx * 2]    ; Set current video memory pointer to beginning of line
    mov dword [cur_col], 0      ; Set current column to 0
    jmp .getch                  ; Process next character
.chk_lf:
    cmp al, LF                  ; Is the character a line feed?
    jne .write_chr              ;     If not then write character
    mov eax, [screen_width]
    lea edi, [edi + eax * 2]    ; Set current video memory ptr to same pos on next line
    inc dword [cur_row]         ; Set current row to next line
    mov ah, ATTR_WHITE_ON_BLACK ; Reset attribute
    jmp .getch                  ; Process next character

.write_chr:
    inc dword [cur_col]         ; Update current column
    stosw

.getch:
    lodsb                       ; Get character from string
    test al, al                 ; Have we reached end of string?
    jnz .repeat                 ;     if not process next character

.end:
    call set_cursor             ; Update hardware cursor position

    pop ebx
    pop esi
    pop edi
    ret

bits 16

; Function: print_string_rm
;           Display a string to the console on display page 0 in real mode
;
; Inputs:   SI = Offset of address to print
; Clobbers: AX, BX, SI

print_string_rm:
    mov ah, 0x0e                ; BIOS tty Print
    xor bx, bx                  ; Set display page to 0 (BL)
    jmp .getch
.repeat:
    int 0x10                    ; print character
.getch:
    lodsb                       ; Get character from string
    test al,al                  ; Have we reached end of string?
    jnz .repeat                 ;     if not process next character
.end:
    ret

cur_row:      dd 0x00
cur_col:      dd 0x00
screen_width: dd 0x00

boot_init_msg:
    db "Booting sequence initialized...", CR, LF, 0
load_gdt_msg:
    db "Loading GDT...", CR, LF, 0
enter_pm_msg:
    db "Entering 32-bit Protected Mode...", CR, LF, 0
in_pm_msg:
    db "Executing code in protected mode!", CR, LF, 0
    ;----------------------------------
    ;call "C:/EDOS/SYSTEM/bootanim.exe
    ;----------------------------------

align 8
gdt_start:
    dd 0                        ; null descriptor
    dd 0

gdt32_code:
    dw 0FFFFh                   ; limit low
    dw 0                        ; base low
    db 0                        ; base middle
    db 10011010b                ; access
    db 11001111b                ; 32-bit, 4kb granularity, limit 0xffffffff bytes
    db 0                        ; base high

gdt32_data:
    dw 0FFFFh                   ; limit low (Same as code)
    dw 0                        ; base low
    db 0                        ; base middle
    db 10010010b                ; access
    db 11001111b                ; 32-bit, 4kb granularity, limit 0xffffffff bytes
    db 0                        ; base high
end_of_gdt:

gdtr:
    dw end_of_gdt - gdt_start - 1
                                ; limit (Size of GDT - 1)
    dd gdt_start                ; base of GDT

CODE32_SEL equ gdt32_code - gdt_start
DATA32_SEL equ gdt32_data - gdt_start

; Pad boot sector to 510 bytes and add 2 byte boot signature for 512 total bytes
TIMES 510-($-$$) db  0
dw 0xaa55

I need to call the .EXE file on the in_pm_msg function...

With this, I will boot this code, and execute an hello world in C!

assembly
nasm
x86-16
osdev
protected-mode
asked on Stack Overflow Mar 30, 2019 by Eduardo Procópio Gomez • edited Mar 30, 2019 by Peter Cordes

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0