make: Replace update-extents.py with a Kuroko equivalent
This commit is contained in:
parent
7ce16a005d
commit
1cb7195d75
8
Makefile
8
Makefile
@ -305,10 +305,14 @@ fatbase/efi/boot/bootx64.efi: boot/efi64.so
|
|||||||
mkdir -p fatbase/efi/boot
|
mkdir -p fatbase/efi/boot
|
||||||
objcopy ${EFI_SECTIONS} --target=efi-app-x86_64 $< $@
|
objcopy ${EFI_SECTIONS} --target=efi-app-x86_64 $< $@
|
||||||
|
|
||||||
image.iso: cdrom/fat.img cdrom/boot.sys util/update-extents.py
|
BUILD_KRK=$(TOOLCHAIN)/local/bin/kuroko
|
||||||
|
$(TOOLCHAIN)/local/bin/kuroko: kuroko/src/*.c
|
||||||
|
cc -Ikuroko/src -DNO_RLINE -DSTATIC_ONLY -DKRK_DISABLE_THREADS -o "${TOOLCHAIN}/local/bin/kuroko" kuroko/src/*.c
|
||||||
|
|
||||||
|
image.iso: cdrom/fat.img cdrom/boot.sys util/update-extents.krk $(BUILD_KRK)
|
||||||
xorriso -as mkisofs -R -J -c bootcat \
|
xorriso -as mkisofs -R -J -c bootcat \
|
||||||
-b boot.sys -no-emul-boot -boot-load-size full \
|
-b boot.sys -no-emul-boot -boot-load-size full \
|
||||||
-eltorito-alt-boot -e fat.img -no-emul-boot -isohybrid-gpt-basdat \
|
-eltorito-alt-boot -e fat.img -no-emul-boot -isohybrid-gpt-basdat \
|
||||||
-o image.iso cdrom
|
-o image.iso cdrom
|
||||||
python3 util/update-extents.py
|
kuroko util/update-extents.krk
|
||||||
|
|
||||||
|
2
kuroko
2
kuroko
@ -1 +1 @@
|
|||||||
Subproject commit caf3c1a227f9a5e502d6e0ec6ed92b38da0d2a0e
|
Subproject commit b4887a78b0e8f5d2883c73c0935548d086a7ca9c
|
@ -5,7 +5,6 @@ SYSROOT="$DIR/../base"
|
|||||||
|
|
||||||
cd $DIR
|
cd $DIR
|
||||||
mkdir -p $PREFIX/bin
|
mkdir -p $PREFIX/bin
|
||||||
gcc -I$DIR/../kuroko/src -DNO_RLINE -DSTATIC_ONLY -DKRK_DISABLE_THREADS -o "$PREFIX/bin/kuroko" $DIR/../kuroko/src/*.c
|
|
||||||
|
|
||||||
mkdir -p $DIR/build/binutils
|
mkdir -p $DIR/build/binutils
|
||||||
cd $DIR/build/binutils
|
cd $DIR/build/binutils
|
||||||
|
194
util/update-extents.py → util/update-extents.krk
Executable file → Normal file
194
util/update-extents.py → util/update-extents.krk
Executable file → Normal file
@ -1,29 +1,118 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env kuroko
|
||||||
import array
|
import fileio
|
||||||
import struct
|
|
||||||
|
|
||||||
def read_struct(fmt,buf,offset):
|
def to_int(little: bool, data: bytes):
|
||||||
out, = struct.unpack_from(fmt,buf,offset)
|
let out = 0
|
||||||
return out, offset + struct.calcsize(fmt)
|
if little: data = reversed(data)
|
||||||
|
for x in data:
|
||||||
|
out *= 0x100
|
||||||
|
out += x
|
||||||
|
return out
|
||||||
|
|
||||||
|
def to_bytes(little: bool, val: int, length: int):
|
||||||
|
let out = [0] * length
|
||||||
|
let i = 0
|
||||||
|
while val and i < length:
|
||||||
|
out[i] = val & 0xFF
|
||||||
|
val >>= 8
|
||||||
|
i++
|
||||||
|
if not little:
|
||||||
|
out = reversed(out)
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
def read_struct(fmt: str, data: bytes, offset: int):
|
||||||
|
if not fmt or not isinstance(fmt,str):
|
||||||
|
raise ValueError
|
||||||
|
# First, read the endianness
|
||||||
|
let littleEndian = True
|
||||||
|
if fmt[0] in '@<>#!':
|
||||||
|
if fmt[0] == '>': littleEndian = False
|
||||||
|
else if fmt[0] == '!': littleEndian = False
|
||||||
|
fmt = fmt[1:]
|
||||||
|
# Then read length
|
||||||
|
let length = None
|
||||||
|
if fmt[0] in '0123456789':
|
||||||
|
length = int(fmt[0])
|
||||||
|
fmt = fmt[1:]
|
||||||
|
while fmt[0] in '012345679':
|
||||||
|
length *= 10
|
||||||
|
length += int(fmt[0])
|
||||||
|
fmt = fmt[1:]
|
||||||
|
# Then read type
|
||||||
|
if fmt[0] == 'B':
|
||||||
|
return int(data[offset]), offset + 1
|
||||||
|
else if fmt[0] == 'b':
|
||||||
|
let out = int(data[offset])
|
||||||
|
if out > 0x7F: out = -out
|
||||||
|
return out, offset + 1
|
||||||
|
else if fmt[0] == 's':
|
||||||
|
return bytes([data[x] for x in range(offset,offset+length)]), offset + length
|
||||||
|
else if fmt[0] == 'I':
|
||||||
|
return to_int(littleEndian, bytes([data[x] for x in range(offset,offset+4)])), offset + 4
|
||||||
|
else if fmt[0] == 'H':
|
||||||
|
return to_int(littleEndian, bytes([data[x] for x in range(offset,offset+2)])), offset + 2
|
||||||
|
raise ValueError("Huh")
|
||||||
|
|
||||||
|
def pack_into(fmt: str, data: bytes, offset: int, val: any):
|
||||||
|
if not fmt or not isinstance(fmt,str):
|
||||||
|
raise ValueError
|
||||||
|
# First, read the endianness
|
||||||
|
let littleEndian = True
|
||||||
|
if fmt[0] in '@<>#!':
|
||||||
|
if fmt[0] == '>': littleEndian = False
|
||||||
|
else if fmt[0] == '!': littleEndian = False
|
||||||
|
fmt = fmt[1:]
|
||||||
|
# Then read length
|
||||||
|
let length = None
|
||||||
|
if fmt[0] in '0123456789':
|
||||||
|
length = int(fmt[0])
|
||||||
|
fmt = fmt[1:]
|
||||||
|
while fmt[0] in '012345679':
|
||||||
|
length *= 10
|
||||||
|
length += int(fmt[0])
|
||||||
|
fmt = fmt[1:]
|
||||||
|
# Then read type
|
||||||
|
if fmt[0] == 'B':
|
||||||
|
data[offset] = val
|
||||||
|
return offset + 1
|
||||||
|
else if fmt[0] == 'b':
|
||||||
|
data[offset] = val
|
||||||
|
return offset + 1
|
||||||
|
else if fmt[0] == 's':
|
||||||
|
for x in range(length):
|
||||||
|
data[offset+x] = val[x]
|
||||||
|
return offset + length
|
||||||
|
else if fmt[0] == 'I':
|
||||||
|
for x in to_bytes(littleEndian, val, 4):
|
||||||
|
data[offset] = x
|
||||||
|
offset++
|
||||||
|
return offset
|
||||||
|
else if fmt[0] == 'H':
|
||||||
|
for x in to_bytes(littleEndian, val, 2):
|
||||||
|
data[offset] = x
|
||||||
|
offset++
|
||||||
|
return offset
|
||||||
|
raise ValueError("Huh")
|
||||||
|
|
||||||
class ISO(object):
|
class ISO(object):
|
||||||
|
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
with open(path, 'rb') as f:
|
let data
|
||||||
tmp = f.read()
|
with fileio.open(path, 'rb') as f:
|
||||||
self.data = array.array('b', tmp)
|
self.data = bytearray(f.read())
|
||||||
self.sector_size = 2048
|
self.sector_size = 2048
|
||||||
o = 0x10 * self.sector_size
|
let o = 0x10 * self.sector_size
|
||||||
|
let _unused
|
||||||
self.type, o = read_struct('B',self.data,o)
|
self.type, o = read_struct('B',self.data,o)
|
||||||
self.id, o = read_struct('5s',self.data,o)
|
self.id, o = read_struct('5s',self.data,o)
|
||||||
self.version, o = read_struct('B',self.data,o)
|
self.version, o = read_struct('B',self.data,o)
|
||||||
_unused0, o = read_struct('B',self.data,o)
|
_unused, o = read_struct('B',self.data,o)
|
||||||
self.system_id, o = read_struct('32s',self.data,o)
|
self.system_id, o = read_struct('32s',self.data,o)
|
||||||
self.volume_id, o = read_struct('32s',self.data,o)
|
self.volume_id, o = read_struct('32s',self.data,o)
|
||||||
_unused1, o = read_struct('8s',self.data,o)
|
_unused, o = read_struct('8s',self.data,o)
|
||||||
self.volume_space_lsb, o = read_struct('<I',self.data,o)
|
self.volume_space_lsb, o = read_struct('<I',self.data,o)
|
||||||
self.volume_space_msb, o = read_struct('>I',self.data,o)
|
self.volume_space_msb, o = read_struct('>I',self.data,o)
|
||||||
_unused2, o = read_struct('32s',self.data,o)
|
_unused, o = read_struct('32s',self.data,o)
|
||||||
self.volume_set_lsb, o = read_struct('<H',self.data,o)
|
self.volume_set_lsb, o = read_struct('<H',self.data,o)
|
||||||
self.volume_set_msb, o = read_struct('>H',self.data,o)
|
self.volume_set_msb, o = read_struct('>H',self.data,o)
|
||||||
self.volume_seq_lsb, o = read_struct('<H',self.data,o)
|
self.volume_seq_lsb, o = read_struct('<H',self.data,o)
|
||||||
@ -36,7 +125,7 @@ class ISO(object):
|
|||||||
self.optional_path_table_lsb, o = read_struct('<I',self.data,o)
|
self.optional_path_table_lsb, o = read_struct('<I',self.data,o)
|
||||||
self.path_table_msb, o = read_struct('>I',self.data,o)
|
self.path_table_msb, o = read_struct('>I',self.data,o)
|
||||||
self.optional_path_table_msb, o = read_struct('>I',self.data,o)
|
self.optional_path_table_msb, o = read_struct('>I',self.data,o)
|
||||||
_offset = o
|
let _offset = o
|
||||||
self.root_dir_entry, o = read_struct('34s',self.data,o)
|
self.root_dir_entry, o = read_struct('34s',self.data,o)
|
||||||
|
|
||||||
self.root = ISOFile(self,_offset)
|
self.root = ISOFile(self,_offset)
|
||||||
@ -48,11 +137,11 @@ class ISO(object):
|
|||||||
else:
|
else:
|
||||||
if path in self._cache:
|
if path in self._cache:
|
||||||
return self._cache[path]
|
return self._cache[path]
|
||||||
units = path.split('/')
|
let units = path.split('/')
|
||||||
units = units[1:] # remove root
|
units = units[1:] # remove root
|
||||||
me = self.root
|
let me = self.root
|
||||||
for i in units:
|
for i in units:
|
||||||
next_file = me.find(i)
|
let next_file = me.find(i)
|
||||||
if not next_file:
|
if not next_file:
|
||||||
me = None
|
me = None
|
||||||
break
|
break
|
||||||
@ -67,7 +156,7 @@ class ISOFile(object):
|
|||||||
self.iso = iso
|
self.iso = iso
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
|
||||||
o = offset
|
let o = offset
|
||||||
self.length, o = read_struct('B', self.iso.data, o)
|
self.length, o = read_struct('B', self.iso.data, o)
|
||||||
if not self.length:
|
if not self.length:
|
||||||
return
|
return
|
||||||
@ -88,43 +177,45 @@ class ISOFile(object):
|
|||||||
|
|
||||||
self.name_len, o = read_struct('b', self.iso.data, o)
|
self.name_len, o = read_struct('b', self.iso.data, o)
|
||||||
self.name, o = read_struct('{}s'.format(self.name_len), self.iso.data, o)
|
self.name, o = read_struct('{}s'.format(self.name_len), self.iso.data, o)
|
||||||
self.name = self.name.decode('ascii')
|
self.name = self.name.decode()
|
||||||
|
|
||||||
def write_extents(self):
|
def write_extents(self):
|
||||||
struct.pack_into('<I', self.iso.data, self.offset + 2, self.extent_start_lsb)
|
pack_into('<I', self.iso.data, self.offset + 2, self.extent_start_lsb)
|
||||||
struct.pack_into('>I', self.iso.data, self.offset + 6, self.extent_start_lsb)
|
pack_into('>I', self.iso.data, self.offset + 6, self.extent_start_lsb)
|
||||||
struct.pack_into('<I', self.iso.data, self.offset + 10, self.extent_length_lsb)
|
pack_into('<I', self.iso.data, self.offset + 10, self.extent_length_lsb)
|
||||||
struct.pack_into('>I', self.iso.data, self.offset + 14, self.extent_length_lsb)
|
pack_into('>I', self.iso.data, self.offset + 14, self.extent_length_lsb)
|
||||||
|
|
||||||
def readable_name(self):
|
def readable_name(self):
|
||||||
if not ';' in self.name:
|
if not ';' in self.name:
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
else:
|
else:
|
||||||
|
let tmp, _
|
||||||
tmp, _ = self.name.split(';')
|
tmp, _ = self.name.split(';')
|
||||||
return tmp.lower()
|
return tmp.lower()
|
||||||
|
|
||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
sectors = self.iso.data[self.extent_start_lsb * self.iso.sector_size: self.extent_start_lsb * self.iso.sector_size+ 3 * self.iso.sector_size]
|
let sectors = self.iso.data[self.extent_start_lsb * self.iso.sector_size: self.extent_start_lsb * self.iso.sector_size+ 3 * self.iso.sector_size]
|
||||||
offset = 0
|
let offset = 0
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
f = ISOFile(self.iso, self.extent_start_lsb * self.iso.sector_size + offset)
|
let f = ISOFile(self.iso, self.extent_start_lsb * self.iso.sector_size + offset)
|
||||||
yield f
|
yield f
|
||||||
offset += f.length
|
offset += f.length
|
||||||
if not f.length:
|
if not f.length:
|
||||||
break
|
break
|
||||||
|
|
||||||
def find(self, name):
|
def find(self, name):
|
||||||
sectors = self.iso.data[self.extent_start_lsb * self.iso.sector_size: self.extent_start_lsb * self.iso.sector_size+ 3 * self.iso.sector_size]
|
let sectors = self.iso.data[self.extent_start_lsb * self.iso.sector_size: self.extent_start_lsb * self.iso.sector_size+ 3 * self.iso.sector_size]
|
||||||
offset = 0
|
let offset = 0
|
||||||
if '.' in name and len(name.split('.')[0]) > 8:
|
if '.' in name and len(name.split('.')[0]) > 8:
|
||||||
|
let a, b
|
||||||
a, b = name.split('.')
|
a, b = name.split('.')
|
||||||
name = a[:8] + '.' + b
|
name = a[:8] + '.' + b
|
||||||
if '-' in name:
|
if '-' in name:
|
||||||
name = name.replace('-','_')
|
name = name.replace('-','_')
|
||||||
while 1:
|
while 1:
|
||||||
f = ISOFile(self.iso, self.extent_start_lsb * self.iso.sector_size + offset)
|
let f = ISOFile(self.iso, self.extent_start_lsb * self.iso.sector_size + offset)
|
||||||
if not f.length:
|
if not f.length:
|
||||||
if offset < self.extent_length_lsb:
|
if offset < self.extent_length_lsb:
|
||||||
offset += 1
|
offset += 1
|
||||||
@ -132,6 +223,7 @@ class ISOFile(object):
|
|||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
if ';' in f.name:
|
if ';' in f.name:
|
||||||
|
let tmp, _
|
||||||
tmp, _ = f.name.split(';')
|
tmp, _ = f.name.split(';')
|
||||||
if tmp.endswith('.'):
|
if tmp.endswith('.'):
|
||||||
tmp = tmp[:-1]
|
tmp = tmp[:-1]
|
||||||
@ -148,6 +240,7 @@ class FAT(object):
|
|||||||
self.iso = iso
|
self.iso = iso
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
|
||||||
|
let _
|
||||||
self.bytespersector, _ = read_struct('H', self.iso.data, offset + 11)
|
self.bytespersector, _ = read_struct('H', self.iso.data, offset + 11)
|
||||||
self.sectorspercluster, _ = read_struct('B', self.iso.data, offset + 13)
|
self.sectorspercluster, _ = read_struct('B', self.iso.data, offset + 13)
|
||||||
self.reservedsectors, _ = read_struct('H', self.iso.data, offset + 14)
|
self.reservedsectors, _ = read_struct('H', self.iso.data, offset + 14)
|
||||||
@ -164,33 +257,29 @@ class FAT(object):
|
|||||||
return self.offset + ((cluster - 2) * self.sectorspercluster + self.first_data_sector) * self.bytespersector
|
return self.offset + ((cluster - 2) * self.sectorspercluster + self.first_data_sector) * self.bytespersector
|
||||||
|
|
||||||
def get_file(self, path):
|
def get_file(self, path):
|
||||||
units = path.split('/')
|
let units = path.split('/')
|
||||||
units = units[1:]
|
units = units[1:]
|
||||||
|
|
||||||
me = self.root
|
let me = self.root
|
||||||
out = None
|
let out = None
|
||||||
for i in units:
|
for i in units:
|
||||||
for fatfile in me.list():
|
for fatfile in me.list():
|
||||||
if fatfile.readable_name() == i:
|
if fatfile.readable_name() == i:
|
||||||
me = fatfile.to_dir()
|
me = fatfile.to_dir()
|
||||||
out = fatfile
|
out = fatfile
|
||||||
break
|
break
|
||||||
else:
|
|
||||||
return None
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
class FATDirectory(object):
|
class FATDirectory(object):
|
||||||
|
|
||||||
def __init__(self, fat, offset):
|
def __init__(self, fat, offset):
|
||||||
|
|
||||||
self.fat = fat
|
self.fat = fat
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
|
let o = self.offset
|
||||||
o = self.offset
|
|
||||||
while 1:
|
while 1:
|
||||||
out = FATFile(self.fat, o)
|
let out = FATFile(self.fat, o)
|
||||||
if out.name != '\0\0\0\0\0\0\0\0':
|
if out.name != '\0\0\0\0\0\0\0\0':
|
||||||
yield out
|
yield out
|
||||||
else:
|
else:
|
||||||
@ -208,17 +297,22 @@ class FATFile(object):
|
|||||||
self.size = 0
|
self.size = 0
|
||||||
self.long_name = ''
|
self.long_name = ''
|
||||||
|
|
||||||
o = self.offset
|
let o = self.offset
|
||||||
self.actual_offset = o
|
self.actual_offset = o
|
||||||
|
|
||||||
|
let _
|
||||||
self.attrib, _ = read_struct('B',self.fat.iso.data,o+11)
|
self.attrib, _ = read_struct('B',self.fat.iso.data,o+11)
|
||||||
|
|
||||||
while (self.attrib & 0x0F) == 0x0F:
|
while (self.attrib & 0x0F) == 0x0F:
|
||||||
# Long file name entry
|
# Long file name entry
|
||||||
tmp = read_struct('10s',self.fat.iso.data,o+1)[0]
|
let tmp = read_struct('10s',self.fat.iso.data,o+1)[0]
|
||||||
tmp += read_struct('12s',self.fat.iso.data,o+14)[0]
|
tmp += read_struct('12s',self.fat.iso.data,o+14)[0]
|
||||||
tmp += read_struct('4s',self.fat.iso.data,o+28)[0]
|
tmp += read_struct('4s',self.fat.iso.data,o+28)[0]
|
||||||
tmp = "".join([chr(x) for x in tmp[::2] if x != '\xFF']).strip('\x00')
|
let s = []
|
||||||
|
for i = 0; i < len(tmp); i += 2:
|
||||||
|
if tmp[x] != '\xFF':
|
||||||
|
s.append(chr(tmp[x]))
|
||||||
|
tmp = "".join(s).strip('\x00')
|
||||||
self.long_name = tmp + self.long_name
|
self.long_name = tmp + self.long_name
|
||||||
self.size += 32
|
self.size += 32
|
||||||
o = self.offset + self.size
|
o = self.offset + self.size
|
||||||
@ -241,8 +335,8 @@ class FATFile(object):
|
|||||||
self.clusterlow, o = read_struct('H',self.fat.iso.data,o)
|
self.clusterlow, o = read_struct('H',self.fat.iso.data,o)
|
||||||
self.filesize, o = read_struct('I',self.fat.iso.data,o)
|
self.filesize, o = read_struct('I',self.fat.iso.data,o)
|
||||||
|
|
||||||
self.name = self.name.decode('ascii')
|
self.name = self.name.decode()
|
||||||
self.ext = self.ext.decode('ascii')
|
self.ext = self.ext.decode()
|
||||||
|
|
||||||
self.size += 32
|
self.size += 32
|
||||||
|
|
||||||
@ -268,11 +362,9 @@ class FATFile(object):
|
|||||||
else:
|
else:
|
||||||
return self.name.strip().lower()
|
return self.name.strip().lower()
|
||||||
|
|
||||||
|
let image = ISO('image.iso')
|
||||||
image = ISO('image.iso')
|
let fat = image.root.find('FAT.IMG')
|
||||||
fat = image.root.find('FAT.IMG')
|
let fatfs = FAT(image, fat.extent_start_lsb * image.sector_size)
|
||||||
|
|
||||||
fatfs = FAT(image, fat.extent_start_lsb * image.sector_size)
|
|
||||||
|
|
||||||
def process(fatfile, path):
|
def process(fatfile, path):
|
||||||
if fatfile.is_long():
|
if fatfile.is_long():
|
||||||
@ -285,7 +377,7 @@ def process(fatfile, path):
|
|||||||
for i in fatfile.to_dir().list():
|
for i in fatfile.to_dir().list():
|
||||||
process(i, path + fatfile.readable_name() + '/')
|
process(i, path + fatfile.readable_name() + '/')
|
||||||
else:
|
else:
|
||||||
cdfile = image.get_file(path + fatfile.readable_name())
|
let cdfile = image.get_file(path + fatfile.readable_name())
|
||||||
if not cdfile:
|
if not cdfile:
|
||||||
if fatfile.readable_name() != 'bootia32.efi' and fatfile.readable_name() != 'bootx64.efi':
|
if fatfile.readable_name() != 'bootia32.efi' and fatfile.readable_name() != 'bootx64.efi':
|
||||||
print("Warning:", fatfile.readable_name(), "not found in ISO")
|
print("Warning:", fatfile.readable_name(), "not found in ISO")
|
||||||
@ -298,6 +390,6 @@ def process(fatfile, path):
|
|||||||
for i in fatfs.root.list():
|
for i in fatfs.root.list():
|
||||||
process(i,'/')
|
process(i,'/')
|
||||||
|
|
||||||
with open('image.iso','wb') as f:
|
with fileio.open('image.iso','wb') as f:
|
||||||
f.write(image.data)
|
f.write(bytes(image.data))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user