📄 build-initrd.sh
字号:
#!/bin/bash## build-initrd.sh## Written by Jari Ruusu, October 19 2007## Copyright 2001-2007 by Jari Ruusu.# Redistribution of this file is permitted under the GNU Public License.## Changes by Hauke Johannknecht <ash@ash.de> 11/2001# - added Pivot mode# - added conffile-loading# - added initrdonly-mode# - added device 0 nodes### Initrd can use three different methods to switch to encrypted root# device: change_root (USEPIVOT=0), pivot_root (USEPIVOT=1) and# initramfs/switch_root (USEPIVOT=2). change_root method is available on at# least 2.2, 2.4 and 2.6 kernels, and it works ok. pivot_root method is# available on 2.4 and later kernels, and offers much nicer wrong# passphrase case handling because initrd code can properly shutdown the# kernel. initramfs/switch_root method is available on 2.6.13 and later# kernels, and is similar to pivot_root. Proper shutdown is important for# software RAID devices and such. change_root, pivot_root, and# initramfs/switch_root require slightly different kernel and bootloader# configurations.## kernel .config : CONFIG_BLK_DEV_RAM=y# (USEPIVOT=0) CONFIG_BLK_DEV_RAM_SIZE=4096# CONFIG_BLK_DEV_INITRD=y# CONFIG_MINIX_FS=y# CONFIG_PROC_FS=y# CONFIG_CRAMFS=n (or CONFIG_CRAMFS=m)## kernel .config : CONFIG_BLK_DEV_RAM=y# (USEPIVOT=1) CONFIG_BLK_DEV_RAM_SIZE=4096# CONFIG_BLK_DEV_INITRD=y# CONFIG_MINIX_FS=y## kernel .config : CONFIG_BLK_DEV_INITRD=y# (USEPIVOT=2)## /etc/lilo.conf : initrd=/boot/initrd.gz# (USEPIVOT=0) root=/dev/ram1# ^# /etc/lilo.conf : append="init=/linuxrc rootfstype=minix"# (USEPIVOT=1) initrd=/boot/initrd.gz# root=/dev/ram0# ^# /etc/lilo.conf : initrd=/boot/initrd.gz# (USEPIVOT=2)## /boot/grub/menu.lst : root (hd0,0)# (USEPIVOT=0) kernel /vmlinuz root=101# initrd /initrd.gz ^## /boot/grub/menu.lst : root (hd0,0)# (USEPIVOT=1) kernel /vmlinuz root=100 init=/linuxrc rootfstype=minix# initrd /initrd.gz ^## /boot/grub/menu.lst : root (hd0,0)# (USEPIVOT=2) kernel /vmlinuz# initrd /initrd.gz## usage : ./build-initrd.sh [configfile]# lilo# mkdir /boot/modules-`uname -r`# cp -p /lib/modules/`uname -r`/block/loop.*o /boot/modules-`uname -r`/# or ^^^^^# cp -p /lib/modules/`uname -r`/extra/loop.*o /boot/modules-`uname -r`/# ^^^^^# 2.4 and older kernels always install to block/ directory# 2.6 kernels with loop-AES-v3.2a and later install to extra/ directory#### All default-values can be altered via the configfile# 1 = use devfs, 0 = use classic disk-based device names. If this is# enabled (USEDEVFS=1) then setting USEPIVOT=1 is also required and kernel# must be configured with CONFIG_DEVFS_FS=y CONFIG_DEVFS_MOUNT=yUSEDEVFS=0# 0 = use old change_root, 1 = use pivot_root, 2 = use initramfs/switch_root# See above header for root= and append= lilo.conf definitions.# pivot_root is not available on 2.2 and older kernels.# initramfs/switch_root is not available on kernels older than 2.6.13USEPIVOT=1# Unencrypted /boot partition. If devfs is enabled (USEDEVFS=1), this must# be specified as genuine devfs name.BOOTDEV=/dev/hda1# /boot partition file system typeBOOTTYPE=ext2# Encrypted root partition. If devfs is enabled (USEDEVFS=1), this must# be specified as genuine devfs name.CRYPTROOT=/dev/hda2# root partition file system typeROOTTYPE=ext2# Encryption type (AES128 / AES192 / AES256) of root partitionCIPHERTYPE=AES128# Optional password seed for root partition# (this option is obsolete when gpg encrypted key file is used)#PSEED="-S XXXXXX"# Optional password iteration count for root partition# (this option is obsolete when gpg encrypted key file is used)#ITERCOUNTK="-C 100"# This code is passed to cipher transfer function.LOINIT="-I 0"# 1 = use gpg key file to mount root partition, 0 = use normal key.# If this is enabled (USEGPGKEY=1), file named rootkey.gpg or whatever# GPGKEYFILE is set to must be manually copied to /boot (or to# EXTERNALGPGDEV device if EXTERNALGPGFILES=1). If rootkey.gpg is not# encrypted with symmetric cipher, pubring.gpg and secring.gpg must be# manually copied to /boot (or to EXTERNALGPGDEV device if# EXTERNALGPGFILES=1).USEGPGKEY=1# gpg key filename. Only used if USEGPGKEY=1GPGKEYFILE=rootkey.gpg# 1 = mount removable device EXTERNALGPGDEV that contains gpg key files# 0 = don't mountEXTERNALGPGFILES=0# Device name that contains gpg key files. If devfs is# enabled (USEDEVFS=1), this must be specified as genuine devfs name.# Only used if EXTERNALGPGFILES=1EXTERNALGPGDEV=/dev/fd0# Removable device EXTERNALGPGDEV file system type# Only used if EXTERNALGPGFILES=1EXTERNALGPGTYPE=ext2# 1 = use loop module, 0 = loop driver linked to kernelUSEMODULE=1# 1 = stop after creating and copying initrd, 0 = also copy tools/libsINITRDONLY=0# Source root directory where files are copied fromSOURCEROOT=# Destination root directory where files are written to.# Normally this is empty, but if you run this script on some other root# (i.e. Knoppix live CD), this must be configured to point to directory# where your about-to-be-encrypted root partition is mounted. This script# checks that an initrd directory exists there.DESTINATIONROOT=# dest-dir below dest-rootDESTINATIONPREFIX=/boot# Name of created init ram-diskINITRDGZNAME=initrd.gz# Encrypted root loop device index (0 ... 7), 5 == /dev/loop5# Device index must be one character even if max_loop is greater than 8# _must_ match /etc/fstab entry: /dev/loop5 / ext2 defaults,xxxx 0 1ROOTLOOPINDEX=5# Temporary loop device index used in this script, 7 == /dev/loop7TEMPLOOPINDEX=7# Additional loop module parameters.# Example: LOOPMODPARAMS="max_loop=8 lo_prealloc=125,5,200"LOOPMODPARAMS=""# 1 = set keyboard to UTF-8 mode, 0 = don't setUTF8KEYBMODE=0# 1 = load national keyboard layout, 0 = don't load# You _must_ manually copy correct keyboard layout to /boot/default.kmap# which must be in uncompressed form. (can not be .gz file)LOADNATIONALKEYB=0# Initial delay in seconds before /linuxrc attempts to mount /boot# partition. Slow devices (USB-sticks) may need some delay.INITIALDELAY=0# Delay in seconds before /linuxrc attempts to mount partition containing# external gpg key files. Slow devices (USB-sticks) may need some delay.MOUNTDELAY=0# 1 = prompt for BOOT-TOOLS media and ENTER press before mounting /boot# 0 = normal case, don't promptTOOLSPROMPT=0# 1 = use "rootsetup" program that executes losetup to initialize loop# 0 = use normal "losetup" program directly to initialize loop# If enabled, rootsetup program (+libs) _must_ be manually copied to /boot.USEROOTSETUP=0# 1 = use dietlibc to build /linuxrc. This permits passing parameters to init.# 0 = use glibc to build /linuxrc. This prevents passing parameters to init# and includes hacks that may be incompatible with some versions of glibc.# The dietlibc can be found at http://www.fefe.de/dietlibc/USEDIETLIBC=1# C compiler used to compile /linuxrc program.# 32bit x86 ubuntu-7.04 gcc-4.1.2 is known to miscompile /linuxrc. Affected# users should install gcc-3.3 package, and change this to GCC=gcc-3.3GCC=gcc# 1 = load extra module, 0 = don't load# If this is enabled, module must be manually copied to# /boot/modules-KERNELRELEASE/ directory under name like foomatic.oEXTRAMODULELOAD1=0EXTRAMODULENAME1="foomatic"EXTRAMODULEPARAMS1="frobnicator=123 fubar=abc"# 1 = load extra module, 0 = don't loadEXTRAMODULELOAD2=0EXTRAMODULENAME2=""EXTRAMODULEPARAMS2=""# 1 = load extra module, 0 = don't loadEXTRAMODULELOAD3=0EXTRAMODULENAME3=""EXTRAMODULEPARAMS3=""# 1 = load extra module, 0 = don't loadEXTRAMODULELOAD4=0EXTRAMODULENAME4=""EXTRAMODULEPARAMS4=""# 1 = load extra module, 0 = don't loadEXTRAMODULELOAD5=0EXTRAMODULENAME5=""EXTRAMODULEPARAMS5=""### End of optionsif [ $# = 1 ] ; then if [ ! -f $1 ] ; then echo "ERROR: Can't find configfile '$1'" echo "Usage: $0 [configfile]" exit 1 fi echo "Loading config from '$1'" . $1fiDEVFSSLASH1=DEVFSRAMDSK=/dev/ramif [ ${USEDEVFS} == 1 ] ; then DEVFSSLASH1=/ DEVFSRAMDSK=/dev/rd/fiDEVFSSLASH2=if [ -c /dev/.devfsd ] ; then DEVFSSLASH2=/fiLOSETUPPROG=losetupif [ ${USEROOTSETUP} == 1 ] ; then LOSETUPPROG=rootsetupfiif [ ${USEGPGKEY} == 0 ] ; then EXTERNALGPGFILES=0fiGPGMOUNTDEV=GPGMNTPATH=libif [ ${EXTERNALGPGFILES} == 1 ] ; then GPGMOUNTDEV=${EXTERNALGPGDEV} GPGMNTPATH=mntfiif [ ${USEDIETLIBC} == 1 ] ; then x=`which diet` if [ x${x} == x ] ; then echo "*****************************************************************" echo "*** This script was configured to build linuxrc using ***" echo "*** dietlibc, but it appears that dietlibc is unavailable. ***" echo "*** Script aborted. ***" echo "*****************************************************************" exit 1 fifiset -eumask 077cat - <<EOF >tmp-c-$$.c/* Note: this program does not initialize C library, so all level 3 *//* library calls are forbidden. Only level 2 system calls are allowed. */#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/mount.h>#include <sys/utsname.h>#include <sys/stat.h>#include <sys/mount.h>#include <fcntl.h>#include <time.h>#ifndef MS_MOVE# define MS_MOVE 8192#endif#if ${USEPIVOT} == 1# if ${USEDIETLIBC} extern int pivot_root(const char *, const char *);# else# include <sys/syscall.h># include <errno.h># include <linux/unistd.h># if !defined(__NR_pivot_root) && !defined(SYS_pivot_root) && defined(__i386__)# define __NR_pivot_root 217 static _syscall2(int,pivot_root,const char *,new_root,const char *,put_old)# else# define pivot_root(new_root,put_old) syscall(SYS_pivot_root,new_root,put_old)# endif# endif#endif#if (defined(__GLIBC__) && __GLIBC__ >= 2) || defined(__dietlibc__)# include <sys/reboot.h># define HaltKernel() reboot(0xCDEF0123) /* LINUX_REBOOT_CMD_HALT */#elseextern int reboot(int, int, int);# define HaltKernel() reboot(0xfee1dead, 672274793, 0xCDEF0123)#endif#if ${USEDIETLIBC}static char ** argv_init;static char ** envp_init;extern char ** environ;#elsestatic char * argv_init[] = { "init", 0, };static char * envp_init[] = { "HOME=/", "TERM=linux", 0, };#endifvoid strCat(char *d, char *s){ while(*d) d++; while(*s) *d++ = *s++; *d = 0;}void wrStr(char *s){ char *p = s; int x = 0; while(*p) p++, x++; write(1, s, x);}int exeWait(char *p){ int x, y; char *a[50], *e[1]; if(!(x = fork())) { while(*p && (x < ((sizeof(a) / sizeof(char *)) - 1))) { a[x++] = p; while(*p && (*p != ' ') && (*p != '\t')) p++; while((*p == ' ') || (*p == '\t')) *p++ = 0; } e[0] = a[x] = 0; if(x) execve(a[0], &a[0], &e[0]); _exit(1); } if(x == -1) { wrStr("linuxrc: fork failed\n"); return(1); } waitpid(x, &y, 0); if(!WIFEXITED(y) || (WEXITSTATUS(y) != 0)) { wrStr("Command \""); wrStr(p); wrStr("\" returned error\n"); return(1); } return(0);}void doHalt(){ int x, y; struct timespec req; sync(); if(!(x = fork())) HaltKernel(); waitpid(x, &y, 0); for(;;) { req.tv_sec = 5; req.tv_nsec = 0; nanosleep(&req, 0); }}void runInit(){#if ${USEDIETLIBC} if(argv_init[0]) argv_init[0] = "init"; envp_init = environ;#endif execve("/sbin/init", argv_init, envp_init); execve("/etc/init", argv_init, envp_init); execve("/bin/init", argv_init, envp_init); wrStr("Bummer! Launching init failed\n"); doHalt();}#if ${USEPIVOT} == 2void removeInitramfsFiles(){ int x; x = unlink("${BOOTDEV}"); x |= unlink("${CRYPTROOT}");#if ${EXTERNALGPGFILES} x |= unlink("${GPGMOUNTDEV}");#endif x |= unlink("/dev/console"); x |= unlink("/dev/tty"); x |= unlink("/dev/tty1"); x |= unlink("/dev/null"); x |= unlink("/dev/zero"); x |= unlink("/dev/ram0"); x |= unlink("/dev/ram1"); x |= unlink("/dev/loop${ROOTLOOPINDEX}"); x |= rmdir("/dev"); x |= rmdir("/lib"); x |= unlink("/lib64");#if ${EXTERNALGPGFILES} x |= rmdir("/mnt");#endif#if ${USEGPGKEY} x |= unlink("/bin");#endif x |= unlink("/init"); if(x) wrStr("removing initramfs files failed. (not fatal)\n");}#endif#if ${USEDIETLIBC}int main(int argc, char **argv)#elsevoid _start()#endif{ int x = 0; struct utsname un; char buf[1000], *modext;#if ${USEDIETLIBC} argv_init = argv;#endif#if ${USEPIVOT} if(getpid() != 1) { /* pivot_root was configured, but kernel has */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -