Page 1 of 3

Kernel loading from cd

Posted: Sat Aug 14, 2010 4:27 pm
by Payn3
Hi guys. I've developed(90% copied from your page, but i understand it) a bootloader. After entering in 32 bits protected mode i try to load my kernel, but the bootloader freezes.

Here is my code

bootloader.asm

Code: Select all

[BITS 16]    
[ORG 0x7C00]   

        cli ;disable interupts                 

        xor ax, ax
        mov ds, ax              ; set ds to 0
        lgdt [gdt_desc]         ; Load the GDT
        mov eax, cr0            ; Copy the contents of CR0 into EAX
        or eax, 1               ; Set bit 0
        mov cr0, eax            ; Copy the contents of EAX into CR0
        jmp 08h:clear_pipe      ; Jump to code segment, offset clear_pipe


[BITS 32]                       ; We now need 32-bit instructions
clear_pipe:
        mov ax, 10h             ; Save data segment identifyer
        mov ds, ax              ; Move a valid data segment into the data segment register
        mov ss, ax              ; Move a valid data segment into the stack segment register
        mov esp, 090000h        ; Move the stack pointer to 090000h

        mov byte [ds:0B8000h], 'P'      ; Move the ASCII-code of 'P' into first video memory
        mov byte [ds:0B8001h], 0x07      ; Assign a color code
		start: ;read kernel
			mov ax,0
			mov es,ax
			mov bx,0x1200 ;memory location where we will load the kernel
			mov ah,0x02
			mov al,0x01
			mov ch,0x00
			mov dl,80h
			mov dh,1
			mov bx,0x000
			int 13h
		jc start
		mov byte [ds:0B8002h], 'P'      ; Move the ASCII-code of 'P' into first video memory
        mov byte [ds:0B8003h], 0x07      ; Assign a color code
		jmp 0x120:0000
		

gdt:                    ; Address for the GDT

gdt_null:               ; Null Segment
        dd 0
        dd 0

gdt_code:               ; Code segment, read/execute, nonconforming
        dw 0FFFFh
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0

gdt_data:               ; Data segment, read/write, expand down
        dw 0FFFFh
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0

gdt_end:                ; Used to calculate the size of the GDT

gdt_desc:                       ; The GDT descriptor
        dw gdt_end - gdt - 1    ; Limit (size)
        dd gdt                  ; Address of the GDT

times 510-($-$$) db 0x00           ; Fill up the file with zeros
dw 0AA55h                ; Boot sector identifyer
kernel.cpp

Code: Select all

