呼叫从汇编引导程序C内核 [英] Call C kernel from assembly bootloader
问题描述
编辑: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屋!