Discussion:
Booting from FAT16
(too old to reply)
James Harris
2021-12-19 22:43:43 UTC
Permalink
I've just started looking at booting from FAT16 and it's proving to be a
bit of a challenge. That's because of what I want it to do and because
space is soooo limited! I've set out my idea below. How does it look to
you?

For nomenclature, the sequence to boot from a hard disk can be seen as

MBR --> VBR --> OSloader

i.e. Master Boot Record (first sector of a disk) loads the Volume Boot
Record (first sector of a partition). It, in turn, loads the (larger) OS
loader which is big enough to include code to do a lot more.

As a reminder, the layout of a FAT16 volume is

<reserved><FATs><rootdir><filespace>

AIUI there are two 'traditional' approaches. One is to make the reserved
area large enough for plenty of code. The other (taken by LILO, IIRC) is
to have the os loader in unmovable sectors of the filespace and to
'hardcode' their location into the VBR.

It is /possible/ for there to be plenty of space in the reserved section
of a FAT volume but that cannot be counted on. AIUI it depends on how it
has been formatted. In an already formatted volume the reserved area
might be only one sector, the VBR itself and nothing else. So I don't
believe I can rely on there being any more than 512 bytes in that space.

I'd also like to avoid the LILO approach. It's a pain when a new OS
loader is installed, requiring something to update the hardcoded block
addresses in the VBR.

So, what can be done?

Going back to the boot steps the MBR will be 'standard', i.e. although
the BIOS will have loaded it to 0x7c00 it will move itself out of the
way (often to 0x600) and load the VBR to 0x7c00. It could be any MBR. It
would not need to be specific to a particular OS.

Effectively, the first point I will get control is when my VBR is loaded
to 0x7c00 and started.

I will then need to load the OS loader but than can be difficult in just
512 bytes as I would like it to be a normal file. No special sectors. No
unmovable sectors. My plan, then, is to split the work as follows.

The VBR will look through the root directory until it finds the OS
loader by name. When it finds it it will load just its first sector and
will transfer control to that sector.

The first sector of the OS loader won't have to include code to read the
root directory again meaning it will /hopefully/! have enough program
space to follow the FAT chain to load more of itself.

So loading would be in at least these parts:

1. VBR finds OS loader file and loads 1st sector of it.

2. OS loader's first sector follows the FAT chain to load more of (maybe
all of) OS loader.

3. The OS loader is then large enough to do whatever's necessary.


That's the plan. What do you think of it? Any better ideas? Suggestions
welcome.
--
James Harris
muta...@gmail.com
2021-12-20 00:49:13 UTC
Permalink
Post by James Harris
That's the plan. What do you think of it? Any better ideas? Suggestions
welcome.
I don't know if there is enough space in a boot sector
to do what you want. Also I think it is better to support
CHS which uses up some space.

I have a FAT-12/16 boot sector you can take code from
if you want it. It's public domain so there is no restriction
on what you use it for, no matter what license you choose.

However, there appears to be a bug in it when used on a
disk with the root sector starting on a non-multiple of
track length.

It's available here:

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/src/pbootsec.asm

