209 lines
6.0 KiB
Python
209 lines
6.0 KiB
Python
# implemented in python to support all platforms
|
|
# xOS
|
|
# fat16 in xOS
|
|
|
|
from config import format_settings
|
|
|
|
filename = format_settings['filename']
|
|
|
|
file_descriptor = {
|
|
'name': filename,
|
|
'size': 0, #(bytes)
|
|
}
|
|
|
|
def open_file():
|
|
size = 0
|
|
with open(filename, "rb") as f:
|
|
byte = f.read(1)
|
|
while byte != b"":
|
|
size+=1
|
|
byte = f.read(1)
|
|
|
|
file_descriptor['size'] = size
|
|
|
|
def write_file(dd, withPos = 0):
|
|
with open(filename, "rb+") as f:
|
|
f.seek(withPos, 0)
|
|
f.write(bytes(x for x in dd))
|
|
|
|
def merge(res, plus, offset):
|
|
for (id,el) in enumerate(plus):
|
|
res[id + offset] = el
|
|
return res
|
|
|
|
def test_id():
|
|
result = bytearray(8)
|
|
textCode = 'xOSToP'
|
|
for (id,el) in enumerate(textCode):
|
|
result[id] = ord(el)
|
|
return result
|
|
|
|
def bytes_per_sector():
|
|
result = bytearray(2)
|
|
result[0] = format_settings['BytesPerSector'] % 256
|
|
result[1] = format_settings['BytesPerSector'] // 256
|
|
return result
|
|
|
|
def sectors_per_cluster():
|
|
result = bytearray(1)
|
|
result[0] = format_settings['SectorPerClustor'] % 256
|
|
return result
|
|
|
|
def number_of_fats():
|
|
result = bytearray(1)
|
|
result[0] = format_settings['NumberOfFATs'] % 256
|
|
return result
|
|
|
|
def root_entires():
|
|
result = bytearray(2)
|
|
result[0] = format_settings['RootEntires'] % 256
|
|
result[1] = format_settings['RootEntires'] // 256
|
|
return result
|
|
|
|
def load_kernel():
|
|
result = bytearray(2)
|
|
result[0] = format_settings['ReservedSectors'] % 256
|
|
result[1] = format_settings['ReservedSectors'] // 256
|
|
return result
|
|
|
|
def reserved_sectors():
|
|
result = bytearray(2)
|
|
result[0] = format_settings['ReservedSectors'] % 256
|
|
result[1] = format_settings['ReservedSectors'] // 256
|
|
return result
|
|
|
|
def volume_label():
|
|
result = bytearray(11)
|
|
for i in range(11):
|
|
result[i] = 0x20
|
|
textCode = format_settings['VolumeName']
|
|
for (id,el) in enumerate(textCode):
|
|
result[id] = ord(el)
|
|
return result
|
|
|
|
def system_id():
|
|
result = bytearray(8)
|
|
for i in range(8):
|
|
result[i] = 0x20
|
|
textCode = 'FAT16'
|
|
for (id,el) in enumerate(textCode):
|
|
result[id] = ord(el)
|
|
return result
|
|
|
|
def header():
|
|
result = bytearray(512)
|
|
result = merge(result, test_id(), 0x3)
|
|
result = merge(result, bytes_per_sector(), 0xB)
|
|
result = merge(result, sectors_per_cluster(), 0xD)
|
|
result = merge(result, reserved_sectors(), 0xE)
|
|
result = merge(result, number_of_fats(), 0x10)
|
|
result = merge(result, root_entires(), 0x11)
|
|
result = merge(result, sectors_per_fat(), 0x16)
|
|
result = merge(result, volume_label(), 0x2B)
|
|
result = merge(result, system_id(), 0x36)
|
|
result[511] = 0x00
|
|
result[510] = 0x00
|
|
print_g(result)
|
|
return result
|
|
|
|
def fat_size():
|
|
if (format_settings['RootEntires'] * 32) % 512 != 0:
|
|
print("RootEntires error [couldn't fit into sectors]")
|
|
exit(0)
|
|
root_dir_sectors = (format_settings['RootEntires'] * 32) // 512
|
|
load_sectors = format_settings['ReservedSectors']
|
|
data_sectors = file_descriptor['size'] // 512 - root_dir_sectors - load_sectors
|
|
for fat_sectors in range(1, 256):
|
|
free_data_sectors = data_sectors - fat_sectors * format_settings['NumberOfFATs']
|
|
covered_data_sectors = fat_sectors * 512 // 2 - 2
|
|
print(free_data_sectors, covered_data_sectors)
|
|
if free_data_sectors <= format_settings['SectorPerClustor'] * covered_data_sectors:
|
|
return fat_sectors
|
|
return 256
|
|
|
|
def sectors_per_fat():
|
|
fsize = fat_size()
|
|
result = bytearray(2)
|
|
result[0] = fsize % 256
|
|
result[1] = fsize // 256
|
|
return result
|
|
|
|
def fat():
|
|
fsize = fat_size()
|
|
print(fsize)
|
|
result = bytearray(512 * fsize)
|
|
result[0] = 0xf8
|
|
result[1] = 0xff
|
|
result[2] = 0xff
|
|
result[3] = 0xff
|
|
root_dir_sectors = (format_settings['RootEntires'] * 32) // 512
|
|
load_sectors = format_settings['ReservedSectors']
|
|
data_sectors = file_descriptor['size'] // 512 - root_dir_sectors - load_sectors
|
|
free_data_sectors = data_sectors - fsize * format_settings['NumberOfFATs']
|
|
covered_data_clusters = fsize * 512 // 2 - 2
|
|
data_clusters = (free_data_sectors - format_settings['SectorPerClustor'] + 1) // format_settings['SectorPerClustor'] + 1
|
|
unused_clusters = covered_data_clusters - data_clusters
|
|
print(covered_data_clusters, data_clusters, unused_clusters)
|
|
if unused_clusters < 0:
|
|
print("Error with clusters")
|
|
exit(0)
|
|
for i in range(unused_clusters):
|
|
result[512 * fsize - 2 * unused_clusters + 2 * i] = 0xff
|
|
result[512 * fsize - 2 * unused_clusters + 2 * i + 1] = 0xff
|
|
|
|
print_g(result)
|
|
return result
|
|
|
|
def root_dir():
|
|
result = bytearray(format_settings['RootEntires'] * 32)
|
|
return result
|
|
|
|
def print_gh(el):
|
|
if (el >= 10):
|
|
return chr(el - 10 + ord('A'))
|
|
return chr(el + ord('0'))
|
|
|
|
def print_g(result):
|
|
for (id,el) in enumerate(result):
|
|
if id % 16 == 0:
|
|
print()
|
|
print(print_gh(el//16), end="")
|
|
print(print_gh(el%16), end=" ")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("xOS Formatter")
|
|
print("To change setting change config file")
|
|
open_file()
|
|
|
|
pos = 0
|
|
|
|
print("writing header")
|
|
print("Header starts at ", pos)
|
|
# writing header
|
|
header_e = header()
|
|
write_file(header_e, pos)
|
|
pos += format_settings['ReservedSectors'] * 512
|
|
print("Kernel starts at ", 512)
|
|
|
|
print("writing fats")
|
|
print("Fats start at ", pos)
|
|
# writing fats
|
|
fat_e = fat()
|
|
for i in range(format_settings['NumberOfFATs']):
|
|
write_file(fat_e, pos)
|
|
pos += len(fat_e)
|
|
|
|
print("writing root_dir")
|
|
print("Root dir starts at ", pos)
|
|
# writing root_dir
|
|
root_dir_e = root_dir()
|
|
write_file(root_dir_e, pos)
|
|
pos += len(root_dir_e)
|
|
|
|
write_file(bytearray(file_descriptor['size'] - pos), pos)
|
|
|
|
print("Data starts at ", pos)
|
|
print("Data size is ", file_descriptor['size'] - pos)
|
|
print("Data size is (Mb)", (file_descriptor['size'] - pos) / (1024 * 1024))
|