Example #1
0
def recursion(root, outf):
    "Recursive directory walk"

    for item in listdir_items(root):
        if item.is_file:
            dentry = xstruct.create(DENTRY_FILE % len(item.name))
            dentry.kind = TMPFS_FILE
            dentry.fname_len = len(item.name)
            dentry.fname = item.name.encode("ascii")
            dentry.flen = item.size

            outf.write(dentry.pack())

            for data in chunks(item, 4096):
                outf.write(data)

        elif item.is_dir:
            dentry = xstruct.create(DENTRY_DIRECTORY % len(item.name))
            dentry.kind = TMPFS_DIRECTORY
            dentry.fname_len = len(item.name)
            dentry.fname = item.name.encode("ascii")

            outf.write(dentry.pack())

            recursion(item.path, outf)

            dentry = xstruct.create(DENTRY_NONE)
            dentry.kind = TMPFS_NONE
            dentry.fname_len = 0

            outf.write(dentry.pack())
Example #2
0
def main():
    if (len(sys.argv) < 3):
        usage(sys.argv[0])
        return

    path = os.path.abspath(sys.argv[1])
    if (not os.path.isdir(path)):
        print("<PATH> must be a directory")
        return

    outf = open(sys.argv[2], "wb")

    header = xstruct.create(HEADER)
    header.tag = b"TMPFS"

    outf.write(header.pack())

    recursion(path, outf)

    dentry = xstruct.create(DENTRY_NONE)
    dentry.kind = TMPFS_NONE
    dentry.fname_len = 0

    outf.write(dentry.pack())

    outf.close()
Example #3
0
def recursion(root, outf):
    "Recursive directory walk"

    for item in listdir_items(root):
        if item.is_file:
            dentry = xstruct.create(DENTRY_FILE % len(item.name))
            dentry.kind = TMPFS_FILE
            dentry.fname_len = len(item.name)
            dentry.fname = item.name.encode('ascii')
            dentry.flen = item.size

            outf.write(dentry.pack())

            for data in chunks(item, 4096):
                outf.write(data)

        elif item.is_dir:
            dentry = xstruct.create(DENTRY_DIRECTORY % len(item.name))
            dentry.kind = TMPFS_DIRECTORY
            dentry.fname_len = len(item.name)
            dentry.fname = item.name.encode('ascii')

            outf.write(dentry.pack())

            recursion(item.path, outf)

            dentry = xstruct.create(DENTRY_NONE)
            dentry.kind = TMPFS_NONE
            dentry.fname_len = 0

            outf.write(dentry.pack())
Example #4
0
def main():
    if len(sys.argv) < 3:
        usage(sys.argv[0])
        return

    path = os.path.abspath(sys.argv[1])
    if not os.path.isdir(path):
        print("<PATH> must be a directory")
        return

    outf = open(sys.argv[2], "wb")

    header = xstruct.create(HEADER)
    header.tag = b"TMPFS"

    outf.write(header.pack())

    recursion(path, outf)

    dentry = xstruct.create(DENTRY_NONE)
    dentry.kind = TMPFS_NONE
    dentry.fname_len = 0

    outf.write(dentry.pack())

    outf.close()
Example #5
0
	def init_gdt(self):
		"Initialize block group descriptor table"
		
		self.superblock_positions = []
		self.gdt = []
		consumed_blocks_per_group = (1 + self.gdt_blocks +
			    self.inode_bitmap_blocks_per_group +
			    self.block_bitmap_blocks_per_group +
			    self.inode_table_blocks_per_group)
		initial_free_blocks = self.blocks_per_group - consumed_blocks_per_group
		for bg in range(self.block_groups):
			base = bg * self.blocks_per_group
			if (bg == 0):
				base = self.superblock_at_block
				self.superblock_positions.append(1024)
			else:
				self.superblock_positions.append(base * self.block_size)
			self.block_allocator.mark_used_all(range(base, base+consumed_blocks_per_group))
			pos = base + 1 + self.gdt_blocks
			gde = xstruct.create(STRUCT_BLOCK_GROUP_DESCRIPTOR)
			gde.block_bitmap_block = pos
			pos += self.block_bitmap_blocks_per_group
			gde.inode_bitmap_block = pos
			pos += self.inode_bitmap_blocks_per_group
			gde.inode_table_first_block = pos
			gde.free_block_count = initial_free_blocks
			gde.free_inode_count = self.inodes_per_group
			gde.directory_inode_count = 0
			self.gdt.append(gde)
