浏览代码

Major improvements to early boot stage

Simplified boot parameters handling: all parameters, except
"cdroot_hash", are now omitted by default. Syslinux
configuration files for SYSLINUX, EXTLINUX and ISOLINUX are
not separate anymore.

Initramfs has better handling of (default) "cdroot_type=auto":
all filesystem modules are loaded, and after the filesystem
is mounted, it is remounted with appropriate options according
to its type -- unless "cdroot_flags=..." was specified. Unused
modules are then unloaded. In addition, "cdroot_type" (if
specified) is validated against known filesystems list.

For CD boot, "readonly" and "toram" parameters are inferred
automatically. Inference of "toram" can be overridden with
the new "notoram" parameter.

A new small ISO image is now generated, which is identical
to the regular image, but lacks the SquashFS loopback file.
This allows using persistence on writable media when booting
from a CD, which is useful for computers that cannot boot
from USB media, and for keeping persistence on media which
is otherwise used in untrusted environment. The writable
media still needs to have a regular installation performed.
A normal ISO CD can be used for the same purpose, if, e.g.,
"cdroot_type=vfat" is added to boot parameters. Sometimes
even that might not be necessary, if the USB media is
recognized quickly enough at early boot.

(U)EFI boot now implements a trusted boot chain beginning at
EFI boot binaries. BOOT*.EFI GRUB images embed an early boot
manifest authenticating non-embedded GRUB configuration and
manifest, which authenticates GRUB auxiliary files and Linux
kernel. SquashFS image checksum is then passed with kernel
parameters as usual.

EFI images are now significantly smaller, due to LZMA
compression of individual modules (Savannah: #36770).
Maxim Kammerer 13 年之前
父节点
当前提交
d7663bee34

+ 3 - 0
doc/changelog.txt

@@ -2,11 +2,14 @@
   + 2012.3 release
 
   * Kernel image is now bundled with initramfs
+  * (U)EFI trusted boot chain beginning at EFI boot binaries
   * Xorg server 1.12 and Mesa 8.0 with Gallium3D for Radeon cards
   * Better support for VMware graphics virtualization
 
+  * Simplified boot parameters handling, most are now omitted
   * Added "blacklist" boot parameter for kernel modules blacklisting
 
+  * Added small CD -> USB bootstrapping ISO image
   * Added optional PKCS#11 smart-cards support to GnuPG
   * Added reaver-wps, a WiFi Protected Setup cracking tool
 

+ 2 - 2
mkvmdist

@@ -31,7 +31,7 @@ distname=liberte-${version}
 
 # Derived paths
 logosvg=${src}/src/home/anon/config/images/liberte-logo-nofont.svg
-efiboot=${cdroot}/isolinux/efiboot.img
+efiboot=${cdroot}/boot/efiboot.img
 syslinux=${cdroot}/liberte/boot/syslinux/syslinux-x86.tbz
 
 ovfpath=${vmstage}/${distname}.ovf
@@ -149,7 +149,7 @@ test -e ${vmstage}/vpart/EFI/BOOT/BOOTx64.EFI
 vmware-mount -d ${vmstage}/vpart
 
 vmware-mount ${diskpath} 2 ${vmstage}/vpart
-test -e ${vmstage}/vpart/liberte/boot/syslinux/ext/ldlinux.sys
+test -e ${vmstage}/vpart/liberte/boot/syslinux/ldlinux.sys
 vmware-mount -d ${vmstage}/vpart
 
 

+ 24 - 7
src/root/config/grub-early.cfg

@@ -1,16 +1,33 @@
 echo "Liberté Linux VERSION: Early boot using GRUB ${grub_cpu}-${grub_platform}"
+set manifest=(memdisk)/grub/grub.mf
+set chaingrub=/liberte/boot/grub/grub.cfg
+
 
 # Search for media with grub.cfg to switch to
-# ${root}:   default for paths without explicit device name
-# ${prefix}: dynamic modules location
 echo "Searching for the boot device ..."
 insmod part_msdos
 insmod part_gpt
-search -f --set root --no-floppy PREFIX/boot/grub/grub.cfg
 
-if [ -z "${root}"  -o  "${root}" = memdisk ]; then
-    echo "Could not find media with PREFIX/boot/grub/grub.cfg"
-fi
+# fs list must match fs.lst (Savannah: #36770)
+insmod iso9660
+insmod fat
+insmod ext2
+insmod hfsplus
 
+# ${prefix}: dynamic modules location
+# ${root}:   default for paths without explicit device name
+search -f -n -s root ${chaingrub}
 
-configfile PREFIX/boot/grub/grub.cfg
+if [ -z "${root}"  -o  "${root}" = memdisk ]; then
+    echo "Could not find media with ${chaingrub}"
+    sleep 3
+else
+    echo -e "Verifying early manifest checksums ...\n"
+    if ! sha256sum -k -c ${manifest}; then
+        echo -e "\nWARNING: Bootloader configuration is corrupted!"
+        echo -e "Abort the boot (recommended), or press [Enter] to continue anyway.\n"
+        read
+    fi
+
+    configfile ${chaingrub}
+fi

+ 17 - 26
src/root/config/grub.cfg

@@ -1,9 +1,7 @@
 ## Variables:
-## PREFIX:      /liberte, image root                     (replaced in gen-efi)
 ## VERSION:     distribution version                     (replaced in gen-efi)
 ## CONSOLEFONT: PFF2 gfxterm font                        (replaced in gen-efi)
 ## FSHASH:      SquashFS image hexadecimal SHA-256 hash  (replaced in mkimage)
-## {VFAT,ISOFS,EXT,HFSP}FLAGS: filesystem-specific flags (replaced in mkimage)
 ##
 # Regular kernel parameters:
 #     (see syslinux.cfg)
@@ -18,20 +16,24 @@ set default=0
 set timeout=7
 
 set pager=1
-set fontfile=PREFIX/boot/grub/CONSOLEFONT
 
 
-# Parameters that are supplied in mkimage
+# File paths (${root} is set in (memdisk)/grub/grub.cfg)
+set manifest=/liberte/boot/grub/grub.mf
+set kernel=/liberte/boot/kernel-x86.zi
+set fontfile=/liberte/boot/grub/CONSOLEFONT
+
+# SquashFS checksum (kernel checksum is in manifest)
 set fshash=FSHASH
-set vfatflags=VFATFLAGS
-set isofsflags=ISOFSFLAGS
-set extflags=EXTFLAGS
-set hfspflags=HFSPFLAGS
 
-# Kernel and live image paths
-# ${root} is set in (memdisk)/grub/grub.cfg
-set kernel=PREFIX/boot/kernel-x86.zi
-set squash=PREFIX/boot/root-x86.sfs
+
+# This file and manifest are recorded in (memdisk)/grub/grub.mf
+echo -e "Verifying manifest checksums ...\n"
+if ! sha256sum -k -c ${manifest}; then
+    echo -e "\nWARNING: Liberté kernel or bootloader files are corrupted!"
+    echo -e "Abort the boot (recommended), or press [Enter] to continue anyway.\n"
+    read
+fi
 
 
 # Set an architecture ID from
@@ -49,10 +51,6 @@ else
 fi
 
 
-# cdroot_type/flags are auto/noatime by default (set in initramfs)
-set cdflags="cdroot_hash=${fshash}"
-
-
 # Switch to gfxterm
 # Alternatively: gfxpayload=1024x768x32,800x600x32,auto
 if loadfont ${fontfile}; then
@@ -69,23 +67,16 @@ set menu_color_normal=light-gray/blue
 set menu_color_highlight=yellow/red
 
 
-# Detect CD boot by presence of /isolinux directory
-if [ -e /isolinux ]; then
-    set tag="${tag} CD"
-    set cdflags="${cdflags} cdroot_type=iso9660 cdroot_flags=${isofsflags} readonly toram"
-fi
-
-
 menuentry "[${tag}] Liberté Linux VERSION"                         --class=linux {
-    linux  ${kernel} loop=${squash} ${cdflags} add_efi_memmap quiet memtest=1 loglevel=4
+linux  ${kernel} cdroot_hash=${fshash} add_efi_memmap quiet memtest=1 loglevel=4
 }
 
 menuentry "[${tag}] Liberté Linux VERSION (Framebuffer Graphics)"  --class=linux {
-    linux  ${kernel} loop=${squash} ${cdflags} add_efi_memmap nomodeset gentoo=xfb quiet memtest=1 loglevel=4
+linux  ${kernel} cdroot_hash=${fshash} add_efi_memmap nomodeset gentoo=xfb quiet memtest=1 loglevel=4
 }
 
 menuentry "[${tag}] Liberté Linux VERSION (Administrator Console)" --class=linux {
-    linux  ${kernel} loop=${squash} ${cdflags} nomodeset gentoo=nox,root memtest=2 loglevel=6
+linux  ${kernel} cdroot_hash=${fshash} nomodeset gentoo=nox,root memtest=2 loglevel=6
 }
 
 

+ 1 - 1
src/root/config/linux-3.2.11-hardened.config

@@ -3524,7 +3524,7 @@ CONFIG_FAT_FS=m
 # CONFIG_MSDOS_FS is not set
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #

+ 22 - 27
src/root/config/syslinux.cfg

@@ -1,22 +1,17 @@
 ## Variables
-## PREFIX:      /liberte, image root                     (replaced in gen-syslinux)
 ## VERSION:     distribution version                     (replaced in gen-syslinux)
 ## CONSOLEFONT: psf(u) console font                      (replaced in gen-syslinux)
-## TAG:         [USB], [CD], ...                         (replaced in mkimage)
-## ROOTFS:      vfat, ext4, iso9660, squashfs, ...       (replaced in mkimage)
-## FSFLAGS:     noatime,...                              (replaced in mkimage)
 ## FSHASH:      SquashFS image hexadecimal SHA-256 hash  (replaced in mkimage)
 ##
 # Liberté-specific kernel parameters (all are optional):
-#     cdroot_type={auto,vfat,ext4,iso9660,squashfs} - boot media filesystem type
+#     cdroot_type={auto,vfat,ext4,iso9660,hfsplus,squashfs} - boot media filesystem type
 #     cdroot_flags=...   - boot media mount flags
 #     cdroot=/dev/xxx    - boot media device (can be a glob pattern)
-#     cdroot_hash=<hex>  - verify given SquahFS image hexadecimal SHA-256 hash
+#     cdroot_hash=<hex>  - verify given SquashFS image hexadecimal SHA-256 hash
 #     loop=...           - path to SquashFS image on boot media
-#                          (must have cdroot_type=squashfs if unspecified)
 #     debug              - pause initramfs before mount probing and before booting
 #     readonly           - set read-only access for boot media device (no OTFE)
-#     toram              - copy SquashFS image to RAM (useful for CDs)
+#     toram / notoram    - cache SquashFS image in RAM (automatic for CDs)
 #     blacklist=...      - comma-separated list of kernel modules to blacklist
 #
 #     gentoo=root        - unlock root password ("liberte")
@@ -46,35 +41,35 @@
 DEFAULT liberte
 TIMEOUT 70
 
-UI   PREFIX/boot/syslinux/menu.c32
-FONT PREFIX/boot/syslinux/CONSOLEFONT
+UI   /liberte/boot/syslinux/menu.c32
+FONT /liberte/boot/syslinux/CONSOLEFONT
 
 MENU TITLE Liberté Linux Boot Menu
 MENU CLEAR
 
 
 LABEL liberte
-    MENU LABEL TAG Liberté Linux VERSION
-    LINUX  PREFIX/boot/kernel-x86.zi
-    APPEND loop=PREFIX/boot/root-x86.sfs cdroot_type=ROOTFS cdroot_flags=FSFLAGS cdroot_hash=FSHASH video=800x600-32 quiet memtest=1 loglevel=4
+    MENU LABEL Liberté Linux VERSION
+    LINUX  /liberte/boot/kernel-x86.zi
+    APPEND cdroot_hash=FSHASH video=800x600-32 quiet memtest=1 loglevel=4
     TEXT HELP
 Select for normal boot.
-Optional params: readonly, toram, gentoo={i2p,nosettings}.
+Optional params: readonly, [no]toram, gentoo={i2p,nosettings}.
     ENDTEXT
 
 LABEL vesa
-    MENU LABEL TAG Liberté Linux VERSION (VESA Graphics)
-    LINUX  PREFIX/boot/kernel-x86.zi
-    APPEND loop=PREFIX/boot/root-x86.sfs cdroot_type=ROOTFS cdroot_flags=FSFLAGS cdroot_hash=FSHASH nomodeset gentoo=xvesa quiet memtest=1 loglevel=4
+    MENU LABEL Liberté Linux VERSION (VESA Graphics)
+    LINUX  /liberte/boot/kernel-x86.zi
+    APPEND cdroot_hash=FSHASH nomodeset gentoo=xvesa quiet memtest=1 loglevel=4
     TEXT HELP
 Disables framebuffer console and forces VESA graphics in X.
-Optional params: readonly, toram, gentoo={i2p,nosettings}.
+Optional params: readonly, [no]toram, gentoo={i2p,nosettings}.
     ENDTEXT
 
 LABEL console
-    MENU LABEL TAG Liberté Linux VERSION (Administrator Console)
-    LINUX  PREFIX/boot/kernel-x86.zi
-    APPEND loop=PREFIX/boot/root-x86.sfs cdroot_type=ROOTFS cdroot_flags=FSFLAGS cdroot_hash=FSHASH nomodeset gentoo=nox,root memtest=2 earlyprintk=vga loglevel=6
+    MENU LABEL Liberté Linux VERSION (Administrator Console)
+    LINUX  /liberte/boot/kernel-x86.zi
+    APPEND cdroot_hash=FSHASH nomodeset gentoo=nox,root memtest=2 earlyprintk=vga loglevel=6
     TEXT HELP
 Select for troubleshooting. Add "debug" for initramfs shell.
 After boot, press Alt-F2 to switch to root console.
@@ -87,7 +82,7 @@ MENU SEPARATOR
 
 LABEL disk1
     MENU LABEL Boot Hard Disk 1
-    COM32  PREFIX/boot/syslinux/chain.c32
+    COM32  /liberte/boot/syslinux/chain.c32
     APPEND hd0
     TEXT HELP
 The boot media is typically configured as the first hard disk by BIOS.
@@ -96,7 +91,7 @@ If this is the case, try the the next option to boot the hard drive.
 
 LABEL disk2
     MENU LABEL Boot Hard Disk 2
-    COM32  PREFIX/boot/syslinux/chain.c32
+    COM32  /liberte/boot/syslinux/chain.c32
     APPEND hd1
 
 
@@ -105,11 +100,11 @@ MENU SEPARATOR
 
 LABEL hdt
     MENU LABEL Hardware Detection Tool
-    COM32 PREFIX/boot/syslinux/hdt.c32
+    COM32 /liberte/boot/syslinux/hdt.c32
 
 LABEL memtest
     MENU LABEL Memory Test 86+
-    LINUX PREFIX/boot/memtest86plus/memtest
+    LINUX /liberte/boot/memtest86plus/memtest
     TEXT HELP
 Note that simple memory testing is done
 during each boot of Liberté Linux.
@@ -121,11 +116,11 @@ MENU SEPARATOR
 
 LABEL reboot
     MENU LABEL Reboot
-    COM32 PREFIX/boot/syslinux/reboot.c32
+    COM32 /liberte/boot/syslinux/reboot.c32
 
 LABEL poweroff
     MENU LABEL Power Off
-    COMBOOT PREFIX/boot/syslinux/poweroff.com
+    COMBOOT /liberte/boot/syslinux/poweroff.com
 
 
 # 0=reset, 1/22=bold, 4/24=underline, 5/25=blink, 7/27=reverse

+ 5 - 0
src/root/dist/README.txt

@@ -15,6 +15,11 @@ from USB drive in your computer BIOS, and give it
 precedence over regular hard disk boot. Or, you can
 enable the Multiboot menu in BIOS.
 
+Another option is to install Liberté to USB or SD media,
+but boot from a bootstrap CD, which then continues with
+USB/SD. This also allows to ensure that the booted kernel
+has not been corrupted by malware.
+
 NOTE: The USB stick needs to be formatted as FAT/FAT32.
 Older computers might be able to boot only FAT(16)-formatted
 USB keys - the corresponding BIOS boot option is typically

+ 1 - 1
src/root/dist/qemulate.sh

@@ -8,7 +8,7 @@ bootdir=`dirname $0`/boot
 
 cdrom="if=virtio,format=raw,media=cdrom,aio=native,cache=none"
 
-params="cdroot_type=squashfs cdroot_hash=FSHASH video=800x600-32 quiet loglevel=4"
+params="loop=/ cdroot_hash=FSHASH video=800x600-32 quiet loglevel=4"
 
 export QEMU_AUDIO_DRV=alsa
 

+ 2 - 2
src/root/dist/setup.sh

@@ -196,7 +196,7 @@ case "${devfs}" in
         echo "Detected FAT(32) filesystem, will install using SYSLINUX"
         devfs=fat
         ;;
-    ext2|ext3|ext4)
+    ext[234])
         echo "Detected ext[234] filesystem, will install using EXTLINUX"
         devfs=ext2
         ;;
@@ -297,7 +297,7 @@ elif [ ${devfs} = ext2 ]; then
 
     # Install EXTLINUX
     echo "*** Installing EXTLINUX in ${devdir} ***"
-    ${extbin} -i "${devdir}"${sysdir}/ext
+    ${extbin} -i "${devdir}"${sysdir}
 
     if [ -n "${mntexec}" ]; then
         echo "Remounting ${mntexec} with noexec option"

+ 13 - 5
src/root/helpers/gen-efi

@@ -21,11 +21,12 @@ consolefont=euro.pf2
 
 
 # Included modules (command.lst, partmap.lst, fs.lst, video.lst)
-modules_core="normal configfile echo test true minicmd ls search"
+modules_core="normal configfile echo test true minicmd sleep ls"
 modules_fs="part_msdos part_gpt iso9660 fat ext2 hfsplus loopback"
 modules_boot="boot linux halt reboot chain appleldr"
 modules_arch="cpuid loadbios gfxterm efi_gop efi_uga fixvideo"
-modules="${modules_core} ${modules_fs} ${modules_boot} ${modules_arch}"
+modules_io="search hashsum gcry_sha256 read"
+modules="${modules_core} ${modules_fs} ${modules_boot} ${modules_arch} ${modules_io}"
 
 
 # Building a memdisk (see grub2-mkstandalone (Savannah: #36772))
