|
|
1.1 root 1: #!/bin/sh 1.1.1.2 ! root 2: # script for creating a compatible DOS HD image for Hatari with ! 3: # a single FAT16 partition of given size, with given contents 1.1 root 4: 5: # defaults for disk attributes 6: diskfile=hd.img # HD image filename 7: partname=DOS # partition name 8: 1.1.1.2 ! root 9: # no args or first arg has non-digit characters? ! 10: if [ $# -lt 1 ] || [ \! -z "$(echo $1|tr -d 0-9)" ]; then 1.1 root 11: name=${0##*/} 12: echo 13: echo "usage: $name <size> [filename] [partition name] [directory]" 14: echo 15: echo "Create an ACSI/IDE harddisk image for Hatari with a single Atari" 16: echo "compatible DOS partition. Arguments are (defaults in parenthesis):" 17: echo "- size: harddisk image size in megabytes, 8-256" 18: echo "- filename: name for the harddisk image ($diskfile)" 19: echo "- partition name: name for that single partition ($partname)" 20: echo "- directory: directory for initial content copied to the image" 21: echo 22: echo "For example:" 23: echo "- 16MB '$diskfile' HD image:" 24: echo " $name 16" 25: echo "- 8MB image with 'TEST' partition having files from content/:" 26: echo " $name 8 8mb-disk.img TEST content/" 27: echo 28: exit 1 29: fi 30: 31: # sfdisk/mkdosfs reside in /sbin 32: PATH=/sbin:$PATH 33: export PATH 34: 35: # check tools 1.1.1.2 ! root 36: if [ -z $(which mkdosfs) ] || [ -z $(which python) ]; then ! 37: echo "ERROR: either mkdosfs or python tool missing!" 1.1 root 38: exit 1 39: fi 40: 41: # check disk size 42: if [ $1 -lt 5 ]; then 43: echo "ERROR: disk size needs to be at least 5 (MB) to work properly." 44: exit 1 45: fi 46: if [ $1 -gt 256 ]; then 47: echo "ERROR: EmuTOS supports only partitions up to 256 (MB)." 48: exit 1 49: fi 1.1.1.2 ! root 50: 1.1 root 51: # disk geometry 1.1.1.2 ! root 52: skip=0 # alignment / "padding" sectors between MBR before partition 1.1 root 53: diskheads=16 1.1.1.2 ! root 54: tracksectors=32 # same as used by mkdosfs 1.1 root 55: sectorsize=512 56: 1.1.1.2 ! root 57: # partition size in sectors: ! 58: # 16*32*512 is 1/4MB -> multiply by 4 to get number of required sectors ! 59: partsectors=$((4*$1*$diskheads*$tracksectors)) 1.1 root 60: 61: # check optional arguments 62: if [ \! -z $2 ]; then 63: diskfile=$2 64: fi 65: if [ \! -z $3 ]; then 66: partname=$3 67: fi 68: if [ \! -z $4 ]; then 69: if [ -z $(which mcopy) ]; then 70: echo "ERROR: mcopy (from Mtools) missing!" 71: exit 1 72: fi 73: contentdir=$4 74: fi 75: 76: # don't overwrite files by accident 77: if [ -f $diskfile ]; then 78: echo "ERROR: given harddisk image already exits. Give another name or remove it:" 79: echo " rm $diskfile" 80: exit 1 81: fi 82: 83: # temporary files 84: tmppart=$diskfile.part 85: 1.1.1.2 ! root 86: error="premature script exit" 1.1 root 87: # script exit/error handling 88: exit_cleanup () 89: { 90: echo 1.1.1.2 ! root 91: if [ -z "$error" ]; then 1.1 root 92: echo "$step) Cleaning up..." 93: else 1.1.1.2 ! root 94: echo "ERROR: $error" 1.1 root 95: echo 1.1.1.2 ! root 96: echo "cleaning up..." 1.1 root 97: echo "rm -f $diskfile" 98: rm -f $diskfile 99: fi 100: echo "rm -f $tmppart" 101: rm -f $tmppart 102: echo "Done." 103: } 104: trap exit_cleanup EXIT 105: 106: echo 107: step=1 1.1.1.2 ! root 108: echo "$step) Creating DOS Master Boot Record / partition table..." ! 109: # See: ! 110: # - http://en.wikipedia.org/wiki/Master_boot_record ! 111: # - http://en.wikipedia.org/wiki/Cylinder-head-sector ! 112: # - http://en.wikipedia.org/wiki/File_Allocation_Table#Boot_Sector ! 113: # For DOS MBR, the values are little endian. ! 114: # ----------- ! 115: python << EOF ! 116: #!/usr/bin/env python ! 117: mbr = bytearray(512) ! 118: ! 119: def set_long(idx, value): ! 120: mbr[idx+0] = value & 0xff ! 121: mbr[idx+1] = value >> 8 & 0xff ! 122: mbr[idx+2] = value >> 16 & 0xff ! 123: mbr[idx+3] = value >> 24 ! 124: ! 125: def set_word(idx, value): ! 126: mbr[idx] = value & 0xff ! 127: mbr[idx+1] = value >> 8 & 0xff ! 128: ! 129: def set_CHS(idx, values): ! 130: c, h, s = values ! 131: print "CHS: %3d,%3d,%3d @ $%x" % (c,h,s,idx) ! 132: mbr[idx] = h ! 133: mbr[idx+1] = (s & 0x3F) | ((c >> 2) & 0xC0) ! 134: mbr[idx+2] = c & 0xFF ! 135: ! 136: def LBA2CHS(lba): ! 137: c = lba / ($tracksectors * $diskheads) ! 138: h = (lba / $tracksectors) % $diskheads ! 139: s = (lba % $tracksectors) + 1 ! 140: return (c,h,s) ! 141: ! 142: # disk size ! 143: sectors = 1 + $skip + $partsectors ! 144: if sectors < 65536: ! 145: set_word(0x13, sectors) ! 146: set_long(0x20, sectors) ! 147: parttype=0x4 ! 148: else: ! 149: set_long(0x20, sectors) ! 150: parttype=0x6 ! 151: ! 152: # reserved sectors = MBR ! 153: mbr[0x0E] = 1 ! 154: ! 155: # CHS information ! 156: set_word(0x0B, $sectorsize) ! 157: mbr[0x0D] = 2 # sectors / cluster ! 158: set_word(0x18, $tracksectors) ! 159: set_word(0x1A, $diskheads) ! 160: ! 161: # non-removable disk ! 162: mbr[0x15] = 0xF8 ! 163: mbr[0x24] = 0x80 ! 164: ! 165: # partition size in sectors ! 166: partsectors = $partsectors - 1 ! 167: # first partition takes all ! 168: offset = 0x1BE ! 169: mbr[offset] = 0x80 # bootable ! 170: mbr[offset+4] = parttype ! 171: # partition start & sector count in LBA ! 172: set_long(offset + 0x08, 1) ! 173: set_long(offset + 0x0C, partsectors) ! 174: # partition start & end in CHS ! 175: set_CHS(offset + 1, LBA2CHS(1)) ! 176: set_CHS(offset + 5, LBA2CHS(partsectors)) ! 177: # 3 last partitions are empty ! 178: for i in (1,2,3): ! 179: offset += 0x10 ! 180: set_long(offset + 0x08, partsectors+1) ! 181: set_long(offset + 0x0C, 0) ! 182: set_CHS(offset + 1, LBA2CHS(partsectors+1)) ! 183: set_CHS(offset + 5, LBA2CHS(partsectors)) ! 184: ! 185: # MBR signature ! 186: mbr[0x1FE] = 0x55 ! 187: mbr[0x1FF] = 0xAA 1.1 root 188: 1.1.1.2 ! root 189: open("$diskfile", "wb").write(bytes(mbr)) 1.1 root 190: EOF 1.1.1.2 ! root 191: # ----------- ! 192: od -t x1 $diskfile 1.1 root 193: 194: echo 195: step=$(($step+1)) 1.1.1.2 ! root 196: echo "$step) Creating an Atari TOS compatible DOS partition..." 1.1 root 197: # mkdosfs keeps the sector count below 32765 when -A is used by increasing 198: # the logical sector size (this is for TOS compatibility, -A guarantees 199: # also 2 sectors / cluster and Atari serial number etc). Mtools barfs 200: # if partition size doesn't divide evenly with its track size. Determine 201: # suitable cluster count & corresponding track size and align (decrease) 202: # the file system sector count accordingly. 203: tracksize=32 1.1.1.2 ! root 204: clustertmp=$((partsectors/2)) ! 205: echo "Sectors: $partsectors, sectors/track: $tracksize, clusters: $clustertmp" 1.1 root 206: while [ $clustertmp -gt 32765 ]; do 207: clustertmp=$((clustertmp/2)) 208: tracksize=$(($tracksize*2)) 209: echo "Doubling sector size as >32765 clusters -> $clustertmp clusters" 210: done 1.1.1.2 ! root 211: sectors=$(($partsectors/$tracksize)) 1.1 root 212: sectors=$(($sectors*$tracksize)) 213: kilobytes=$(($sectors/2)) 1.1.1.2 ! root 214: if [ $sectors -ne $partsectors ]; then ! 215: echo "Align sector count with clusters/sectors/track: $partsectors -> $sectors ($kilobytes kB)" 1.1 root 216: fi 1.1.1.2 ! root 217: echo "mkdosfs -A -F 16 -n $partname -C $tmppart $kilobytes" ! 218: mkdosfs -A -F 16 -n $partname -C $tmppart $kilobytes 1.1 root 219: 220: if [ \! -z $contentdir ]; then 221: echo 222: step=$(($step+1)) 223: # copy contents of given directory to the new partition 224: echo "$step) Copying the initial content to the partition..." 225: echo "MTOOLS_NO_VFAT=1 mcopy -i $tmppart -spmv $contentdir/* ::" 226: MTOOLS_NO_VFAT=1 mcopy -i $tmppart -spmv $contentdir/* :: 227: if [ $? -ne 0 ]; then 1.1.1.2 ! root 228: error="mcopy failed." 1.1 root 229: exit 2 230: fi 231: fi 232: 233: echo 234: step=$(($step+1)) 235: # copy the partition into disk 236: echo "$step) Copying the partition to disk image..." 1.1.1.2 ! root 237: echo "dd if=$tmppart of=$diskfile bs=512 seek=$((1+$skip)) count=$sectors" ! 238: dd if=$tmppart of=$diskfile bs=512 seek=$((1+$skip)) count=$sectors 1.1 root 239: 240: step=$(($step+1)) 241: # cleanup is done by exit_cleanup() trap 1.1.1.2 ! root 242: error=""
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.