Changeset 04619ba in mainline


Ignore:
Timestamp:
2008-10-27T15:51:10Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fc840d9
Parents:
beb17734
Message:

root directory population

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/mkfat.py

    rbeb17734 r04619ba  
    3535import random
    3636import xstruct
     37import array
    3738
    3839def align_up(size, alignment):
     
    4445        return (((size / alignment) + 1) * alignment)
    4546
    46 def subtree_size(root, cluster_size):
     47def subtree_size(root, cluster_size, dirent_size):
    4748        "Recursive directory walk and calculate size"
    4849       
     
    5859               
    5960                if (os.path.isdir(canon)):
    60                         size += subtree_size(canon, cluster_size)
     61                        size += subtree_size(canon, cluster_size, dirent_size)
    6162                        files += 1
    6263       
    63         return size + align_up(files * 32, cluster_size)
     64        return size + align_up(files * dirent_size, cluster_size)
    6465
    6566def root_entries(root):
     
    6768       
    6869        return len(os.listdir(root))
     70
     71def write_file(path, outf, cluster_size, data_start, fat):
     72        "Store the contents of a file"
     73       
     74        size = os.path.getsize(path)
     75        prev = -1
     76        first = -1
     77       
     78        inf = file(path, "r")
     79        rd = 0;
     80        while (rd < size):
     81                data = inf.read(cluster_size);
     82               
     83                empty_cluster = fat.index(0)
     84               
     85                fat[empty_cluster] = 0xffff
     86                if (prev != -1):
     87                        fat[prev] = empty_cluster
     88                else:
     89                        first = empty_cluster
     90               
     91                prev = empty_cluster
     92               
     93                outf.seek(data_start + empty_cluster * cluster_size)
     94                outf.write(data)
     95                rd += len(data)
     96        inf.close()
     97       
     98        return first, size
     99
     100DIR_ENTRY = """little:
     101        char name[8]               /* file name */
     102        char ext[3]                /* file extension */
     103        uint8_t attr               /* file attributes */
     104        padding[1]                 /* reserved for NT */
     105        uint8_t ctime_fine         /* create time (fine resolution) */
     106        uint16_t ctime             /* create time */
     107        uint16_t cdate             /* create date */
     108        uint16_t adate             /* access date */
     109        padding[2]                 /* EA-index */
     110        uint16_t mtime             /* modification time */
     111        uint16_t mdate             /* modification date */
     112        uint16_t cluster           /* first cluster */
     113        uint32_t size              /* file size */
     114"""
     115
     116def mangle_fname(name):
     117        # FIXME: filter illegal characters
     118        fname = (name.split('.')[0] + '          ').upper()[0:8]
     119        return fname
     120
     121def mangle_ext(name):
     122        # FIXME: filter illegal characters
     123        ext = (name.split('.')[1] + '  ').upper()[0:3]
     124        return ext
     125
     126def create_dirent(name, directory, cluster, size):
     127        dir_entry = xstruct.create(DIR_ENTRY)
     128       
     129        dir_entry.name = mangle_fname(name)
     130        dir_entry.ext = mangle_ext(name)
     131       
     132        if (directory):
     133                dir_entry.attr = 0x30
     134        else:
     135                dir_entry.attr = 0x20
     136       
     137        dir_entry.ctime_fine = 0 # FIXME
     138        dir_entry.ctime = 0 # FIXME
     139        dir_entry.cdate = 0 # FIXME
     140        dir_entry.adate = 0 # FIXME
     141        dir_entry.mtime = 0 # FIXME
     142        dir_entry.mdate = 0 # FIXME
     143        dir_entry.cluster = cluster
     144        dir_entry.size = size
     145       
     146        return dir_entry
     147
     148def recursion(head, root, outf, cluster_size, root_start, data_start, fat):
     149        "Recursive directory walk"
     150       
     151        directory = []
     152        for name in os.listdir(root):
     153                canon = os.path.join(root, name)
     154               
     155                if (os.path.isfile(canon)):
     156                        rv = write_file(canon, outf, cluster_size, data_start, fat)
     157                        directory.append(create_dirent(name, False, rv[0], rv[1]))
     158       
     159        if (head):
     160                outf.seek(root_start)
     161                for dir_entry in directory:
     162                        outf.write(dir_entry.pack())
    69163
    70164BOOT_SECTOR = """little:
     
    96190
    97191EMPTY_SECTOR = """little:
    98         padding[512]
     192        padding[512]               /* empty sector data */
     193"""
     194
     195FAT_ENTRY = """little:
     196        uint16_t next              /* FAT16 entry */
    99197"""
    100198
     
    113211                return
    114212       
     213        fat16_clusters = 4096
     214       
    115215        sector_size = 512
    116216        cluster_size = 4096
    117        
    118         root_size = align_up(root_entries(sys.argv[1]) * 32, sector_size)
    119         size = subtree_size(sys.argv[1], cluster_size)
    120         fat_size = align_up(size / cluster_size * 2, sector_size)
    121        
    122         sectors = (cluster_size + 2 * fat_size + root_size + size) / sector_size
     217        dirent_size = 32
     218        fatent_size = 2
     219        fat_count = 2
     220        reserved_clusters = 2
     221       
     222        # Make sure the filesystem is large enought for FAT16
     223        size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size
     224        while (size / cluster_size < fat16_clusters):
     225                if (cluster_size > sector_size):
     226                        cluster_size /= 2
     227                        size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size
     228                else:
     229                        size = fat16_clusters * cluster_size + reserved_clusters * cluster_size
     230       
     231        root_size = align_up(root_entries(path) * dirent_size, cluster_size)
     232       
     233        fat_size = align_up(align_up(size, cluster_size) / cluster_size * fatent_size, sector_size)
     234       
     235        sectors = (cluster_size + fat_count * fat_size + root_size + size) / sector_size
     236        root_start = cluster_size + fat_count * fat_size
     237        data_start = root_start + root_size
    123238       
    124239        outf = file(sys.argv[2], "w")
     
    130245        boot_sector.cluster = cluster_size / sector_size
    131246        boot_sector.reserved = cluster_size / sector_size
    132         boot_sector.fats = 2
    133         boot_sector.rootdir = root_size / 32
     247        boot_sector.fats = fat_count
     248        boot_sector.rootdir = root_size / dirent_size
    134249        boot_sector.sectors = (sectors if (sectors <= 65535) else 0)
    135250        boot_sector.descriptor = 0xF8
     
    151266        empty_sector = xstruct.create(EMPTY_SECTOR)
    152267       
    153         # Reserved sectors (boot_sector.reserved - boot_sector)
    154         for i in range(1, boot_sector.reserved):
     268        # Reserved sectors
     269        for i in range(1, cluster_size / sector_size):
    155270                outf.write(empty_sector.pack())
    156271       
    157272        # FAT tables
    158         for i in range(0, boot_sector.fats):
     273        for i in range(0, fat_count):
    159274                for j in range(0, boot_sector.fat_sectors):
    160275                        outf.write(empty_sector.pack())
     
    168283                outf.write(empty_sector.pack())
    169284       
     285        fat = array.array('L', [0] * (fat_size / fatent_size))
     286        fat[0] = 0xfff8
     287        fat[1] = 0xffff
     288       
     289        recursion(True, path, outf, cluster_size, root_start, data_start, fat)
     290       
     291        # Store FAT
     292        fat_entry = xstruct.create(FAT_ENTRY)
     293        for i in range(0, fat_count):
     294                outf.seek(cluster_size + i * fat_size)
     295                for j in range(0, fat_size / fatent_size):
     296                        fat_entry.next = fat[j]
     297                        outf.write(fat_entry.pack())
     298       
    170299        outf.close()
    171300       
Note: See TracChangeset for help on using the changeset viewer.