BFN. Paul.
Rod Pemberton
2021-12-31 09:37:34 UTC
Permalink
On Fri, 31 Dec 2021 04:22:24 -0500
On Mon, 20 Dec 2021 16:17:40 +0000
Post by James Harris
So far I have a VBR which reads through the root dir, finds the
target file, and loads its first sector.
Why wouldn't you require that the file always be the first entry in
the root dir? ... That conserves space for more code, right? ...
Most OSes have special utilities which you're probably aware of that
place system files and structures into their proper locations on the
hard disk. Yes?
So, I'd think that a simple utility should be able to switch two
directory entries, rewrite the first directory entry with the target
file, rewrite the other entry also.
Post by James Harris
I have been working on getting that sector to walk the FAT
Avoiding this "extra" code is obviously the reason other solutions
hard code specific sectors. Well, it could be extra code, if you
avoided doing this.
Post by James Harris
with mkfs.fat (or mkfs.vfat)
(I'm unsure if this is complete ...)
ms-sys /dev/sdc
mkfs.vfat -v -F 16 /dev/sdc1
ms-sys -6 /dev/sdc1
Oops, that's not complete ...

dd if=/dev/zero of=/dev/sdc count=16470 bs=512
fdisk /dev/sdc

/* now the stuff above */

The options used for Linux fdisk were: c n p 1 a t e w

That was for 16470 sectors for 8MB FAT16.

For a floppy, count=1440.

Just an FYI, I'm not sure why I was using fdisk with a floppy
image/disk, but the Linux fdisk options I used were: n p 2 t 11 w.

If you're not familiar with Linux fdisk, you'll have to work through
those Linux fdisk options on your own, as I think some of them required
inputting information, like partition size or starting track number,
etc.

FAT32 was more convoluted.


--
James Harris
2022-01-02 14:59:16 UTC
Permalink
Post by Rod Pemberton
On Fri, 31 Dec 2021 04:22:24 -0500
On Mon, 20 Dec 2021 16:17:40 +0000
Post by James Harris
So far I have a VBR which reads through the root dir, finds the
target file, and loads its first sector.
Why wouldn't you require that the file always be the first entry in
the root dir? ... That conserves space for more code, right? ...
Well, what's best, to make it easy to update the boot files or to make
it difficult? AFAICS it's an open question. I don't know if there is one
right answer.

If I wanted to make it difficult then I could store boot code in special
locations. But the whole point of looking through the root directory is
to treat the OS loader as a normal file so that updates are easier and
the process is more transparent.
Post by Rod Pemberton
Most OSes have special utilities which you're probably aware of that
place system files and structures into their proper locations on the
hard disk. Yes?
I agree that boot steps often use non-standard mechanisms. Whether they
should or not is another matter.

...
Post by Rod Pemberton
Post by James Harris
with mkfs.fat (or mkfs.vfat)
(I'm unsure if this is complete ...)
ms-sys /dev/sdc
mkfs.vfat -v -F 16 /dev/sdc1
ms-sys -6 /dev/sdc1
I'd never heard of ms-sys and it's not part of my distribution but it
looks useful.
Post by Rod Pemberton
Oops, that's not complete ...
dd if=/dev/zero of=/dev/sdc count=16470 bs=512
fdisk /dev/sdc
/* now the stuff above */
I do similar:

dd bs=1024 count=20480 if=/dev/zero of=1-flat.vmdk
sfdisk .... [see below]
sudo losetup --show -Pf 1-flat.vmdk
sudo mkfs.fat -h 2048 /dev/loop???p1 {with ??? replaced}

Then

dd bs=1 count=446 ${DDPARMS} if=mbr of=1-flat.vmdk
dd bs=1 count=2 ${DDPARMS} if=mbr of=1-flat.vmdk skip=510
dd bs=1 count=3 ${DDPARMS} if=vbr of=${PBEG}
dd bs=1 count=450 ${DDPARMS} if=vbr of=${PSTA} skip=62

where
DDPARAMS is conv=notrunc status=none
PBEG is 1-flat.vmdk seek=$(( 2048 * 512 ))
PSTA is 1-flat.vmdk seek=$(( 2048 * 512 + 62 ))

Block 2048 is where the partition begins.
Post by Rod Pemberton
The options used for Linux fdisk were: c n p 1 a t e w
That was for 16470 sectors for 8MB FAT16.
For a floppy, count=1440.
Just an FYI, I'm not sure why I was using fdisk with a floppy
image/disk, but the Linux fdisk options I used were: n p 2 t 11 w.
If you're not familiar with Linux fdisk, you'll have to work through
those Linux fdisk options on your own, as I think some of them required
inputting information, like partition size or starting track number,
etc.
Rather than controlling fdisk manually one can recreate a partition
table from a text file. For example, I use

sfdisk 1-flat.vmdk <<END
label: dos
label-id: 0xe70bb971
device: 1-flat.vmdk
unit: sectors
1-flat.vmdk1 : start= 2048, size= 79872, type=6, bootable
END

The text file can be created by hand or by

sfdisk --dump

or option O once in fdisk.
--
James Harris
s***@yahoo.com
2021-12-20 04:54:43 UTC
Permalink
Post by James Harris
I've just started looking at booting from FAT16 and it's proving to be a
bit of a challenge. That's because of what I want it to do and because
space is soooo limited! I've set out my idea below. How does it look to
you?
For nomenclature, the sequence to boot from a hard disk can be seen as
MBR --> VBR --> OSloader
i.e. Master Boot Record (first sector of a disk) loads the Volume Boot
Record (first sector of a partition). It, in turn, loads the (larger) OS
loader which is big enough to include code to do a lot more.
As a reminder, the layout of a FAT16 volume is
<reserved><FATs><rootdir><filespace>
AIUI there are two 'traditional' approaches. One is to make the reserved
area large enough for plenty of code. The other (taken by LILO, IIRC) is
to have the os loader in unmovable sectors of the filespace and to
'hardcode' their location into the VBR.
It is /possible/ for there to be plenty of space in the reserved section
of a FAT volume but that cannot be counted on. AIUI it depends on how it
has been formatted. In an already formatted volume the reserved area
might be only one sector, the VBR itself and nothing else. So I don't
believe I can rely on there being any more than 512 bytes in that space.
I'd also like to avoid the LILO approach. It's a pain when a new OS
loader is installed, requiring something to update the hardcoded block
addresses in the VBR.
So, what can be done?
Going back to the boot steps the MBR will be 'standard', i.e. although
the BIOS will have loaded it to 0x7c00 it will move itself out of the
way (often to 0x600) and load the VBR to 0x7c00. It could be any MBR. It
would not need to be specific to a particular OS.
Effectively, the first point I will get control is when my VBR is loaded
to 0x7c00 and started.
I will then need to load the OS loader but than can be difficult in just
512 bytes as I would like it to be a normal file. No special sectors. No
unmovable sectors. My plan, then, is to split the work as follows.
The VBR will look through the root directory until it finds the OS
loader by name. When it finds it it will load just its first sector and
will transfer control to that sector.
The first sector of the OS loader won't have to include code to read the
root directory again meaning it will /hopefully/! have enough program
space to follow the FAT chain to load more of itself.
1. VBR finds OS loader file and loads 1st sector of it.
2. OS loader's first sector follows the FAT chain to load more of (maybe
all of) OS loader.
3. The OS loader is then large enough to do whatever's necessary.
That's the plan. What do you think of it? Any better ideas? Suggestions
welcome.
--
James Harris
Q. Is this fat-LFN?
Q. What is the size of the OS?
Q. Are you sure the VBR cannot be made to load the entire OS? - eliminating the separate OS Loader?

The MBR I use is a vanilla ibm ~32 mb with one volume bootable, with the VBR expected at LBA = 20h.
The VBR is at LB 20h, The hobby OS begins at LB 21h and runs for 63.5k, it is outside the file system. The file system directory follows the OS, the file data follows the directory area. The file system is under development, it isn't needed to boot the OS, it will be needed to save data to files and to load utilities. - non fat.

I don't support fat, nor LFN, LFN is covered by ms patents, so I dropped my work on it. But back when I was working with fat, that VBR code was enough to load a hobby os off the fat filesystem --non-lfn.

The VBR that I'm using is of course loaded at 07C00h, it then relocates itself to below the EBDA and continues on to load the OS to 80:0000h, then far jumps to the OS. The self relocation is simple enough, and gets the vbr boot code out of the way of loading the OS, avoiding the possibility of over-writing itself.

Steve
muta...@gmail.com
2021-12-20 05:31:49 UTC
Permalink
I don't support fat, nor LFN, LFN is covered by ms patents,
so I dropped my work on it.
Patents only last 20 years, so LFN should be free from
any patents, if you wanted to restart work on it.

Note that I have public domain FAT code, including LFN
support (provided by someone else) available here:

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/src/fat.c

BFN. Paul.
Alexei A. Frounze
2021-12-20 09:27:34 UTC
Permalink
On Sunday, December 19, 2021 at 2:43:46 PM UTC-8, James Harris wrote:
...
Post by James Harris
I will then need to load the OS loader but than can be difficult in just
512 bytes as I would like it to be a normal file. No special sectors. No
unmovable sectors.
Not too difficult (beware of the overflow bug, though).
https://github.com/alexfru/BootProg

Alex
Rod Pemberton
2021-12-31 09:22:06 UTC
Permalink
On Sun, 19 Dec 2021 22:43:43 +0000
Post by James Harris
I've just started looking at booting from FAT16 and it's proving to
be a bit of a challenge. That's because of what I want it to do and
because space is soooo limited! I've set out my idea below. How does
it look to you?
For nomenclature, the sequence to boot from a hard disk can be seen as
MBR --> VBR --> OSloader
i.e. Master Boot Record (first sector of a disk) loads the Volume
Boot Record (first sector of a partition). It, in turn, loads the
(larger) OS loader which is big enough to include code to do a lot
more.
As a reminder, the layout of a FAT16 volume is
<reserved><FATs><rootdir><filespace>
Ok.

Here you say this is for FAT16, but later on in the thread, you state
Post by James Harris
I'm using my own MBR for now as it made testing easier but the VBR
should work with any normal MBR.
and,
Post by James Harris
So far I have a VBR which reads through the root dir, finds the
target file, and loads its first sector.
If your stuff is actually FAT16, you can study how other DOS and
Windows MBRs and VBRs conserve space here:
https://thestarman.pcministry.com/asm/mbr/index.html

--
Loading...