Example #6
0
    def init_gdt(self):
        "Initialize block group descriptor table"

        self.superblock_positions = []
        self.gdt = []
        consumed_blocks_per_group = (1 + self.gdt_blocks +
                                     self.inode_bitmap_blocks_per_group +
                                     self.block_bitmap_blocks_per_group +
                                     self.inode_table_blocks_per_group)
        initial_free_blocks = self.blocks_per_group - consumed_blocks_per_group
        for bg in range(self.block_groups):
            base = bg * self.blocks_per_group
            if (bg == 0):
                base = self.superblock_at_block
                self.superblock_positions.append(1024)
            else:
                self.superblock_positions.append(base * self.block_size)
            self.block_allocator.mark_used_all(
                range(base, base + consumed_blocks_per_group))
            pos = base + 1 + self.gdt_blocks
            gde = xstruct.create(STRUCT_BLOCK_GROUP_DESCRIPTOR)
            gde.block_bitmap_block = pos
            pos += self.block_bitmap_blocks_per_group
            gde.inode_bitmap_block = pos
            pos += self.inode_bitmap_blocks_per_group
            gde.inode_table_first_block = pos
            gde.free_block_count = initial_free_blocks
            gde.free_inode_count = self.inodes_per_group
            gde.directory_inode_count = 0
            self.gdt.append(gde)
Example #7
0
    def pack(self):
        "Pack the inode structure and return the result"

        data = xstruct.create(STRUCT_INODE)
        data.mode = (Inode.TYPE2MODE[self.type] << 12)
        data.mode |= 0x1ff  # ugo+rwx
        data.user_id = 0
        data.size = self.size & 0xFFFFFFFF
        data.group_id = 0
        curtime = int(time.time())
        data.access_time = curtime
        data.modification_time = curtime
        data.creation_time = curtime
        data.deletion_time = 0
        data.usage_count = self.refcount
        data.reserved_512_blocks = self.blocks * (self.fs.block_size // 512)
        data.flags = 0
        blockconv = lambda x: 0 if x == None else x
        data.direct_blocks = list(map(blockconv, self.direct))
        data.indirect_blocks = list(map(blockconv, self.indirect))
        data.version = 0
        data.file_acl = 0
        if self.type == Inode.TYPE_FILE:
            data.size_high = (self.size >> 32)
        else:
            # size_high represents dir_acl in this case
            data.size_high = 0
        data.mode_high = 0
        data.user_id_high = 0
        data.group_id_high = 0
        return data.pack()
Example #8
0
	def pack(self):
		"Pack the inode structure and return the result"
		
		data = xstruct.create(STRUCT_INODE)
		data.mode = (Inode.TYPE2MODE[self.type] << 12)
		data.mode |= 0x1ff # ugo+rwx
		data.user_id = 0
		data.size = self.size & 0xFFFFFFFF
		data.group_id = 0
		curtime = int(time.time())
		data.access_time = curtime
		data.modification_time = curtime
		data.creation_time = curtime
		data.deletion_time = 0
		data.usage_count = self.refcount
		data.reserved_512_blocks = self.blocks * (self.fs.block_size // 512)
		data.flags = 0
		blockconv = lambda x: 0 if x == None else x
		data.direct_blocks = list(map(blockconv, self.direct))
		data.indirect_blocks = list(map(blockconv, self.indirect))
		data.version = 0
		data.file_acl = 0
		if self.type == Inode.TYPE_FILE:
			data.size_high = (self.size >> 32)
		else:
			# size_high represents dir_acl in this case
			data.size_high = 0
		data.mode_high = 0
		data.user_id_high = 0
		data.group_id_high = 0
		return data.pack()
Example #9
0
	def write(self, inode):
		"Write the directory entry into the inode"
		
		head = xstruct.create(STRUCT_DIR_ENTRY_HEAD)
		head.inode = self.inode
		head.skip = self.skip
		head.name_length = len(self.name)
		head.inode_type = self.type
		inode.write(head.pack())
		inode.write(self.name+'\0'.encode())
		inode.align_pos(4)
Example #10
0
    def write(self, inode):
        "Write the directory entry into the inode"

        head = xstruct.create(STRUCT_DIR_ENTRY_HEAD)
        head.inode = self.inode
        head.skip = self.skip
        head.name_length = len(self.name)
        head.inode_type = self.type
        inode.write(head.pack())
        inode.write(self.name + '\0'.encode())
        inode.align_pos(4)
Example #11
0
    def get_or_add_block_indirect(self, block):
        "Get or add a real block to the file (indirect blocks)"

        # Determine the indirection level for the desired block
        level = None
        for i in range(4):
            if block < self.fs.indirect_limits[i]:
                level = i
                break

        assert level != None

        # Compute offsets for the topmost level
        block_offset_in_level = block - self.fs.indirect_limits[level - 1]
        if self.indirect[level - 1] == None:
            self.indirect[level - 1] = self.new_block(data=False)
        current_block = xstruct.create(STRUCT_BLOCK_REFERENCE)
        current_block.block_id = self.indirect[level - 1]
        offset_in_block = block_offset_in_level // self.fs.indirect_blocks_per_level[
            level - 1]

        # Navigate through other levels
        while level > 0:
            assert offset_in_block < self.fs.block_ids_per_block

            level -= 1

            self.fs.seek_to_block(current_block.block_id, offset_in_block * 4)
            current_block.unpack(self.fs.outf.read(4))

            if current_block.block_id == 0:
                # The block does not exist, so alloc one and write it there
                self.fs.outf.seek(-4, os.SEEK_CUR)
                current_block.block_id = self.new_block(data=(level == 0))
                self.fs.outf.write(current_block.pack())

            # If we are on the last level, break here as
            # there is no next level to visit
            if level == 0:
                break

            # Visit the next level
            block_offset_in_level %= self.fs.indirect_blocks_per_level[level]
            offset_in_block = block_offset_in_level // self.fs.indirect_blocks_per_level[
                level - 1]

        return current_block.block_id
