2

Following link http://www.c-jump.com/CIS24/Slides/FAT/lecture.html say Fat12 file starts at 0x4200, but when I use hexeditor watch the floppy image created by following commands, file seems start at 0x4400, and bootloader assembly code used jmp 0xc400 (0x8000+0x4400). I tried change to jmp 0xc200, seems works as well. Which confuses me.

all:img

boot:
    nasm -o boot.bin ipl.nas
    nasm -o os.bin os.nas
    
img:boot
    dd if=boot.bin of=myos.img count=1 bs=512
    dd if=/dev/zero of=myos.img bs=512 seek=1 skip=1 count=2879
    
copy:
    mkdir -p /tmp/floppy
    sudo mount -o loop myos.img /tmp/floppy -o fat=12
    sleep 1
    sudo cp os.bin /tmp/floppy
    sleep 1
    sudo umount /tmp/floppy
run:copy
    qemu-system-i386 -drive file=myos.img,if=floppy

clean:
    rm *.bin *.img

os.nas starts with

; haribote-os
; TAB=4

        ORG     0xc400          

        MOV     AL,0x13         
        MOV     AH,0x00
        INT     0x10
fin:
        HLT
        JMP     fin

ipl.nas jmp part of code

CMP CH, CYLS
JB readloop ; If CH < CYLS, go to readloop

; Now that you've read it, run haribote.sys!

JMP 0xc400

myos.img at 0x4200 and 0x4400

00004200  00 00 00 00  00 00 00 00
00004210  00 00 00 00  00 00 00 00
00004220  00 00 00 00  00 00 00 00
00004230  00 00 00 00  00 00 00 00


00004400  B0 13 B4 00  CD 10 F4 EB
00004410  00 00 00 00  00 00 00 00

ipl.nas first sector

; haribote-ipl
; TAB=4

CYLS EQU 10     ; How far to read

ORG 0x7c00      ; where this program is loaded

; the following is for a standard FAT12 formatted floppy disk