@@ -58,15 +59,23 @@ memdisk() {
     mods=`echo "${mods}" | sed "s:.*:${libdir}/${arch}/&.mod:"`
     cp -p ${mods} ${moddir}
 
-    sed "s@PREFIX@/liberte@; s@VERSION@${LVERSION}@" ${templearlycfg} \
+    sed "s@VERSION@${LVERSION}@" ${templearlycfg} \
         > ${build}/grub/grub.cfg
 
+    # Compress all files (*.mod, *.lst, grub.cfg)
+    xz -C crc32 --lzma2=dict=1MiB `find ${build}/grub -type f`
+    rename .xz ""                 `find ${build}/grub -type f`
+
+    # Add bogus manifest (to be patched in mkimage)
+    echo "replace_hash__________________________________________________01  /liberte${grubcfg}"        > ${build}/grub/grub.mf
+    echo "replace_hash__________________________________________________02  /liberte${grubcfg%.*}.mf" >> ${build}/grub/grub.mf
+
     tar -cf ${build}/memdisk.tar -C ${build} grub
 
     # NOTE: -C has no effect      (#424527), (Savannah: #36770)
     # NOTE: -p must come after -m (#424521), (Savannah: #36771)
     grub2-mkimage -C xz -O ${arch} -m ${build}/memdisk.tar -p "(memdisk)/grub" \
-                  -o ${out} memdisk tar
+                  -o ${out} memdisk tar xzio gcry_crc
     rm -r ${build}
 }
 
