Bootloader does not work on real hardware
Bootloader does not work on real hardware
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)
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.
Re: Bootloader does not work on real hardware
You don't appear to initialize the segment registers.
Re: Bootloader does not work on real hardware
The VBR is loaded by the MBR in memory, it is the one that initializes everything and runs some checks. here is the codeiansjack wrote:You don't appear to initialize the segment registers.
Regards, Bonfra.
Re: Bootloader does not work on real hardware
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.
Re: Bootloader does not work on real hardware
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?Bonfra wrote:BOCHS appears to not support int 13h ah=42
Re: Bootloader does not work on real hardware
Oh... so I need to move also the GDT and the memory map... Ok, thanks I'll try that and let you know.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.
I use an HDD image, I read that it should work but somehow in the console it prints that it isn't.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?
Regards, Bonfra.
Re: Bootloader does not work on real hardware
It should be fine -- the typical BIOS data area only extends from 0x400-0x4ff, unless we're talking about different things.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.
Those who understand Unix are doomed to copy it, poorly.
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Bootloader does not work on real hardware
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.Bonfra wrote:I use an HDD image, I read that it should work but somehow in the console it prints that it isn't.
Re: Bootloader does not work on real hardware
I use every single bit of memory from 0x500 to 0x9FC00-1 so it should be ok right?Minoto wrote:It should be fine -- the typical BIOS data area only extends from 0x400-0x4ff, unless we're talking about different things.
This is my function to read the disk: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.
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.
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Bootloader does not work on real hardware
No! The EBDA can be bigger than 1KiB, so you must check if memory above 0x7FFFF is available before you use it.Bonfra wrote:I use every single bit of memory from 0x500 to 0x9FC00-1 so it should be ok right?
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.Bonfra wrote:This is my function to read the disk:
Re: Bootloader does not work on real hardware
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:No! The EBDA can be bigger than 1KiB, so you must check if memory above 0x7FFFF is available before you use it.
I've used the disk address packet explained here where it lists also the size of the fieldsOctocontrabass wrote: Why is the block count a word and not a byte? You can't transfer more than 127 sectors at once.
When I get back home I'll post the result of this test. (~2/3 hours)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
Regards, Bonfra.
Re: Bootloader does not work on real hardware
Ok, I think I've found the big issue...
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
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)Bonfra wrote:When I get back home I'll post the result of this test. (~2/3 hours)
Code: Select all
dl => 0x80
ebx => 0x20000000
ecx => 0x804
ax => 0x80
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.
Re: Bootloader does not work on real hardware
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).Bonfra wrote:Now I need to do an enormous amount of work to flash the image to a real HDD
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.
Re: Bootloader does not work on real hardware
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.
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.
Re: Bootloader does not work on real hardware
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
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.