void kernel_main(){
	unsigned char *videoram = (unsigned char *) 0xb8000;
	videoram[0] = 65; /* character 'A' */
	videoram[1] = 0x07; /* forground, background color. */
	for(;;);
Also when i compile the kernel i get the next warning
Cannot find entry symbol kernel_main
linker.ld

Code: Select all

ENTRY (kernel_main)

SECTIONS{
    . = 0x00100000;

    .text :{
        *(.text)
    }

    .rodata ALIGN (0x1000) : {
        *(.rodata)
    }

    .data ALIGN (0x1000) : {
        *(.data)
    }

    .bss : {
        sbss = .;
        *(COMMON)
        *(.bss)
        ebss = .;
    }
}
Sorry for my bad english and i hope that somebody can help me.

L.E Oh, and for testing I use a file created with windows command copy /b

Code: Select all

copy /b bootloader.bin+kernel.bin out.img
and i use that image as bootsector of an iso image(Ultra ISO)
Then i emulate that iso image in Virtualbox.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:42 pm
by gerryg400
It looks like you are calling int 0x13 from 32 bit mode. You can't do that. You need to load your kernel from disk in real mode.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:44 pm
by Payn3
There is no solution to load the kernel in 32 bit mode?

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:45 pm
by Combuster
That's the only way that i found on internet. How i load the kernel in 32 bit mode?
You don't, use real mode as said

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:47 pm
by MDM
Try loading up the kernel while still in real mode (16 bit mode) and then after that changing the cr0 register so its 32 bit mode. So do


start:
code ; code here is in 16 bit mode.
... ; load kernel
code

clear_pipes:
code ; change to 32 bit mode.
... ; reprogram PIC so you can use interrupts again
code

In protected mode the PIC needs to be reprogrammed, otherwise interrupts won't work correctly.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:51 pm
by Combuster
MDM wrote:In 32 bit mode the PIC needs to be reprogrammed, otherwise interrupts won't work correctly.
Interrupts will work, they only fire different interrupt numbers.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:53 pm
by MDM
Combuster wrote:
MDM wrote:In 32 bit mode the PIC needs to be reprogrammed, otherwise interrupts won't work correctly.
Interrupts will work, they only fire different interrupt numbers.
That's what I meant, should have made that more apparent : )

Just a quick question that goes along these lines, in long mode is PIC still somewhat messed up when you first load in from real mode?

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:55 pm
by Payn3

Code: Select all

[BITS 16]    
[ORG 0x7C00]   
		start: ;read kernel
			mov ax,0
			mov es,ax
			mov bx,0x1000 ;memory location where will be stored the kernel
			mov ah,0x02
			mov al,0x01
			mov ch,0x00
			mov dl,80h
			mov dh,1
			mov bx,0x000
			int 13h
		jc start
        cli ;disable interupts                 

        xor ax, ax
        mov ds, ax              ; set ds to 0
        lgdt [gdt_desc]         ; Load the GDT
        mov eax, cr0            ; Copy the contents of CR0 into EAX
        or eax, 1               ; Set bit 0
        mov cr0, eax            ; Copy the contents of EAX into CR0
        jmp 08h:clear_pipe      ; Jump to code segment, offset clear_pipe


[BITS 32]                       ; We now need 32-bit instructions
clear_pipe:
        mov ax, 10h             ; Save data segment identifyer
        mov ds, ax              ; Move a valid data segment into the data segment register
        mov ss, ax              ; Move a valid data segment into the stack segment register
        mov esp, 090000h        ; Move the stack pointer to 090000h

        mov byte [ds:0B8000h], 'P'      ; Move the ASCII-code of 'P' into first video memory
        mov byte [ds:0B8001h], 0x07      ; Assign a color code
	jmp 0x1000:0000					 ;jump to kernel
		

But still freezes, and if y press any key prints the "P" and nothing else.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:58 pm
by gerryg400
Just a quick question that goes along these lines, in long mode is PIC still somewhat messed up when you first load in from real mode?
No. The PIC doesn't know what mode you are in. So will always behave the same.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 4:59 pm
by Brynet-Inc
Payn3 wrote:There is no solution to load the kernel in 32 bit mode?
It is fairly difficult to write drivers for ATA/ATAPI, which is needed if you want to jump to protected/long mode earlyl, on a CD you have a little extra space for the initial bootsrap, but you can't reliably use more than 2048 bytes.

One option would be a second stage loader which is loaded using BIOS interrupts, in the second stage loader you could switch to protected/long mode, write disk drivers, and load the kernel.

That's about it.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 5:00 pm
by gerryg400
Cannot find entry symbol kernel_main
This is a very important error. You must fix it.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 5:02 pm
by Payn3
I know i have to fix it, but how? I found some solutions to that problem , but only for asm kernels.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 5:30 pm
by gerryg400
How are you building the kernel ? What tools, command line etc ?

BTW, in your linker script you have

Code: Select all

ENTRY (kernel_main)
This will put the value of the kernel_main into the ELF (or other) header entry point of your kernel executable. But there is no guarantee that the entry point is 0x100000 as you assume.

It's much better to have some startup code in assembler that contains the entry point and tell the linker to put that code at 0x100000. You can control the position of the assy code easier than c code.

Re: Kernel loading from cd

Posted: Sat Aug 14, 2010 10:45 pm
by egos
Brynet-Inc wrote:on a CD you have a little extra space for the initial bootsrap, but you can't reliably use more than 2048 bytes.
With emulation he can use only 512 bytes, but with no emulation there is able to use more than 2048 bytes. BIOS is able to fill all base memory with image data.

Re: Kernel loading from cd

Posted: Sun Aug 15, 2010 2:37 am
by Owen
egos wrote:
Brynet-Inc wrote:on a CD you have a little extra space for the initial bootsrap, but you can't reliably use more than 2048 bytes.
With emulation he can use only 512 bytes, but with no emulation there is able to use more than 2048 bytes. BIOS is able to fill all base memory with image data.
on a CD you have a little extra space for the initial bootsrap, but you can't reliably use more than 2048 bytes.

Read: Yet again BIOSes are buggy sacks of crap