@@ -86,7 +95,6 @@ cp -p /usr/share/grub*/${consolefont} ${grubroot}
 # Substitute and copy template
 cat ${templcfg}                           \
     | sed "/^##/d ;
-           s@PREFIX@/liberte@ ;
            s@VERSION@${LVERSION}@ ;       \
            s@CONSOLEFONT@${consolefont}@" \
     > ${grubcfg}

+ 2 - 8
src/root/helpers/gen-kernel

@@ -42,24 +42,18 @@ rmake="make -s ${makeopts} -C ${kernsrc} ${bver} ${bts} ${buser} ${bhost}"
 make="sudo -n -u bin ${rmake}"
 
 
-# Reset build version
-rm -f ${mainobj}/${compile_h}
-rm -f ${kexecobj}/${compile_h}
-rm -f ${kexec64obj}/${compile_h}
-
-
 # Handle kernel preparation for building external modules
 if [ "${cmd}" = prepare ]; then
     ${make} O=${mainobj} modules_prepare 2>/dev/null
     exit
 elif [ "${cmd}" = modules ]; then
-    # bzImage is necessary for System.map (although initramfs may not exist yet,
+    # vmlinux is necessary for System.map (although initramfs may not exist yet,
     # or is outdated), which is needed for module dependencies to be used by
     # gen-initramfs; this also generates gen_init_cpio
     if [ ! -e ${initrd} ]; then
         touch ${initrd}
     fi
-    ${make}  O=${mainobj} bzImage 2>/dev/null
+    ${make}  O=${mainobj} vmlinux 2>/dev/null
 
     # Build main kernel modules (chmod due to GRKERNSEC_HIDESYM)
     ${make}  O=${mainobj} modules 2>/dev/null

+ 0 - 1
src/root/helpers/gen-syslinux

@@ -41,7 +41,6 @@ gunzip ${sysroot}/${consolefont}.gz
 # Substitute and copy template
 cat ${templcfg}                           \
     | sed "/^##/d ;
-           s@PREFIX@/liberte@ ;
            s@VERSION@${LVERSION}@ ;
            s@CONSOLEFONT@${consolefont}@" \
     | iconv -f UTF-8 -t ${encoding}       \

+ 44 - 14
src/root/initrd/init

@@ -40,14 +40,17 @@ mkdir -m 755 ${srwroot}/etc ${srwroot}/var ${srwroot}/home
 mount -t devtmpfs -o nosuid,noexec devtmpfs /dev
 
 
-# Parse kernel options
-param_cdroot='/dev/sd* /dev/sr* /dev/vd* /dev/mmcblk*'
-param_cdroot_type=auto
-param_cdroot_flags=noatime
+# Parse kernel options, with sensible defaults
 for param in `cat /proc/cmdline`; do
