Page 1 of 1

Selfmade pm-bootsector loads only asm-kernelfiles but no c o

Posted: Wed Jul 16, 2003 11:01 am
by Freanan
I just coded a bootsector that switches to protected mode, loads a kernel-file to memory adress 0x1000 and jumps to it.
It loads a test 'kernel.bin', which is written in 32 bit assembler and assembled with nasm without problems, but there are problems when the 'kernel.bin' - file is written in c and compiled with gcc (i used -ffreestanding and all the parameters that are described in every tutorial to be sure that it is able to run as a kernel, and i tested the 'kernel.bin' with another bootsector before, so the kernel itsself should be valid):
First my system just rebootet, when i tried to jump to the kernel.
After that i searched the web for an explanation and found out that the a20-line has to be enabled to run a gcc-compiled kernel.
After i added the a20-code to my bootsector, the kernel seems to be loaded, but instead of printing out a string as it should, it just prints a space," " , to the upper left corner of the screen and hangs.
Please tell me why!
Thanks in advance..

Re:Selfmade pm-bootsector loads only asm-kernelfiles but no

Posted: Wed Jul 16, 2003 11:43 am
by anubis
Hi,
Have you enabled protected mode before loading the 'kernel.bin??
It might be better if you posted ur code.

Re:Selfmade pm-bootsector loads only asm-kernelfiles but no

Posted: Wed Jul 16, 2003 11:54 am
by bkilgore
I'm not sure if this is your problem but it's something to think about.

I think you have to be careful with c files comipled into binary, because the entry point into the program isn't necessarily at offset 0. With elf files and other executables, this isn't important because the point of entry is recorded, but with binary, I'm guessing you jump to offset 0 in your code which is probably not correct.

What I found to work well (and other people seem to as well) is to make an assembly file that just jumps to the entry point in your c file, and then have the c file take over from there. For example:

Code: Select all

kernel.c

void kmain()
{
  while (1);
}
and

Code: Select all

entry.asm

;the kmain function is in kernel.c
EXTERN _kmain

;We want the linker script to see our entry point
GLOBAL _entry

;Make sure the first line of code is a command so we can load at offset 0
jmp _entry


; Now you can place any other code you want to here
;
;


_entry:

;Do any processing you want to do before loading the kernel here (i.e. enabling paging, loading gdt and idt, etc).

;Finally, load the kernel
jmp _kmain
hlt

Then link them together, and when you jump to offset 0 of the loaded kernel, it will jump to _entry, which wil then jump into your c code.

Re:Selfmade pm-bootsector loads only asm-kernelfiles but no

Posted: Wed Jul 16, 2003 12:27 pm
by Freanan
anubis wrote: Hi,
Have you enabled protected mode before loading the 'kernel.bin??
It might be better if you posted ur code.
OK, here goes the code:
code wrote: [BITS 16]
[org 0x7C00]

; ---------------------------------------------------------
; Main Program
; ---------------------------------------------------------

;;;;;;;;;;;;;;kernel-loading;;;;;;;;;;;
;reset drive
reset_drive:
push ds
mov ax,0
int 13h
pop ds
or ah,ah
jnz reset_drive
;load kernel
mov ax,0
mov es,ax
mov bx,0x1000
mov ah,2
mov al,7
mov cx,2
mov dx,0
int 13h
or ah,ah
jnz reset_drive

;;;;;;;;;;;;;;;pmode;;;;;;;;;;;;
;load gdt
cli
xor ax,ax
mov ds,ax
lgdt[gdtinfo]
;set pe-bit--> pmode
mov eax, cr0
or eax,1
mov cr0,eax
;far jump
jmp 08h:clear
[BITS 32]
clear:
mov ax,10h
mov ds,ax
mov ss,ax
;stack
mov esp,090000h
;Enable A20
enablea20a:   
in   al, 0x64      
test   al, 2
jnz   enablea20a
mov   al, 0xD1
out   0x64, al
enablea20b:
in   al, 0x64
and   ax, byte 2
jnz   enablea20b
mov   al, 0xDF
out   0x60, al

;;;;;;;;;;;;jump to the kernel;;;;;;;;;
jmp 08h:01000h

; ---------------------------------------------------------
; Functions und Variables
; ----------------------------------------------------------

;;;;;;;;gdt;;;;;;;;
gdt: ;gdt
gdt_null: ;nulldescriptor
dw 0
dw 0
dw 0
dw 0
gdt_code: ;codesegment-descriptor
dw 0FFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
gdt_data: ;datasegment-descriptor
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:
;;;;;;gdt-register;;;;
gdtinfo:
dw gdt_end-gdt-1
dd gdt

times 512-($-$$)-2 db 0
dw 0AA55h


And thanks to bkilgore! This MIGHT be the problem, though i don't know if it is. I will try it anyway and even if it's not the problem, it might be better to remember it in the future.

I think it might perhaps also have to do with the constant, that i am trying to print...?
Because the kernel is loaded correctly and just does not print the text -perhaps it just does not find the string to output because gcc or ld put it to some strange place in the file. -Is this or something similar possible?

Re:Selfmade pm-bootsector loads only asm-kernelfiles but no

Posted: Thu Jul 17, 2003 12:58 am
by Pype.Clicker
depending on the target binary format, strings are placed in .text or .rodata* If for instance you use ELF, they go in .rodata, and if you don't include .rodata in your linker script when you produce kernel.bin, then you'll fail to read any strings. Maybe looking at your .bin file with hexdump, hexedit or any other similar tool may help...

Re:Selfmade pm-bootsector loads only asm-kernelfiles but no

Posted: Thu Jul 17, 2003 10:09 am
by Freanan
I just wrote an own kernel and loaded it with my bootsector- and... it worked :o!
I tested two different other 'kernel.bin's (i had temporarily no compiler, so i had to use an already compiled kernel), that had worked with John Fine's Bootloader but not with my own and now i wrote a kernel that does pretty much the same, but it works with my bootloader.
I wonder if there is any rational explanation to that...
Anyway, my problem is solved... Thank you all for your thoughts on the topic (and please post more, if you have any idea, why the old kernel only worked with the other bootsector - it just interrests me, even if my problem is solved)!