Bootloader does not work on real hardware

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.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Bootloader does not work on real hardware

Post by Bonfra »

Hi, so I've always debugged my bootloader/os using QEMU, last week I tried to flash it to a real HDD and run it on a real PC but the bootloader seems to get in an infinite loop. I've tested it on VirtualBox since it has an integrated debugger (that sucks but still works) and I got what I thought was the same issue: it was a segment limit problem so after fixing it I straight re-flashed the image to the HDD to test it. The problem was not gone so I started searching for other VMs to debug. BOCHS appears to not support int 13h ah=42 so I went for VMWare and there it seems to be the same issue as the real PC (I hope) so now I'm trying to find this issue but I really can't find anything... May I ask you to check the code for some issue that I can't see?
https://github.com/Bonfra04/BonsOS/blob ... rc/vbr.asm, https://github.com/Bonfra04/BonsOS/blob ... /fat16.inc

So far I've somehow managed to make some commands of GDB work on VMWare and I think I've tracked the issue to this loop (ends at line 251)
Regards, Bonfra.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Bootloader does not work on real hardware

Post by iansjack »

You don't appear to initialize the segment registers.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: Bootloader does not work on real hardware

Post by Bonfra »

iansjack wrote:You don't appear to initialize the segment registers.
The VBR is loaded by the MBR in memory, it is the one that initializes everything and runs some checks. here is the code
Regards, Bonfra.
rdos
Member
Member
Posts: 3297
Joined: Wed Oct 01, 2008 1:55 pm

Re: Bootloader does not work on real hardware

Post by rdos »

You seem to copy the MBR from 7C00 to 7A00 and then you put the stack top at 7A00. I don't think this is safe with a real BIOS since the BIOS data area is in this region, and you are potentially thrashing it. I woudn't assume that anything below the load point is free to use.
sj95126
Member
Member
Posts: 151
Joined: Tue Aug 11, 2020 12:14 pm

Re: Bootloader does not work on real hardware

Post by sj95126 »

Bonfra wrote:BOCHS appears to not support int 13h ah=42
Bochs does support function 0x42 (I use it) but it's not supported for all device types, like floppies. Are you using a floppy image under Bochs, or a HDD image?
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: Bootloader does not work on real hardware

Post by Bonfra »

rdos wrote:You seem to copy the MBR from 7C00 to 7A00 and then you put the stack top at 7A00. I don't think this is safe with a real BIOS since the BIOS data area is in this region, and you are potentially thrashing it. I woudn't assume that anything below the load point is free to use.
Oh... so I need to move also the GDT and the memory map... Ok, thanks I'll try that and let you know.
sj95126 wrote:Bochs does support function 0x42 (I use it) but it's not supported for all device types, like floppies. Are you using a floppy image under Bochs, or a HDD image?
I use an HDD image, I read that it should work but somehow in the console it prints that it isn't.
Regards, Bonfra.
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

Re: Bootloader does not work on real hardware

Post by Minoto »

rdos wrote:You seem to copy the MBR from 7C00 to 7A00 and then you put the stack top at 7A00. I don't think this is safe with a real BIOS since the BIOS data area is in this region, and you are potentially thrashing it. I woudn't assume that anything below the load point is free to use.
It should be fine -- the typical BIOS data area only extends from 0x400-0x4ff, unless we're talking about different things.
Those who understand Unix are doomed to copy it, poorly.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Bootloader does not work on real hardware

Post by Octocontrabass »

Bonfra wrote:I use an HDD image, I read that it should work but somehow in the console it prints that it isn't.
It does work, but only if you pass correct values to INT 0x13. What values are you passing to INT 0x13? Use the debugger to dump all of the registers as well as the disk address packet.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: Bootloader does not work on real hardware

Post by Bonfra »

Minoto wrote:It should be fine -- the typical BIOS data area only extends from 0x400-0x4ff, unless we're talking about different things.
I use every single bit of memory from 0x500 to 0x9FC00-1 so it should be ok right?
Octocontrabass wrote: It does work, but only if you pass correct values to INT 0x13. What values are you passing to INT 0x13? Use the debugger to dump all of the registers as well as the disk address packet.
This is my function to read the disk:

Code: Select all

;***********************************;
; Reads a series of sectors         ;
; Parameters:                       ;
;   dl => bootdrive                 ;
;   ax => sectors count             ;
;   ebx => address to load to       ;
;   ecx => LBA address              ;
; Returns:                          ;
;   cf => set if error              ;
;***********************************;
ReadSectorsLBA:
    mov word [LBA_Packet.block_cout], ax
    mov dword [LBA_Packet.transfer_buffer], ebx
    mov dword [LBA_Packet.lba_value], ecx
    mov si, LBA_Packet
    mov ah, 0x42    ; Read sectors function
    int 0x13
    ret