-    eval param_${param%%[=.]*}=${param#*=} 2>/dev/null
+    eval param_${param%%[^a-z0-9_]*}=\"\${param#*=}\"
 done
 
+: ${param_cdroot:='/dev/sd* /dev/sr* /dev/vd* /dev/mmcblk*'}
+: ${param_loop:=/liberte/boot/root-x86.sfs}
+
+# Sets/validates param_cdroot_{type,flags}
+set_cdroot_type
+
 
 # Handle blacklisted modules
 if [ -n "${param_blacklist}" ]; then
@@ -61,7 +64,7 @@ good_msg 'Loading modules'
 
 # Specify required filesystem modules (no autoloading on mount)
 # Load EHCI unconditionally, otherwise USB 1.1 might be forced if OHCI/UHCI comes up first
-eval force_load=\"loop squashfs ehci-hcd \${force_load_"${param_cdroot_type}"}\"
+force_load="loop ${force_load_fs} ehci-hcd"
 
 oldmods=
 newmods=" ${force_load} "
@@ -110,11 +113,15 @@ while :; do
                 mediaro=`blockdev --getro ${mediadev} 2>/dev/null` || mediaro=1
                 [ ${mediaro} = 1 ] || blockdev --setro ${mediadev}
 
-                if mount -r -t ${param_cdroot_type} -o ${param_cdroot_flags} ${mediadev} ${sboot} >/dev/null 2>&1; then
+                if mount -r -t ${param_cdroot_type} -o "${param_cdroot_flags}" ${mediadev} ${sboot} >/dev/null 2>&1; then
                     # Check for the recognition file
-                    if [ -e ${sboot}${param_loop} ]; then
+                    if [ -e ${sboot}"${param_loop}" ]; then
                         good_msg "Media found on ${mediadev}"
 
+                        # Force 'toram' and readonly device mode on CD boot
+                        real_cdroot_type=`grep " ${sboot} " /proc/mounts | cut -d' ' -f3`
+                        [ "${real_cdroot_type}" != iso9660 ] || param_readonly=1 param_toram=1
+
                         [ ${mediaro} = 1 -o -n "${param_readonly}" ] || blockdev --setrw ${mediadev}
                         break 2
                     else
@@ -134,13 +141,32 @@ done
 test_success "find media to mount"
 
 
+# Determine fs type and remount with specific flags
+if [ ${had_cdroot_flags} = 0 -a "${real_cdroot_type}" != ${param_cdroot_type} ]; then
+    param_cdroot_type="${real_cdroot_type}" param_cdroot_flags=
+    set_cdroot_type
+
+    good_msg "Remounting ${mediadev} with ${param_cdroot_type}-specific flags"
+    umount ${sboot}
+    mount -r -t ${param_cdroot_type} -o "${param_cdroot_flags}" ${mediadev} ${sboot}
+fi
+
+
+# Unload unused filesystem modules
+for modname in `echo "${force_load_fs}" | tr - _`; do
+    if [ "`cat /sys/module/${modname}/refcnt 2>/dev/null`" = 0 ]; then
+        modprobe -r ${modname}
+    fi
+done
+
+
 # Setup the loopback mounts
 verifyroot() {
     local image="$1"
 
     if [ -n "${param_cdroot_hash}" ]; then
         good_msg 'Verifying filesystem image ...'
-        sfshash=`sha256sum ${image}`
+        sfshash=`sha256sum "${image}"`
         param_cdroot_hash=`echo "${param_cdroot_hash}" | tr A-F a-f`
 
         [ "${param_cdroot_hash}" = "${sfshash%% *}" ]
@@ -150,8 +176,11 @@ verifyroot() {
     fi
 }
 
-if [ -n "${param_loop}" ]; then
-    rootimg=${sboot}${param_loop}
+if [ "${param_loop}" != / ]; then
+    rootimg=${sboot}"${param_loop}"
+
+    # Let 'notoram' override 'toram' enforcement for CDs
+    [ -z "${param_notoram}" ] || param_toram=
 
     # If copying squashfs image to RAM, force read-only losetup
     # (BusyBox does not do that automatically (Busybox: #4784), fixed in git: 2012-06-21)
@@ -160,17 +189,18 @@ if [ -n "${param_loop}" ]; then
         rootimgram=${srwroot}/cache/root.sfs
 
         mkdir -m 700  ${srwroot}/cache
-        cp ${rootimg} ${rootimgram} || rm ${rootimgram}
+        cp "${rootimg}" ${rootimgram} || rm ${rootimgram}
         rootimg=${rootimgram}
 
         mount -o remount,ro ${srwroot}
     fi
 
-    verifyroot ${rootimg}
+    verifyroot "${rootimg}"
 
     # CONFIG_FEATURE_DEVFS must be disabled for BusyBox
     good_msg 'Mounting SquashFS filesystem'
-    mount -r -t squashfs -o loop,nodev ${rootimg} ${slive}
+    modprobe -b squashfs
+    mount -r -t squashfs -o loop,${fs_flags_squashfs} "${rootimg}" ${slive}
     test_success 'mount compressed filesystem'
 
     [ -z "${param_toram}" ] || mount -o remount,rw ${srwroot}

+ 39 - 9
src/root/initrd/modules.fs

@@ -1,10 +1,40 @@
-# Modules to force-load during initramfs stage
+# Modules to force-load during initramfs stage (see modules.extra)
 # (no module autoloading on mount in Busybox)
-force_load_vfat='vfat nls_cp437 nls_iso8859-1 nls_utf8'
-force_load_iso9660='isofs nls_iso8859-1 nls_utf8'
-force_load_ext2='ext4'
-force_load_ext3='ext4'
-force_load_ext4='ext4'
-force_load_hfsplus='hfsplus nls_utf8'
-
-force_load_auto="${force_load_vfat} ${force_load_iso9660} ${force_load_ext4}"
+force_load_fs="squashfs vfat isofs ext4 hfsplus nls_cp437 nls_iso8859-1 nls_utf8"
+
+
+# Default filesystem mount flags
+# (see also /usr/local/sbin/ps-mount)
+luser=2101
+lgroup=9000
+
+fs_flags_vfat=noatime,noexec,flush,iocharset=iso8859-1,utf8,uid=${luser},gid=${lgroup},umask=0177,dmask=077
+fs_flags_iso9660=nosuid,nodev,iocharset=iso8859-1,utf8
+fs_flags_ext2=noatime,nosuid,nodev,acl,user_xattr
+fs_flags_ext3=${fs_flags_ext2}
+fs_flags_ext4=${fs_flags_ext3}
+fs_flags_hfsplus=noatime,nosuid,nodev,uid=${luser},gid=${lgroup},umask=077
+fs_flags_squashfs=nodev
+fs_flags_auto=noatime,nosuid,nodev
+
+
+# Sets:
+#   + param_cdroot_type   legal filesystem type ('auto' if unset or unknown)
+#   + param_cdroot_flags  ${fs_flags_${param_cdroot_type}} if unset
+#   + had_cdroot_flags    0 if param_cdroot_flags was empty, 1 otherwise
+set_cdroot_type() {
+    case "${param_cdroot_type:=auto}" in
+        vfat|iso9660|ext[234]|hfsplus|squashfs|auto)
+            ;;
+        *)
+            warn_msg "Unknown cdroot_type, using 'auto'"
+            param_cdroot_type=auto
+            ;;
+    esac
+
+    had_cdroot_flags=1
+    if [ -z "${param_cdroot_flags}" ]; then
+        had_cdroot_flags=0
+        eval param_cdroot_flags=\"\${fs_flags_${param_cdroot_type}}\"
+    fi
+}