Example #12
0
	def get_or_add_block_indirect(self, block):
		"Get or add a real block to the file (indirect blocks)"
		
		# Determine the indirection level for the desired block
		level = None
		for i in range(4):
			if block < self.fs.indirect_limits[i]:
				level = i
				break

		assert level != None
	
		# Compute offsets for the topmost level
		block_offset_in_level = block - self.fs.indirect_limits[level-1];
		if self.indirect[level-1] == None:
			self.indirect[level-1] = self.new_block(data = False)
		current_block = xstruct.create(STRUCT_BLOCK_REFERENCE)
		current_block.block_id = self.indirect[level-1]
		offset_in_block = block_offset_in_level // self.fs.indirect_blocks_per_level[level-1]
	
		# Navigate through other levels
		while level > 0:		
			assert offset_in_block < self.fs.block_ids_per_block
			
			level -= 1
			
			self.fs.seek_to_block(current_block.block_id, offset_in_block*4)
			current_block.unpack(self.fs.outf.read(4))
			
			if current_block.block_id == 0:
				# The block does not exist, so alloc one and write it there
				self.fs.outf.seek(-4, os.SEEK_CUR)
				current_block.block_id = self.new_block(data=(level==0))
				self.fs.outf.write(current_block.pack())
		
			# If we are on the last level, break here as
			# there is no next level to visit
			if level == 0:
				break
		
			# Visit the next level
			block_offset_in_level %= self.fs.indirect_blocks_per_level[level];
			offset_in_block = block_offset_in_level // self.fs.indirect_blocks_per_level[level-1]

		return current_block.block_id
Example #13
0
def create_dotdot_dirent(parent_cluster):
    dir_entry = xstruct.create(DOTDOT_DIR_ENTRY)

    dir_entry.signature = [0x2E, 0x2E]
    dir_entry.name = b"      "
    dir_entry.ext = b"   "
    dir_entry.attr = 0x10

    dir_entry.ctime_fine = 0  # FIXME
    dir_entry.ctime = 0  # FIXME
    dir_entry.cdate = 0  # FIXME
    dir_entry.adate = 0  # FIXME
    dir_entry.mtime = 0  # FIXME
    dir_entry.mdate = 0  # FIXME
    dir_entry.cluster = parent_cluster
    dir_entry.size = 0

    return dir_entry
Example #14
0
def create_dot_dirent(empty_cluster):
	dir_entry = xstruct.create(DOT_DIR_ENTRY)
	
	dir_entry.signature = 0x2e
	dir_entry.name = b'       '
	dir_entry.ext = b'   '
	dir_entry.attr = 0x10
	
	dir_entry.ctime_fine = 0 # FIXME
	dir_entry.ctime = 0 # FIXME
	dir_entry.cdate = 0 # FIXME
	dir_entry.adate = 0 # FIXME
	dir_entry.mtime = 0 # FIXME
	dir_entry.mdate = 0 # FIXME
	dir_entry.cluster = empty_cluster
	dir_entry.size = 0
	
	return dir_entry
Example #15
0
def create_dotdot_dirent(parent_cluster):
    dir_entry = xstruct.create(DOTDOT_DIR_ENTRY)

    dir_entry.signature = [0x2e, 0x2e]
    dir_entry.name = b'      '
    dir_entry.ext = b'   '
    dir_entry.attr = 0x10

    dir_entry.ctime_fine = 0  # FIXME
    dir_entry.ctime = 0  # FIXME
    dir_entry.cdate = 0  # FIXME
    dir_entry.adate = 0  # FIXME
    dir_entry.mtime = 0  # FIXME
    dir_entry.mdate = 0  # FIXME
    dir_entry.cluster = parent_cluster
    dir_entry.size = 0

    return dir_entry
Example #16
0
def create_dirent(name, name83_list, directory, cluster, size):
    short_name, short_ext, lfn = fat_name83(name, name83_list)

    dir_entry = xstruct.create(DIR_ENTRY)

    dir_entry.name = short_name
    dir_entry.ext = short_ext

    if directory:
        dir_entry.attr = 0x30
    else:
        dir_entry.attr = 0x20

    dir_entry.lcase = 0x18
    dir_entry.ctime_fine = 0  # FIXME
    dir_entry.ctime = 0  # FIXME
    dir_entry.cdate = 0  # FIXME
    dir_entry.adate = 0  # FIXME
    dir_entry.mtime = 0  # FIXME
    dir_entry.mdate = 0  # FIXME
    dir_entry.cluster = cluster

    if directory:
        dir_entry.size = 0
    else:
        dir_entry.size = size

    if not lfn:
        return [dir_entry]

    long_name = name.encode("utf_16_le")
    entries = [dir_entry]

    seq = 1
    checksum = lfn_checksum(dir_entry.name + dir_entry.ext)

    while len(long_name) > 0:
        long_entry, long_name = create_lfn_dirent(long_name, seq, checksum)
        entries.append(long_entry)
        seq += 1

    entries.reverse()
    return entries
