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