From dc55813b69f515c389569bc32948bf0dd9a2b982 Mon Sep 17 00:00:00 2001 From: XeonSquared Date: Wed, 19 Feb 2020 18:39:48 +1100 Subject: [PATCH] added some partitioning-related stuff --- partition/README.md | 31 +++++++++++++++++++++++++ partition/partition.lua | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 partition/README.md create mode 100644 partition/partition.lua diff --git a/partition/README.md b/partition/README.md new file mode 100644 index 0000000..5c45d76 --- /dev/null +++ b/partition/README.md @@ -0,0 +1,31 @@ +# Simple partition table format + +This document specifies a general partition table format suitable for both unmanaged disks, and tapes. + +## Partition table + +The partition table resides at the end of the disk - the last sector of the disk, for several reasons: + + - Ease of implementation for firmware to load from first partition + - Compatibility with existing partition table formats + +The partition table takes one sector (512 bytes) and is divided into 16 entries, 32 bytes each. + +### Partition entry + +Each entry consists of: + + - A 20 byte name field, padded with null characters. + - A 4 byte type field. This can be used either as a number or a string. + - A 4-byte start sector field. + - A 4-byte length field. + +Any entry with no name should be ignored. + +## Tape considerations + +It may prove easier to use a tape if one were to implement a virtual drive component that maps to the data on a tape. + +## Booting + +It is suggested that firmware loads and runs the first partition with type "boot". More advanced booting logic may be implemented if desired. diff --git a/partition/partition.lua b/partition/partition.lua new file mode 100644 index 0000000..43e0c98 --- /dev/null +++ b/partition/partition.lua @@ -0,0 +1,50 @@ +local partition = {} + +local entryPattern = "(" .. ("."):rep(20) .. ")(....)(....)(....)" + +local function cint(n,l) + local t={} + for i = 0, 7 do + t[i+1] = (n >> (i * 8)) & 0xFF + end + return string.reverse(string.char(table.unpack(t)):sub(1,l)) +end +local function toint(s) + local n = 0 + local i = 1 + for p in s:gmatch(".") do + n = n << 8 + n = n | string.byte(p) + i=i+1 + end + return n +end + +function partition.parse(sector) + local pt = {} + for name,ptype,sstart,slen in sector:gmatch(entryPattern) do + local pte = {} + pte.name = name:gsub("\0","") + if pte.name:len() > 0 then + pte.type = ptype + pte.start = toint(sstart) + pte.len = toint(slen) + pte.last = pte.start + toint(slen) + pt[#pt+1] = pte + end + end + return pt +end +function partition.generate(pt) + local ps = "" + for k,v in pairs(pt) do + if not v.len then + v.len = v.last - v.start + end +-- ps = ps .. ("\0"):rep(math.max(20-v.name:len(),0)) .. v.name:sub(1,20) .. v.type:sub(1,4) .. cint(v.start,4) .. cint(v.len,4) + ps = ps .. (("\0"):rep(20) .. v.name):sub(-20) .. v.type:sub(1,4) .. cint(v.start,4) .. cint(v.len,4) + end + return ps..("\0"):rep(512-ps:len()) +end + +return partition