logo

bootstrap-initrd

Linux initrd to bootstrap from a small binary seed git clone https://hacktivis.me/git/bootstrap-initrd.git

make-root.sh (7150B)


  1. #!/bin/sh
  2. # bootstrap-initrd: Linux initrd to bootstrap from a small binary seed
  3. # SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  4. # SPDX-License-Identifier: MPL-2.0
  5. tarballs="
  6. lolibc-f6e9da7.tar.gz
  7. loksh-7.5.tar.gz
  8. yacc-oyacc-6.6.tar.gz
  9. utils-std-69fb55f.tar.gz
  10. pdpmake-2.0.1.tgz
  11. nawk-20240422.tar.gz
  12. bzip2-bzip2-1.0.8.tar.gz
  13. zlib-1.3.1.tar.gz
  14. pigz-2.8.tar.gz
  15. heirloom-070715.tar.bz2
  16. heirloom-devtools-070527.tar.bz2
  17. sbase-b30fb568.tar.gz
  18. "
  19. local_files="
  20. init.sh
  21. ls-stub.c
  22. grep-stub.c
  23. cp-stub.c
  24. getty-stub.c
  25. mount-stub.c
  26. "
  27. distfiles="
  28. make-4.4.1.tar.gz
  29. xz-5.6.2.tar.gz
  30. lua-5.4.6.tar.gz
  31. pkgconf-2.2.0.tar.gz
  32. iproute2-6.6.0.tar.gz
  33. skalibs-2.14.2.0.tar.gz
  34. mdevd-0.1.6.4.tar.gz
  35. bearssl-0.6.tar.gz
  36. tiny-curl-8.4.0.tar.gz
  37. cacert-2024-03-11.pem
  38. gettext-tiny-0.3.2.tar.gz
  39. git-2.45.1.tar.gz
  40. e2fsprogs-1.47.1.tar.gz
  41. "
  42. local_distfiles="
  43. bootstrap-make.sh
  44. bootstrap-xz.sh
  45. bootstrap-lua.sh
  46. bootstrap-pkgconf.sh
  47. bootstrap-iproute2.sh
  48. bootstrap-skalibs.sh
  49. bootstrap-mdevd.sh
  50. bootstrap-bearssl.sh
  51. bootstrap-tiny-curl.sh
  52. bootstrap-gettext-tiny.sh
  53. bootstrap-git.sh
  54. bootstrap-e2fsprogs.sh
  55. build-extras.sh
  56. "
  57. WORKDIR="$(dirname "$0")"
  58. WORKDIR="$(realpath "$WORKDIR")"
  59. . "$WORKDIR/common.sh"
  60. : ${ALPINE_ARCH:=x86_64}
  61. name_base="bootstrap-initrd"
  62. out_base="${WORKDIR}/${name_base}/${ALPINE_ARCH}"
  63. gen_loksh_tcc_h() {
  64. cd loksh-*/ || die
  65. printf 'char *loksh_tcc_cmd[] = {'
  66. # -DSMALL to not need ncurses
  67. printf '"%s", ' /usr/bin/tcc -o /bin/loksh \
  68. -D_GNU_SOURCE -DEMACS -DVI -DSMALL -DHAVE_STRLCPY -DHAVE_STRLCAT -DHAVE_ISSETUGID \
  69. -I ../lolibc-*/include/ *.c \
  70. ../lolibc-*/sys_signame.c ../lolibc-*/strsignals.c ../lolibc-*/unvis.c ../lolibc-*/vis.c ../lolibc-*/strtonum.c
  71. printf '0};'
  72. cd "$out_base" || die "Failed: cd $out_base"
  73. }
  74. set -e
  75. sha512sum -c distfiles.SHA512SUM
  76. if test -e "$out_base"; then
  77. rm -fr "$out_base"
  78. fi
  79. mkdir -p "$out_base" || die "Failed: mkdir $out_base"
  80. cd "$out_base" || die "Failed: cd $out_base"
  81. for i in $tarballs; do
  82. tar xof "${WORKDIR}/distfiles/$i" || die "Failed extracting $i"
  83. done
  84. for i in $local_files; do
  85. cp "${WORKDIR}/$i" ./ || die "Failed copying $i"
  86. done
  87. if ! test "${EXCLUDE_EXTRAS:+y}" = "y"; then
  88. for i in $local_distfiles; do
  89. cp "${WORKDIR}/$i" ./ || die "Failed copying $i"
  90. done
  91. for i in $distfiles
  92. do
  93. cp "${WORKDIR}/distfiles/$i" ./ || die "Failed copying $i"
  94. done
  95. fi
  96. deblob
  97. mkdir -p dev proc sys etc usr/bin var/empty || die "Failed creating base directories"
  98. ln -s /proc/mounts etc/mtab || die "Failed symlink for /etc/mtab"
  99. ln -s bin sbin
  100. ln -s usr/lib lib
  101. ln -s usr/bin bin
  102. ln -s usr/bin sbin
  103. mkdir -m 777 tmp
  104. cat >etc/passwd <<EOF
  105. root:x:0:0:root:/root:/bin/sh
  106. nobody:x:65534:65534:nobody:/var/empty:/bin/false
  107. EOF
  108. cat >etc/group <<EOF
  109. root:x:0:root
  110. nobody:x:65534:
  111. nogroup:x:65533:
  112. EOF
  113. for i in fd stderr stdin stdout; do
  114. ln -fs proc/self/$i dev/$i
  115. done
  116. cp "${WORKDIR}/init.c" ./init || die "copying init"
  117. sed -i '1i#!/usr/bin/tcc -run' ./init || die "failed adding tcc shebang to init"
  118. chmod 755 init || die "init chmod"
  119. cp -p "${WORKDIR}/ar-stub.sh" ./bin/ar
  120. for apk in $APKS_main $APKS_testing
  121. do
  122. tar xof "${WORKDIR}/distfiles/$apk.${ALPINE_ARCH}" --exclude '.*'
  123. done
  124. # Allows to shave off ~9.1M from the binary seed
  125. rm usr/lib/libc.a
  126. # For CLOCK_MONOTONIC and clock_gettime
  127. sed -i -e '1a#include <time.h>' loksh-*/c_sh.c || die "Failed patching loksh/c_sh.c"
  128. # For u_char
  129. sed -i -e '1a#include <sys/types.h>' loksh-*/edit.c || die "Failed patching loksh/c_sh.c"
  130. # For int64_t
  131. sed -i -e '1a#include <stdint.h>' loksh-*/table.h || die "Failed patching loksh/table.h"
  132. sed -i -e '1a#include <limits.h>' -e 's;_PW_NAME_LEN;LOGIN_NAME_MAX;' loksh-*/main.c || die "Failed patching loksh/main.c"
  133. gen_loksh_tcc_h > loksh_tcc.h
  134. ln -s loksh bin/sh
  135. oyacc=$(echo ./yacc-oyacc-*/)
  136. cat >"${oyacc}/config.h" <<EOF
  137. // __dead and __dead2 are absent in musl
  138. #define __dead __attribute__((__no_return__))
  139. // HAVE_PROGNAME: Absent in musl
  140. #define HAVE_ASPRINTF
  141. // HAVE_PLEDGE: Absent in musl
  142. #define HAVE_REALLOCARRAY
  143. #define HAVE_STRLCPY
  144. EOF
  145. sed -i -e 's;bzip2-shared;bzip2;' bzip2-*/Makefile-libbz2_so || die "Failed patching /bzip2-*/Makefile-libbz2_so"
  146. sed -i -e 's;all: libbz2.a;all: libbz2.so;' -e 's;bzip2: libbz2.a;bzip2: libbz2.so;' bzip2-*/Makefile || die "Failed patching /bzip2-*/Makefile"
  147. rm bzip2-*/sample* || die "Failed removing sample bzip2 files"
  148. patch -p0 <"${WORKDIR}/zlib-1.3.1_no_staticlib.patch"
  149. patch -p0 <"${WORKDIR}/zlib-1.3.1-use-LDFLAGS-in-configure.patch"
  150. patch -p0 <"${WORKDIR}/zlib-1.3.1-use-LDFLAGS-in-configure_no_gcc.patch"
  151. rm zlib-*/doc/crc-doc.1.0.pdf || die "Failed removing zlib crc-doc.1.0.pdf"
  152. rm zlib-*/crc32.h || die "Failed removing autogenerated zlib-*/crc32.h"
  153. rm -r zlib-*/examples/ || die "Failed removing zlib-*/examples/"
  154. rm -r zlib-*/contrib/ || die "Failed removing zlib-*/contrib/"
  155. sed -i 's;^clean: minizip-clean;clean:;' zlib-*/Makefile.in || die "Failed disabling minizip cleanup"
  156. sed -i \
  157. -e 's;INSTALL=.*;INSTALL=install;' \
  158. -e 's;PREFIX=.*;PREFIX=/usr;;' \
  159. -e 's;STRIP=.*;STRIP=true;' \
  160. -e 's;#?AR=.*;AR ?= ar;' \
  161. -e 's;RANLIB=.*;RANLIB ?= ranlib;' \
  162. -e 's;YACC=.*;YACC ?= yacc;' \
  163. heirloom-devtools-*/mk.config \
  164. || die "Failed configuring heirloom-devtools"
  165. # pdpmake-1.4.3+ consider them invalid "macros"
  166. sed -i \
  167. -e '/^\.c\.o:/s/;/\n\t/' \
  168. heirloom-devtools-*/lex/Makefile.mk heirloom-devtools-*/m4/Makefile.mk \
  169. || die "Failed patching .c.o: infered targets in heirloom-devtools"
  170. # - maninst Fails to create parent dir, just noop it, we don't have man anyway
  171. # -e 's;MANINST =.*;MANINST = $(SHELL) ../build/maninst.sh;' \
  172. # - Turns out tcc comes with an ar(1)
  173. # -e 's;LCOMMON =.*;LCOMMON = ../libcommon/*.c;' \
  174. sed -i \
  175. -e 's;DEFBIN =.*;DEFBIN = /bin;' \
  176. -e 's;DEFSBIN =.*;DEFSBIN = /bin;' \
  177. -e 's;STRIP =.*;STRIP = true;' \
  178. -e 's;SPELLHIST =.*;SPELLHIST = /dev/null;' \
  179. -e 's;UCBINST =.*;UCBINST = install;' \
  180. -e 's;MANINST =.*;MANINST = true;' \
  181. heirloom-0*/build/mk.config \
  182. || die "Failed configuring heirloom (toolchest)"
  183. sed -i \
  184. -e 's;__GLIBC__;__linux__;' \
  185. -e '/#define getdents/s;^;//;' \
  186. heirloom-070715/libcommon/getdir.c || die "Failed fixing heirloom libcommon for musl"
  187. sed -i \
  188. -e 's;#ifdef _AIX;#if defined(_AIX) || defined(__linux__);' \
  189. -e '/static int utf8/avoid writerr(struct oblok *op, int count, int written) {}' \
  190. heirloom-070715/tar/tar.c || die "Failed fixing heirloom tar for musl"
  191. sed -i \
  192. -e 's;#ifdef _AIX;#if defined(_AIX) || defined(__linux__);' \
  193. heirloom-070715/find/find.c || die "Failed fixing heirloom find for musl"
  194. sed -i -e 's;libwchar.a: fake;libwchar.a:;' heirloom-070715/libwchar/Makefile.mk || die
  195. sed -i -e 's;getdir.o regexpr.o gmatch.o;getdir.o gmatch.o;' heirloom-*/libcommon/Makefile.mk || die
  196. rm -r heirloom-*/libuxre heirloom-*/libcommon/regexp.h || die
  197. rm -r pigz-*/zopfli || die
  198. rm -r heirloom-devtools-*/make heirloom-devtools-*/sccs || die
  199. for i in cpio spell mail nawk oawk
  200. do
  201. rm -r heirloom-0*/$i || die
  202. done
  203. rm -r awk-*/testdir || die
  204. deblob -n | tee /dev/stderr | awk '/detected: /{ print $2 }' | xargs du -bach | sort -h
  205. cd "${WORKDIR}"