The DS-OS File System


This page will describe the format of the DS-OS file system.  If you would like to know how to create a floppy disk image yourself, then you should read this.  Currently there is no image creation program, so if you want to reassemble DS-OS and create your own image, you'll have to create the image by hand.

How to assemble DS-OS

First of all, you must use the A86 assembler.  You could convert it to TASM if you had too much time on your hands, but there is no need to.  Just do this:

a86 boot.a86
a86 cmd.a86
a86 os.a86

They should all assemble into *.bin files.  After you've made changes to the source code and reassembled it, you must create an empty DS-OS image on a floppy disk.  An empty image is a new image with no files on it.  Then you much put the files onto the disk manually.  It's not as hard as it seems.  We'll take it step by step.

Some things to know first

First understand that DS-OS does not use clusters.  It uses sectors.  Each sector must be 512 bytes.  If they're not, DS-OS can't run on that particular disk.  However, as long as the sector size is 512 bytes, DS-OS will run off of it.  That means that it will run off of the old floppy disks too.  Also, DS-OS uses LBA addresses to address sectors.  An LBA address is simply a linear address(starting at 0) that is used to access sectors.  When it is ready to access a certain sector, it translates the LBA address to the hard disk's native CHS address using the following formulas:

sector   = (LBA mod SPT) + 1
head     = (LBA  /  SPT) mod heads
cylinder = (LBA  /  SPT)  /  heads

The LBA is the LBA address to be converted into CHS.  The SPT is the number of sectors per track.  The heads is the number of heads on the disk.  Using LBA addresses greatly simplifies disk driver code.  From now on when I refer to LBA addresses, you'll know what I mean.  Play around with these formulas by putting in different values in for the LBA variable and see what the results are.

Creating an empty DS-OS IMAGE

Before you start creating an image, you have to understand how a DS-OS formatted floppy disk is layed out.  Here's how:
 
Boot sector
FAT
Root Table
File data
File data
File data
File data
....
....
File data
File data
File data

Note that DS-OS can run off of a hard disk.  But I'll be writing instructions for that later on.  For now let's just stick to floppy disks which have the above format.

How big are each of those sections?  Well, the size of the boot sector is 1 sector.  The size of the file data section is whatever is left over after the boot sector, FAT, and Root Table.  So the question is, how big are the FAT and Root table?  The answer is they can be any size.  DS-OS was designed to run off of any size disk.  Therefore, the size of the FAT and Root Table can change to accomodate different sized disks which would have smaller FATs.  Where are the size of the FAT and Root table stored?

The disk parameter table

In the boot sector of a DS-OS formatted floppy disk, there exists a data structure in a fixed location that holds the parameters and attributes of that particular disk.  The structure starts at offset 2 from the beginning of the boot sector.  It is 12 bytes long, and has the following format:

reserved        db 0       ; reserved for OS.SYS
logical_drive   db 0       ; logical drive of boot drive(HD only)
sectors         db 18      ; # of sectors per track
heads           db 2       ; # of heads
boot_lba        dw 0,0     ; lba address of boot sector
fat_end         dw 13      ; end of fat(relative to base)
root_end        dw 21      ; end of root(relative to base)

The values that are set in these fields are the values that are used for a 3.5 in. floppy disk.  However, they can be changed.  These are just the values that I thought would be best for a 3.5 in. floppy disk.  Here is a description of each field:

The reserved byte is reserved for the operating system kernel.

The logical_drive byte is used only with hard disks.  It contains the logical drive letter(C-Z) which represents the partition on which it is located.  When the user attempts to switch to a logical drive letter of C-Z, the operating system will scan each partition on the first hard disk.  If it finds a partition to be of the DS-OS operating system, it will load the partition's boot sector and retrieve the logical drive that represents that partition to see if it is the one the user(or a program) is requesting.  But more on hard disks later.  Just know that this field should be set to zero when dealing with floppy disks.

The sectors field contains the number of sectors per track on the floppy disk on which it resides.  When formatting a disk for DS-OS, the formatting program(not completed yet) calculates this value and stores it here.

The heads field contains the number of heads present on the floppy disk on which it resides.

The boot_lba field is the LBA address from the beginning of the disk at which the boot sector is stored.  This value is always zero in floppy disks, because the boot sector is always the first sector on the disk disk(LBA 0).  On hard disks, however, the boot sector is not the first sector on the disk.  Therefore, the kernel uses this field as a base from which to access all of the other sections of the file system.

