Clean up the disk image creation script.
authorcoderain <coderain@sdf.org>
Fri, 17 Feb 2017 21:43:58 +0000 (22:43 +0100)
committercoderain <coderain@sdf.org>
Fri, 17 Feb 2017 21:43:58 +0000 (22:43 +0100)
Makefile
tests/mkfat.sh

index 14e3b73003b6c633ce144df87bf915d9d38faa48..c213b2fbe53e68da3c7cdd11ae5138884f9d10a5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-.PHONY: all clean kernel library
+.PHONY: all clean kernel library tests
 
-all: livecd.iso
+all: livecd.iso tests
 
 kernel:
        $(MAKE) -C kernel all
@@ -8,6 +8,9 @@ kernel:
 library: kernel
        $(MAKE) -C library all
 
+tests:
+       $(MAKE) -C tests all
+
 livecd.iso: kernel library
        mkdir -p livecd
        mkdir -p livecd/boot
@@ -19,4 +22,5 @@ livecd.iso: kernel library
 clean:
        $(MAKE) -C kernel clean
        $(MAKE) -C library clean
+       $(MAKE) -C tests clean
        rm livecd.iso
index c1891f4bb75fe5a27532ffae3b056ced347ecbe9..4a4a06daaf7d7eb2233c7c65ca21d1fc8e0c8555 100755 (executable)
 #
 
 OUTPUT_FILE=floppy.img
+ROOT_DIR_ENTRIES=224
+NUMBER_OF_FATS=2
+TOTAL_SECTORS=2880
+BYTES_PER_SECTOR=512
+
+SECTORS_PER_FAT=$((((TOTAL_SECTORS * 3 / 2) + BYTES_PER_SECTOR - 1) / BYTES_PER_SECTOR))
+FIRST_ROOT_SECTOR=$((1 + NUMBER_OF_FATS * SECTORS_PER_FAT))
+ROOT_DIR_OFFSET=$((FIRST_ROOT_SECTOR * BYTES_PER_SECTOR))
+FIRST_DATA_SECTOR=$((FIRST_ROOT_SECTOR + (ROOT_DIR_ENTRIES * 32) / BYTES_PER_SECTOR))
 
 function get_free_cluster()
 {
     local cluster=2
 
-    while [[ "$cluster" -lt 3072 ]]
+    while [[ "$cluster" -lt $TOTAL_SECTORS ]]
     do
-        local cluster_pair=`dd if=$OUTPUT_FILE skip=$((0x200 + 3 * (cluster / 2))) bs=1 count=3 2>/dev/null | xxd -p`
+        local cluster_pair=`dd if=$OUTPUT_FILE skip=$((BYTES_PER_SECTOR + 3 * (cluster / 2))) bs=1 count=3 2>/dev/null | xxd -p`
 
         if [[ "${cluster_pair:3:1}${cluster_pair:0:2}" == "000" ]] && [[ "$cluster" -ne 2 ]]
         then
@@ -54,7 +63,7 @@ function set_next_cluster()
 
     local cluster=$1
     local value=$(printf "%03X" $2)
-    local cluster_pair=`dd if=$OUTPUT_FILE skip=$((0x200 + 3 * (cluster / 2))) bs=1 count=3 2>/dev/null | xxd -p`
+    local cluster_pair=`dd if=$OUTPUT_FILE skip=$((BYTES_PER_SECTOR + 3 * (cluster / 2))) bs=1 count=3 2>/dev/null | xxd -p`
 
     if [[ "$((cluster % 2))" -eq 0 ]]
     then
@@ -63,26 +72,21 @@ function set_next_cluster()
         cluster_pair="${cluster_pair:0:2}${value:2:1}${cluster_pair:3:1}${value:0:2}"
     fi
 
-    echo $cluster_pair | xxd -r -p | dd conv=notrunc \
-                                        iflag=fullblock \
-                                        oflag=seek_bytes \
-                                        of=$OUTPUT_FILE \
-                                        seek=$((0x200 + 3 * (cluster / 2))) \
-                                        bs=3 \
-                                        count=1 \
-                                        2>/dev/null
-    echo $cluster_pair | xxd -r -p | dd conv=notrunc \
-                                        iflag=fullblock \
-                                        oflag=seek_bytes \
-                                        of=$OUTPUT_FILE \
-                                        seek=$((0x1400 + 3 * (cluster / 2))) \
-                                        bs=3 \
-                                        count=1 \
-                                        2>/dev/null
+    for fat in `seq 0 $((NUMBER_OF_FATS - 1))`
+    do
+        echo $cluster_pair | xxd -r -p | dd conv=notrunc \
+                                            iflag=fullblock \
+                                            oflag=seek_bytes \
+                                            of=$OUTPUT_FILE \
+                                            seek=$((BYTES_PER_SECTOR + fat * SECTORS_PER_FAT + 3 * (cluster / 2))) \
+                                            bs=3 \
+                                            count=1 \
+                                            2>/dev/null
+    done
 }
 
