summaryrefslogtreecommitdiff
path: root/mkinitramfs
blob: f06811ecba49579000a9e60213941c38e4c51e09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#!/bin/sh

# Takes a file containing a list of modules to be added as an argument
# Figures out dependancies and adds it in.
manual_add_modules()
{
	# Sanity check
	if [ ! -e ${1} ]; then
		return
	fi

	for x in $(sed -e '/^#/d' ${1}); do
		for y in $(modprobe --set-version=${version} --show-depends ${x} | awk '{ print $2 }'); do
			# Prune duplicates
			if [ -e ${TMPDIR}/${y} ]; then
				continue
			fi
	
			mkdir -p ${TMPDIR}/$(dirname ${y})
			ln -s ${y} ${TMPDIR}/$(dirname ${y})
			echo $(basename ${y} .ko) >>${TMPDIR}/conf/modules
		done
	done
}

# Copy entire subtrees to the initramfs
copy_modules_dir()
{
	tmpdir_modbase=${TMPDIR}/lib/modules/${version}
	mkdir -p $(dirname ${tmpdir_modbase}/${1})
	cp -a /lib/modules/${version}/${1} ${tmpdir_modbase}/${1}
}

# Modules that we always add to the initramfs
auto_add_modules()
{
	copy_modules_dir kernel/drivers/net
	copy_modules_dir kernel/drivers/scsi
	copy_modules_dir kernel/drivers/ide
	copy_modules_dir kernel/drivers/md
	copy_modules_dir kernel/drivers/usb
	copy_modules_dir kernel/drivers/block
	copy_modules_dir kernel/drivers/input
	copy_modules_dir kernel/fs/ext2
	copy_modules_dir kernel/fs/ext3
	copy_modules_dir kernel/fs/isofs
	copy_modules_dir kernel/fs/jbd
	copy_modules_dir kernel/fs/jfs
	copy_modules_dir kernel/fs/nfs
	copy_modules_dir kernel/fs/reiserfs
	copy_modules_dir kernel/fs/xfs

	# These aren't caught by the above but really need to be there:
	for x in mbcache nfs af_packet raid1; do
		for y in $(modprobe --set-version=${version} --show-depends ${x} | awk '{ print $2 }'); do
			# Prune duplicates
			if [ -e ${TMPDIR}/${y} ]; then
				continue
			fi
	
			mkdir -p ${TMPDIR}/$(dirname ${y})
			ln -s ${y} ${TMPDIR}/$(dirname ${y})
			depmod -b ${TMPDIR} ${version}
		done
	done
}

usage()
{
	cat >&2 << EOF

Usage: ${0} [OPTION]... <-o outfile> [version]

Options:
  -d confdir  Specify an alternative configuration directory.
  -k          Keep temporary directory used to make the image.
  -o outfile  Write to outfile.
  -r root     Override ROOT setting in mkinitrd.conf.

See ${0}(8) for further details.
EOF
	exit 1

}

# Defaults
keep="n"
CONFDIR="/etc/mkinitramfs"

while getopts "d:ko:r:" flag; do
	case $flag in
	d)
		CONFDIR="${OPTAGS}"
		if [ ! d "${CONFDIR}" ]; then
			echo "${0}: ${CONFDIR}: Not a directory" >&2
			exit 1
		fi
		;;
	o)
		outfile="${OPTARG}"
		;;
	v)
		version="${OPTARG}"
		;;
	k)
		keep="y"
		;;
	esac
done

shift $((${OPTIND} - 1))

. ${CONFDIR}/initramfs.conf

if [ x${outfile} = x ] || [ ${#} -ne 1 ]; then
	usage
fi

# And by "version" we really mean path to kernel modules
# This is braindead, and exists to preserve the interface with mkinitrd
version=${1}
[ $# -gt 0 ] || unset version
case ${version} in
/lib/modules/*/[!/]*)
        ;;
/lib/modules/[!/]*)
        version=${version#/lib/modules/}
        version=${version%%/*}
        ;;
esac

case ${version} in
*/*)
        echo $PROG: ${version} is not a valid kernel version >&2
        exit 1
        ;;
esac

version="${version-$(uname -r)}"

if [ -d ${outfile} ]; then
	echo "${outfile} is a directory"
	exit 1
fi

if [ ! -e /lib/modules/${version} ]; then
	echo "Cannot find /lib/modules/${version}"
	exit 1
fi

TMPDIR=$(mktemp -d) || exit 1
mkdir -p ${TMPDIR}/modules ${TMPDIR}/conf ${TMPDIR}/etc
mkdir -p ${TMPDIR}/bin ${TMPDIR}/lib ${TMPDIR}/scripts
mkdir -p ${TMPDIR}/sbin

for x in ${CONFDIR}/modules /usr/share/initramfs-tools/modules.d/*; do
	manual_add_modules ${x}
done

auto_add_modules

# Have to do each file, because cpio --dereference doesn't recurse down
# symlinks.

ln -s /usr/lib/klibc/bin/* ${TMPDIR}/bin
ln -s /usr/lib/klibc/lib/* ${TMPDIR}/lib
ln -s /usr/share/initramfs-tools/init ${TMPDIR}/init
cp -a /usr/share/initramfs-tools/scripts/* ${TMPDIR}/scripts
ln -s ${CONFDIR}/initramfs.conf ${TMPDIR}/conf
ln -s /etc/udev ${TMPDIR}/etc

# Hack until udev is built with klibc
ln -s /sbin/udev ${TMPDIR}/bin
ln -s /sbin/udevstart ${TMPDIR}/bin
ln -s /lib/libc.so.* ${TMPDIR}/lib
ln -s /lib/ld*.so.* ${TMPDIR}/lib
rm ${TMPDIR}/lib/*lsb*

# Busybox
rm ${TMPDIR}/bin/sh
ln -s /usr/lib/initramfs-tools/bin/busybox ${TMPDIR}/bin/sh
# This is ugly, but needed atm to make the builtins work =(
ln -s /usr/lib/initramfs-tools/bin/busybox ${TMPDIR}/bin/busybox

# Modutils
ln -s /sbin/modprobe ${TMPDIR}/sbin
ln -s /sbin/depmod ${TMPDIR}/sbin
ln -s /sbin/rmmod ${TMPDIR}/sbin
mkdir -p ${TMPDIR}/etc/modprobe.d
ln -s /etc/modprobe.d/aliases ${TMPDIR}/etc/modprobe.d

# Raid
ln -s /sbin/mdadm ${TMPDIR}/sbin
ln -s /sbin/mdrun ${TMPDIR}/sbin

(cd ${TMPDIR} && find . | cpio --quiet --dereference -o -H newc | gzip -9 >${outfile})

if [ "${keep}" = "y" ]; then
	echo "Working files in ${TMPDIR}"
else
	rm -rf "${TMPDIR}"
fi