呼叫从汇编引导程序C内核 [英] Call C kernel from assembly bootloader

查看:180
本文介绍了呼叫从汇编引导程序C内核的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:PLZ跳到我的第二个职位低于...

我在寻找一个最低限度的办法从我的引导程序进入到我的内核。
你有什么可行的例子这样做呢?

下面是进入保护模式的引导程序:
boot.asm

  [组织0x7C00]MOV BP,0×9000
MOV SP,BPCLI
LGDT [gdt_descriptor];输入PM
MOV EAX,CR0
或EAX,为0x1
MOV CRO,EAXJMP 0x8中:init_pm
[比特32]
init_pm:
    MOV AX,为0x10
    MOV DS,AX
    MOV SS,AX
    MOV ES,AX
    MOV FS,斧
    MOV GS,斧    ;试图从这里调用我的C函数
    调用为0x8000;内核入口点    JMP $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[位16]GDT:
;空值 :
    DD为0x0
    DD为0x0code:
    DW 0xFFFF的;限制
    DW为0x0;基地
    DB为0x0;基地
    DB 0b10011010; 1旗,旗型
    DB 0b11001111;第二标志,限制
    DB为0x0;基地;数据:
    DW为0xFFFF
    DW为0x0
    分贝为0x0
    DB 0b10010010
    DB 0b11001111
    分贝为0x0gdt_descriptor:
    DW $ - GDT - 1; 16位大小
    DD GDT; 32位起始地址
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;
;启动扇区填充
次510 - ($ - $$)0分贝
DW 0xAA55将

下面我的内核入口点我想从引导加载程序调用:
kernel.c

 无效的主要(){
    字符* VGA =(字符*)0xb8000;
    * VGA =X;
}

感谢您的帮助,

到目前为止,这是我试图这样做,但它不工作:
我只是把内核为0x8000与LD和猫串联,然后从引导程序跳转为0x8000

  NASM boot.asm -f -o BOOT.BIN斌
GCC -ffreestanding -c kernel.c -o kernel.o
LD -o kernel.bin -Ttext为0x8000 kernel.o --oformat二进制
猫BOOT.BIN kernel.bin> OS-图像


解决方案

呵呵,这绝对作品。它只是似乎是你的C知识,真的。

我变卦了你的C内核了一下,得到这个:

 无效的主要(无效)
{
   无符号字符* VGA =(无符号字符*)0xb8000;
   VGA [0] =X; //需要确保这是一个字符
   VGA [1] = 0×09; //附加属性字节
   对于(;;); //确保我们的内核永远不会停止,用一个无限循环
}

这似乎已经解决了这个问题对我来说!一切都在现在的工作秩序,只是写在该文件中的壳,然后BAM!你去那里!

EDIT: plz jump to my second post below...

I'm looking for a minimalist way to enter to my kernel from my bootloader. Do you have any workable example to do so ?

Here is the bootloader which enters protected mode : "boot.asm"

[org 0x7C00]

mov bp , 0x9000
mov sp , bp

cli
lgdt [gdt_descriptor] 

; Enter PM
mov eax, cr0
or  eax, 0x1
mov cr0, eax

jmp 0x8:init_pm 


[bits 32]
init_pm :
    mov ax, 0x10
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    ;Tried to call my C function from here 
    call 0x8000      ; Kernel entry point       

    jmp $


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[bits 16]

GDT:
;null : 
    dd 0x0 
    dd 0x0

;code : 
    dw 0xffff       ;Limit
    dw 0x0          ;Base
    db 0x0          ;Base
    db 0b10011010   ;1st flag, Type flag
    db 0b11001111   ;2nd flag, Limit
    db 0x0          ;Base

;data : 
    dw 0xffff       
    dw 0x0          
    db 0x0
    db 0b10010010 
    db 0b11001111 
    db 0x0

gdt_descriptor :
    dw $ - GDT - 1      ;16-bit size
    dd GDT              ;32-bit start address


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Bootsector padding
times 510-($-$$) db 0
dw 0xaa55

Here my kernel entry point I would like to call from the bootloader : "kernel.c"

void main() {
    char * vga = (char *) 0xb8000 ;
    *vga = "X";
}

Thanks for your help,

So far, this is what I tried to do, but it doesn't work : I just put the kernel to 0x8000 with ld and concatenate with cat, then jump from the bootloader to 0x8000

nasm boot.asm -f bin -o boot.bin
gcc -ffreestanding -c kernel.c -o kernel.o
ld -o kernel.bin -Ttext 0x8000 kernel.o --oformat binary
cat boot.bin kernel.bin > os-image

解决方案

Oh, this definitely works. It just seems to be your knowledge of C, really.

I changed around your C kernel a bit and got this:

void main (void) 
{
   unsigned char* vga = (unsigned char*) 0xb8000;
   vga[0] = 'X'; //need to make sure that this is a character
   vga[1] = 0x09; //append the attribute byte
   for(;;); //make sure our kernel never stops, with an infinite loop
}

This seems to have solved the problem for me! Everything is in working order now, just write a shell in that file and then BAM! there you go!

这篇关于呼叫从汇编引导程序C内核的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