Picking up
It is assumed that you have followed part I and that you have the following files in your directory.
- boot.img — a link to an image of the file system
- boot.BPB.img — the BIOS Parameter Block
You will also need to know the following parameters discovered by following part I to search the BIOS Parameter Block. You’ll only need a few of these and you can copy them as needed.
…$ BPB_BytsPerSec=512 …$ BPB_SecPerClus=16 …$ BPB_NumFATs=2 …$ BPB_RootEntCnt=512 …$ TotSec=122880 …$ FATSz=32 …$ BPB_RsvdSecCnt=1 …$ BPB_ResvdSecCnt=$BPB_RsvdSecCnt …$ FirstDataSector=97 …$ rootDirStart=$(( $BPB_RsvdSecCnt + $BPB_NumFATs * $FATSz )) …$ RootDirSectors=32 …$ TotSec=114688 …$ FATSz=32
Copying the root directory and the file allocation table
Be sure you have a copy of the root directory.
…$ dd if=boot.img of=boot.rootdir.img bs=512 count=$RootDirSectors skip=$rootDirStart
Also, copy the file allocation table.
…$ dd if=boot.img of=boot.fat.img bs=512 skip=$BPB_RsvdSecCnt count=$FATSz
A quick look at the root directory
The directory entries are 32 bytes long. Take a look at the first twenty entries.
…$ od -A d -t a -N 320 boot.rootdir.img
It will start with something like the following.
0000000 b o o t sp sp sp sp sp sp sp bs nul nul C E 0000016 r H r H nul nul C E r H nul nul nul nul nul nul 0000032 A o nul v nul e nul r nul l nul si nul G a nul 0000048 y nul s nul nul nul del del del del nul nul del del del del 0000064 O V E R L A Y S sp sp sp dle nul nul 7 can 0000080 S J S J nul nul 7 can S J gs nul nul nul nul nul
A new directory entry starts every 32 bytes. (That’s every four lines.) However, files with long names have multiple entries: one for the short name and one or more for the long name. In the above example, the first set of two lines is a short entry for the name of the volume, boot. The next set of two is a long entry for the long name overlays. Read every other byte to find overlays. overlays is considered a long file name because it contains lower-case letters. The third set of two lines is the short entry for overlays, spelled in all capitals as its abbreviated name.
The eleventh (numbered from zero) byte of a directory entry is special. Use the following command to take a look at the directory entry as hex.
…$ od -t -A d a -N 320 boot.rootdir.img
Search for the eleventh byte of each entry.
You should find some of the following:
08
for a volume label,
0f
for a long file name,
10
for a directory, and
20
for an unarchived file.
A quick look at the file allocation table
Open up a link to Wikipedia’s discussion of the file allocation table. It’s nothing more than a collection of linked lists.
Each entry in the file allocation table occupies two bytes and corresponds to a cluster of the file system. Display the first 20 entries.
…$ od -A d -t d2 -N 40 boot.fat.img
The long consecutive sequences of increasing integers map files that are stored consecutively on the disk. In this case you find that the i’th entry (number from 0) of the file allocation table is i+1. -1 indicates the last cluster of file.
Here’s a useful dd command for displaying the next “link” for cluster 50. (100 is 2*50.) Expect to see 51.
…$ od -A d -t d2 -j 100 -N 2 boot.fat.img
Or you could try this.
…$ od -A d -t d2 -j $(( 2 * 50 )) -N 2 boot.fat.img
Finding the file
The /boot directory of your Pi should contain the files issue.txt and COPYING.linux. Use the following command to search for the (short) directory entries for these two files. Don’t whine about having to do a sequential search. That’s also what the operating system does. (On the other hand you could let grep do the search for you.)
…$od -A d -t a boot.rootdir.img | more
Once you have found the offsets of the appropriate short, not long, 32-byte directory entries, copy them using commands similar to the following:
…$dd if=boot.rootdir.img of=filename.direntry.txt bs=1 skip=offset count=32
For example, since the offset for issue.txt is byte 672, you can copy it with the following command. (Gave that one away.)
…$dd if=boot.rootdir.img of=issue.txt.direntry.txt bs=1 skip=672 count=32
This should be give you two files containing directory entries:
- issue.txt.direntry.txt
- COPYING.linux.direntry.txt
Now determine the starting cluster, at offset 26, and file size, at offset 28, of each file. Here is what worked for me for issue.txt .
…$od -A d -j 26 -N 2 -t d2 issue.txt.direntry.txt …$od -A d -j 28 -N 4 -t d4 issue.txt.direntry.txt
You better write these numbers down The two file size numbers should be close to 103 for issue.txt and to 18693 for COPYING.linux. Since clusters are 8192 bytes long, a 18693 byte file would be stored in three cluster.
Reading a cluster
Even through clusters are (on this file system) 8192 bytes long,
the are not stored on 8192-byte boundaries.
The Microsoft EFI FAT32 File System Specification contains
the following formula for finding the starting sector for a
cluster N.
FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector
Since you are only doing this a four (or maybe two) times, the easiest way to
perform this operation would be the use a calculator or some useful Linux
program such as
bc,
python or even
nodejs. But, if you are really determined,
you could use the following bash shell
function.
(Be sure to define BPB_SecPerClus
and FirstDataSector
first.)
function DataSector2Cluster() { local result=$(( ( ( $1 - 2 ) * $BPB_SecPerClus ) + $FirstDataSector )) echo "$result" }
In any case, assume that your have gone through this procedure and have discovered issue_txt_sector, the starting sector address of the file issue.txt, and that your result has been verified by at least one other person. Now execute that one command needed to copy the cluster containing issue.txt and an additional 8000 or more null charaters. Remember, the block size must be 512, the sector size, and that you must copy 16 sectors to read the entire 8192 byte cluster.
Homework 11
You really should try to do this one in the lab today. It is also very similar to the last half of a lab used in the Spring 2015 System Administration course.
Copy the three clusters for the file COPYING.linux and concatenate them into a single file. Next use dd to remove all the extra null characters from the three-cluster file.
Use the history to save a copy of the dd commands you used in this low-level creation of COPYING.linux. Download a copy of these commands to the Homework 11 moodle page by 11:00 PM on Saturday, 29 April.