Example #17
0
def create_dirent(name, name83_list, directory, cluster, size):
    short_name, short_ext, lfn = fat_name83(name, name83_list)

    dir_entry = xstruct.create(DIR_ENTRY)

    dir_entry.name = short_name
    dir_entry.ext = short_ext

    if (directory):
        dir_entry.attr = 0x30
    else:
        dir_entry.attr = 0x20

    dir_entry.lcase = 0x18
    dir_entry.ctime_fine = 0  # FIXME
    dir_entry.ctime = 0  # FIXME
    dir_entry.cdate = 0  # FIXME
    dir_entry.adate = 0  # FIXME
    dir_entry.mtime = 0  # FIXME
    dir_entry.mdate = 0  # FIXME
    dir_entry.cluster = cluster

    if (directory):
        dir_entry.size = 0
    else:
        dir_entry.size = size

    if not lfn:
        return [dir_entry]

    long_name = name.encode('utf_16_le')
    entries = [dir_entry]

    seq = 1
    checksum = lfn_checksum(dir_entry.name + dir_entry.ext)

    while len(long_name) > 0:
        long_entry, long_name = create_lfn_dirent(long_name, seq, checksum)
        entries.append(long_entry)
        seq += 1

    entries.reverse()
    return entries
Example #18
0
def mkuimage(inf_name, outf_name, image_name, load_addr, start_addr, os_type):
	inf = open(inf_name, 'rb')
	outf = open(outf_name, 'wb')

	header = xstruct.create(UIMAGE_HEADER)
	header_size = header.size()

	#
	# Write data
	#
	outf.seek(header_size, os.SEEK_SET)
	data = inf.read()
	data_size = inf.tell()
	data_crc = calc_crc32(data)
	data_tstamp = (int)(os.path.getmtime(inf_name))
	outf.write(data)
	data = ''

	#
	# Write header
	#
	outf.seek(0, os.SEEK_SET)

	header.magic = 0x27051956	# uImage magic
	header.header_crc = 0
	header.c_tstamp = data_tstamp
	header.data_size = data_size
	header.load_addr = load_addr	# Address where to load image
	header.start_addr = start_addr	# Address of entry point
	header.data_crc = data_crc
	header.os = os_type
	header.arch = 2			# ARM
	header.img_type = 2		# Kernel
	header.compression = 0		# None
	header.img_name = image_name.encode('ascii')

	header_crc = calc_crc32(header.pack())
	header.header_crc = header_crc

	outf.write(header.pack())
	outf.close()
Example #19
0
def mkuimage(inf_name, outf_name, image_name, load_addr, start_addr, os_type):
    inf = open(inf_name, 'rb')
    outf = open(outf_name, 'wb')

    header = xstruct.create(UIMAGE_HEADER)
    header_size = header.size()

    #
    # Write data
    #
    outf.seek(header_size, os.SEEK_SET)
    data = inf.read()
    data_size = inf.tell()
    data_crc = calc_crc32(data)
    data_tstamp = (int)(os.path.getmtime(inf_name))
    outf.write(data)
    data = ''

    #
    # Write header
    #
    outf.seek(0, os.SEEK_SET)

    header.magic = 0x27051956  # uImage magic
    header.header_crc = 0
    header.c_tstamp = data_tstamp
    header.data_size = data_size
    header.load_addr = load_addr  # Address where to load image
    header.start_addr = start_addr  # Address of entry point
    header.data_crc = data_crc
    header.os = os_type
    header.arch = 2  # ARM
    header.img_type = 2  # Kernel
    header.compression = 0  # None
    header.img_name = image_name.encode('ascii')

    header_crc = calc_crc32(header.pack())
    header.header_crc = header_crc

    outf.write(header.pack())
    outf.close()
Example #20
0
def create_lfn_dirent(name, seq, checksum):
    "Create LFN directory entry"

    entry = xstruct.create(LFN_DIR_ENTRY)
    name_rest = name[26:]

    if len(name_rest) > 0:
        entry.seq = seq
    else:
        entry.seq = seq | 0x40

    entry.name1 = name[0:10]
    entry.name2 = name[10:22]
    entry.name3 = name[22:26]

    entry.attr = 0x0F
    entry.rec_type = 0
    entry.checksum = checksum
    entry.cluster = 0

    return (entry, name_rest)
Example #21
0
def create_lfn_dirent(name, seq, checksum):
    "Create LFN directory entry"

    entry = xstruct.create(LFN_DIR_ENTRY)
    name_rest = name[26:]

    if len(name_rest) > 0:
        entry.seq = seq
    else:
        entry.seq = seq | 0x40

    entry.name1 = name[0:10]
    entry.name2 = name[10:22]
    entry.name3 = name[22:26]

    entry.attr = 0x0F
    entry.rec_type = 0
    entry.checksum = checksum
    entry.cluster = 0

    return (entry, name_rest)
