diff options
Diffstat (limited to 'make-boot-image.sh')
-rwxr-xr-x | make-boot-image.sh | 260 |
1 files changed, 146 insertions, 114 deletions
diff --git a/make-boot-image.sh b/make-boot-image.sh index 032398d..c6728cf 100755 --- a/make-boot-image.sh +++ b/make-boot-image.sh @@ -1,11 +1,11 @@ #!/bin/bash -xe - # Config # ########## -WORKDIR=/tmp/work +WORKDIR=./work DLDIR=./downloads OUTDIR=./out OUTUSB=/dev/sdb1 +KERNEL_TOOLS=y RUN_QEMU=y ROOTCMD=sudo WGET="wget --no-check-certificate" @@ -48,26 +48,148 @@ function mkchroot done } - # Environement and dependencies # ################################# +codename=$(lsb_release -sc || true) +if [ "x$codename" != "xjessie" ] +then cat >&2 <<EOT +This script is tested only on Debian 8 (aka jessie). +The fastest way to have the right environnment is : + * download debian live http://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-8.5.0-amd64-standard.iso + * burn it or copy it on a USB stick, alternatively launch a VM with it + * run this script from there +EOT + exit 1 +fi + [ -d "$WORKDIR" ] || mkdir "$WORKDIR" [ -d "$DLDIR" ] || mkdir "$DLDIR" [ -d "$OUTDIR" ] || mkdir "$OUTDIR" if [ ! -e "$WORKDIR/apt-done" ] then $ROOTCMD apt-get update - # Dependencies of this script + # Dependencies of this script (assuming default debian install or live) + $ROOTCMD apt-get install wget libncurses5-dev + # Dependencies for kernel building $ROOTCMD apt-get build-dep linux-source - $ROOTCMD apt-get install wget libncurses5-dev - # Optionnally qemu to make some santity checks + # Dependancies for kernel tools + [ "x$KERNEL_TOOLS" == "xy" ] && $ROOTCMD apt-get install libelf-dev libunwind-dev \ + libdw-dev libaudit-dev libssl-dev libslang2-dev libiberty-dev + # Optionnally qemu to run the result for santity checking [ "x$RUN_QEMU" = "xy" ] && $ROOTCMD apt-get install qemu-system-x86 # Dependencies to put into the initrd - $ROOTCMD apt-get install dmidecode pciutils usbutils lshw sysstat iftop atop + $ROOTCMD apt-get install dmidecode pciutils usbutils lshw sysstat iftop strace $ROOTCMD apt-get install partclone udpcast gdisk efibootmgr tcpdump > "$WORKDIR/apt-done" fi +# Kernel build setup # +###################### +kernel_tarball=$DLDIR/$(basename $KERNEL_TARBALL_URL) +[ -f "$kernel_tarball" ] || $WGET -O "$kernel_tarball" "$KERNEL_TARBALL_URL" +if [ ! -d "$WORKDIR/kernel" ] +then mkdir "$WORKDIR/kernel" + tar xf "$kernel_tarball" --strip-components=1 -C "$WORKDIR/kernel" +fi + +if [ ! -d "$WORKDIR/kernel/scripts/Kconfiglib" ] +then + [ -f "$DLDIR/kconfiglib.py" ] || $WGET -O "$DLDIR/kconfiglib.py" "$KCONFIGLIB_MAIN_URL" + [ -f "$DLDIR/makefile.patch" ] || $WGET -O "$DLDIR/makefile.patch" "$KCONFIGLIB_PATCH_URL" + mkdir "$WORKDIR/kernel/scripts/Kconfiglib" + cp "$DLDIR/kconfiglib.py" "$WORKDIR/kernel/scripts/Kconfiglib/kconfiglib.py" + patch -t -p1 -d "$WORKDIR/kernel" < "$DLDIR/makefile.patch" +fi + +cat >"$WORKDIR/kernel/scripts/Kconfiglib/customize.py" <<"EOT" +#!/usr/bin/env python +import kconfiglib +import sys + +def sset(sym, value=None): + if not sym.is_modifiable(): + print("%s is not modifiable at all"%(sym.get_name())) + return True + if value is None and sym.get_type() in [ kconfiglib.BOOL, kconfiglib.TRISTATE ]: + value = sym.get_upper_bound() + old_value = sym.get_value() + if old_value == value: + return False + print("CONFIG_%s=%s [was: %s]"%(sym.get_name(),value,old_value)) + sym.set_user_value(value) + return True + +conf = kconfiglib.Config(sys.argv[1]) +conf.load_config('.config') +support_xz = conf['KERNEL_XZ'] is not None +i = 0 +more_work = True +while more_work and i < 10: + more_work = False + i += 1 + print("Kconfiglib/customize.py pass %i"%i) + + for sym in conf.get_symbols(): + name = sym.get_name() + if name in ['DEFAULT_HOSTNAME']: + # default is (none) and could make FreeBSD's dhcpd complain because unallowed '()' + more_work = sset(sym, 'eficast') or more_work + + if name in ['INITRAMFS_SOURCE']: + # embed initrd in the EFI bootable kernel + more_work = sset(sym, '../initrd/') or more_work + + if name in ['EFI_STUB', 'EFI_VARS', 'DELL_RBU', 'USB_XHCI_HCD', 'IKCONFIG']: + # Make kernel directly loadable by EFI, add USB3, Dell flash... + more_work = sset(sym) or more_work + + if name in ['LOGO', 'SUSPEND', 'HIBERNATION', 'CPU_FREQ', 'PCCARD', 'HAMRADIO', 'WIRELESS', 'RFKILL', 'WLAN', 'SOUND', 'NETWORK_FILESYSTEMS', 'KEYS', 'SECURITY', 'VIRTUALIZATION']: + more_work = sset(sym, 'n') or more_work + + if support_xz: + # Compress everything with XZ if available (slower, smaller) + if name in ['KERNEL_XZ']: + more_work = sset(sym, 'y') or more_work + if name in ['RD_GZIP', 'RD_BZIP2', 'RD_LZMA', 'RD_LZO', 'RD_LZ4']: + more_work = sset(sym, 'n') or more_work + + # Following generic actions are meant for features, not choices + if not sym.is_choice_symbol(): + + # Build all available net/ethernet drivers + if sym.is_modifiable() and sym.get_type() in [ kconfiglib.BOOL, kconfiglib.TRISTATE ] \ + and True in [ ('drivers/net/ethernet' in filename) for (filename,_) in sym.get_def_locations() ]: + more_work = sset(sym) or more_work + + # Try to get everything in kernel, not as a module + if sym.get_value() == 'm' and sym.get_upper_bound() == 'y': + more_work = sset(sym, 'y') or more_work + +if i == 10: + print("ERROR : can't set some of kernel config symbols after 10 passes") + sys.exit(1) +else: + sys.exit( conf.write_config(".config") ) +EOT +chmod +x "$WORKDIR/kernel/scripts/Kconfiglib/customize.py" + +# Kernel prepare + make tools # +############################### +( + cd "$WORKDIR/kernel" + if [ ! -f .config ] + then make defconfig + make scriptconfig SCRIPT=scripts/Kconfiglib/customize.py + fi +) + +if [ "x$KERNEL_TOOLS" == "xy" ] +then ( + cd "$WORKDIR/kernel" + make tools/perf + ) +fi + # Initial Ram Disk building (embed in kernel) # ############################################### if [ ! -d "$WORKDIR/initrd" ] @@ -90,9 +212,9 @@ fi ( set +x - PATH="/usr/sbin:/usr/bin:/sbin:/bin" + PATH="$WORKDIR/kernel/tools/perf:/usr/sbin:/usr/bin:/sbin:/bin" # Diagnostic tools - mkchroot "$WORKDIR/initrd" atop dmidecode iftop iostat lshw lspci lsusb mpstat tcpdump + mkchroot "$WORKDIR/initrd" dmidecode iftop iostat lshw lspci lsusb mpstat tcpdump # Manpage display mkchroot "$WORKDIR/initrd" strace groff nroff troff grotty gtbl # Cloning tools @@ -101,14 +223,18 @@ fi mkchroot "$WORKDIR/initrd" /lib/x86_64-linux-gnu/libusb-1.0.so.0 ) -#if [ ! -L "$WORKDIR/initrd/lib/x86_64-linux-gnu/tls/x86_64" ] -#then mkdir -p "$WORKDIR/initrd/lib/x86_64-linux-gnu/tls" -# ln -s "../.." "$WORKDIR/initrd/lib/x86_64-linux-gnu/tls/x86_64" -#fi +if [ "x$KERNEL_TOOLS" == "xy" ] +then ( + p="$WORKDIR/kernel/tools/perf/perf" + cp -a "$p" "$WORKDIR/initrd/sbin/" + set +x + mkchroot "$WORKDIR/initrd" $(ldd "$p" | egrep -o '/.* ') + ) +fi if [ ! -d "$WORKDIR/initrd/usr/man" ] -then mkdir -p "$WORKDIR"/initrd/usr/man/man{1,8} "$WORKDIR"/initrd/usr/share/groff/1.22.2/font "$WORKDIR/initrd/etc/groff" - cp /usr/share/man/man1/{atop.1,iostat,mpstat,strace,udp-receiver}* "$WORKDIR/initrd/usr/man/man1/" +then mkdir -p "$WORKDIR"/initrd/usr/man/man{1,8} "$WORKDIR"/initrd/usr/share/groff/1.22.2/font "$WORKDIR/initrd/etc/groff/" + cp /usr/share/man/man1/{iostat,mpstat,strace,udp-receiver}* "$WORKDIR/initrd/usr/man/man1/" cp /usr/share/man/man8/{dmidecode,partclone,efibootmgr,gdisk,iftop,tcpdump}* "$WORKDIR/initrd/usr/man/man8/" cp -r /usr/share/groff/1.22.2/font/devascii "$WORKDIR/initrd/usr/share/groff/1.22.2/font/" cp -r /usr/share/groff/1.22.2/tmac "$WORKDIR/initrd/usr/share/groff/1.22.2/" @@ -211,109 +337,15 @@ ip -o addr show | sed -ne 's/[0-9]*:\s*\(\S*\)\s*inet6*\s\(\S*\)\s.*$/\1: \2/p' EOT chmod +x "$WORKDIR/initrd/init" - -# Kernel build setup # -###################### -kernel_tarball=$DLDIR/$(basename $KERNEL_TARBALL_URL) -[ -f "$kernel_tarball" ] || $WGET -O "$kernel_tarball" "$KERNEL_TARBALL_URL" -if [ ! -d "$WORKDIR/kernel" ] -then mkdir "$WORKDIR/kernel" - tar xf "$kernel_tarball" --strip-components=1 -C "$WORKDIR/kernel" -fi - -if [ ! -d "$WORKDIR/kernel/scripts/Kconfiglib" ] -then - [ -f "$DLDIR/kconfiglib.py" ] || $WGET -O "$DLDIR/kconfiglib.py" "$KCONFIGLIB_MAIN_URL" - [ -f "$DLDIR/makefile.patch" ] || $WGET -O "$DLDIR/makefile.patch" "$KCONFIGLIB_PATCH_URL" - mkdir "$WORKDIR/kernel/scripts/Kconfiglib" - cp "$DLDIR/kconfiglib.py" "$WORKDIR/kernel/scripts/Kconfiglib/kconfiglib.py" - patch -t -p1 -d "$WORKDIR/kernel" < "$DLDIR/makefile.patch" -fi - -cat >"$WORKDIR/kernel/scripts/Kconfiglib/customize.py" <<"EOT" -#!/usr/bin/env python -import kconfiglib -import sys - -def sset(sym, value=None): - if not sym.is_modifiable(): - print("%s is not modifiable at all"%(sym.get_name())) - return True - if value is None and sym.get_type() in [ kconfiglib.BOOL, kconfiglib.TRISTATE ]: - value = sym.get_upper_bound() - old_value = sym.get_value() - if old_value == value: - return False - print("CONFIG_%s=%s [was: %s]"%(sym.get_name(),value,old_value)) - sym.set_user_value(value) - return True - -conf = kconfiglib.Config(sys.argv[1]) -conf.load_config('.config') -support_xz = conf['KERNEL_XZ'] is not None -i = 0 -more_work = True -while more_work and i < 10: - more_work = False - i += 1 - print("Kconfiglib/customize.py pass %i"%i) - - for sym in conf.get_symbols(): - name = sym.get_name() - if name in ['DEFAULT_HOSTNAME']: - # default is (none) and could make FreeBSD's dhcpd complain because unallowed '()' - more_work = sset(sym, 'eficast') or more_work - - if name in ['INITRAMFS_SOURCE']: - # embed initrd in the EFI bootable kernel - more_work = sset(sym, '../initrd/') or more_work - - if name in ['EFI_STUB', 'EFI_VARS', 'DELL_RBU', 'USB_XHCI_HCD', 'IKCONFIG']: - # Make kernel directly loadable by EFI, add USB3, Dell flash... - more_work = sset(sym) or more_work - - if name in ['LOGO', 'SUSPEND', 'HIBERNATION', 'CPU_FREQ', 'PCCARD', 'HAMRADIO', 'WIRELESS', 'RFKILL', 'WLAN', 'SOUND', 'NETWORK_FILESYSTEMS', 'KEYS', 'SECURITY', 'VIRTUALIZATION']: - more_work = sset(sym, 'n') or more_work - - if support_xz: - # Compress everything with XZ if available (slower, smaller) - if name in ['KERNEL_XZ']: - more_work = sset(sym, 'y') or more_work - if name in ['RD_GZIP', 'RD_BZIP2', 'RD_LZMA', 'RD_LZO', 'RD_LZ4']: - more_work = sset(sym, 'n') or more_work - - # Following generic actions are meant for features, not choices - if not sym.is_choice_symbol(): - - # Build all available net/ethernet drivers - if sym.is_modifiable() and sym.get_type() in [ kconfiglib.BOOL, kconfiglib.TRISTATE ] \ - and True in [ ('drivers/net/ethernet' in filename) for (filename,_) in sym.get_def_locations() ]: - more_work = sset(sym) or more_work - - # Try to get everything in kernel, not as a module - if sym.get_value() == 'm' and sym.get_upper_bound() == 'y': - more_work = sset(sym, 'y') or more_work - -if i == 10: - print("ERROR : can't set some of kernel config symbols after 10 passes") - sys.exit(1) -else: - sys.exit( conf.write_config(".config") ) -EOT -chmod +x "$WORKDIR/kernel/scripts/Kconfiglib/customize.py" - -# Kernel build kernel # -####################### +# Kernel build (with embed initramfs) # +####################################### ( cd "$WORKDIR/kernel" - if [ ! -f .config ] - then make defconfig - make scriptconfig SCRIPT=scripts/Kconfiglib/customize.py - fi # Workaround : some kernel version forget to update embed initramfs in certain cases [ -f usr/initramfs_data.cpio.gz ] && rm usr/initramfs_data.cpio.gz - make -j8 + make ) + # Copy / run result EFI file # ############################## cp "$WORKDIR/kernel/arch/x86/boot/bzImage" "$OUTDIR/BOOTX64.EFI" @@ -327,5 +359,5 @@ then [ -d "$WORKDIR/mountpoint" ] || mkdir "$WORKDIR/mountpoint" $ROOTCMD umount "$WORKDIR/mountpoint" fi -[ "x$RUN_QEMU" == "xy" ] && qemu-system-x86_64 -kernel "$OUTDIR/BOOTX64.EFI" +[ "x$RUN_QEMU" == "xy" ] && qemu-system-x86_64 -M q35 -m 256 -kernel "$OUTDIR/BOOTX64.EFI" |