Bootloader doesn't appear to load kernel correctly

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
yvesbastos
Posts: 1
Joined: Mon Nov 24, 2014 6:19 am

Bootloader doesn't appear to load kernel correctly

Post by yvesbastos »

Hello,
I'm following Bran's Kernel development tutorial, but with my own bootloader. However, I'm not being able to print to the screen after the kernel is loaded.
I'm thinking that the kernel is not being loaded correctly... I've added some stuff to it (load gdt, idt, isrs) and maybe there's not enough space for it using the old allocation.
If anyone can help me or give me some directions, I'd really appreciate.

Here's my bootloader code:

Code: Select all

	

        ;call clear_screen

	;mov bx, BOOTLOADER_MSG
	;mov dl, 1
	;mov dh, 20
	;call cursorposition
	;call print_string	

	;mov bx, KERNEL_MSG
	;mov dl, 1
	;mov dh, 21
	;call cursorposition
	;call print_string	
		
	call load_kernel
	
	cli
	call load_gdt
	call switch_protected_mode
	 ;sti
	
	jmp 0x08:0x8000 

	

load_kernel:
	push bp
	mov bp, sp

	mov ah, 0x02 ; read from disk
	mov al, 0x30 ; read 2 sectors
	mov ch, 0x00 ; 1 cilinder floppy
	mov cl, 0x02 ; 2nd sector 
	mov dh, 0x00 
	mov dl, 0x00 ; 1st floppy

	mov bx, 0x800
	mov es, bx ; ES:BX - 512 bytes after the bootloader
	mov bx, 0x00  ;

	int 13h

	leave
	ret

clear_screen:

	pusha
	mov bp, sp
	mov ax, 0600H 
	mov bh, 07
   	mov cx, 0000
   	mov dx, 184FH
 	int 10h
	popa   	
  	ret

global cursorposition
cursorposition: 
	pusha  	
	mov ah, 02h
   	mov bh, 00
  	int 10h
	popa
	ret

load_gdt:

	push bp
	mov bp, sp
	mov ax, 0x7c0
	mov ds, ax
	
	lgdt [gdt_ptr]
	
	leave
	ret
	
	
	
switch_protected_mode:
	
	push bp
	mov bp, sp
	
	mov eax, cr0
	or eax, 1
	mov cr0, eax
	

	mov ax, 0x10
	
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ss, ax
	
	jmp 0x08:0x8000 
	
	; leave
	ret


gdt_ptr:
	dw 24
	dd 0x7c00 + gdt
	
gdt:
	db 0, 0, 0, 0, 0, 0, 0, 0 			  ; null segment
	db 0xff, 0xff, 0, 0, 0, 0x9A, 0xCF, 0 ; code segment
	db 0xff, 0xff, 0, 0, 0, 0x92, 0xCF, 0 ; data segment
	

;Data	
%include "src/bootloader/printstring.asm"


BOOTLOADER_MSG:
    db 'My Bootloader', 13, 10, 0

KERNEL_MSG:
    db 'Loading Kernel...', 13, 10, 0


times 510-($-$$) db 0
db 0x55
db 0xAA
Here's the beginning of my kernel:

Code: Select all

global start

STACKSIZE equ 0x4000 ; that's 16k.

extern main

start:

	; xchg bx, bx
	mov esp, stack+STACKSIZE ; set up the stack
	call main
	hlt ; halt machine should kernel return

Again, any tips would be really appreciated.
Thanks!

EDIT: Maybe my linker has something to do with it:

link.ld

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
. = 0x00100000;

.text :
{
*(.text)
}

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

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

.bss :
{
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}

EDIT2:
I am getting a few strange bochs output messages. Here's part of its output:

Code: Select all

