Как правильно выполнить код C на barebone? - PullRequest
0 голосов
/ 21 апреля 2019

Пытаюсь сделать ОС без GRUB.Теперь я хочу выполнить код C из защищенного режима, но я не знаю как.

Я попробовал эти команды (pm.bin - это скомпилированный код ASM, где я хочу вызвать код C, а bootloader.bin - загрузчик первого этапа, он работает корректно):

nasm -f bin bootloader.asm -o bootloader.bin
nasm -f bin pm.asm -o pm.bin

gcc -ffreestanding -c kernel.c -o kernel.o
ld -o kernel.bin -Ttext 0x0 --oformat binary kernel.o
cat pm.bin kernel.bin > fin.bin

sudo dd if=bootloader.bin ibs=512 count=1 of=boot.img obs=512
sudo dd if=fin.bin ibs=1024 count=1 of=boot.img obs=512 seek=1
sudo qemu-system-x86_64 boot.img -monitor stdio

Хорошо, с помощью команды "cat" у меня будет двоичный код C после моего двоичного кода ASM, но как я могу перейти к коду C?

Код C (kernel.c):

void main() {
   char* vga = (char*)0xb8000;
   vga[0] = 'y';
   vga[1] = 0x4;
}

bootloader.asm:

bits 16
org 0x7c00

jmp start

%include "print_hex.asm"

; ================================================

start:
    cli
    mov ah, 0x00              ; clearing the screen
    mov al, 0x03
    int 0x10

    xor ax, ax                ; segment reg. init
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x07c0            ; stack init


    mov [bootdisk], dl
    jmp reset

reset:
    ; reset the disk
    xor ax, ax
    mov dl, [bootdisk]
    int 0x13
    jc error

load_disk:
    mov bx, 0x07e0            ; загружаем код по адресу 0x7e00
    mov es, bx
    xor bx, bx                ; обнуляем bx, получается 0x07e0:0x0000

    mov ah, 0x02              ; функция
    mov dl, [bootdisk]        ; номер накопителя
    mov al, 0x1               ; количество читаемых секторов
    mov ch, 0x0
    mov cl, 0x2               ; номер сектора
    mov dh, 0x0               ; head

    int 0x13                  ; читаем, используя все параметры

    jc error                  ; если ошибка

    jmp 0x07e0:0x0000

error:
    mov dx, ax
    call print_hex_dx

    jmp $


bootdisk: db 0 ; for boot disk number

times 510 - ($ - $$) db 0
dw 0xaa55

pm.asm (мне нужно вызвать C из этого файла):

bits 16
org 0x7e00

jmp mainf

%include "gdt.inc"

mainf:
    cli                       ; disable interrupts
    xor ax, ax                ; null segments
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x07c0            ; the stack is under 0x7c00
    sti                       ; enable interrupts

    call installGDT           ; installing GDT

    ; entering PM
    cli
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x8:final_stage


; =============================================================
[bits 32]

%include "driver_print_string.asm"
%include "color_clear_screen.asm"

; maybe I'll need "extern main" here

final_stage:
    cli

    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov ss, ax

    mov esp, 0x07c0

disable_cursor:
    mov dx, 0x3d4
    mov al, 0xa
    out dx, al

    inc dx
    mov al, 0x20    
    out dx, al

ccode:
    ; here I want my code to call C, but I don't know how to link it correctly!

jmp $

times 1024 - ($ - $$) db 0

gdt.inc:

installGDT:
    cli
    pusha
    lgdt [toc]
    sti
    popa
    ret

;*******************************************
; Global Descriptor Table (GDT)
;*******************************************

gdt_data:
    dd 0                ; null descriptor
    dd 0

; gdt code:             ; code descriptor
    dw 0FFFFh           ; limit low
    dw 0                ; base low
    db 0                ; base middle
    db 10011010b            ; access
    db 11001111b            ; granularity
    db 0                ; base high

; gdt data:             ; data descriptor
    dw 0FFFFh           ; limit low (Same as code)
    dw 0                ; base low
    db 0                ; base middle
    db 10010010b            ; access
    db 11001111b            ; granularity
    db 0                ; base high

end_of_gdt:
toc:
    dw end_of_gdt - gdt_data - 1    ; limit (Size of GDT)
    dd gdt_data             ; base of GDT

Так как же правильно скомпилировать и связать код C и ASM и перейти к первому?

...