Bootloader made to kill
-
Tux
Bootloader made to kill
My friend is making a bootloader for my OS. We can't solve a problem when it loads. It seems that the bootloader doesn't load the kernel in correct sections. Here is the kernel loader part of the 32kb p-mode kernel: ;load kernel.bin from disk to 0x100000 | loads 73KB max.
read:
xor ax,ax ; Floppy Reset BIOS Function
mov dl,[drive] ; Select floppy that was booted from
int 0x13
jc read
mov ax,0xffff
mov es,ax ; Data buffer for file
mov bx,0x10 ; Start of segment
mov ah,2 ; Function to read disk
mov al,17 ; Total sectors to read
mov ch,0 ; Track
mov cl,2 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
jc read
mov ax,0xffff
mov es,ax
mov bx, 0x2210
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,0 ; Track
mov cl,1 ; Sector
mov dh,1 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0x4610
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,1 ; Track
mov cl,1 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0x6A10
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,1 ; Track
mov cl,1 ; Sector
mov dh,1 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0x8E10
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,2 ; Track
mov cl,1 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0xB210
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,2 ; Track
mov cl,1 ; Sector
mov dh,1 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0xD610
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,3 ; Track
mov cl,1 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0xFA10
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,3 ; Track
mov cl,1 ; Sector
mov dh,1 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
read:
xor ax,ax ; Floppy Reset BIOS Function
mov dl,[drive] ; Select floppy that was booted from
int 0x13
jc read
mov ax,0xffff
mov es,ax ; Data buffer for file
mov bx,0x10 ; Start of segment
mov ah,2 ; Function to read disk
mov al,17 ; Total sectors to read
mov ch,0 ; Track
mov cl,2 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
jc read
mov ax,0xffff
mov es,ax
mov bx, 0x2210
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,0 ; Track
mov cl,1 ; Sector
mov dh,1 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0x4610
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,1 ; Track
mov cl,1 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0x6A10
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,1 ; Track
mov cl,1 ; Sector
mov dh,1 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0x8E10
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,2 ; Track
mov cl,1 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0xB210
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,2 ; Track
mov cl,1 ; Sector
mov dh,1 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0xD610
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,3 ; Track
mov cl,1 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
mov ax,0xffff
mov es,ax
mov bx, 0xFA10
mov ah,2 ; Function to read disk
mov al,18 ; Total sectors to read
mov ch,3 ; Track
mov cl,1 ; Sector
mov dh,1 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
-
Nairou
Re:Bootloader made to kill
Why are you loading the kernel to FFFF:0010 ? It's not possible to load the kernel to 0x100000 (the 1 meg mark) from real mode, since the segment:offset scheme is limited to 1 meg of address space. So you'll have to load the kernel into memory somewhere (i.e. just after the bootloader), and then switch to protected mode and move it to 0x100000 afterwards before transferring control to the kernel.
Also, it'd be more efficient to put those disk reads into a loop, rather than repeating each one over and over.
Also, it'd be more efficient to put those disk reads into a loop, rather than repeating each one over and over.
Re:Bootloader made to kill
..
Last edited by Perica on Thu Nov 30, 2006 10:37 pm, edited 1 time in total.
-
pskyboy
Re:Bootloader made to kill
Perica,
Im not sure your correct there i think you'll find in real mode even with the A20 line enabled you can only acces up to 1Mb. The point is when A20 is enabled this gives you 20 Physical address lines and the maximum addressable memory with that is 0x100000 or 1mb.
Im not sure your correct there i think you'll find in real mode even with the A20 line enabled you can only acces up to 1Mb. The point is when A20 is enabled this gives you 20 Physical address lines and the maximum addressable memory with that is 0x100000 or 1mb.
-
distantvoices
- Member

- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:Bootloader made to kill
The a 20 gate is a relict of older times.
When you tell the processor to use the a 20 line, then you can adress more than the from you mentioned 1 mb, because then all 32 adress lines are available. the technical mumbojumbo behind this I can not repeat for now it is too late, but perica is right. I myself have loaded a kernel in RM sucessfully to 1 mb (=0x100000).
stay safe...
When you tell the processor to use the a 20 line, then you can adress more than the from you mentioned 1 mb, because then all 32 adress lines are available. the technical mumbojumbo behind this I can not repeat for now it is too late, but perica is right. I myself have loaded a kernel in RM sucessfully to 1 mb (=0x100000).
stay safe...
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
-
Nairou
Re:Bootloader made to kill
I know how A20 works, but I don't think it works the way you think in real mode. The real mode addressing scheme functions like this:Perica Senjak wrote: Wrong, 0xFFFF:0x0010 is the 1mb mark in RealMode Addressing (0xFFFF << 16 + 0x0010 = 0x00100000);
As long as the A20-Gate is enabled you can load it there.
If you don't know what the A20-Gate is, or don't understand RealMode Addressing..... read this tutorial: http://osdev.neopages.net/tutorials/rm_addressing.php ;D
linear address = (segment << 4) + offset
(Example: Video memory is at address 0xA0000, which is A000:0000 in real mode. (0xA000 << 4) + 0 = 0xA0000)
Given that you only have 16 bits for the segment and offset, that gets you a maximum address of 0x10FFEF. Enabling A20 only gets you 64K above the 1meg mark in real mode. If your kernel is under 64K it may work, but I would consider that to be a special case.
-
pskyboy
Re:Bootloader made to kill
Okay i was wondeing if all 32 lines where available on a modern processor but i couldn't find anything in my books or intel manual specifically stating that.
As for the addressing its quite simple really back in the days of the 286 (so as to avoid the 1Mb limit arguments) you had 20 address lines but 16bit registers. So the idea was to use segments and offsets to access more then 64k of memory.
Now a bit of hex eduction in hex 0-F represents 1 nibble or 4 bits so two hex digits represents 8bits or 1 byte. So if you want to get 20bits you need 5 nibbles or 5 hex digits. this is where the segment offset stuff comes in.
The segment address has an implicit 0 added to the end of its address. So say you have the address 0x7C0:0x100
the segment will actually become 0x07C00 which gives you 5 nibbles or 20 bits. If you then add the offset to it you get 0x07D00.
You will also see that this is why 0x7C00 and 0X7C0 both work. Because when you specify 0x7C00 as an offset you get to the right location and when you specify 0x7C0 as a segment an implict 0 is added and you get 0x7C00.
One other little thing this should now explain why you sometimes see segment:offset written as as the 0 in [] is showing the 0 that the processor adds. This also shows why you can access above 1Mb if there isn't the 20 address line limit as you can add almost a full 64Kb to the highest 20Bit address which would be 0xFFFF0:0xFFFF as you can see this would allow you to access up to 1Mb + 65519bytes
Peter
As for the addressing its quite simple really back in the days of the 286 (so as to avoid the 1Mb limit arguments) you had 20 address lines but 16bit registers. So the idea was to use segments and offsets to access more then 64k of memory.
Now a bit of hex eduction in hex 0-F represents 1 nibble or 4 bits so two hex digits represents 8bits or 1 byte. So if you want to get 20bits you need 5 nibbles or 5 hex digits. this is where the segment offset stuff comes in.
The segment address has an implicit 0 added to the end of its address. So say you have the address 0x7C0:0x100
the segment will actually become 0x07C00 which gives you 5 nibbles or 20 bits. If you then add the offset to it you get 0x07D00.
You will also see that this is why 0x7C00 and 0X7C0 both work. Because when you specify 0x7C00 as an offset you get to the right location and when you specify 0x7C0 as a segment an implict 0 is added and you get 0x7C00.
One other little thing this should now explain why you sometimes see segment:offset written as
Code: Select all
0x7C0[0]:0x100Peter
-
Tux
Re:Bootloader made to kill
The first 17 sectors load without a problem. The rest, something bogs it down, and the code messes up after around 8 or 9 Kb.
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Bootloader made to kill
did you made sure the A20 gate is enabled (and yes, it can be used to load the kernel, but your kernel will be limited to 64K ...) ?
Is the code you posted a part of the 2nd stage bootloader or the bootsector itself ? if bootsector, where is the "55AA" signature and isn't it too large ?
Is the code you posted a part of the 2nd stage bootloader or the bootsector itself ? if bootsector, where is the "55AA" signature and isn't it too large ?
Re:Bootloader made to kill
..
Last edited by Perica on Fri Dec 01, 2006 8:40 pm, edited 2 times in total.
-
Whatever5k
Re:Bootloader made to kill
Perica, I doubt it is true what you are saying (although I don't have any experience with VM86). GRUB is known as a very good boot loader, and it loads the kernel at 1MB physical, too. And I know TheMobieus (sorry Tim, I don't know how your OS is spelled correctly
) for example uses VM86 and it is loaded by GRUB.
Correct me if I am wrong
Correct me if I am wrong
Re:Bootloader made to kill
..
Last edited by Perica on Fri Dec 01, 2006 8:41 pm, edited 1 time in total.
Re:Bootloader made to kill
..
Last edited by Perica on Fri Dec 01, 2006 8:41 pm, edited 1 time in total.
-
Tim
Re:Bootloader made to kill
It's a clash of less than 64KB. It should only be a problem if you're trying to run a DOS app which tries to use the HMA.