align 4
LBA_Packet:
    .packet_size     db 0x10 ; use_transfer_64 ? 10h : 18h
    .reserved        db 0x00 ; always zero    
    .block_cout      dw 0x00 ; number of sectors to read
    .transfer_buffer dd 0x00 ; address to load in ram
    .lba_value       dq 0x00 ; LBA addres value   
Regards, Bonfra.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Bootloader does not work on real hardware

Post by Octocontrabass »

Bonfra wrote:I use every single bit of memory from 0x500 to 0x9FC00-1 so it should be ok right?
No! The EBDA can be bigger than 1KiB, so you must check if memory above 0x7FFFF is available before you use it.
Bonfra wrote:This is my function to read the disk:
Why is the block count a word and not a byte? You can't transfer more than 127 sectors at once. If that doesn't fix it, try using the debugger to dump all of the registers as well as the disk address packet. It will be easier to find the problem that way.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: Bootloader does not work on real hardware

Post by Bonfra »

Octocontrabass wrote:No! The EBDA can be bigger than 1KiB, so you must check if memory above 0x7FFFF is available before you use it.
Oops, I've referenced this scheme when I planned memory. How can I check if that memory is available? is there some interrupt for it?
Octocontrabass wrote: Why is the block count a word and not a byte? You can't transfer more than 127 sectors at once.
I've used the disk address packet explained here where it lists also the size of the fields
Octocontrabass wrote: try using the debugger to dump all of the registers as well as the disk address packet. It will be easier to find the problem that way
When I get back home I'll post the result of this test. (~2/3 hours)
Regards, Bonfra.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: Bootloader does not work on real hardware

Post by Bonfra »

Ok, I think I've found the big issue...
Bonfra wrote:When I get back home I'll post the result of this test. (~2/3 hours)
Whenever I call the function ReadSectorsLBA the relevant registers have these values: (I'm examining the case when I read the FAT table in memory)

Code: Select all

dl => 0x80
ebx => 0x20000000
ecx => 0x804
ax => 0x80
DL is the drive to read to and since I boot from HDD is right
EBX is the address where I want to load the FAT
ECX is the LBA address in the disk
and here comes the error...
AX is the number of sectors to read and for some reason, I was loading both the tables in memory so instead, the value should've been 0x40. In fact, with the right calculation (without multiplying by two) it boots up in VMWare.
Now I need to do an enormous amount of work to flash the image to a real HDD so I can't yet post the result for real hardware but at least I wanted to point out this error
Regards, Bonfra.
sj95126
Member
Member
Posts: 151
Joined: Tue Aug 11, 2020 12:14 pm

Re: Bootloader does not work on real hardware

Post by sj95126 »

Bonfra wrote:Now I need to do an enormous amount of work to flash the image to a real HDD
There's a couple of things I did that make testing on real hardware a whole lot easier than flashing a HDD. Like you, I have my own bootloader. (my boot image is just bootblock+secondaryloader+kernel catted together; I don't have filesystem-based boot yet).

First option is to boot from a USB flash drive. I took an older Ubuntu Linux live boot USB drive, I think it's 16.04, one that doesn't force UEFI on you. The beginning of the device has an MBR boot block, which then loads the first sector from partition 1 and jumps to it, just like booting from a hard drive. You should be able to write your image there (e.g. dd if=img of=/dev/sdX1) and boot. I didn't use this option for very long, but it seemed to work.

The other option is PXE (netboot). There's a few PXE packages out there you can use, such as pybootd. This takes a little more work to set up, but makes testing easier, because you can point the boot server directly at your build image and boot at any time.

There were some changes necessary to make this work (for example, because of my boot+kernel blob, PXE can deliver the entire thing at once, so my bootsect has to detect this and not try to load the kernel) but now it's so much easier to test.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: Bootloader does not work on real hardware

Post by Bonfra »

I used to boot my os from a usb stick on an old pc but now in the kernel, I've written an AHCI driver and since it is really bare bone it only read from HDD devices. The image still boots from the usb stick but now to test the AHCI driver I also need to boot it from the HDD (i can boot from the usb and then read the hdd but then I have to write things in fat16 there and is much quicker to just flash the image)
The long process I mentioned was burning a small linux distro to a usb and connect it to my testing pc to burn the image from the ubuntu usb to the installed hdd and then boot from there.
Regards, Bonfra.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: Bootloader does not work on real hardware

Post by Bonfra »

Ok, I've finally tested the OS in the real hardware, and... it doesn't work :(
the VBR seems to work in fact the second stage bootloader prints a string but then nothing, maybe the VBR does not load correctly all the file: the instruction right after the print is a call to a function very deep in the code...
I don't know I need to do some more testing... If you notice something weird in this code let me know but I'm pretty sure about that, maybe is the fact that I assume that the memory that could be used by the EBDA is free, I may need to move around some bits
Regards, Bonfra.
Post Reply