JMP entry
DB 0x90
DB "HARIBOTE"      ; You can freely write the boot sector name (8     
DW 512             ; one sector size (must be 512)
DB 1               ; cluster size (must be 1 sector)
DW 1               ; where the FAT starts (usually sector 1)
DB 2               ; Number of FATs (must be 2)
DW 224             ; Size of root directory area (usually 224      
DW 2880            ; Size of this drive (must be 2880 sectors)
DB 0xf0            ; Media type (must be 0xf0)
DW 9               ; Length of FAT area (must be 9 sectors)
DW 18              ; how many sectors per track (must be 18)
DW 2               ; number of heads (must be 2)
DD 0               ; Always 0 here because no partition is used
DD 2880            ; write this drive size again
DB 0,0,0x29        ;
DD 0xffffffff      ; probably volume serial number
DB "HARIBOTEOS "   ; Disk name (11 bytes)
DB "FAT12 "        ; Name of format (8 bytes)
RESB 18            ; Reserve 18 bytes for now

; program body

entry:
MOV AX,0          ; Register initialization
MOV SS,AX
MOV SP, 0x7c00
MOV DS,AX

; read disk

MOV AX, 0x0820
MOV ES,AX
MOV CH,0          ; Cylinder 0
MOV DH,0          ; head 0
MOV CL,2          ; sector 2
readloop:
MOV SI,0          ; register to count the number of failures
retry:
MOV AH,0x02 ; AH=0x02 : Disk read
MOV AL,1         ; 1 sector
MOV BX,0
MOV DL,0x00      ; Drive A
INT 0x13         ; Disk BIOS call
JNC next         ; To next if no error occurs
ADD SI,1         ; Add 1 to SI
CMP SI,5         ; Compare SI and 5
JAE error        ; If SI >= 5, go to error
MOV AH,0x00
MOV DL,0x00       ; Drive A
INT 0x13          ; Drive reset
JMP retry
next:
MOV AX,ES         ; Advance address by 0x200
ADD AX, 0x0020
MOV ES,AX         ; ADD ES,0x020 This is because there is no      
ADD CL,1          ; add 1 to CL
CMP CL,18         ; Compare CL with 18
JBE readloop      ; If CL <= 18, go to readloop
MOV CL,1
ADD DH,1
CMP DH,2
JB readloop       ; If DH < 2, go to readloop
MOV DH,0
ADD CH,1
CMP CH, CYLS
JB readloop      ; If CH < CYLS, go to readloop

; Now that you've read it, run haribote.sys!

JMP 0xc400
lewis
  • 51
  • 3
  • Can you send the image? Another recommendation: Open it in 010 Editor (you can download a free trial) and analyze it with the Drive.bt template. It may explain better what is going on. – CherryDT Oct 13 '22 at 12:17
  • 1
    Also, if you jump to some memory before the actual code and that memory happens to be all zeroes, it will "work" as well because it will just run many times the `ADD byte [BX+SI], AL` instruction. If you are lucky and `BX+SI` points to valid memory, it won't immediately crash but instead corrupt something, and if you are _very_ lucky and `AL` is also zero, it won't even do that (unless `BX+SI` is an I/O port maybe). Eventually it will be done with executing all the zeroes and reach the actual code. – CherryDT Oct 13 '22 at 12:19
  • just add more info – lewis Oct 13 '22 at 21:17

2 Answers2

1

The webpage about FAT that you studied, deals with the matter in general and details what constitutes a legal FAT volume. However, an implementation can still make its own choices like about allocation strategies.

Not having your OS.BIN file stored in cluster #2, which corresponds to the very first cluster in the data region, might be considered a surprise. eg. MS-DOS does store its IO.SYS file starting with cluster #2.

It could be a Linux thing because skipping cluster #2 and starting from cluster #3 instead also happens in this superuser Q/A.

The data region starts at offset (1 + 9 + 9 + 14) * 512 = 16896 (0x4200)
Cluster #2 is at 0x4200
Cluster #3 is at 0x4400
...

Use your hex utility on MYOS.IMG to see what is in the first FAT structure at file offset 512.

                               cluster #2         cluster #3
00000200  F0 FF FF 00 F0 FF     free cluster       io.bin
00000200  F0 FF FF F7 FF FF     bad cluster        io.bin
00000200  F0 FF FF ?? F? FF     some file 512+     io.bin
00000200  F0 FF FF FF FF FF     some file 512-     io.bin

I think you can omit the skip=1 mention in the line dd if=/dev/zero of=myos.img bs=512 seek=1 skip=1 count=2879.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
1

Following link ... say Fat12 file starts at 0x4200 ...

It says that the area for files starts at 0x4200 on the disk whose boot sector is shown in chapter 10: A 1440K disk.

On a 720K or 360K disk, the area for files starts at a different offset; you have to calculate the offset from the information in the boot sector.

And the text is talking about the "file storage space", not about the "first file":

Just like a hard disk, multiple files are typically stored on a floppy disk.

The first file on the disk will typically be stored at the start of the file area (0x4200).

However, imagine the following scenario:

  • The disk formatting program (or the disk image creation tool) creates a temporary file; this file will be stored at offset 0x4200.

  • Now your file is copied to the disk. Because the cluster size is 0x200, the next free space is at 0x4200+0x200 = 0x4400.

  • The disk formatting program deletes the temporary file on the disk.

  • In this case, the already existing files (your file at position 0x4400) are NOT moved ...

Please also note that files can be "fragmented": This means that the first 0x200 bytes of a file may be stored at some position (for example 0x5000), the next 0x200 bytes of a file may be stored at a completely different position (for example 0x4800) and the next 0x200 bytes may be stored elsewhere (for example at offset 0xD000).

If you want to create a boot loader that is capable of booting from a file, you must parse the root directory and read out the "starting cluster" to calculate the first sector of the file.

Later, you must parse the FAT to calculate the next sector of the file.

... at least if you don't want to rely on the file to be "unfragmented" and to be stored at a certain offset. (MS-DOS copied the file to a certain offset and the MS-DOS boot loader assumed that the file was found there...)

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38