+ 48 - 49
src/root/mkimage

@@ -19,28 +19,20 @@ distroot=/mnt/boot
 distname=liberte-${LVERSION}
 zipfile=${distroot}/${distname}.zip
 isofile=${distroot}/${distname}.iso
+isobsfile=${distroot}/${distname}-bootstrap.iso
 
 efilabel=LIBERTE_EFI
-efiboot=${cdroot}/isolinux/efiboot.img
+efiboot=${cdroot}/boot/efiboot.img
 
+ziimage=${cdroot}/liberte/boot/kernel-x86.zi
 sqimage=${cdroot}/liberte/boot/root-x86.sfs
 sqsort=${live}/tmp/transient/pkg/squashfs.sort
 sqpseudo=${HOME}/config/rootfs.pseudo
 sqignore=${HOME}/config/rootfs.ignore
 
-luser=`id -u anon`
-lgroup=`id -g anon`
-
 sysver=`syslinux -v 2>&1 | cut -d' ' -f2`
 
 
-# See also /usr/local/sbin/ps-mount
-vfatflags=noatime,noexec,flush,iocharset=iso8859-1,utf8,uid=${luser},gid=${lgroup},umask=0177,dmask=077
-isofsflags=nosuid,nodev,iocharset=iso8859-1,utf8
-extflags=noatime,nosuid,nodev,acl,user_xattr
-hfspflags=noatime,nosuid,nodev,uid=${luser},gid=${lgroup},umask=077
-
-
 mibsize() {
     local bytes=`stat -c %s "$1"`
     echo $(((bytes + 512 * 1024) / (1024 * 1024)))
@@ -79,6 +71,11 @@ rsync -aHS --delete-excluded ${live}/boot ${cdroot}/liberte
 mv ${cdroot}/liberte/boot/EFI ${cdroot}
 
 
+sinfo "Converting text files to DOS line endings"
+find ${cdroot} \( -name '*.txt' -o -name '*.bat' -o -name '*.cfg' \) \
+    -exec sed -i 's/$/\r/' {} \;
+
+
 # Using default block size of 128KiB
 # (chmod due to GRKERNSEC_HIDESYM)
 sinfo "Creating SquashFS image"
@@ -88,69 +85,71 @@ mksquashfs ${live} ${sqimage} -noappend -no-progress -no-exports \
     -pf ${sqpseudo} -sort ${sqsort} -ef ${sqignore}
 chmod go= ${sqimage}
 
-sfshash=`sha256sum ${sqimage}`
-sfshash="${sfshash%% *}"
-
 
 sinfo "Adapting Syslinux and GRUB configuration"
 
-sed -i "s/TAG //; s/ROOTFS/vfat/; s/FSFLAGS/${vfatflags}/; s/FSHASH/${sfshash}/" \
-    ${cdroot}/liberte/boot/syslinux/syslinux.cfg
-sed -i "s/FSHASH/${sfshash}/; s/VFATFLAGS/${vfatflags}/; s/EXTFLAGS/${extflags}/;
-        s/ISOFSFLAGS/${isofsflags}/; s/HFSPFLAGS/${hfspflags}/" \
-    ${cdroot}/liberte/boot/grub/grub.cfg
-
-# EXTLINUX config takes precedence over SYSLINUX one when in same directory
-mkdir ${cdroot}/liberte/boot/syslinux/ext
-cp -p ${live}/boot/syslinux/syslinux.cfg ${cdroot}/liberte/boot/syslinux/ext/extlinux.conf
-sed -i "s/TAG //; s/ROOTFS/ext4/; s/FSFLAGS/${extflags}/;  s/FSHASH/${sfshash}/" \
-    ${cdroot}/liberte/boot/syslinux/ext/extlinux.conf
-
-# ISOLINUX doesn't support RockRidge/Joliet, so must replace '-' in filenames
-# (translation equivalent to mount's map=normal is still performed)
-cp -p ${live}/boot/syslinux/syslinux.cfg ${cdroot}/liberte/boot/syslinux/isolinux.cfg
-sed -i "s/TAG/[CD]/; s/ROOTFS/iso9660 readonly toram/; s/FSFLAGS/${isofsflags}/;
-        s/FSHASH/${sfshash}/; s/\(\(FONT\|LINUX\|INITRD\) [^-]*\)-/\1_/" \
-    ${cdroot}/liberte/boot/syslinux/isolinux.cfg
-
-mkdir ${cdroot}/isolinux
-cp -p ${cdroot}/liberte/boot/syslinux/isolinux.cfg ${cdroot}/isolinux/isolinux.cfg
-
-sed -i "s/FSHASH/${sfshash}/" ${cdroot}/liberte/qemulate.sh
+fshash=`sha256sum ${sqimage}`
+sed -i "s/FSHASH/${fshash%% *}/"                  \
+    ${cdroot}/liberte/boot/syslinux/syslinux.cfg  \
+    ${cdroot}/liberte/boot/grub/grub.cfg          \
+    ${cdroot}/liberte/qemulate.sh
 
+sha256sum ${cdroot}/liberte/boot/grub/* ${ziimage}  \
+    | sed "/\<grub\.\(cfg\|mf\)\>/d; s:${cdroot}::" \
+    > ${cdroot}/liberte/boot/grub/grub.mf
 
-sinfo "Converting text files to DOS line endings"
-find ${cdroot} \( -name '*.txt' -o -name '*.bat' -o -name '*.cfg' \) \
-    -exec sed -i 's/$/\r/' {} \;
+grub1hash=`sha256sum ${cdroot}/liberte/boot/grub/grub.cfg`
+grub2hash=`sha256sum ${cdroot}/liberte/boot/grub/grub.mf`
+sed -i "s/replace_hash_\{50\}01/${grub1hash%% *}/ ; \
+        s/replace_hash_\{50\}02/${grub2hash%% *}/"  \
+    ${cdroot}/EFI/BOOT/*.EFI
 
 
 # UEFI Spec 2.3.1 Err. A, Sec. 12.3.3: "UEFI implementations may allow
 # the use of conforming FAT partitions which do not use the ESP GUID."
-sinfo "Building binary distribution ${distname}.zip"
+sinfo "Building binary distribution ${zipfile##*/}"
 rm -f ${zipfile}
 (cd ${cdroot}; zip -r9 -q ${zipfile} EFI liberte)
