xref: /minix/releasetools/image.functions (revision 03ac74ed)
1
2#
3# spec file handling
4#
5
6#
7# Add a directory to a spec file
8#
9# $1 : directory to add
10# $2 : spec file
11add_dir_spec()
12{
13	echo "./$1 type=dir uid=0 gid=0 mode=0755" >> ${WORK_DIR}/$2
14}
15
16#
17# Add a file to a spec file
18#
19# $1 : file to add
20# $2 : spec file
21add_file_spec()
22{
23	echo "./$1 type=file uid=0 gid=0 mode=0755 size=$(wc -c < ${ROOT_DIR}/${1})" >> ${WORK_DIR}/$2
24}
25
26#
27# Add a symbolic link to a spec file
28#
29# $1 : symlink to add
30# $2 : link to
31# $3 : spec file
32add_link_spec()
33{
34	echo "./$1 type=link uid=0 gid=0 mode=0755 link=$2" >> ${WORK_DIR}/$3
35}
36
37#
38# workdir handling
39#
40
41#
42# Create the workdir (a directory where Minix is built using sets)
43# spec files are put in WORK_DIR, the file system created in ROOT_DIR
44#
45# $1 : sets to extract
46build_workdir()
47{
48	mkdir -p ${ROOT_DIR}
49
50	# Don't do anything if we don't use sets
51	if [ -n "$1" ]
52	then
53		# Extract sets
54		for set in $1; do
55			if [ ! -e ${SETS_DIR}/${set}.tgz ]; then
56				echo "Missing ${SETS_DIR}/${set}.tgz, aborting"
57				echo "Are the release sets tarballs created?"
58				exit 1
59			fi
60			echo " * Extracting $set..."
61			(cd ${ROOT_DIR}; ${CROSS_TOOLS}/nbpax -rnz -f ${SETS_DIR}/${set}.tgz .)
62		done
63
64		# add rc (if any)
65		if [ -f ${RC} ]; then
66			cp ${RC} ${ROOT_DIR}/usr/etc/rc.local
67		fi
68
69		# Build login/password files
70		${CROSS_TOOLS}/nbpwd_mkdb -V 0 -p -d ${ROOT_DIR} ${ROOT_DIR}/etc/master.passwd
71
72		# Build specifications files
73		cp ${ROOT_DIR}/etc/mtree/set* ${WORK_DIR}
74		${ROOT_DIR}/usr/bin/MAKEDEV -s -m all >> ${WORK_DIR}/extra.dev
75	fi
76
77	if [ ${BUNDLE_SETS} -eq 1 ]
78	then
79		echo " * Bundling sets..."
80		workdir_add_sets
81	fi
82}
83
84#
85# Add tarball sets to the workdir (for installation CD)
86#
87workdir_add_sets()
88{
89	# Add sets to the root
90	mkdir -p ${ROOT_DIR}/usr/${ARCH}/binary/sets;
91	add_dir_spec "usr/${ARCH}" extra.sets
92	add_dir_spec "usr/${ARCH}/binary" extra.sets
93	add_dir_spec "usr/${ARCH}/binary/sets" extra.sets
94
95	add_link_spec "${ARCH}" "usr/${ARCH}" extra.sets
96
97	DEST_SETS_DIR="usr/${ARCH}/binary/sets"
98	for set in ${SETS_DIR}/*.tgz; do
99		# Copy set itself
100		cp ${set} ${ROOT_DIR}/${DEST_SETS_DIR}
101		add_file_spec "${DEST_SETS_DIR}/$(basename ${set})" extra.sets
102
103		# Add file count
104		COUNT_SRC=$(echo $(basename ${set}) | sed -e "s/\(.*\)\.tgz/\set.\1/")
105		COUNT_NAME=$(echo $(basename ${set}) | sed -e "s/\.tgz/\.count/")
106		if [ -e "${DESTDIR}/etc/mtree/${COUNT_SRC}" ]
107		then
108			wc -l < ${DESTDIR}/etc/mtree/${COUNT_SRC} > ${ROOT_DIR}/${DEST_SETS_DIR}/${COUNT_NAME}
109		else
110			# Can't find mtree file, set bogus number
111			echo 1 > ${ROOT_DIR}/${DEST_SETS_DIR}/${COUNT_NAME}
112		fi
113		add_file_spec "${DEST_SETS_DIR}/${COUNT_NAME}" extra.sets
114
115		# Add file sizes
116		SIZE_NAME=$(echo $(basename ${set}) | sed -e "s/\.tgz/\.size/")
117		${CROSS_TOOLS}/nbpax -zvf ${set} . |grep -v 'bytes written in 1 secs [(]' | ${CROSS_TOOLS}/nbawk '{s+=$5} END{print s}' > ${ROOT_DIR}/${DEST_SETS_DIR}/${SIZE_NAME}
118		add_file_spec "${DEST_SETS_DIR}/${SIZE_NAME}" extra.sets
119	done
120
121	# Add checksums
122	cp ${SETS_DIR}/MD5 ${ROOT_DIR}/${DEST_SETS_DIR}
123	add_file_spec "${DEST_SETS_DIR}/MD5" extra.sets
124	cp ${SETS_DIR}/SHA512 ${ROOT_DIR}/${DEST_SETS_DIR}
125	add_file_spec "${DEST_SETS_DIR}/SHA512" extra.sets
126}
127
128#
129# Add HDD files to the workdir
130#
131workdir_add_hdd_files()
132{
133	# create a fstab entry in /etc
134	cat >${ROOT_DIR}/etc/fstab <<END_FSTAB
135/dev/c0d0p1	/usr		mfs	rw			0	2
136/dev/c0d0p2	/home		mfs	rw			0	2
137none		/sys		devman	rw,rslabel=devman	0	0
138none		/dev/pts	ptyfs	rw,rslabel=ptyfs	0	0
139END_FSTAB
140	add_file_spec "etc/fstab" extra.fstab
141
142	# Add boot monitor
143	cp ${DESTDIR}/usr/mdec/boot_monitor ${ROOT_DIR}/boot_monitor
144	add_file_spec "boot_monitor" extra.boot
145}
146
147#
148# Add CD boot files to the workdir
149#
150workdir_add_cd_files()
151{
152	# create a fstab entry in /etc
153	cat >${ROOT_DIR}/etc/fstab <<END_FSTAB
154none		/sys		devman	rw,rslabel=devman	0	0
155none		/dev/pts	ptyfs	rw,rslabel=ptyfs	0	0
156END_FSTAB
157	add_file_spec "etc/fstab" extra.fstab
158
159	# Add boot monitor
160	cp ${DESTDIR}/usr/mdec/boot_monitor ${ROOT_DIR}/minixboot
161	add_file_spec "minixboot" extra.cdfiles
162
163	# Add README
164	cp releasetools/release/cd/README.TXT ${ROOT_DIR}/README.TXT
165	add_file_spec "README.TXT" extra.cdfiles
166}
167
168#
169# Add ramdisk files to the workdir
170#
171workdir_add_ramdisk_files()
172{
173	# create a fstab entry in /etc
174	cat >${ROOT_DIR}/etc/fstab <<END_FSTAB
175none		/sys		devman	rw,rslabel=devman	0	0
176none		/dev/pts	ptyfs	rw,rslabel=ptyfs	0	0
177END_FSTAB
178	add_file_spec "etc/fstab" extra.fstab
179
180	# add early boot rc script
181	cp minix/drivers/storage/ramdisk/rc ${ROOT_DIR}/etc/rc.ramdisk
182	add_file_spec "etc/rc.ramdisk" extra.fstab
183
184	# Add README
185	cp releasetools/release/cd/README.TXT ${ROOT_DIR}/README.TXT
186	add_file_spec "README.TXT" extra.cdfiles
187}
188
189#
190# Extract kernel to designated directory
191#
192# $1: Directory where to extract
193workdir_add_kernel()
194{
195	(cd ${ROOT_DIR}; ${CROSS_TOOLS}/nbpax -rnz -f ${SETS_DIR}/minix-kernel.tgz .)
196
197	# Move kernel files to the correct directory
198	if [ ! -d ${ROOT_DIR}/boot/$1 ]
199	then
200		mkdir -p ${ROOT_DIR}/boot/$1
201		add_dir_spec "boot/$1" extra.kernel
202	fi
203
204	mv ${ROOT_DIR}/boot/minix/.temp/* ${ROOT_DIR}/boot/$1
205	rm -rf ${ROOT_DIR}/boot/minix/.temp
206	for i in $(cd ${ROOT_DIR}/boot/$1 && echo *)
207	do
208		add_file_spec "boot/$1/$i" extra.kernel
209	done
210}
211
212#
213# Read METALOG and use mtree to convert the user and group names into uid and gids.
214# Used as the reference mtree for building file systems.
215#
216create_input_spec()
217{
218	if [ -n "$SETS" ]
219	then
220		cat ${WORK_DIR}/set* ${WORK_DIR}/extra* | ${CROSS_TOOLS}/nbmtree -N ${ROOT_DIR}/etc -C -K device > ${WORK_DIR}/input
221	else
222		cat ${WORK_DIR}/extra* | ${CROSS_TOOLS}/nbmtree -C > ${WORK_DIR}/input
223	fi
224
225	if [ ${ASR_HACK} -eq 1 ]
226	then
227		# Hacky workaround for ASR-randomized service binaries since they don't get nicely packaged in a tarball
228		# add any generated ASR-randomized service binaries
229		# TODO: apply stricter file permissions for both these and the base /service binaries, against local attacks
230		(cd ${DESTDIR} && find ./usr/service/asr -type f | sed 's/$/ type=file uid=0 gid=0 mode=0755/') >> ${WORK_DIR}/input
231		cp -r ${DESTDIR}/usr/service/asr ${ROOT_DIR}/usr/service
232	fi
233}
234
235#
236# Split mtree into partitions and create proto files for nbmkfs.mfs
237#
238# $1 : partitions to create (example: usr home)
239create_protos()
240{
241	# build filter
242	FILTER_COMMAND="cat ${WORK_DIR}/input"
243	for i in $1
244	do
245		FILTER_COMMAND="$FILTER_COMMAND | grep -v \"^./$i/\" "
246	done
247
248	# fill root.img (skipping entries inside partitions while keeping partition mount points)
249	eval $FILTER_COMMAND | ${CROSS_TOOLS}/nbtoproto -b ${ROOT_DIR} -o ${WORK_DIR}/proto.root
250
251	# create proto files for partitions using toproto
252	for i in $1
253	do
254		cat ${WORK_DIR}/input | grep  "^\./$i/\|^. " | sed "s,\./$i,\.,g" | ${CROSS_TOOLS}/nbtoproto -b ${ROOT_DIR}/$i -o ${WORK_DIR}/proto.$i
255	done
256}
257
258#
259# Clone grub repository and build efi boot binary
260#
261fetch_and_build_grub()
262{
263       if [ -d ${RELEASETOOLSDIR}/grub ]
264       then
265         echo grub is already checked out
266       else
267         git clone git://git.savannah.gnu.org/grub.git ${RELEASETOOLSDIR}/grub
268         pushd ${RELEASETOOLSDIR}/grub
269         # most recent known working commit at the time of writing
270         git checkout a0bf403f66dbaca4edd8e667bfc397dd91c8d71c
271         ./autogen.sh
272         ./configure --with-platform=efi --target=i386
273         make clean
274         make -j ${JOBS}
275         cd grub-core
276         ../grub-mkimage -v -d . -o booti386.efi -O i386-efi -p /boot/efi normal part_msdos fat chain boot configfile multiboot minix3 gzio efi_uga
277         ls -l booti386.efi
278         popd
279       fi
280}
281
282#
283# Create grub.cfg for efi boot
284#
285create_grub_cfg()
286{
287	cat > ${EFI_DIR}/boot/efi/grub.cfg <<END_GRUBCFG
288
289insmod serial
290insmod minix3
291insmod gzio
292#insmod efi_uga
293#insmod video_fb
294insmod all_video
295
296set timeout=30
297set default=0
298
299set gfxmode=text
300
301menuentry "Minix Boot" {
302        set root=(hd0,1)
303        multiboot /boot/minix_default/kernel rootdevname=c0d0p0
304        module /boot/minix_default/mod01_ds
305        module /boot/minix_default/mod02_rs
306        module /boot/minix_default/mod03_pm
307        module /boot/minix_default/mod04_sched
308        module /boot/minix_default/mod05_vfs
309        module /boot/minix_default/mod06_memory
310        module /boot/minix_default/mod07_tty
311        module /boot/minix_default/mod08_mib
312        module /boot/minix_default/mod09_vm
313        module /boot/minix_default/mod10_pfs
314        module /boot/minix_default/mod11_mfs
315        module /boot/minix_default/mod12_init
316}
317
318menuentry "Minix Boot (serial)" {
319        set root=(hd0,1)
320        multiboot /boot/minix_default/kernel rootdevname=c0d0p0 cttyline=0 ttybaud=115200 console=tty00 consdev=com0
321        module /boot/minix_default/mod01_ds
322        module /boot/minix_default/mod02_rs
323        module /boot/minix_default/mod03_pm
324        module /boot/minix_default/mod04_sched
325        module /boot/minix_default/mod05_vfs
326        module /boot/minix_default/mod06_memory
327        module /boot/minix_default/mod07_tty
328        module /boot/minix_default/mod08_mib
329        module /boot/minix_default/mod09_vm
330        module /boot/minix_default/mod10_pfs
331        module /boot/minix_default/mod11_mfs
332        module /boot/minix_default/mod12_init
333}
334END_GRUBCFG
335}
336
337#
338# Create ramdisk image from root directory
339#
340# $1 : size of ramdisk (optional)
341create_ramdisk_image()
342{
343	PATH=$(cd ${CROSS_TOOLS}; pwd):$PATH
344	if [ -z $1 ]
345	then
346		RAMSIZE="-x 5"
347	else
348		RAMSIZE="-b $(( $1 / 512 / 8))"
349	fi
350
351	# Build image
352	_RAMDISKSIZE=$(${CROSS_TOOLS}/nbmkfs.mfs -d ${RAMSIZE} -I 0 ${WORK_DIR}/imgrd.mfs ${WORK_DIR}/proto.root)
353	(cd ${WORK_DIR}; ${TOOLCHAIN_TRIPLET}objcopy -Ibinary -Bi386 -Oi586-elf32-minix imgrd.mfs imgrd.o)
354	${TOOLCHAIN_TRIPLET}clang --sysroot=${DESTDIR} -L ${DESTDIR}/usr/lib -static -o ${WORK_DIR}/mod06_memory ${OBJ}/minix/drivers/storage/memory/memory.o ${WORK_DIR}/imgrd.o -nodefaultlibs -lblockdriver -lchardriver -lsys -lminc
355}
356
357#
358# Bundle packages (won't preinstall them)
359#
360# $1 : packages to bundle
361bundle_packages()
362{
363	if [ -z $PACKAGE_DIR ]
364	then
365		echo " * PACKAGE_DIR not set, skipping package bundling..."
366		return
367	fi
368
369	if [ ! -x "$(which $PKG_INFO)" ]
370	then
371		echo "Error: PKG_INFO ("$(which $PKG_INFO)") not executable."
372		echo "Can't create package index without pkg_info."
373		echo "Bootstrap pkgsrc on host to get pkg_info."
374		exit 1
375	fi
376
377	# Bundle all available packages if no list was given
378	if [ -z "$1" ]
379	then
380		PACKAGES=$(for i in $(echo "$PACKAGE_DIR"/*.tgz); do basename $i | sed s/\.tgz//; done)
381	else
382		PACKAGES=$1
383	fi
384
385	DESTPACKAGES="usr/packages/$RELEASE_VERSION/$ARCH/All"
386	RELEASEPACKAGE="${ROOT_DIR}/$DESTPACKAGES"
387	index=pkg_summary
388
389	# create directories
390	mkdir -p $RELEASEPACKAGE
391	add_dir_spec "usr/packages" extra.pkgsrc
392	add_dir_spec "usr/packages/$RELEASE_VERSION" extra.pkgsrc
393	add_dir_spec "usr/packages/$RELEASE_VERSION/$ARCH" extra.pkgsrc
394	add_dir_spec "usr/packages/$RELEASE_VERSION/$ARCH/All" extra.pkgsrc
395	add_link_spec "packages" "usr/packages" extra.pkgsrc
396	for pkgprefix in $PACKAGES
397	do
398		realfn=$(echo $PACKAGE_DIR/${pkgprefix}*.tgz | cut -d' ' -f1)
399		if [ -f "$realfn" ]
400		then
401			# Copy package
402			p="$(basename $realfn)"
403			echo " * Bundling $p..."
404			cp "$realfn" "$RELEASEPACKAGE/$p"
405			add_file_spec "$DESTPACKAGES/$p" extra.pkgsrc
406		else
407			echo "Error: Can't find $pkgprefix in directory $PACKAGE_DIR for bundling package."
408			exit 1
409		fi
410	done
411
412	# Create packages index
413	echo " * Generating package index..."
414	indexname=$indexpath/$p.$index
415	$PKG_INFO -X $RELEASEPACKAGE/*.tgz >> $RELEASEPACKAGE/$index
416
417	# Compress index
418	echo " * Compressing index..."
419	bzip2 -f $RELEASEPACKAGE/$index
420	add_file_spec "$DESTPACKAGES/$index.bz2" extra.pkgsrc
421}
422
423#
424# stuff executed automatically to set up environment
425#
426
427usage()
428{
429	echo "Usage: $0 [options]"
430	echo "  -X xsrc       Build with X11 located in \"xsrc\""
431	echo "  -x            Add X11 sets to extraction list"
432	echo "  -b            Add ASR service binaries to the image"
433	echo "                (said binaries must be built beforehand)"
434	echo ""
435	echo "Environment variables:"
436	echo "  CREATE_IMAGE_ONLY     If set to 1, skip invocation of build.sh (default: 0)"
437	echo "  JOBS                  Number of CPUs to use for build.sh to use (default: 1)"
438	echo "  SETS                  Sets to extract for image (default: depends on script)"
439	echo "  BUILDVARS             Extra options passed to build.sh (default: none)"
440	echo ""
441	echo "  PACKAGE_DIR           Path to packages to bundle (default: none)"
442	echo "  BUNDLE_PACKAGES       List of packages to bundle (default: none)"
443	echo "  PKG_INFO              Path to 'pkg_info' for bundling (default: pkg_info)"
444	echo ""
445	echo "  BUNDLE_SETS           If set to 1, bundle sets for setup (default: only for CD)"
446}
447
448# parse options
449while getopts "ixX:bh" c
450do
451	case "$c" in
452		i)	echo "This method of generating the ISO installation media is obsolete."
453			echo "Run ./releasetools/x86_cdimage.sh instead."
454			exit 1;;
455
456		x)	SETS="$SETS xbase xcomp xetc xfont xserver";;
457
458		X)	MKX11=yes
459			export MKX11
460			BUILDVARS="$BUILDVARS -X $OPTARG";;
461
462		b)      # bitcode build: increase partition sizes
463			ROOT_SIZE="$((${ROOT_SIZE} + 192*(2**20)))"
464			USR_SIZE="$((${USR_SIZE} + 256*(2**20)))"
465			ASR_HACK=1;;
466
467		h)	usage
468			exit 0;;
469
470		:)	usage
471			exit 2;;
472
473		\?)
474			usage
475			exit 2;;
476	esac
477done
478
479#
480# Are we going to build the minix sources?
481#
482
483if [ ${CREATE_IMAGE_ONLY} -eq 1 ]
484then
485	if [ ! -d ${DESTDIR} ]
486	then
487		echo "Minix source code doesn't appear to have been built."
488		echo "Please try with \$CREATE_IMAGE_ONLY set to 0."
489		exit 1
490	fi
491	if [ ! -d ${RELEASEDIR} ]
492	then
493		echo "Minix release tarball sets don't appear to have been created."
494		echo "Please try with \$CREATE_IMAGE_ONLY set to 0."
495		exit 1
496	fi
497	# FIXME: this won't change anything for tarballs
498	#${CROSS_TOOLS}/nbmake-i386 -C releasetools do-hdboot
499else
500	echo "Going to build Minix source code..."
501	#
502	# Remove the generated files to allow us call build.sh without '-V SLOPPY_FLIST=yes'.
503	#
504	rm -f ${FSTAB}
505
506	#
507	# Now start the build.
508	#
509	sh ${BUILDSH} -j ${JOBS} -m ${ARCH} -O ${OBJ} -D ${DESTDIR} ${BUILDVARS} -U -u release
510
511fi
512
513# sanity check
514if [ -d "${WORK_DIR}/.git" ]
515then
516	echo "WORK_DIR directory has a Git repository in it, abort!"
517	exit 1
518fi
519
520# clean working directory
521if [ -e "${WORK_DIR}" ]
522then
523	rm -rf "${WORK_DIR}"
524fi
525mkdir -p ${WORK_DIR}
526
527# get absolute paths to those directories
528CROSS_TOOLS=$(cd ${CROSS_TOOLS} && pwd)
529DESTDIR=$(cd ${DESTDIR} && pwd)
530MODDIR=$(cd ${MODDIR} && pwd)
531OBJ=$(cd ${OBJ} && pwd)
532SETS_DIR=$(cd ${SETS_DIR} && pwd)
533WORK_DIR=$(cd ${WORK_DIR} && pwd)
534ROOT_DIR=${WORK_DIR}/fs
535
536# get list of mods
537mods="`( cd ${MODDIR}; echo mod* | tr ' ' ',' )`"
538