[SOLVED] Bootloader Problem

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
azurfire
Posts: 5
Joined: Sat Jul 26, 2008 1:29 pm

[SOLVED] Bootloader Problem

Post by azurfire »

I'm trying to make a bootloader and I'm running into a little trouble with loading the kernel into memory and then jumping to it. I believe I've figured out how to read the disk, just not where to read it to and then how to jump to it.

Is there anything the bootloader needs to do other than load and then jump to the kernel? Such as enter protected mode or enable A20? All mine does is switch the screen mode and draw a pixel. Here is my code for the bootloader so far:

Code: Select all

BITS 16
ORG 7C00h ;BIOS jumps to 7C00

JMP short START
START:

;**********Switch Screen Mode**********
;switch to screen mode 13
MOV AH, 00h ;set interrupt 10h to  change screen mode
MOV AL, 13h ;screen mode 13
INT 10h ;switch the mode
;**********Switch Screen Mode**********


;**********Draw Pixel**********
MOV DX, 0A000h ;move screen address into data register
MOV ES, DX ;move screen address from data register for STOSB
MOV DI, 0F9FFh ;set drawing offset
MOV AL, 10 ;select the color of the pixel
STOSB ;transfer byte from register AL to ES:DI
;**********Draw Pixels**********

MOV BX, ????
MOV ES, BX
MOV BX, ???? 

MOV AH, 02 ;read sectors into memory
MOV AL, 17 ;read 17 sectors
MOV CH, 00 ;track 0
MOV CL, 02 ;sector 2
MOV DH, 01 ;head number 1
MOV DL, 00 ;drive number 0
INT 13h

JMP ????

LOOP: JMP LOOP ;endless loop

TIMES 0200h - 2 - ($ - $$) DB 0 ;fill all but last two bytes of first sector
DW 0AA55h ;last two bytes myst be 0xAA and 0x55 inorder to be bootable
I'm unsure what I should place in ES and BX when loading the kernel (the '????'s) Everything I have tried has given me errors such as prefetch: EIP [00010000] > CS.limit [0000ffff]

If anyone can't tell, I'm new to this, so I was also wondering where people figured out what they had to do to make an OS, other than tutorials. I've followed some tutorials on making kernels, but I feel that I don't actually learn very much from them. For example: what is a GDT, why do you need it, how you know it's implemented properly, its structure, etc.

Thanks.
Last edited by azurfire on Sat Jul 26, 2008 9:33 pm, edited 3 times in total.
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: Custom Bootloader Question

Post by 01000101 »

shouldn't the floppy track be 0x00 instead of 1?
I'm pretty sure that the track/heads starts at 0 and flops every 18 sectors, and then every 2 track/head flops the cylinder incriments.
azurfire
Posts: 5
Joined: Sat Jul 26, 2008 1:29 pm

Re: Custom Bootloader Question

Post by azurfire »

The floppy track is set to 0x00, I just had an incorrect comment. Any ideas?

Thanks.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: Bootloader Problem

Post by bewing »

You are in Real Mode, so the memory addresses that are available are quite limited. See http://wiki.osdev.org/Memory_Map_%28x86%29 for details. You will want to load the kernel somewhere between physical address 0x8000 (32K) and 0x80000 (512K), most likely. There is no real reason to pick one address over another. It's your OS. Just pick one. And make sure you understand how to use the segment registers in Real Mode.

Technically, all the bootloader must do is load the kernel. However, there are several more things that it is often best to do before you jump to the kernel. See the article bootloader for some suggestions. Generally they will include setting A20, getting an E820 memory map, getting PCI info, getting VBE info, setting Protected Mode, perhaps getting APM info, perhaps getting PnP info, perhaps getting ACPI info.
azurfire
Posts: 5
Joined: Sat Jul 26, 2008 1:29 pm

Re: Bootloader Problem

Post by azurfire »

Ok, thanks.

So if I want to load it at 0x8000, I could do this:

Code: Select all

MOV BX, 0x0800
MOV ES, BX
MOV BX, 0x0000
so ES:BX = 0x0800:0x0000 = 0x8000

and then after loading, I jump to it like this?

Code: Select all

JMP 0x0800:0x0000
It loads the data into memory okay, but on the jump, I get
"write_virtual_checks(): write beyond limit, r/w" spammed in BOCHS
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: Bootloader Problem

Post by bewing »

Hmmmm. Well, in your code, you need to set up a stack somewhere in memory, too -- but that's not your problem here.

I would think that a better "far jump" to use would be JMP 0:0x8000 -- you really don't want to go around setting CS to some funky value that your kernel will choke on, because it doesn't expect it.

But I'm having trouble understanding why bochs would be giving you that particular error. You might want to post the end of your bochs log file here, for everyone to peruse.
azurfire
Posts: 5
Joined: Sat Jul 26, 2008 1:29 pm

Re: Bootloader Problem

Post by azurfire »

Grrr...stupid mistake. I added something like "TIMES 128 DB 65" at the end of the code that I was copying into memory, saved the memory from Bochs, and then searched for the characters and didn't find them.

Turns out I was copying from the wrong floppy head. A site I had read said that the second sector was located on head 1. I guess not. So I switched the head from 1 to 0 and it works now.

Thanks anyway :)
haroldmei
Posts: 1
Joined: Wed Oct 01, 2008 10:54 am

Re: [SOLVED] Bootloader Problem

Post by haroldmei »

I had a similar problem.
I compiled a linux0.11 kernel and run on bochs2.3.1,
but it didn't work.
The end of the log file is:

00016897027i[BIOS ] int13_harddisk: function 15, unmapped device for ELDL=81
00017851068e[CPU0 ] prefetch: EIP [000a0000] > CS.limit [0009ffff]
00017868919e[CPU0 ] read_virtual_checks(): read beyond limit

Can any one give me suggestions for it?

Thanks very much!
Post Reply