5-FAT12
5-FAT12
( )/10
1 Submission
Turn in your well-formatted and commented source code and a copy of the output as two separate files.
Be ready to discuss your work with me.
2 Introduction
In this lab, you will gain hands-on experience reading a FAT-12 file system. Using information we provide,
you will decode the boot sector by hand. You will then write a program to do this automatically.
2.1 Terms
Sector the smallest unit of transfer; It’s also called a block. There are 512 bytes / sector on a floppy
disk.
Boot sector stores vital information about the file system. The boot sector is laid out in the following
way, starting at the beginning of the disk (logical sector 0, byte 0):
All values are stored as unsigned little-endian numbers unless otherwise specified.
1
ssize_t read(int fd, void *buf, size_t count)
Reads count bytes from the file descriptor fd into the memory location starting at buf. It starts
reading from the current offset into the file. The offset is set to zero if the file has just been opened.
off_t lseek(int fd, off_t offset, int whence)
Sets the offset of the file descriptor fd to offset, depending on whence. If whence is SEEK_SET,
then the offset is figured from the start of the file. If whence is SEEK_CUR, then the offset is relative
to the current offset.
A program to read from the floppy disk is in the compressed file. Given a filename and an offset (in dec-
imal notation), it will print out 32 bytes of hex and ASCII values. For example, ./bytedump image 1536
will produce the following output with this particular floppy image: Note that you have to give the
offset to bytedump in the decimal format, not in Hex.
$./bytedump image 1536
addr value ascii
0x0600 0x31 1
0x0601 0x36 6
0x0602 0x53 S
0x0603 0x45 E
0x0604 0x43 C
.....
0x061e 0x00
0x061f 0x00
The first column is the address (in hexadecimal), and the second is the data at that address (also in
hexadecimal). The third column is the ASCII value of the data, but only if it was fit for printing. We can
see that 0x31 is the ASCII character ’1’, and 0x00 is not printable.
Note that data is stored in the little endian format. This means that the most significant byte comes
last. For example, if we had the output
$./bytedump image 120
addr value ascii
0x0078 0x20
0x0079 0x50 P
We would know that 0x20 is stored at 0x0078, and 0x50 is stored at 0x0079. If we interpret this as
a short value (2 bytes) starting at address 0x0078, then the value is stored as 0x2050, but it represents
0x5020. Similarly, if we were storing an int (4 bytes), the bytes would be stored in reverse order, from
the least significant byte to the most significant byte.
When reading data from the floppy disk into memory, we should be careful to understand the little
endian format. For example, in reading a short value into memory, we should read two bytes from the
file, and then reverse their order, before storing them into memory as a short value. A character is only a
single byte, and hence there is no need for reversing the byte order if we read a single character from the
file.
Alternately, there is a utility in Unix called hexdump that will show the binary contents of a file. This
is useful to inspect a file containing binary data. If you use hexdump -C on the supplied image, the output
will look something like this (use hexdump -C image | less to more easily read it)
2
00000000 eb 3c 90 6d 6b 64 6f 73 66 73 00 00 02 10 01 00 |.<.mkdosfs......|
00000010 02 e0 00 40 0b f0 01 00 12 00 02 00 00 00 00 00 |...@............|
00000020 00 00 00 00 00 00 29 79 d6 c9 3d 20 20 20 20 20 |......)y..= |
...
The first column is the hexadecimal offset into the file. Since each line contains 16 bytes, this will always
end in a 0. The middle 16 columns are the hexadecimal bytes of the file. The third column contains the
ASCII representation of the bytes, or a ’.’ if the byte is not a printable character. For example, the second
byte, having offset 0x01 has value 0x3c corresponding to the character <, while the third byte 0x90 is not
printable, so is rendered as a dot.
3 Exercises
3.1 Decoding the boot sector by hand
(1)(4 pt) Using the supplied program and the offsets in the tables above, find and decode the values for
each of the following fields in the boot sector (remember that it starts at offset 0):
Hex Decimal
Bytes/sector
Sectors/cluster
Root directory entries
Sectors/FAT
Your conversion function should take advantage of bit shifting to reverse the bytes. One sugges-
tion is to take two chars and return a short. Restrict your solution to the bitwise operators (no
multiplication or addition).
Do not write a conversion function for binary to hex or hex to decimal. Let the format string in
printf handle the dirty work. Format strings are described in “man 3 printf”.
3
Do not attempt to generalize the decoding process simply write a function to decode a FAT12 boot
sector one field after another. You shouldn’t use any loops (except possibly for printing the name).
Printing tips:
– When you print out the values, make the values line up in a column (it’s OK to hardcode
spaces). For example, the following would be acceptable:
Sectors/cluster 37
# of FATs 2
Media descriptor 0xA8
When printing out your code, ensure that the lines do not wrap around. Format your source so it
fits within the limits of the printer. Not doing so makes it hard to read which defeats the purpose
of indenting.