+unzip -qt ${zipfile}
 
 
 # Add two extra 4K blocks (may need adjustment)
 sinfo "Creating EFI boot image for El-Torito"
+
+mkdir ${cdroot}/boot
 efiblocks=`du -s -B 4K --apparent-size ${cdroot}/EFI | cut -f1`
 truncate -s $(((efiblocks + 2) * 4))K ${efiboot}
+
 mkdosfs -n "${efilabel}" -I -f 1 -r 16 -R 1 ${efiboot}
 MTOOLS_SKIP_CHECK=1 mcopy -i ${efiboot} -smQ ${cdroot}/EFI ::
 
 
 # Hide root directories on Windows, and reset volume information
-sinfo "Creating ISO image ${distname}.iso"
-mkisofs -quiet -iso-level 2 -no-pad -sysid '' -V '' -A '' -R \
-    -no-emul-boot -boot-load-size 4 -boot-info-table         \
-    -c boot.cat -b liberte/boot/syslinux/isolinux.bin        \
-    -eltorito-alt-boot -no-emul-boot                         \
-    -eltorito-platform efi -b isolinux/efiboot.img           \
-    -hide boot.cat -hidden isolinux -hidden liberte -m EFI   \
-    -o ${isofile} ${cdroot}
+# Allow '-' in filenames, since ISOLINUX doesn't support RockRidge/Joliet
+# (translation equivalent to mount's map=normal is still performed)
+sinfo "Creating ISO image ${isofile##*/}"
+
+mkdir ${cdroot}/boot/syslinux
+cp -p ${cdroot}/liberte/boot/syslinux/syslinux.cfg \
+      ${cdroot}/boot/syslinux/syslinux.cfg
+
+set -- -quiet -iso-level 2 -relaxed-filenames -R -no-pad \
+       -sysid '' -V '' -A ''                             \
+       -no-emul-boot -boot-load-size 4 -boot-info-table  \
+       -c boot/eltorito.cat                              \
+       -b liberte/boot/syslinux/isolinux.bin             \
+       -eltorito-alt-boot -no-emul-boot                  \
+       -eltorito-platform efi -b boot/efiboot.img        \
+       -hidden boot -hidden liberte -m EFI
+mkisofs "$@" -o ${isofile} ${cdroot}
 isovfy ${isofile}
 
 
+sinfo "Creating ISO image ${isobsfile##*/}"
+mkisofs "$@" -m ${sqimage##*/} -o ${isobsfile} ${cdroot}
+isovfy ${isobsfile}
+
+
 echo "Disk usage: `du -s --apparent-size -B 1M ${cdroot} | cut -f1` MiB"
 echo "ZIP size:   `mibsize ${zipfile}` MiB"
 echo "ISO size:   `mibsize ${isofile}` MiB"