The fat_end is an LBA address relative to the boot sector that marks two things:  the end of the FAT, and the beginning of the root table.  The root table always comes immediately after the end of the FAT.  Therefore, this one field tells us the start of the root table, and allows us to calculate the size of the FAT.  To calculate the size of the fat from this field, just take it and subtract one.  You must subtract one in order to remove the boot sector.  That will give you the size of the FAT in sectors.  More on the FAT later.

The root_end is an LBA address relative to the boot sector that marks the end of the the root table and the beginning of the file data.  To find the size of the root table, just subtract the fat_end field from this field like so:

root_size = (root_end-fat_end)

In a floppy disk(with my configuration), root_end = 21, fat_end = 13, so it looks something like this:

root_size = (   21   -   13  )  =  8 sectors

Note that the fat_end and root_end point to the sector after the last sector.  They do not point to the last sector.

Note: DS-OS does not support subdirectories.  Therefore it has only one root table in which to keep files.  The start of the root table can be found in the fat_end field and the size can be found by subtracting (root_end-fat_end).  These entries are in the disk parameter block as discussed above.

All sectors after the end of the root table are file sectors.

The File Allocation Table(FAT)

The file allocation table(FAT) is very simple.  With the floppy disk configuration that I provided above, the FAT is 12 sectors.  Each sector contains 256 WORDS.  Each WORD represents one file data sector.  Therefore, the FAT represents 12*256=3072 sectors of disk space.  We multiply that by 512 bytes per sector to get 1572864 bytes which is a little over 1.4 megs that the 3.5 in. high density floppy disk holds.  Here are the values that each WORD in the FAT can hold:

0000h        *Free sector; available for use
0001h        *Unavailable or Bad
0002h-FFFEh  *Used sector.  The specific number contained here
              not only marks the sector as being used, but also
              points to the next sector in the file's chain.
FFFFh        *The end of a chain/file

If you've downloaded the image.bin file provided by me on this web page, you'll see that the first 21 sectors are marked as 0001h in the FAT.  This is to let the kernel know that these sectors are unavailable and cannot be used.  What are they used for?  They're used for the (boot_sector+FAT+root_table) = (1+12+8) = 21 sectors.

When a value contained in a FAT entry is between 0002h and FFFEh, that means that the sector is used.  If it is used, then the number contained there points to the next sector in the file's chain.  I probably don't have to explain this any further because most people that are reading this are probably familiar with the way that MS-DOS's system works, which is very similar to this.  Let me know if you want a further explanation.

The Root Directory Table

Immediately after the FAT starts the Root directory table.  With the configuration that I've provided above, it is 8 sectors long.  Each root directory entry is 32 bytes long, so each sector contains 512/32=16 root directory entries.  There are 8 root directory sectors, so a disk formatted with this configuration can have a maximum of 8*16=128 files on it.  You could make it bigger if you wanted to(as big as you want), but I thought that 128 files would be enough.

Here is the format of a root directory table entry(32 bytes):

00h  +--------------------------------------------------------------------+
     |                    File Name Before Extension                      |
10h  +----------------+----------------+--------+--------+----------------+
     |   Extension    |   File Size    | Start  | Atribs |   Reserved     |
20h  +----------------+----------------+--------+--------+----------------+

This is how you would see it in a hex editor.  The File name before extension field is 16 bytes long, and holds the file name without the extension or dot.  The Extension field holds the extension which can be 4 bytes long.  Both the file name and extension fields are padded with spaces if there are unused characters.  The file size field is a dword indicating the file size in bytes.  The Start field is a WORD containing the LBA address of the first sector of the file.  The Attribs field is a WORD containing the various flags and attributes of that file.  Reserved is reserved.

Here are the attributes that go in attribs field of the root table enties:

0000000000000011b
              ||
              |+-------- Readable
              +--------- Writable

Those are the only two flags that are currently supported.  If the readable flag is not set, than the file is not readable.  If the writable bit is not set, than the file is not writable.

Putting it all together to build an image

So, to build a new image, here are the steps you have to do:

  1. Modify any of the source code that you want to change
  2. Assemble them with A86
  3. Copy the boot sector to the image.
  4. Next copy an empty FAT to the image(all zero's) of the size that is specified in the disk parameter table in the boot sector.
  5. Next create an empty root table(all zero's) of the size that is specified in the disk parameter table in the boot sector.
  6. Next create a few entries in the first sector of the root table for two system files(os.sys, cmd.pgrm) and any other programs you wish to add.  Fill out all the fields with the appropriate values.
  7. Then modify the FAT to map out where on the disk you'll be putting the files.  Make sure to terminate the chains with an FFFFh.
  8. Next copy the files to the file data sectors at the location specified in the FAT.
  9. You're done !
If you have any questions, don't hesitate to e-mail me.