rockbox/utils/hwpatcher/lib.lua

118 lines
3.3 KiB
Lua
Raw Normal View History

--[[
hwpatcher library
The C code provides the following functions.
At global level:
- quit() Quit the interactive mode
- exit() Same as quit()
In the hwp table:
- load_file(filename) Load a firmware and guess type
- load_elf_file(filename) Load a firmware as ELF
- load_sb_file(filename) Load a firmware as SB
- load_sb1_file(filename) Load a firmware as SB1
- load_bin_file(filename) Load a firmware as binary
- save_file(fw, filename) Save a firmware to a file
- read(fw, addr, len) Read data from a firmware
- write(fw, addr, data) Write data to a firmware
- section_info(fw, sec) Return information about a section in a table (or nil)
- md5sum(filename) Compute the MD5 sum of a file
- crc_buf(crc_type, buf) Compute the CRC of a byte buffer and return a byte buffer
- crc(crc_type, fw, addr, len) Compute the CRC of a firmware part
The list of CRCs available is available the hwp.CRC table:
- RKW
Data read/written from/to a firmware must must be an array of bytes.
The address must be a table of the following fields:
- address: contain the address
- section: optional section name
Data section information is a table with the following fields:
- address: first address if the section
- size: size of the section
We provide the following functions to help dealing with addresses:
- make_addr(addr, section) Build a firmware address from a raw address and a section
]]--
function hwp.deepcopy(o, seen)
seen = seen or {}
if o == nil then return nil end
if seen[o] then return seen[o] end
local no
if type(o) == 'table' then
no = {}
seen[o] = no
for k, v in next, o, nil do
no[hwp.deepcopy(k, seen)] = hwp.deepcopy(v, seen)
end
setmetatable(no, hwp.deepcopy(getmetatable(o), seen))
else -- number, string, boolean, etc
no = o
end
return no
end
function hwp.make_addr(addr, section)
local t = {addr = addr, section = section}
local addr_to_string = function(self)
if self.section == nil then
return string.format("%#x", self.addr)
else
return string.format("%#x@%s", self.addr, self.section)
end
end
setmetatable(t, {__tostring = addr_to_string})
return t
end
function hwp.inc_addr(addr, amount)
return hwp.make_addr(addr.addr + amount, addr.section)
end
-- pack an array of bytes in a integer (little-endian)
function hwp.pack(arr)
local v = 0
for i = #arr, 1, -1 do
v = bit32.bor(bit32.lshift(v, 8),bit32.band(arr[i], 0xff))
end
return v
end
-- do the converse
function hwp.unpack(v, n)
local t = {}
for i = 1, n do
t[i] = bit32.band(v, 0xff)
v = bit32.rshift(v, 8)
end
return t
end
-- read a 32-bit value
function hwp.read32(obj, addr)
return hwp.pack(hwp.read(obj, addr, 4))
end
-- write a 32-bit value
function hwp.write32(obj, addr, v)
return hwp.write(obj, addr, hwp.unpack(v, 4))
end
-- convert a MD5 hash to a string
function hwp.md5str(md5)
local s = ""
for i = 1, #md5 do
s = s .. string.format("%02x", md5[i])
end
return s
end
-- compute the CRC of a firmware part
function hwp.crc(crc_type, fw, addr, len)
return hwp.crc_buf(crc_type, hwp.read(fw, addr, len))
end