-dd if=/dev/zero of=$OUTPUT_FILE bs=512 count=2880 2>/dev/null
-/sbin/mkfs.vfat $OUTPUT_FILE 2>&1 >/dev/null
+dd if=/dev/zero of=$OUTPUT_FILE bs=$BYTES_PER_SECTOR count=$TOTAL_SECTORS 2>/dev/null
+/sbin/mkfs.vfat -r $ROOT_DIR_ENTRIES -f $NUMBER_OF_FATS -s 1 -S $BYTES_PER_SECTOR $OUTPUT_FILE >/dev/null 2>&1
 
 echo "Created empty FAT12 disk image $OUTPUT_FILE" > /dev/stderr
 
@@ -92,18 +96,24 @@ do
     echo "Copying $file to the disk image..." > /dev/stderr
 
     size=`stat --printf '%s' $file`
-    clusters=$(((size + 511) / 512))
+    clusters=$(((size + BYTES_PER_SECTOR - 1) / BYTES_PER_SECTOR))
     dosname=$(printf '%-8s%-3s' `echo ${file%%.*} | tr 'a-z' 'A-Z'` `echo ${file##*.} | tr 'a-z' 'A-Z'`)
 
-    for ((dirent = 0; dirent < 16; dirent++))
+    if [[ ${#dosname} -ne 11 ]]
+    then
+        echo "Cannot easily create a DOS name for $file" > /dev/stderr
+        continue
+    fi
+
+    for dirent in `seq 0 $((ROOT_DIR_ENTRIES - 1))`
     do
-        if [[ `dd if=$OUTPUT_FILE skip=$((dirent * 32 + 0x2600)) bs=1 count=1 2>/dev/null | xxd -p` == "00" ]]
+        if [[ `dd if=$OUTPUT_FILE skip=$((dirent * 32 + ROOT_DIR_OFFSET)) bs=1 count=1 2>/dev/null | xxd -p` == "00" ]]
         then
             break
         fi
     done
 
-    if [[ $dirent -ge 224 ]]
+    if [[ $dirent -ge $ROOT_DIR_ENTRIES ]]
     then
         echo 'Too many files, sorry.' > /dev/stderr
         exit 1
@@ -125,20 +135,32 @@ do
 
     (
         echo -en "${dosname}\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-        printf '%02X%02X' $((first_cluster % 256)) $((first_cluster / 256)) | xxd -r -p | tr -d '\n'
+        printf '%02X%02X' $((first_cluster & 0xFF)) $((first_cluster >> 8)) | xxd -r -p | tr -d '\n'
         printf "%02X%02X%02X%02X" \
-               $((size % 256)) \
-               $(((size / 256) % 256)) \
-               $(((size / 65536) % 256)) \
-               $(((size / 16777216) % 256)) | xxd -r -p | tr -d '\n'
-    ) | dd conv=notrunc iflag=fullblock of=$OUTPUT_FILE seek=$((304 + dirent)) bs=32 count=1 2>/dev/null
+               $((size & 0xFF)) \
+               $(((size >> 8) & 0xFF)) \
+               $(((size >> 16) & 0xFF)) \
+               $(((size >> 24) & 0xFF)) | xxd -r -p | tr -d '\n'
+    ) | dd conv=notrunc \
+           iflag=fullblock \
+           of=$OUTPUT_FILE \
+           seek=$(((ROOT_DIR_OFFSET / 32) + dirent)) \
+           bs=32 \
+           count=1 \
+           2>/dev/null
 
     current_cluster=$first_cluster
 
     for ((i = 0; i < $clusters; i++))
     do
         echo "Writing cluster #$i of $file to cluster $current_cluster" > /dev/stderr
-        dd conv=notrunc if=$file of=$OUTPUT_FILE skip=$i seek=$((31 + current_cluster)) bs=512 count=1 2>/dev/null
+        dd conv=notrunc \
+           if=$file \
+           of=$OUTPUT_FILE \
+           skip=$i \
+           seek=$((FIRST_DATA_SECTOR + current_cluster)) \
+           bs=$BYTES_PER_SECTOR count=1 \
+           2>/dev/null
 
         set_next_cluster $current_cluster 4095