Page 1 of 3

Bootloader made to kill

Posted: Mon Apr 14, 2003 4:54 pm
by Tux
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

Re:Bootloader made to kill

Posted: Tue Apr 15, 2003 12:03 am
by Nairou
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.

Re:Bootloader made to kill

Posted: Tue Apr 15, 2003 12:15 am
by Perica
..

Re:Bootloader made to kill

Posted: Tue Apr 15, 2003 1:33 pm
by pskyboy
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.

Re:Bootloader made to kill

Posted: Tue Apr 15, 2003 2:22 pm
by distantvoices
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...

Re:Bootloader made to kill

Posted: Tue Apr 15, 2003 2:22 pm
by Nairou
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
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:

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.

Re:Bootloader made to kill

Posted: Tue Apr 15, 2003 3:37 pm
by pskyboy
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

Code: Select all

0x7C0[0]:0x100
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

Re:Bootloader made to kill

Posted: Tue Apr 15, 2003 6:19 pm
by Tux
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.

Re:Bootloader made to kill

Posted: Wed Apr 16, 2003 3:23 am
by Pype.Clicker
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 ?

Re:Bootloader made to kill

Posted: Wed Apr 16, 2003 4:12 am
by Perica
..

Re:Bootloader made to kill

Posted: Wed Apr 16, 2003 4:37 am
by Whatever5k
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

Re:Bootloader made to kill

Posted: Wed Apr 16, 2003 5:20 am
by Perica
..

Re:Bootloader made to kill

Posted: Wed Apr 16, 2003 5:53 am
by df
there is no clash with vm86 and having a kernel at 1mb.

Re:Bootloader made to kill

Posted: Wed Apr 16, 2003 6:18 am
by Perica
..

Re:Bootloader made to kill

Posted: Wed Apr 16, 2003 12:18 pm
by Tim
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.