Bootloader Help

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.
Warrior

Bootloader Help

Post by Warrior »

Hello again,
I've been trying to write a bootloader (I've used GRUB but want to do this as a learning experience :p) and I've been using Ralphs Browns Interrupt List (HTML format) to help me along the way.

Well I setup my segment segisters (DS, ES, SS, SP)

Now I know that to read from the floppy I must first reset my floppy disk and that it may fail several times. I managed (using RBIL) to write this bit of code to reset the floppy.

Code: Select all

reset_floppy:
; Here we want to reset our floppy so that we can perform read operations on it
; INT 13h Parameters: None
   
   mov ah, 00h
   mov dl, 0
   int 13h
   jc reset_floppy ; Retry if an error occurs
   ret

Now to actually read from the floppy I use int 13h with ah being 02h

Code: Select all

read_floppy:
; Here we want to read sectors off our floppy disk to load our kernel
; INT 13h Parameters: None
   
    mov ax, 1000h
    mov es, ax ; Load 1000h into ES
    mov bx, 0 ; Load 0 into BX
   
    mov ah, 2          ; 02h Function
    mov al, 5          ; Read 5 Sectors
    mov ch, 0          ; Cyclinder
    mov cl, 1          ; Sector
    mov dh, 0          ; Head
    mov dl, 0          ; Drive
    int 13h
   jc read_floppy ; Retry if an error occurs
    ret
After I have performed both of these functions I want to jump to the kernel loaded in the memory like this:

Code: Select all

jmp 1000h:0000 ; Jump to our kernel
Now I copy the bootloader to the first sector of the floppy and the kernel to the second

Now when I boot up my OS, and my video cursor skips one line and it just hangs there.

Any ideas?
AR

Re:Bootloader Help

Post by AR »

I don't remember very well as it's been quite some time but Sector 1 may be the root bootsector not the second one.
Kemp

Re:Bootloader Help

Post by Kemp »

Sector 0 (the first sector) is where the bootloader goes. You should add some code in to display messages at various points so you know how far the code has got before something goes wrong (and whether in fact something *does* go wrong).
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Bootloader Help

Post by Candy »

Kemp wrote: Sector 0 (the first sector) is where the bootloader goes. You should add some code in to display messages at various points so you know how far the code has got before something goes wrong (and whether in fact something *does* go wrong).
No, in fact, sectors start counting at 1. So, you boot from cluster 0, head 0 and sector 1. Good luck.
B.E

Re:Bootloader Help

Post by B.E »

try change the sector number to 2
Warrior

Re:Bootloader Help

Post by Warrior »

Changing the sector number fixed my problem, thanks. When in the kernel I can't perform any instructions like jmp or anything, it's really weird. Is there anything special I need to do?
wacco

Re:Bootloader Help

Post by wacco »

Sounds like the offset given to the compiler is
1) not present, or
2) wrong :)

I assume that your kernel loaded in the second sector is still assembly (x86, nasm) in 16 bit mode (not yet pmode) and you load it at 1000h:0000h (like you said). Which translates to:

[ORG 0x10000]
[BITS 16]

Put this at the beginning of your kernel file if it wasn't there yet, and recompile. If there was something like that and it still doesn't work, a code snippet would be nice :)

HtH && HH

Edit: Oops, said 0x1000, should be 0x10000 (segment x 10h) instead.
Warrior

Re:Bootloader Help

Post by Warrior »

Thanks for your help so far! I still havn't gotten it fixed unfortunately. Here is the code when the boot loader dumps us to the kernel

Code: Select all

[BITS 16]
[ORG 0x10000]
   jmp begin

begin:

   mov ah, 0Eh
   mov al, ':'
   mov bh, 0Fh
   mov bl, 0
   int 10h

   mov ah, 0Eh
   mov al, ')'
   mov bh, 0Fh
   mov bl, 0
   int 10h
      
   jmp $         ;Hang
Kemp

Re:Bootloader Help

Post by Kemp »

Candy wrote:
Kemp wrote: Sector 0 (the first sector) is where the bootloader goes. You should add some code in to display messages at various points so you know how far the code has got before something goes wrong (and whether in fact something *does* go wrong).
No, in fact, sectors start counting at 1. So, you boot from cluster 0, head 0 and sector 1. Good luck.
"The following shows the start of sector 0 of a FAT volume, which contains the BPB:"

From the official docs. Please don't tell me they're wrong or I may have to print it out just so I can burn it ;)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Bootloader Help

Post by Candy »

Kemp wrote:
Candy wrote:
Kemp wrote: Sector 0 (the first sector) is where the bootloader goes. You should add some code in to display messages at various points so you know how far the code has got before something goes wrong (and whether in fact something *does* go wrong).
No, in fact, sectors start counting at 1. So, you boot from cluster 0, head 0 and sector 1. Good luck.
"The following shows the start of sector 0 of a FAT volume, which contains the BPB:"

From the official docs. Please don't tell me they're wrong or I may have to print it out just so I can burn it ;)
OK, in LBA you start at 0 and count linearly. In CHS you start at 1 and count with the CHS counting method (sector first, then head, then cylinder).
Kemp

Re:Bootloader Help

Post by Kemp »

Ok. And lol, you're pretty much single-handedly patching my hard disk knowledge in this thread and the other ;D
Warrior

Re:Bootloader Help

Post by Warrior »

*punt*

Hey, I got it fixed but whenever I try to print anything to the screen it prints weird characters
Loading Kernel..
?g
I was wondering if I had to setup any segment registers again in the second stage or what, this is really weird.

Below is the code for my second stage:

Code: Select all

[BITS 16]
[ORG 0x0000]
   JMP Begin
   
Begin:
   MOV SI, Success
   CALL PutStr
   
   JMP $

PutStr:   
   MOV AH, 0EH
   MOV BH, 00h
   MOV BL, 07h
.nextchar:   
   LODSB   
   OR AL, AL
   JZ .return   
   INT 10h
   JMP .nextchar
.return:
   RETN

Success db 'Welcome to the Kernel!', 13, 10 ,0
AR

Re:Bootloader Help

Post by AR »

If the segment registers contain 0x7c0 and you load the next stage at 0x8000, when the second loader executes LODSB it will read from DS:SI since SI=0x34 (random pick) and DS=0x7c0, you are trying to print the string at 0x7c34.

Realmode code is a never ending battle against the segment registers.
Warrior

Re:Bootloader Help

Post by Warrior »

Wow, this sucks.

Is there any way to get over this issue?

I tried resetting my registers with 0 in AX with nothing, I also tried to XOR out SI and I got a different result.

I'm out of ideas

Edit: I try moving a new value in DS but it results in a even different result. (Setting it to the segment I jumped with btw)
AR

Re:Bootloader Help

Post by AR »

Code: Select all

start:
    mov ax, cs
    mov ds, ax
    mov es, ax
This should work fine, provided you far jumped to the code.
Post Reply