Problems with loading the kernel

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
proog
Posts: 4
Joined: Sat May 29, 2010 2:32 pm

Problems with loading the kernel

Post by proog »

First of all, I'm rather new to Assembly on x86, and my understanding of the language is somewhat limited, so please bear with me.

By using examples on the Internet and experimenting with the language, I'm trying to write a very simple bootloader that should load a very simple kernel in real mode. However, I'm having a problem in the loading process. My intention is to have the bootloader occupy the first 512 bytes (naturally) with the kernel following right behind. From what I understand, I can do this by reading the kernel part from the drive into a memory location with interrupt 13 and then jump to that point in memory. This is my bootloader code:

Code: Select all

[ORG 0x7C00]    ; The BIOS loads the boot sector into memory location 0x7C00

mov     ah, 02h ;read function.
mov     al, 1 ;sectors to read.
mov     ch, 0 ;track.
mov     cl, 2 ;sector.
mov     dh, 0 ;head.

mov     bx, 0800h ;kernel memory point
mov     es, bx
mov     bx, 0h

int     13h ;read!
jmp     0800h:0000h ;go to kernel memory point

times 510-($-$$) db 0	;Fill the rest of the files with zeros, until we reach 510 bytes
db 0x55
db 0xAA
This code is supposed to read sector 2 (512+ bytes) into memory, and then jumping to the kernel. The kernel code is this:

Code: Select all

mov si, msgwelcome
print_str:
	lodsb
	cmp al, 0 ;0 is end of string
	je stop
	mov ah, 0Eh ;teletype output
	int 10h ;write!
	jmp print_str ;next char!

stop:
	cli
	hlt

msgwelcome db 'Welcome.', 13, 10, 0
My intention is to simply printing each character in the string and then halting.
I'm using NASM to assemble the two files and writing them to a disk image with dd (on Windows):

Code: Select all

nasm -f bin -o boot.bin boot.asm
nasm -f bin -o kernel.bin kernel.asm
dd if=boot.bin of=run.img
dd if=kernel.bin of=run.img seek=1
After this, I have a "run.img" file of 540 bytes. When booting it with Bochs, however, it boots and seemingly loads something, saying:

Code: Select all

Booting from Floppy...
  _
... and then hanging. The last lines from the Bochs console are as follows:

Code: Select all

00014041543i[BIOS ] Booting from 0000:7c00
00014042376i[FDD  ] partial read() on floppy image returns 28/512
00014088485i[CPU0 ] WARNING: HLT instruction with IF=0!
I have found that when adding [ORG 0x8000] at the start of the kernel source makes it print the string correctly. This, however, does not work when booting it on a real machine. I hope someone can point out the error. :)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Problems with loading the kernel

Post by Combuster »

All addresses depend on a pair of values. Right now, you are making assumptions about the value in DS - the second of the two registers used by lodsb. If you look lodsb in the manual you'll see it does the same as mov AL, [DS:SI]; add SI, 1; only in far less bytes.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
proog
Posts: 4
Joined: Sat May 29, 2010 2:32 pm

Re: Problems with loading the kernel

Post by proog »

I see. It seems to me that I can use

Code: Select all

mov ax, <segment>
mov ds, ax
to assign the segment to DS. How should I determine the segment for the string?
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Problems with loading the kernel

Post by Gigasoft »

DS should be set to 0, since you have org 0x7c00.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Problems with loading the kernel

Post by Combuster »

Have you noticed something odd?

Code: Select all

jmp     0800h:0000h ;go to kernel memory point
(...)
org 0x8000
The offset part seems to differ between your jump, and your file.

Also, do you know how physical addresses are calculated in real mode? In the common case its (segment * 16 + offset) So you can calculate the correct values with a 6-years-old's math knowledge. There are two obvious ways to fix the above problem. In one gigasoft's value works, in the other it doesn't. Consider it homework to discover both ways and figure which one requires what value in DS.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
proog
Posts: 4
Joined: Sat May 29, 2010 2:32 pm

Re: Problems with loading the kernel

Post by proog »

Thank you, both of you.
The offset wasn't originally set in the kernel code, but for some reason it worked when running it in Bochs.

Here's what I've been able to figure out:
The kernel's memory point is at segment 0x800, which equals 2048. 2048*16 + offset 0 = 0x8000, and according to the OSDev article on real mode, "physical address 0x210 can be 0020:0010, 0000:0210, or 0021:0000". I would then say that I could assign 0x0800 to DS for DS:SI to be 0800:message. Is this correct or am I just thick?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Problems with loading the kernel

Post by Combuster »

It's only half the answer. Setting DS to 0x800 or 0 or 0xABCD does not affect the value of message, in each case the linear address is different. The value of message however depends on two other things: the location in the file, and the ORG directive. Since the ORG gets added to all absolute addresses, it is important that you get it right: 0x800:0x0000+message isn't the same address as 0x800:0x8000+message, but it is the same as 0x000:0x8000+message...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: Problems with loading the kernel

Post by qw »

Another issue. You should test if the read succeeded. If it didn't, you should reset the disk system and try again. Attempt to read at least four times. On emulators this is usually not necessary, but on real hardware the first few attempts may fail.
proog
Posts: 4
Joined: Sat May 29, 2010 2:32 pm

Re: Problems with loading the kernel

Post by proog »

Alright, I'll look into the issues, thanks again.
Post Reply