local version=cpio.new_version 'version' package.cpath=package.cpath..';files/lib/?.so' elf = require 'elfutil' ffi = require 'ffi' ffi.cdef 'int access(const char *path, int mode);' local output=io.popen('lzma -3 >'..cpio.cwd..'/minboot.lzma', 'w') cpio.set_output(output) local verfile=assert(io.open('.version', 'w')) verfile:write(version..' - '..cpio.time_now('%F')..'\n') verfile:close() local stored = {} local function file(names, source, mode) assert(not stored[source], 'Duplicated store of: '..source) stored[source] = source ~= '/dev/null' cpio.emit_file(names, source, mode, 0, 0) end pprint = require 'pprint' local needed = {} local satisfied = {} local function exec(names, source) file(names, source, '0755') local results = elf.scan_elf(source) if results then local soname = results.soname if soname then satisfied[soname] = true needed[soname] = nil end for _, need in ipairs(results.needed) do if not satisfied[need] then needed[need] = true end end end end local function slink(sources, target) cpio.emit_symlink(sources, target, '0777', 0, 0) end local function dir(path, mode) cpio.emit_directory(path, mode, 0, 0) end local function nod(dev, mode, isblock, major, minor) cpio.emit_node('/dev/'..dev, mode, 0, 0, isblock, major, minor) end local pipe file('.version', '.version', '0644') file('.mkcpio', cpio.script, '0644') local function dirs(path, mode) local subpath = '' for part in path:gmatch '([^/]+)/?' do subpath = subpath..part dir(subpath, mode) subpath = subpath..'/' end end for _,v in ipairs { 'bin', 'dev', 'dltool', 'etc/rc.d', 'etc/ssh', 'lib/firmware/radeon', 'lib/udev/rules.d', 'mnt', 'proc', 'sys', 'tmp', 'share/tabset', 'share/udhcpc', 'var/log', 'var/empty', 'var/run', 'dev/pts', 'run', 'share/lua/5.1', 'lib64/lua/5.1', 'root/stdirfs/files/bin' } do dirs(v, '0755') end slink('lib/lua', '/lib64/lua') file('root/.screenrc', 'files/root/screenrc', '0644') slink('.screenrc', '/root/.screenrc') dir('root/.ssh', '0700') file('root/.ssh/authorized_keys', 'files/root/ssh/authorized_keys', '0600') exec('root/dolilo', 'files/root/dolilo') slink('sbin', 'bin') slink('libexec', 'bin') slink('usr', '/') slink('local', '/') slink('lib/terminfo', '/root/.terminfo') -- Configurations for _,v in ipairs { 'HOSTNAME', 'fstab', 'group', 'hosts', 'inittab', 'networks', 'nsswitch.conf', 'passwd', 'services', 'syslog.conf', 'syslog.conf.remote', 'termcap', 'profile' } do file('etc/'..v, 'files/etc/'..v, '0644') end for _,v in ipairs { 'ssh/ssh_known_hosts', 'ssh/ssh_config', 'ssh/sshd_config', 'ssh/host_key', 'ssh/host_key.pub' } do file('etc/'..v, 'files/etc/'..v, '0600') end -- Scripts exec('/etc/rc.d/rc.S', 'files/etc/rc.d/rc.S') file('etc/ssh/moduli', '/etc/ssh/moduli', '0644') file('etc/shadow', 'files/etc/shadow', '0640') exec('share/udhcpc/default.script', 'files/share/udhcpc/default.script') -- Lua support for _,v in ipairs{'ffi+.lua', 'pprint.lua', 'zstd.lua'} do file('share/lua/5.1/'..v, '/usr/local/share/lua/5.1/'..v, '0644') end for _,v in ipairs{ 'freezer.so', 'twinmap.so', 'struct.so', 'taskman.so', 'strbuff.so' } do file('lib64/lua/5.1/'..v, '/usr/local/lib64/lua/5.1/'..v, '0755') end slink('lib64/lua/5.1/lua-freezer.so.0.0', 'freezer.so') slink('lib64/lua/5.1/lua-twinmap.so.0.0', 'twinmap.so') slink('lib64/lua/5.1/lua-strbuff.so.0.0', 'strbuff.so') -- Firmware for _,v in ipairs { 'RS780_me.bin', 'RS780_pfp.bin', 'R600_rlc.bin' } do file('/lib/firmware/radeon'..v, 'files/firmware/'..v, '0644') end -- Empty files for _,v in ipairs { 'var/log/wtmp', 'var/log/lastlog', 'var/run/utmp', 'etc/issue', 'etc/mtab' } do file(v, '/dev/null', '0644') end -- Devices for _,v in ipairs { {'mem', 1, 1}, {'kmem', 1, 2}, {'null', 1, 3} , {'port', 1, 4}, {'zero', 1, 5}, {'full', 1, 7}, {'random', 1, 8}, {'urandom', 1, 9}, {'tty', 5, 0}, {'console', 5, 1}, {'vcs', 7, 0}, {'mouse', 13, 32}, {'psaux', 10, 1}} do nod(v[1], '0644', false, v[2], v[3]) end for n=0,7 do nod('tty'..n, '0644', false, 4, n) nod('ttyp'..n, '0644', false, 3, n) nod('ptyp'..n, '0644', false, 2, n) end for n=0,3 do nod('rd'..n, '0640', true, 1, n) nod('loop'..n, '0644', true, 7, n) nod('cua'..n, '0640', false, 5, 64+n) nod('ttyS'..n, '0640', false, 4, 64+n) nod('par'..n, '0640', false, 99, n) end -- DL Tool do for _,f in ipairs { 'completions', 'dlspec', 'dltool.lua' } do file('dltool/'..f, 'files/dltool/'..f, '0644') end exec('dltool/dltool', 'files/dltool/dltool') exec('lib64/lua/5.1/elfutil.so', 'files/lib/elfutil.so') slink('root/dlspec', '/dltool/dlspec') slink('bin/dltool', '/dltool/dltool') end -- udev DM rules for _, rule in ipairs { '10-dm.rules', '11-dm-lvm.rules', '13-dm-disk.rules', '69-dm-lvm-metad.rules', '60-block.rules', '95-dm-notify.rules' } do file('lib/udev/rules.d/'..rule, '/lib/udev/rules.d/'..rule, '0644') end -- Terminfo support do local terminfos={ 's/screen', 'v/vanilla', 'l/linux*', 'x/xterm*', 'r/rxvt*', 'v/vt10*' } local dst='root/.terminfo' local src = '/usr/share/terminfo' local dirs_made= {} dir(dst, '0755') for _,t in ipairs (terminfos) do local d,f=t:match '^(.*)/(.*)$' if not dirs_made[d] then dir(dst..'/'..d, '0755') dirs_made[d] = true end pipe = io.popen('cd '..src..' 1>/dev/null; find '..d..' -name '..f) for line in pipe:lines() do file(dst..'/'..line, src..'/'..line, '0644') end pipe:close() end end slink('.terminfo', '/root/.terminfo') -- Custom utilities pipe = io.popen 'cd files 1>/dev/null;find bin -mindepth 1' for util in pipe:lines() do exec(util, 'files/'..util) end pipe:close() slink('init', '/bin/busybox') -- Rebuilds for thinned dependencies exec('lib64/libpcap.so.1', 'files/lib/libpcap.so.1.10.1') exec('lib64/libprocps.so.8', 'files/lib/libprocps.so.8.0.3') exec('lib64/libtirpc.so.3', 'files/lib/libtirpc.so.3.0.0') -- NSS support isn't a load time dependency. for _, nsstype in ipairs { 'compat', 'db', 'dns', 'files', 'hesiod', 'nis' } do local name='lib64/libnss_'..nsstype..'.so.2'; exec(name, '/'..name) end -- Busykbox symlinks pipe = io.popen 'files/bin/busybox --list | grep -v reboot' for link in pipe:lines() do slink('bin/'..link, 'busybox') end pipe:close() -- stdirfs file('root/stdirfs/version', 'files/root/stdirfs/version', '0644') file('root/stdirfs/mkcpio.irfs', 'files/root/stdirfs/mkcpio.irfs', '0644') file('root/stdirfs/files/init', 'files/root/stdirfs/files/init', '0644') exec('root/stdirfs/files/bin/busybox', 'files/root/stdirfs/files/bin/busybox') -- Utilities from system for _,bins in ipairs { { '/sbin/', { 'badblocks', 'blkid', 'cryptsetup', 'debugfs', 'dumpe2fs', 'e2fsck', 'e2image', 'fsck', 'lilo', 'logsave', 'lvm', 'mklost+found', 'nameif', 'resize2fs', 'tune2fs', 'dmsetup', 'udevd', 'udevadm' }}, { '/bin/', { 'cpio', 'dialog', 'mg', 'setterm' }}, { '/usr/bin/', { 'ls', 'mksquashfs', 'ps', 'uuidgen', 'tcpdump', 'rsync', 'unsquashfs', 'xxhsum', 'zstd', 'zstdgrep', 'zstdless' }}, { '/usr/sbin/', { 'ethtool', 'gpm', 'hdparm', 'smartctl', 'dmidecode' }}, { '/usr/local/bin/', { 'lua', 'rlwrap' }}, { '/usr/local/sbin/', { 'wipe', 'mkcpio' }}, { '/usr/libexec/', { 'sftp-server' }}} do for _,v in ipairs(bins[2]) do exec('bin/'..v, bins[1]..v) end end exec({'bin/fsck.ext2', 'bin/fsck.ext3', 'bin/fsck.ext4', 'bin/fsck.ext4dev'}, '/sbin/fsck.ext2') exec({'bin/lzma', 'bin/xz', 'bin/lzcat', 'bin/xzcat', 'bin/unlzma', 'bin/unxz' }, '/usr/bin/lzma') exec({'bin/mke2fs', 'bin/mkfs.ext2', 'bin/mkfs.ext3', '/bin/mkfs.ext4', '/bin/mkfs.ext4dev' }, '/sbin/mke2fs') slink('bin/e2label', 'tune2fs') slink('bin/zstdcat', 'zstd') slink('bin/zstdmt', 'zstd') slink('bin/unzstd', 'zstd') slink('bin/xxh32sum', 'xxhsum') slink('bin/xxh64sum', 'xxhsum') slink('bin/xxh128sum', 'xxhsum') -- Generate LVM symlinks from usage message pipe=io.popen 'lvm 2>&1' repeat local line = pipe:read '*l' until line:match '^[%s]+$' local skip_lvm = { help=true } while true do local line = pipe:read '*l' if not line then break end local cmd = line:match '^[%s]*([%S]+)' if not skip_lvm[cmd] then slink('bin/'..cmd, '/bin/lvm') end end pipe:close() -- Copy in needed libraries while next(needed) do local tbl = {} for missing in pairs(needed) do tbl[#tbl+1] = missing end for _, missing in ipairs(tbl) do if ffi.C.access('/lib64/'..missing, 1) == 0 then exec('lib64/'..missing, '/lib64/'..missing) elseif ffi.C.access('/usr/lib64/'..missing, 1) == 0 then exec('lib64/'..missing, '/usr/lib64/'..missing) elseif ffi.C.access('/usr/local/lib64/'..missing, 1) == 0 then exec('lib64/'..missing, '/usr/local/lib64/'..missing) end end end cpio.emit_trailer() cpio.set_output() output:close() os.remove '.version'