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!
Here is what I successed to do but with a kernel written in asm :
boot.asm :
[org 0x7c00]
KERNEL_OFFSET equ 0x1000
call load_kernel
;Switch PM
cli
lgdt [gdt_descriptor]
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
mov ebp, 0x90000
mov esp, ebp
call KERNEL_OFFSET
jmp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[bits 16]
load_kernel:
mov bx, KERNEL_OFFSET
mov dh, 15
mov dl, 0
mov ah, 0x02
mov al, dh
mov ch, 0x00
mov dh, 0x00
mov cl, 0x02
int 0x13
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[bits 16]
GDT:
;null :
dd 0x0
dd 0x0
;code :
dw 0xffff ;Limit
dw 0x0 ;Base
db 0x0 ;Base
db 10011010b ;1st flag, Type flag
db 11001111b ;2nd flag, Limit
db 0x0 ;Base
;data :
dw 0xffff
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_descriptor :
dw $ - GDT - 1 ;16-bit size
dd GDT ;32-bit start address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 510 -($-$$) db 0
dw 0xaa55
kernel.asm:
[bits 32]
mov al, 'K'
mov ah, 3 ; cyan
mov edx, 0xb8000
mov [edx], ax
jmp $
I build the floppy image so that:
nasm boot.asm -o boot.bin
dd if=/dev/zero of=image.bin bs=512 count=2880
dd if=boot.bin of=image.bin conv=notrunc
nasm kernel.asm -o kernel.bin
dd if=kernel.bin of=image.bin conv=notrunc bs=512 seek=1
qemu -fda image.bin -boot a
This way it works ! that's almost that... But now, I replace kernel.asm by this kernel.c
kernel.c
void main () {
char * vga = (char *) 0xb8000 ;
*vga = "X";
}
And the following script:
nasm boot.asm -o boot.bin
dd if=/dev/zero of=image.bin bs=512 count=2880
dd if=boot.bin of=image.bin conv=notrunc
gcc -ffreestanding -m32 -c kernel32.c -o kernel.bin
dd if=kernel.bin of=image.bin conv=notrunc bs=512 seek=1
qemu -fda image.bin -boot a
Note that I'm running a 64bit Linux distro, so I use the '-m32' gcc option to compile to 32bits But it doesn't work...... please help !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With