Exp $
00014040328i[BIOS ] Booting from 0000:7c00
00014132226i[CPU0 ] MOV_EwSw: using of nonexisting segment register 7
00014132226e[CPU0 ] interrupt(): gate.type(9) != {5,6,7,14,15}
00014132226e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00014132226e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00014132226i[CPU0 ] CPU is in protected mode (active)
00014132226i[CPU0 ] CS.mode = 16 bit
00014132226i[CPU0 ] SS.mode = 16 bit
00014132226i[CPU0 ] EFER   = 0x00000000
00014132226i[CPU0 ] | EAX=60000022  EBX=00000000  ECX=00090002  EDX=00000000
00014132226i[CPU0 ] | ESP=00000004  EBP=0000ff53  ESI=000e0000  EDI=0000ffac
00014132226i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00014132226i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00014132226i[CPU0 ] |  CS:0000( 0004| 0|  0) 00000000 0000ffff 0 0
00014132226i[CPU0 ] |  DS:7c00( 0005| 0|  0) 0007c000 0000ffff 0 0
00014132226i[CPU0 ] |  SS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00014132226i[CPU0 ] |  ES:0800( 0005| 0|  0) 00008000 0000ffff 0 0
00014132226i[CPU0 ] |  FS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00014132226i[CPU0 ] |  GS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00014132226i[CPU0 ] | EIP=0000fd6a (0000fd6a)
00014132226i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00014132226i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00014132226e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00014132226i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00014132226i[CPU0 ] cpu hardware reset
00014132226i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x0000fee00000
00014132226i[CPU0 ] CPUID[0x00000000]: 00000005 756e6547 6c65746e 49656e69
00014132226i[CPU0 ] CPUID[0x00000001]: 00000633 00010800 00002028 1fcbfbff
00014132226i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00014132226i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00014132226i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00014132226i[CPU0 ] CPUID[0x00000005]: 00000040 00000040 00000003 00000020
00014132226i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000
00014132226i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000101 2a100000
00014132226i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00014132226i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00014132226i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00014132226i[CPU0 ] CPUID[0x80000005]: 01ff01ff 01ff01ff 40020140 40020140
00014132226i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
00014132226i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
00014132226i[CPU0 ] CPUID[0x80000008]: 00003028 00000000 00000000 00000000
00014132226i[     ] reset of 'pci' plugin device by virtual method
00014132226i[     ] reset of 'pci2isa' plugin device by virtual method
00014132226i[     ] reset of 'cmos' plugin device by virtual method
00014132226i[     ] reset of 'dma' plugin device by virtual method
00014132226i[     ] reset of 'pic' plugin device by virtual method
00014132226i[     ] reset of 'pit' plugin device by virtual method
00014132226i[     ] reset of 'floppy' plugin device by virtual method
00014132226i[     ] reset of 'vga' plugin device by virtual method
00014132226i[     ] reset of 'acpi' plugin device by virtual method
00014132226i[     ] reset of 'ioapic' plugin device by virtual method
00014132226i[     ] reset of 'keyboard' plugin device by virtual method
00014132226i[     ] reset of 'harddrv' plugin device by virtual method
00014132226i[     ] reset of 'pci_ide' plugin device by virtual method
00014132226i[     ] reset of 'unmapped' plugin device by virtual method
00014132226i[     ] reset of 'biosdev' plugin device by virtual method
00014132226i[     ] reset of 'speaker' plugin device by virtual method
00014132226i[     ] reset of 'extfpuirq' plugin device by virtual method
00014132226i[     ] reset of 'parallel' plugin device by virtual method
00014132226i[     ] reset of 'serial' plugin device by virtual method
00014132226i[     ] reset of 'gameport' plugin device by virtual method
00014132226i[     ] reset of 'iodebug' plugin device by virtual method
00014132226i[     ] reset of 'usb_uhci' plugin device by virtual method
00014132227i[CPU0 ] CPU is in real mode (active)
00014132227i[CPU0 ] CS.mode = 16 bit
00014132227i[CPU0 ] SS.mode = 16 bit
00014132227i[CPU0 ] EFER   = 0x00000000
00014132227i[CPU0 ] | EAX=00000000  EBX=00000000  ECX=00000000  EDX=00000000
00014132227i[CPU0 ] | ESP=00000000  EBP=00000000  ESI=00000000  EDI=00000000
00014132227i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
00014132227i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00014132227i[CPU0 ] |  CS:f000( 1e00| 0|  0) ffff0000 0000ffff 0 0
00014132227i[CPU0 ] |  DS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00014132227i[CPU0 ] |  SS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00014132227i[CPU0 ] |  ES:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00014132227i[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00014132227i[CPU0 ] |  GS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00014132227i[CPU0 ] | EIP=0000fff0 (0000fff0)
00014132227i[CPU0 ] | CR0=0x60000010 CR2=0x00000000
00014132227i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00014132227i[CMOS ] Last time is 1416848421 (Mon Nov 24 14:00:21 2014)
00014132227i[CTRL ] quit_sim called with exit code 0
 
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: Bootloader doesn't appear to load kernel correctly

Post by Nessphoro »

Hard to pin point an exact issue as your code has multiple faults that I shall list out in no particular order an one or all of them might be at fault:
1. No clear compilation mode (is it 16-bit or 32 bit)
2. If its 32 bit then you don't enable the A20 gate and you won't be able to access the first megabyte anyway. And bochs is saying you're in 16 bit protected mode so that doesn't make sense either.
3. If it's in 16 bit mode then why are you linking at 1 megabyte?
M2004
Member
Member
Posts: 65
Joined: Sun Mar 07, 2010 2:12 am

Re: Bootloader doesn't appear to load kernel correctly

Post by M2004 »

Some problems of your boot sector:

1) You need to set segment registers and stack properly for the starters.

2) Missing Bios parameter block / missing valid partition data depending
on the type of boot media (floppy/hdd/hdd emulated usb etc.)
Floppy medias most likely need a valid Bios parameter block.
HDD's (and emulated hdd's ) need valid partition table entries.


Regards
M2004
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Bootloader doesn't appear to load kernel correctly

Post by FallenAvatar »

yvesbastos wrote:Hello,
I'm following Bran's Kernel development tutorial, but with my own bootloader.
If you wrote your own bootloader successfully, you clearly must be able to single step debug your own code. Why are you asking us to do it for you?

- Monk
Post Reply