Example #22
0
	def write_superblock(self, block_group):
		"Write superblock at the current position"
		
		sb = xstruct.create(STRUCT_SUPERBLOCK)
		sb.total_inode_count = self.total_inode_count
		sb.total_block_count = self.total_block_count
		sb.reserved_block_count = 0
		sb.free_block_count = self.block_allocator.free
		sb.free_inode_count = self.inode_allocator.free
		sb.first_block = self.superblock_at_block
		sb.block_size_log2 = num_of_trailing_bin_zeros(self.block_size) - 10
		sb.fragment_size_log2 = sb.block_size_log2
		sb.blocks_per_group = self.blocks_per_group
		sb.fragments_per_group = self.blocks_per_group
		sb.inodes_per_group = self.inodes_per_group
		curtime = int(time.time())
		sb.mount_time = curtime
		sb.write_time = curtime
		sb.mount_count = 0
		sb.max_mount_count = 21
		sb.magic = 0xEF53
		sb.state = 5 # clean
		sb.error_behavior = 1 # continue on errors
		sb.rev_minor = 0
		sb.last_check_time = curtime
		sb.max_check_interval = 15552000 # 6 months
		sb.os = 0 # Linux
		sb.rev_major = 1
		sb.first_inode = self.reserved_inode_count + 1
		sb.inode_size = self.inode_size
		sb.block_group_number = block_group
		sb.features_compatible = 0
		sb.features_incompatible = 2 # filetype
		sb.features_read_only = 0
		sb.uuid = self.uuid.bytes_le
		sb.volume_name = 'Einherjar rdimage\0'
		self.outf.write(bytes(sb.pack()))
Example #23
0
    def write_superblock(self, block_group):
        "Write superblock at the current position"

        sb = xstruct.create(STRUCT_SUPERBLOCK)
        sb.total_inode_count = self.total_inode_count
        sb.total_block_count = self.total_block_count
        sb.reserved_block_count = 0
        sb.free_block_count = self.block_allocator.free
        sb.free_inode_count = self.inode_allocator.free
        sb.first_block = self.superblock_at_block
        sb.block_size_log2 = num_of_trailing_bin_zeros(self.block_size) - 10
        sb.fragment_size_log2 = sb.block_size_log2
        sb.blocks_per_group = self.blocks_per_group
        sb.fragments_per_group = self.blocks_per_group
        sb.inodes_per_group = self.inodes_per_group
        curtime = int(time.time())
        sb.mount_time = curtime
        sb.write_time = curtime
        sb.mount_count = 0
        sb.max_mount_count = 21
        sb.magic = 0xEF53
        sb.state = 5  # clean
        sb.error_behavior = 1  # continue on errors
        sb.rev_minor = 0
        sb.last_check_time = curtime
        sb.max_check_interval = 15552000  # 6 months
        sb.os = 0  # Linux
        sb.rev_major = 1
        sb.first_inode = self.reserved_inode_count + 1
        sb.inode_size = self.inode_size
        sb.block_group_number = block_group
        sb.features_compatible = 0
        sb.features_incompatible = 2  # filetype
        sb.features_read_only = 0
        sb.uuid = self.uuid.bytes_le
        sb.volume_name = 'HelenOS-rd\0\0\0\0\0\0'
        self.outf.write(bytes(sb.pack()))
