Is there any way to read the kernel placed on head = 1 with int 13h?

Viewed 165

My bootloader must go to the kernell when I press enter but it doesn't react. Bootloader is located on the first sector of the first track, head - 0, but kernel's address is: sector 3, track -0, head 1.

I even put the kernel on 5th sector of the first track. I already have functions read from floppy and write, tried to read from the head 1 where is located my kernel, and it reads correctly. But when I put in bootloader corresponding head, sector and track, in the read int 13h / ah=02h it doesn't do anything.

BootLoader

readingProcess:
        xor AX, AX     
    mov DS, AX      
    mov BX, 0060h   
    cli           
    mov ss,bx      
    mov sp,ax    
    sti           
    cld

    mov AH, 02h   
    mov AL, 25          
    mov CH, 0           
    mov CL, 3           
    mov DL, 0           
    mov DH, 1               

    mov BX, 0060h
    mov ES, BX
    xor BX, BX

    int 13h

    ;go to kernel
    jmp 0060h:0000h
ret

So, for now I really don't understand how it works, because when I try to write to floppy, to head 1, it should be almost in the middle of my .img file, but it appears me at the beginning of the file. I think that there must be a formula that would help me to get the right track and sector.

1 Answers

After looking at your code, it appears that this is strictly a problem of using the right formula to get the Track(Cylinder), Head and Sector values for a given offset in the disk image file. You want to use the correct values for Int 13h/ah=2 (disk read).

From my previous answer I gave the formula as:

CHS tuples can be mapped to LBA address with the following formula:

LBA = (C × HPC + H) × SPT + (S - 1)

where C, H and S are the cylinder number, the head number, and the sector number

LBA is the logical block address
HPC is the maximum number of heads per cylinder (reported by 
    disk drive, typically 16 for 28-bit LBA)
SPT is the maximum number of sectors per track (reported by
    disk drive, typically 63 for 28-bit LBA)
LBA addresses can be mapped to CHS tuples with the following formula 
    ("mod" is the modulo operation, i.e. the remainder, and "÷" is 
    integer division, i.e. the quotient of the division where any 
    fractional part is discarded):

    C = LBA ÷ (HPC × SPT)
    H = (LBA ÷ SPT) mod HPC
    S = (LBA mod SPT) + 1

Additional information on drive addressing can be found in this Wikipedia article.

For a 1.44MiB floppy there are 2880 sectors total, HPC(Heads per cylinder) is 2, and SPT(Sectors Per Track is 18), and each sector is 512 bytes. What you need is the LBA. The LBA is simply the offset where you write the kernel (in bytes) divided by 512. In your Appender program you place a copy of the kernel at offset 738304. LBA=738304/512=1442.

You just need to convert LBA 1442 to CHS and plug those numbers into the code.

 Formula:
    C = LBA ÷ (HPC × SPT)
    H = (LBA ÷ SPT) mod HPC
    S = (LBA mod SPT) + 1

 We know:
    LBA = 1442
    HPC = 2
    SPT = 18        

Doing substitution we get:

C = 1442 ÷ (2 × 18)
H = (1442 ÷ 18) mod 2
S = (1442 mod 18) + 1

The ÷ means integer division and throw away the remainder (fraction). mod means do the division and keep the remainder, and throw away the whole part.

C = 1442 ÷ (2 × 18) = 40.0555556 = 40
H = (1442 ÷ 18) mod 2 = 80 mod 2 = 0 (80 mod 2 = 40 remainder 0)
S = (1442 mod 18) + 1 = (2) + 1 = 3 (1442 mod 18 = 80 remainder 2)

We now know for LBA 1442 that Cylinder(Track) = 40, Head = 0, Sector = 3. Your code would use those values in the Int 13h/AH=2 BIOS call. You'd place 40 in DH, 0 in CH, and 3 in CL.

You also appear to have placed a copy of the kernel at offset 2048 in the disk image. Offset 2048 is an LBA of 4 (2048/512) Using the formula and values above you'd get Cylinder(Track) = 0, Head = 0, Sector = 5. You'd place 0 in DH, 0 in CH, and 5 in CL.

Special Note: Only sectors numbers start at 1. Cylinders(Tracks) and Heads start at 0.


If you are given Cylinder(Track), Head, and Sector and need to know what LBA that corresponds to on disk the formula is:

LBA = (C × HPC + H) × SPT + (S − 1) 

If you have CHS of (40, 0, 3) with 1.44MiB drive geometry (HPC=2 and SPT=18) the LBA=(40*2+0)*18+(3-1)=1442. 1442*512=738304 would be the disk offset of that sector.

If you have CHS of (0, 0, 5) with 1.44MiB drive geometry (HPC=2 and SPT=18) the LBA=(0*2+0)*18+(5-1)=4. 4*512=2048 would be the disk offset of that sector.

These 2 calculations are the reverse of the results calculated in the first section of this answer.

Related