Example #24
0
def main():
    if (len(sys.argv) < 4):
        usage(sys.argv[0])
        return

    if (not sys.argv[1].isdigit()):
        print("<EXTRA_BYTES> must be a number")
        return

    extra_bytes = int(sys.argv[1])

    path = os.path.abspath(sys.argv[2])
    if (not os.path.isdir(path)):
        print("<PATH> must be a directory")
        return

    fat16_clusters = 4096

    sector_size = 512
    cluster_size = 4096
    dirent_size = 32
    fatent_size = 2
    fat_count = 2
    reserved_clusters = 2

    # Make sure the filesystem is large enough for FAT16
    size = subtree_size(
        path, cluster_size,
        dirent_size) + reserved_clusters * cluster_size + extra_bytes
    while (size // cluster_size < fat16_clusters):
        if (cluster_size > sector_size):
            cluster_size = cluster_size // 2
            size = subtree_size(
                path, cluster_size,
                dirent_size) + reserved_clusters * cluster_size + extra_bytes
        else:
            size = fat16_clusters * cluster_size + reserved_clusters * cluster_size

    root_size = align_up(root_entries(path) * dirent_size, cluster_size)

    fat_size = align_up(
        align_up(size, cluster_size) // cluster_size * fatent_size,
        sector_size)

    sectors = (cluster_size + fat_count * fat_size + root_size +
               size) // sector_size
    root_start = cluster_size + fat_count * fat_size
    data_start = root_start + root_size

    outf = open(sys.argv[3], "wb")

    boot_sector = xstruct.create(BOOT_SECTOR)
    boot_sector.jmp = [0xEB, 0x3C, 0x90]
    boot_sector.oem = b'MSDOS5.0'
    boot_sector.sector = sector_size
    boot_sector.cluster = cluster_size // sector_size
    boot_sector.reserved = cluster_size // sector_size
    boot_sector.fats = fat_count
    boot_sector.rootdir = root_size // dirent_size
    if (sectors <= 65535):
        boot_sector.sectors = sectors
    else:
        boot_sector.sectors = 0
    boot_sector.descriptor = 0xF8
    boot_sector.fat_sectors = fat_size // sector_size
    boot_sector.track_sectors = 63
    boot_sector.heads = 6
    boot_sector.hidden = 0
    if (sectors > 65535):
        boot_sector.sectors_big = sectors
    else:
        boot_sector.sectors_big = 0

    boot_sector.drive = 0x80
    boot_sector.extboot_signature = 0x29
    boot_sector.serial = random.randint(0, 0x7fffffff)
    boot_sector.label = b'HELENOS'
    boot_sector.fstype = b'FAT16   '
    boot_sector.boot_signature = [0x55, 0xAA]

    outf.write(boot_sector.pack())

    empty_sector = xstruct.create(EMPTY_SECTOR)

    # Reserved sectors
    for i in range(1, cluster_size // sector_size):
        outf.write(empty_sector.pack())

    # FAT tables
    for i in range(0, fat_count):
        for j in range(0, fat_size // sector_size):
            outf.write(empty_sector.pack())

    # Root directory
    for i in range(0, root_size // sector_size):
        outf.write(empty_sector.pack())

    # Data
    for i in range(0, size // sector_size):
        outf.write(empty_sector.pack())

    fat = array.array('L', [0] * (fat_size // fatent_size))
    fat[0] = 0xfff8
    fat[1] = 0xffff

    recursion(True, path, outf, cluster_size, root_start, data_start, fat,
              reserved_clusters, dirent_size, 0)

    # Store FAT
    fat_entry = xstruct.create(FAT_ENTRY)
    for i in range(0, fat_count):
        outf.seek(cluster_size + i * fat_size)
        for j in range(0, fat_size // fatent_size):
            fat_entry.next = fat[j]
            outf.write(fat_entry.pack())

    outf.close()
Example #25
0
def main():
    usage = """
%prog [--extra <extra_bytes>] [--size <size>] <source-path> <output-image>"""
    parser = OptionParser(usage=usage)
    parser.add_option("-e",
                      "--extra",
                      action="store",
                      dest="extra_bytes",
                      default=0,
                      type="int",
                      help="Extra bytes to pad filesystem")
    parser.add_option("-s",
                      "--size",
                      action="store",
                      dest="size",
                      default="0",
                      help="Device size (in bytes)")

    (options, args) = parser.parse_args()
    if (len(args) != 2):
        print "Must specify both source-path and output-image"
        return

    extra_bytes = options.extra_bytes
    m = re.search("^(\d+)([kM])?$", options.size)
    fs_size = int(m.group(1))
    if (m.group(2) == "k"):
        fs_size = fs_size * 1024
    elif (m.group(2) == "M"):
        fs_size = fs_size * 1024 * 1024

    path = os.path.abspath(args[0])
    if (not os.path.isdir(path)):
        print("<PATH> must be a directory")
        return

    fat16_clusters = 4096

    sector_size = 4096
    cluster_size = 4096
    dirent_size = 32
    fatent_size = 2
    fat_count = 1
    reserved_clusters = 2

    # Make sure the filesystem is large enough for FAT16
    size = subtree_size(
        path, cluster_size,
        dirent_size) + reserved_clusters * cluster_size + extra_bytes
    if (fs_size > 0 and size > fs_size):
        # can't fit on the device
        print "Directory has size (%dkB) which is larger than device size (%dkB)" % (
            size // 1024, fs_size // 1024)
        return
    if (fs_size > size):
        size = fs_size - reserved_clusters * cluster_size
    #while (size // cluster_size < fat16_clusters):
    #	if (cluster_size > sector_size):
    #		cluster_size = cluster_size // 2
    #		size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size + extra_bytes
    #	else:
    #		size = fat16_clusters * cluster_size + reserved_clusters * cluster_size

    root_size = align_up(root_entries(path) * dirent_size, cluster_size)

    fat_size = align_up(
        align_up(size, cluster_size) // cluster_size * fatent_size,
        sector_size)

    sectors = (cluster_size + fat_count * fat_size + root_size +
               size) // sector_size
    root_start = cluster_size + fat_count * fat_size
    data_start = root_start + root_size

    outf = open(args[1], "wb")

    boot_sector = xstruct.create(BOOT_SECTOR)
    boot_sector.jmp = [0xEB, 0x3C, 0x90]
    boot_sector.oem = b'MSDOS5.0'
    boot_sector.sector = sector_size
    boot_sector.cluster = cluster_size // sector_size
    boot_sector.reserved = cluster_size // sector_size
    boot_sector.fats = fat_count
    boot_sector.rootdir = root_size // dirent_size
    if (sectors * cluster_size // sector_size < fat16_clusters):
        boot_sector.sectors = fat16_clusters * sector_size // cluster_size
    elif (sectors <= 65535):
        boot_sector.sectors = sectors
    else:
        boot_sector.sectors = 0
    boot_sector.descriptor = 0xF8
    boot_sector.fat_sectors = fat_size // sector_size
    boot_sector.track_sectors = 63
    boot_sector.heads = 6
    boot_sector.hidden = 0
    if (sectors > 65535):
        boot_sector.sectors_big = sectors
    else:
        boot_sector.sectors_big = 0

    boot_sector.drive = 0x80
    boot_sector.extboot_signature = 0x29
    boot_sector.serial = random.randint(0, 0x7fffffff)
    boot_sector.label = b'HELENOS'
    boot_sector.fstype = b'FAT16   '
    boot_sector.boot_signature = [0x55, 0xAA]

    outf.write(boot_sector.pack())

    empty_sector = xstruct.create(EMPTY_SECTOR)

    # Reserved sectors
    for i in range(1, cluster_size // sector_size):
        outf.write(empty_sector.pack())

    # FAT tables
    for i in range(0, fat_count):
        for j in range(0, fat_size // sector_size):
            outf.write(empty_sector.pack())

    # Root directory
    for i in range(0, root_size // sector_size):
        outf.write(empty_sector.pack())

    # Data
    for i in range(0, size // sector_size):
        outf.write(empty_sector.pack())

    fat = array.array('L', [0] * (fat_size // fatent_size))
    fat[0] = 0xfff8
    fat[1] = 0xffff

    recursion(True, path, outf, cluster_size, root_start, data_start, fat,
              reserved_clusters, dirent_size, 0)

    # Store FAT
    fat_entry = xstruct.create(FAT_ENTRY)
    for i in range(0, fat_count):
        outf.seek(cluster_size + i * fat_size)
        for j in range(0, fat_size // fatent_size):
            fat_entry.next = fat[j]
            outf.write(fat_entry.pack())

    outf.close()
Example #26
0
def main():
	if (len(sys.argv) < 4):
		usage(sys.argv[0])
		return
	
	if (not sys.argv[1].isdigit()):
		print("<EXTRA_BYTES> must be a number")
		return
	
	extra_bytes = int(sys.argv[1])
	
	path = os.path.abspath(sys.argv[2])
	if (not os.path.isdir(path)):
		print("<PATH> must be a directory")
		return
	
	fat16_clusters = 4096
	
	sector_size = 512
	cluster_size = 4096
	dirent_size = 32
	fatent_size = 2
	fat_count = 2
	reserved_clusters = 2
	
	# Make sure the filesystem is large enough for FAT16
	size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size + extra_bytes
	while (size // cluster_size < fat16_clusters):
		if (cluster_size > sector_size):
			cluster_size = cluster_size // 2
			size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size + extra_bytes
		else:
			size = fat16_clusters * cluster_size + reserved_clusters * cluster_size
	
	root_size = align_up(root_entries(path) * dirent_size, cluster_size)
	
	fat_size = align_up(align_up(size, cluster_size) // cluster_size * fatent_size, sector_size)
	
	sectors = (cluster_size + fat_count * fat_size + root_size + size) // sector_size
	root_start = cluster_size + fat_count * fat_size
	data_start = root_start + root_size
	
	outf = open(sys.argv[3], "wb")
	
	boot_sector = xstruct.create(BOOT_SECTOR)
	boot_sector.jmp = [0xEB, 0x3C, 0x90]
	boot_sector.oem = b'MSDOS5.0'
	boot_sector.sector = sector_size
	boot_sector.cluster = cluster_size // sector_size
	boot_sector.reserved = cluster_size // sector_size
	boot_sector.fats = fat_count
	boot_sector.rootdir = root_size // dirent_size
	if (sectors <= 65535):
		boot_sector.sectors = sectors
	else:
		boot_sector.sectors = 0
	boot_sector.descriptor = 0xF8
	boot_sector.fat_sectors = fat_size // sector_size
	boot_sector.track_sectors = 63
	boot_sector.heads = 6
	boot_sector.hidden = 0
	if (sectors > 65535):
		boot_sector.sectors_big = sectors
	else:
		boot_sector.sectors_big = 0
	
	boot_sector.drive = 0x80
	boot_sector.extboot_signature = 0x29
	boot_sector.serial = random.randint(0, 0x7fffffff)
	boot_sector.label = b'EINHERJAR'
	boot_sector.fstype = b'FAT16   '
	boot_sector.boot_signature = [0x55, 0xAA]
	
	outf.write(boot_sector.pack())
	
	empty_sector = xstruct.create(EMPTY_SECTOR)
	
	# Reserved sectors
	for i in range(1, cluster_size // sector_size):
		outf.write(empty_sector.pack())
	
	# FAT tables
	for i in range(0, fat_count):
		for j in range(0, fat_size // sector_size):
			outf.write(empty_sector.pack())
	
	# Root directory
	for i in range(0, root_size // sector_size):
		outf.write(empty_sector.pack())
	
	# Data
	for i in range(0, size // sector_size):
		outf.write(empty_sector.pack())
	
	fat = array.array('L', [0] * (fat_size // fatent_size))
	fat[0] = 0xfff8
	fat[1] = 0xffff
	
	recursion(True, path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, 0)
	
	# Store FAT
	fat_entry = xstruct.create(FAT_ENTRY)
	for i in range(0, fat_count):
		outf.seek(cluster_size + i * fat_size)
		for j in range(0, fat_size // fatent_size):
			fat_entry.next = fat[j]
			outf.write(fat_entry.pack())
	
	outf.close()
Example #27
0
def main():
    usage = """
%prog [--extra <extra_bytes>] [--size <size>] <source-path> <output-image>"""
    parser = OptionParser(usage=usage)
    parser.add_option(
        "-e", "--extra", action="store", dest="extra_bytes", default=0, type="int", help="Extra bytes to pad filesystem"
    )
    parser.add_option("-s", "--size", action="store", dest="size", default="0", help="Device size (in bytes)")

    (options, args) = parser.parse_args()
    if len(args) != 2:
        print "Must specify both source-path and output-image"
        return

    extra_bytes = options.extra_bytes
    m = re.search("^(\d+)([kM])?$", options.size)
    fs_size = int(m.group(1))
    if m.group(2) == "k":
        fs_size = fs_size * 1024
    elif m.group(2) == "M":
        fs_size = fs_size * 1024 * 1024

    path = os.path.abspath(args[0])
    if not os.path.isdir(path):
        print ("<PATH> must be a directory")
        return

    fat16_clusters = 4096

    sector_size = 4096
    cluster_size = 4096
    dirent_size = 32
    fatent_size = 2
    fat_count = 1
    reserved_clusters = 2

    # Make sure the filesystem is large enough for FAT16
    size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size + extra_bytes
    if fs_size > 0 and size > fs_size:
        # can't fit on the device
        print "Directory has size (%dkB) which is larger than device size (%dkB)" % (size // 1024, fs_size // 1024)
        return
    if fs_size > size:
        size = fs_size - reserved_clusters * cluster_size
        # while (size // cluster_size < fat16_clusters):
        # 	if (cluster_size > sector_size):
        # 		cluster_size = cluster_size // 2
        # 		size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size + extra_bytes
        # 	else:
        # 		size = fat16_clusters * cluster_size + reserved_clusters * cluster_size

    root_size = align_up(root_entries(path) * dirent_size, cluster_size)

    fat_size = align_up(align_up(size, cluster_size) // cluster_size * fatent_size, sector_size)

    sectors = (cluster_size + fat_count * fat_size + root_size + size) // sector_size
    root_start = cluster_size + fat_count * fat_size
    data_start = root_start + root_size

    outf = open(args[1], "wb")

    boot_sector = xstruct.create(BOOT_SECTOR)
    boot_sector.jmp = [0xEB, 0x3C, 0x90]
    boot_sector.oem = b"MSDOS5.0"
    boot_sector.sector = sector_size
    boot_sector.cluster = cluster_size // sector_size
    boot_sector.reserved = cluster_size // sector_size
    boot_sector.fats = fat_count
    boot_sector.rootdir = root_size // dirent_size
    if sectors * cluster_size // sector_size < fat16_clusters:
        boot_sector.sectors = fat16_clusters * sector_size // cluster_size
    elif sectors <= 65535:
        boot_sector.sectors = sectors
    else:
        boot_sector.sectors = 0
    boot_sector.descriptor = 0xF8
    boot_sector.fat_sectors = fat_size // sector_size
    boot_sector.track_sectors = 63
    boot_sector.heads = 6
    boot_sector.hidden = 0
    if sectors > 65535:
        boot_sector.sectors_big = sectors
    else:
        boot_sector.sectors_big = 0

    boot_sector.drive = 0x80
    boot_sector.extboot_signature = 0x29
    boot_sector.serial = random.randint(0, 0x7FFFFFFF)
    boot_sector.label = b"HELENOS"
    boot_sector.fstype = b"FAT16   "
    boot_sector.boot_signature = [0x55, 0xAA]

    outf.write(boot_sector.pack())

    empty_sector = xstruct.create(EMPTY_SECTOR)

    # Reserved sectors
    for i in range(1, cluster_size // sector_size):
        outf.write(empty_sector.pack())

        # FAT tables
    for i in range(0, fat_count):
        for j in range(0, fat_size // sector_size):
            outf.write(empty_sector.pack())

            # Root directory
    for i in range(0, root_size // sector_size):
        outf.write(empty_sector.pack())

        # Data
    for i in range(0, size // sector_size):
        outf.write(empty_sector.pack())

    fat = array.array("L", [0] * (fat_size // fatent_size))
    fat[0] = 0xFFF8
    fat[1] = 0xFFFF

    recursion(True, path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, 0)

    # Store FAT
    fat_entry = xstruct.create(FAT_ENTRY)
    for i in range(0, fat_count):
        outf.seek(cluster_size + i * fat_size)
        for j in range(0, fat_size // fatent_size):
            fat_entry.next = fat[j]
            outf.write(fat_entry.pack())

    outf.close()