1#!/bin/bash
2
3# Copyright 2019 Google Inc. All rights reserved.
4
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8
9#     http://www.apache.org/licenses/LICENSE-2.0
10
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
18
19source "${ANDROID_BUILD_TOP}/external/shflags/src/shflags"
20
21DEFINE_boolean p1 \
22	false "Only generate/write the 1st partition (loader1)" "1"
23DEFINE_boolean p2 \
24	false "Only generate/write the 2nd partition (env)" "2"
25DEFINE_boolean p3 \
26	false "Only generate/write the 3rd partition (loader2)" "3"
27DEFINE_boolean p4 \
28	false "Only generate/write the 4th partition (trust)" "4"
29DEFINE_boolean p5 \
30	false "Only generate/write the 5th partition (rootfs)" "5"
31
32FLAGS_HELP="USAGE: $0 <KERNEL_DIR> [IMAGE] [flags]"
33
34FLAGS "$@" || exit $?
35eval set -- "${FLAGS_ARGV}"
36
37if [ ${FLAGS_p1} -eq ${FLAGS_FALSE} ] &&
38   [ ${FLAGS_p2} -eq ${FLAGS_FALSE} ] &&
39   [ ${FLAGS_p3} -eq ${FLAGS_FALSE} ] &&
40   [ ${FLAGS_p4} -eq ${FLAGS_FALSE} ] &&
41   [ ${FLAGS_p5} -eq ${FLAGS_FALSE} ]; then
42	FLAGS_p1=${FLAGS_TRUE}
43	FLAGS_p2=${FLAGS_TRUE}
44	FLAGS_p3=${FLAGS_TRUE}
45	FLAGS_p4=${FLAGS_TRUE}
46	FLAGS_p5=${FLAGS_TRUE}
47fi
48
49for arg in "$@" ; do
50	if [ -z $KERNEL_DIR ]; then
51		KERNEL_DIR=$arg
52	elif [ -z $IMAGE ]; then
53		IMAGE=$arg
54	else
55		flags_help
56		exit 1
57	fi
58done
59
60USE_IMAGE=`[ -z "${IMAGE}" ] && echo "0" || echo "1"`
61OVERWRITE=`[ -e "${IMAGE}" ] && echo "1" || echo "0"`
62if [ -z $KERNEL_DIR ]; then
63	flags_help
64	exit 1
65fi
66if [ ! -e "${KERNEL_DIR}" ]; then
67	echo "error: can't find '${KERNEL_DIR}'. aborting..."
68	exit 1
69fi
70
71# escalate to superuser
72if [ $UID -ne 0 ]; then
73	cd ${ANDROID_BUILD_TOP}
74	. ./build/envsetup.sh
75	lunch ${TARGET_PRODUCT}-${TARGET_BUILD_VARIANT}
76	mmma external/u-boot
77	cd -
78	exec sudo -E "${0}" ${@}
79fi
80
81if [ $OVERWRITE -eq 1 ]; then
82	OVERWRITE_IMAGE=${IMAGE}
83	IMAGE=`mktemp`
84fi
85
86if [ $USE_IMAGE -eq 0 ]; then
87	init_devs=`lsblk --nodeps -oNAME -n`
88	echo "Reinsert device (to write to) into PC"
89	while true; do
90		devs=`lsblk --nodeps -oNAME -n`
91		new_devs="$(echo -e "${init_devs}\n${devs}" | sort | uniq -u | awk 'NF')"
92		num_devs=`echo "${new_devs}" | wc -l`
93		if [[ "${new_devs}" == "" ]]; then
94			num_devs=0
95		fi
96		if [[ ${num_devs} -gt 1 ]]; then
97			echo "error: too many new devices detected! aborting..."
98			exit 1
99		fi
100		if [[ ${num_devs} -eq 1 ]]; then
101			if [[ "${new_devs}" != "${mmc_dev}" ]]; then
102				if [[ "${mmc_dev}" != "" ]]; then
103					echo "error: block device name mismatch ${new_devs} != ${mmc_dev}"
104					echo "Reinsert device (to write to) into PC"
105				fi
106				mmc_dev=${new_devs}
107				continue
108			fi
109			echo "${init_devs}" | grep "${mmc_dev}" >/dev/null
110			if [[ $? -eq 0 ]]; then
111				init_devs="${devs}"
112				continue
113			fi
114			break
115		fi
116	done
117	# now inform the user
118	echo "Detected device at /dev/${mmc_dev}"
119fi
120
121if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ]; then
122	cd ${ANDROID_BUILD_TOP}/external/arm-trusted-firmware
123	CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rk3399 DEBUG=0 ERROR_DEPRECATED=1 bl31
124	export BL31="${ANDROID_BUILD_TOP}/external/arm-trusted-firmware/build/rk3399/release/bl31/bl31.elf"
125	cd -
126fi
127
128cd ${ANDROID_BUILD_TOP}/external/u-boot
129
130if [ ${FLAGS_p2} -eq ${FLAGS_TRUE} ]; then
131	tmpfile=`mktemp`
132	bootenv=`mktemp`
133	cat > ${tmpfile} << "EOF"
134bootdelay=2
135baudrate=1500000
136scriptaddr=0x00500000
137boot_targets=mmc1 mmc0
138bootcmd=run distro_bootcmd
139distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
140bootcmd_mmc0=devnum=0; run mmc_boot
141bootcmd_mmc1=devnum=1; run mmc_boot
142mmc_boot=if mmc dev ${devnum}; then ; run scan_for_boot_part; fi
143scan_for_boot_part=part list mmc ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype mmc ${devnum}:${distro_bootpart} bootfstype; then run find_script; fi; done; setenv devplist;
144find_script=if test -e mmc ${devnum}:${distro_bootpart} /boot/boot.scr; then echo Found U-Boot script /boot/boot.scr; run run_scr; fi
145run_scr=load mmc ${devnum}:${distro_bootpart} ${scriptaddr} /boot/boot.scr; source ${scriptaddr}
146EOF
147	echo "Sha=`${script_dir}/gen_sha.sh --kernel ${KERNEL_DIR}`" >> ${tmpfile}
148	${ANDROID_HOST_OUT}/bin/mkenvimage -s 32768 -o ${bootenv} - < ${tmpfile}
149fi
150
151if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ] || [ ${FLAGS_p3} -eq ${FLAGS_TRUE} ]; then
152	make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- rock-pi-4-rk3399_defconfig
153	if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ]; then
154		make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- -j`nproc`
155	fi
156	if [ ${FLAGS_p3} -eq ${FLAGS_TRUE} ]; then
157		make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- u-boot.itb
158	fi
159	if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ]; then
160		idbloader=`mktemp`
161		${ANDROID_HOST_OUT}/bin/mkimage -n rk3399 -T rksd -d tpl/u-boot-tpl.bin ${idbloader}
162		cat spl/u-boot-spl.bin >> ${idbloader}
163	fi
164fi
165cd -
166
167if [ ${FLAGS_p5} -eq ${FLAGS_TRUE} ]; then
168	${ANDROID_BUILD_TOP}/kernel/tests/net/test/build_rootfs.sh -a arm64 -s buster -n ${IMAGE}
169	if [ $? -ne 0 ]; then
170		echo "error: failed to build rootfs. exiting..."
171		exit 1
172	fi
173	truncate -s +3G ${IMAGE}
174	e2fsck -f ${IMAGE}
175	resize2fs ${IMAGE}
176
177	mntdir=`mktemp -d`
178	mount ${IMAGE} ${mntdir}
179	if [ $? != 0 ]; then
180		echo "error: unable to mount ${IMAGE} ${mntdir}"
181		exit 1
182	fi
183
184	cat > ${mntdir}/boot/boot.cmd << "EOF"
185setenv start_poe 'gpio set 150; gpio clear 146'
186run start_poe
187setenv bootcmd_dhcp '
188mw.b ${scriptaddr} 0 0x8000
189mmc dev 0 0
190mmc read ${scriptaddr} 0x1fc0 0x40
191env import -b ${scriptaddr} 0x8000
192mw.b ${scriptaddr} 0 0x8000
193if dhcp ${scriptaddr} manifest.txt; then
194	setenv OldSha ${Sha}
195	setenv Sha
196	env import -t ${scriptaddr} 0x8000 ManifestVersion
197	echo "Manifest version $ManifestVersion";
198	if test "$ManifestVersion" = "1"; then
199		run manifest1
200	elif test "$ManifestVersion" = "2"; then
201		run manifest2
202	else
203		run manifestX
204	fi
205fi'
206setenv manifestX 'echo "***** ERROR: Unknown manifest version! *****";'
207setenv manifest1 '
208env import -t ${scriptaddr} 0x8000
209if test "$Sha" != "$OldSha"; then
210	setenv serverip ${TftpServer}
211	setenv loadaddr 0x00200000
212	mmc dev 0 0;
213	setenv file $TplSplImg; offset=0x40; size=0x1f80; run tftpget1; setenv TplSplImg
214	setenv file $UbootItb;  offset=0x4000; size=0x2000; run tftpget1; setenv UbootItb
215	setenv file $TrustImg; offset=0x6000; size=0x2000; run tftpget1; setenv TrustImg
216	setenv file $RootfsImg; offset=0x8000; size=0; run tftpget1; setenv RootfsImg
217	setenv file $UbootEnv; offset=0x1fc0; size=0x40; run tftpget1; setenv UbootEnv
218	mw.b ${scriptaddr} 0 0x8000
219	env export -b ${scriptaddr} 0x8000
220	mmc write ${scriptaddr} 0x1fc0 0x40
221else
222	echo "Already have ${Sha}. Booting..."
223fi'
224setenv manifest2 '
225env import -t ${scriptaddr} 0x8000
226if test "$DFUethaddr" = "$ethaddr" || test "$DFUethaddr" = ""; then
227	if test "$Sha" != "$OldSha"; then
228		setenv serverip ${TftpServer}
229		setenv loadaddr 0x00200000
230		mmc dev 0 0;
231		setenv file $TplSplImg; offset=0x40; size=0x1f80; run tftpget1; setenv TplSplImg
232		setenv file $UbootItb;  offset=0x4000; size=0x2000; run tftpget1; setenv UbootItb
233		setenv file $TrustImg; offset=0x6000; size=0x2000; run tftpget1; setenv TrustImg
234		setenv file $RootfsImg; offset=0x8000; size=0; run tftpget1; setenv RootfsImg
235		setenv file $UbootEnv; offset=0x1fc0; size=0x40; run tftpget1; setenv UbootEnv
236		mw.b ${scriptaddr} 0 0x8000
237		env export -b ${scriptaddr} 0x8000
238		mmc write ${scriptaddr} 0x1fc0 0x40
239	else
240		echo "Already have ${Sha}. Booting..."
241	fi
242else
243	echo "Update ${Sha} is not for me. Booting..."
244fi'
245setenv tftpget1 '
246if test "$file" != ""; then
247	mw.b ${loadaddr} 0 0x400000
248	tftp ${file}
249	if test $? = 0; then
250		setenv isGz 0 && setexpr isGz sub .*\\.gz\$ 1 ${file}
251		if test $isGz = 1; then
252			if test ${file} = ${UbootEnv}; then
253				echo "** gzipped env unsupported **"
254			else
255				setexpr boffset ${offset} * 0x200
256				gzwrite mmc 0 ${loadaddr} 0x${filesize} 100000 ${boffset} && echo Updated: ${file}
257			fi
258		elif test ${file} = ${UbootEnv}; then
259			env import -b ${loadaddr} && echo Updated: ${file}
260		else
261			if test $size = 0; then
262				setexpr x $filesize - 1
263				setexpr x $x / 0x1000
264				setexpr x $x + 1
265				setexpr x $x * 0x1000
266				setexpr x $x / 0x200
267				size=0x${x}
268			fi
269			mmc write ${loadaddr} ${offset} ${size} && echo Updated: ${file}
270		fi
271	fi
272	if test $? != 0; then
273		echo ** UPDATE FAILED: ${file} **
274	fi
275fi'
276if mmc dev 1 0; then; else
277	run bootcmd_dhcp;
278fi
279load mmc ${devnum}:${distro_bootpart} 0x02080000 /boot/Image
280load mmc ${devnum}:${distro_bootpart} 0x04000000 /boot/uInitrd
281load mmc ${devnum}:${distro_bootpart} 0x01f00000 /boot/dtb/rockchip/rk3399-rock-pi-4.dtb
282setenv finduuid "part uuid mmc ${devnum}:${distro_bootpart} uuid"
283run finduuid
284setenv bootargs "earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 loglevel=7 root=PARTUUID=${uuid} rootwait rootfstype=ext4 sdhci.debug_quirks=0x20000000 of_devlink=0"
285booti 0x02080000 0x04000000 0x01f00000
286EOF
287	${ANDROID_HOST_OUT}/bin/mkimage \
288		-C none -A arm -T script -d ${mntdir}/boot/boot.cmd ${mntdir}/boot/boot.scr
289
290	cd ${KERNEL_DIR}
291	export PATH=${ANDROID_BUILD_TOP}/prebuilts/clang/host/linux-x86/clang-r353983c/bin:$PATH
292	export PATH=${ANDROID_BUILD_TOP}/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH
293	make ARCH=arm64 CC=clang CROSS_COMPILE=aarch64-linux-androidkernel- \
294	      CLANG_TRIPLE=aarch64-linux-gnu- rockpi4_defconfig
295	make ARCH=arm64 CC=clang CROSS_COMPILE=aarch64-linux-androidkernel- \
296	      CLANG_TRIPLE=aarch64-linux-gnu- -j`nproc`
297
298	cp ${KERNEL_DIR}/arch/arm64/boot/Image ${mntdir}/boot/
299	mkdir -p ${mntdir}/boot/dtb/rockchip/
300	cp ${KERNEL_DIR}/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtb ${mntdir}/boot/dtb/rockchip/
301	cd -
302
303	mount -o bind /proc ${mntdir}/proc
304	mount -o bind /sys ${mntdir}/sys
305	mount -o bind /dev ${mntdir}/dev
306
307	echo "Installing required packages..."
308	chroot ${mntdir} /bin/bash <<EOF
309apt-get update
310apt-get install -y -f initramfs-tools u-boot-tools network-manager openssh-server sudo man-db vim git dpkg-dev cdbs debhelper config-package-dev gdisk eject lzop binfmt-support ntpdate
311EOF
312
313	echo "Turning on DHCP client..."
314	cat >${mntdir}/etc/systemd/network/dhcp.network <<EOF
315[Match]
316Name=en*
317
318[Network]
319DHCP=yes
320EOF
321
322	chroot ${mntdir} /bin/bash << "EOT"
323echo "Adding user vsoc-01 and groups..."
324useradd -m -G kvm,sudo -d /home/vsoc-01 --shell /bin/bash vsoc-01
325echo -e "cuttlefish\ncuttlefish" | passwd
326echo -e "cuttlefish\ncuttlefish" | passwd vsoc-01
327EOT
328
329	echo "Cloning android-cuttlefish..."
330	cd ${mntdir}/home/vsoc-01
331	git clone https://github.com/google/android-cuttlefish.git
332	cd -
333
334	echo "Creating PoE script..."
335	cat > ${mntdir}/usr/local/bin/poe << "EOF"
336#!/bin/bash
337
338if [ "$1" == "--start" ]; then
339	echo 146 > /sys/class/gpio/export
340	echo out > /sys/class/gpio/gpio146/direction
341	echo 0 > /sys/class/gpio/gpio146/value
342	echo 150 > /sys/class/gpio/export
343	echo out > /sys/class/gpio/gpio150/direction
344	echo 1 > /sys/class/gpio/gpio150/value
345	exit 0
346fi
347
348if [ "$1" == "--stop" ]; then
349	echo 0 > /sys/class/gpio/gpio146/value
350	echo 146 > /sys/class/gpio/unexport
351	echo 0 > /sys/class/gpio/gpio150/value
352	echo 150 > /sys/class/gpio/unexport
353	exit 0
354fi
355
356if [ ! -e /sys/class/gpio/gpio146/value ] || [ ! -e /sys/class/gpio/gpio150/value ]; then
357	echo "error: PoE service not initialized"
358	exit 1
359fi
360
361if [ "$1" == "0" ] || [ "$1" == "off" ] || [ "$1" == "OFF" ]; then
362	echo 0 > /sys/class/gpio/gpio150/value
363	exit 0
364fi
365
366if [ "$1" == "1" ] || [ "$1" == "on" ] || [ "$1" == "ON" ]; then
367	echo 1 > /sys/class/gpio/gpio150/value
368	exit 0
369fi
370
371echo "usage: poe <0|1>"
372exit 1
373EOF
374	chown root:root ${mntdir}/usr/local/bin/poe
375	chmod 755 ${mntdir}/usr/local/bin/poe
376
377	echo "Creating PoE service..."
378	cat > ${mntdir}/etc/systemd/system/poe.service << EOF
379[Unit]
380 Description=PoE service
381 ConditionPathExists=/usr/local/bin/poe
382
383[Service]
384 Type=oneshot
385 ExecStart=/usr/local/bin/poe --start
386 ExecStop=/usr/local/bin/poe --stop
387 RemainAfterExit=true
388 StandardOutput=journal
389
390[Install]
391 WantedBy=multi-user.target
392EOF
393
394	echo "Creating led script..."
395	cat > ${mntdir}/usr/local/bin/led << "EOF"
396#!/bin/bash
397
398if [ "$1" == "--start" ]; then
399	echo 125 > /sys/class/gpio/export
400	echo out > /sys/class/gpio/gpio125/direction
401	chmod 666 /sys/class/gpio/gpio125/value
402	echo 0 > /sys/class/gpio/gpio125/value
403	exit 0
404fi
405
406if [ "$1" == "--stop" ]; then
407	echo 0 > /sys/class/gpio/gpio125/value
408	echo 125 > /sys/class/gpio/unexport
409	exit 0
410fi
411
412if [ ! -e /sys/class/gpio/gpio125/value ]; then
413	echo "error: led service not initialized"
414	exit 1
415fi
416
417if [ "$1" == "0" ] || [ "$1" == "off" ] || [ "$1" == "OFF" ]; then
418	echo 0 > /sys/class/gpio/gpio125/value
419	exit 0
420fi
421
422if [ "$1" == "1" ] || [ "$1" == "on" ] || [ "$1" == "ON" ]; then
423	echo 1 > /sys/class/gpio/gpio125/value
424	exit 0
425fi
426
427echo "usage: led <0|1>"
428exit 1
429EOF
430	chown root:root ${mntdir}/usr/local/bin/led
431	chmod 755 ${mntdir}/usr/local/bin/led
432
433	echo "Creating led service..."
434	cat > ${mntdir}/etc/systemd/system/led.service << EOF
435[Unit]
436 Description=led service
437 ConditionPathExists=/usr/local/bin/led
438
439[Service]
440 Type=oneshot
441 ExecStart=/usr/local/bin/led --start
442 ExecStop=/usr/local/bin/led --stop
443 RemainAfterExit=true
444 StandardOutput=journal
445
446[Install]
447 WantedBy=multi-user.target
448EOF
449
450	echo "Creating SD duplicator script..."
451	cat > ${mntdir}/usr/local/bin/sd-dupe << "EOF"
452#!/bin/bash
453led 0
454
455src_dev=mmcblk0
456dest_dev=mmcblk1
457part_num=p5
458
459if [ -e /dev/mmcblk0p5 ] && [ -e /dev/mmcblk1p5 ]; then
460	led 1
461
462	sgdisk -Z -a1 /dev/${dest_dev}
463	sgdisk -a1 -n:1:64:8127 -t:1:8301 -c:1:loader1 /dev/${dest_dev}
464	sgdisk -a1 -n:2:8128:8191 -t:2:8301 -c:2:env /dev/${dest_dev}
465	sgdisk -a1 -n:3:16384:24575 -t:3:8301 -c:3:loader2 /dev/${dest_dev}
466	sgdisk -a1 -n:4:24576:32767 -t:4:8301 -c:4:trust /dev/${dest_dev}
467	sgdisk -a1 -n:5:32768:- -A:5:set:2 -t:5:8305 -c:5:rootfs /dev/${dest_dev}
468
469	src_block_count=`tune2fs -l /dev/${src_dev}${part_num} | grep "Block count:" | sed 's/.*: *//'`
470	src_block_size=`tune2fs -l /dev/${src_dev}${part_num} | grep "Block size:" | sed 's/.*: *//'`
471	src_fs_size=$(( src_block_count*src_block_size ))
472	src_fs_size_m=$(( src_fs_size / 1024 / 1024 + 1 ))
473
474	dd if=/dev/${src_dev}p1 of=/dev/${dest_dev}p1 conv=sync,noerror status=progress
475	dd if=/dev/${src_dev}p2 of=/dev/${dest_dev}p2 conv=sync,noerror status=progress
476	dd if=/dev/${src_dev}p3 of=/dev/${dest_dev}p3 conv=sync,noerror status=progress
477	dd if=/dev/${src_dev}p4 of=/dev/${dest_dev}p4 conv=sync,noerror status=progress
478
479	echo "Writing ${src_fs_size_m} MB: /dev/${src_dev} -> /dev/${dest_dev}..."
480	dd if=/dev/${src_dev}${part_num} of=/dev/${dest_dev}${part_num} bs=1M conv=sync,noerror status=progress
481
482	echo "Expanding /dev/${dest_dev}${part_num} filesystem..."
483	e2fsck -fy /dev/${dest_dev}${part_num}
484	resize2fs /dev/${dest_dev}${part_num}
485	tune2fs -O has_journal /dev/${dest_dev}${part_num}
486	e2fsck -fy /dev/${dest_dev}${part_num}
487	sync /dev/${dest_dev}
488
489	echo "Cleaning up..."
490	mount /dev/${dest_dev}${part_num} /media
491	chroot /media /usr/local/bin/install-cleanup
492
493	if [ $? == 0 ]; then
494		echo "Successfully copied Rock Pi image!"
495		while true; do
496			led 1; sleep 0.5
497			led 0; sleep 0.5
498		done
499	else
500		echo "Error while copying Rock Pi image"
501		while true; do
502			led 1; sleep 0.1
503			led 0; sleep 0.1
504		done
505	fi
506else
507	echo "Expanding /dev/${dest_dev}${part_num} filesystem..."
508	e2fsck -fy /dev/${dest_dev}${part_num}
509	resize2fs /dev/${dest_dev}${part_num}
510	tune2fs -O has_journal /dev/${dest_dev}${part_num}
511	e2fsck -fy /dev/${dest_dev}${part_num}
512	sync /dev/${dest_dev}
513
514	echo "Cleaning up..."
515	/usr/local/bin/install-cleanup
516fi
517EOF
518	chmod +x ${mntdir}/usr/local/bin/sd-dupe
519
520	echo "Creating SD duplicator service..."
521	cat > ${mntdir}/etc/systemd/system/sd-dupe.service << EOF
522[Unit]
523 Description=Duplicate SD card rootfs to eMMC on Rock Pi
524 ConditionPathExists=/usr/local/bin/sd-dupe
525 After=led.service
526
527[Service]
528 Type=simple
529 ExecStart=/usr/local/bin/sd-dupe
530 TimeoutSec=0
531 StandardOutput=tty
532
533[Install]
534 WantedBy=multi-user.target
535EOF
536
537	umount ${mntdir}/sys
538	umount ${mntdir}/dev
539	umount ${mntdir}/proc
540
541	chroot ${mntdir} /bin/bash << "EOT"
542echo "Installing cuttlefish-common package..."
543dpkg --add-architecture amd64
544apt-get update
545apt-get install -y -f libc6:amd64 qemu-user-static
546cd /home/vsoc-01/android-cuttlefish
547dpkg-buildpackage -d -uc -us
548apt-get install -y -f ../cuttlefish-common_*_arm64.deb
549apt-get clean
550
551usermod -aG cvdnetwork vsoc-01
552chmod 660 /dev/vhost-vsock
553chown root:cvdnetwork /dev/vhost-vsock
554rm -rf /home/vsoc-01/*
555EOT
556
557	echo "Creating cleanup script..."
558	cat > ${mntdir}/usr/local/bin/install-cleanup << "EOF"
559#!/bin/bash
560echo "nameserver 8.8.8.8" > /etc/resolv.conf
561MAC=`ip link | grep eth0 -A1 | grep ether | sed 's/.*\(..:..:..:..:..:..\) .*/\1/' | tr -d :`
562sed -i " 1 s/.*/& rockpi-${MAC}/" /etc/hosts
563sudo hostnamectl set-hostname "rockpi-${MAC}"
564
565rm /etc/machine-id
566rm /var/lib/dbus/machine-id
567dbus-uuidgen --ensure
568systemd-machine-id-setup
569
570systemctl disable sd-dupe
571rm /etc/systemd/system/sd-dupe.service
572rm /usr/local/bin/sd-dupe
573rm /usr/local/bin/install-cleanup
574EOF
575	chmod +x ${mntdir}/usr/local/bin/install-cleanup
576
577	chroot ${mntdir} /bin/bash << "EOT"
578echo "Enabling services..."
579systemctl enable poe
580systemctl enable led
581systemctl enable sd-dupe
582
583echo "Creating Initial Ramdisk..."
584update-initramfs -c -t -k "5.2.0"
585mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n uInitrd -d /boot/initrd.img-5.2.0 /boot/uInitrd-5.2.0
586ln -s /boot/uInitrd-5.2.0 /boot/uInitrd
587EOT
588
589	umount ${mntdir}
590
591	# Turn on journaling
592	tune2fs -O ^has_journal ${IMAGE}
593	e2fsck -fy ${IMAGE} >/dev/null 2>&1
594fi
595
596if [ ${USE_IMAGE} -eq 0 ]; then
597	# 32GB eMMC size
598	end_sector=61071326
599	device=/dev/${mmc_dev}
600	devicep=${device}
601
602	sgdisk -Z -a1 ${device}
603	sgdisk -a1 -n:1:64:8127 -t:1:8301 -c:1:loader1 ${device}
604	sgdisk -a1 -n:2:8128:8191 -t:2:8301 -c:2:env ${device}
605	sgdisk -a1 -n:3:16384:24575 -t:3:8301 -c:3:loader2 ${device}
606	sgdisk -a1 -n:4:24576:32767 -t:4:8301 -c:4:trust ${device}
607	sgdisk -a1 -n:5:32768:${end_sector} -A:5:set:2 -t:5:8305 -c:5:rootfs ${device}
608	if [ ${FLAGS_p5} -eq ${FLAGS_TRUE} ]; then
609		dd if=${IMAGE} of=${devicep}5 bs=1M
610		resize2fs ${devicep}5 >/dev/null 2>&1
611	fi
612else
613	device=$(losetup -f)
614	devicep=${device}p
615	if [ ${FLAGS_p5} -eq ${FLAGS_FALSE} ]; then
616		fs_end=3G
617		end_sector=-
618	fi
619	if [ ${FLAGS_p5} -eq ${FLAGS_TRUE} ]; then
620		# Minimize rootfs filesystem
621		while true; do
622			out=`sudo resize2fs -M ${IMAGE} 2>&1`
623			if [[ $out =~ "Nothing to do" ]]; then
624				break
625			fi
626		done
627		# Minimize rootfs file size
628		block_count=`sudo tune2fs -l ${IMAGE} | grep "Block count:" | sed 's/.*: *//'`
629		block_size=`sudo tune2fs -l ${IMAGE} | grep "Block size:" | sed 's/.*: *//'`
630		sector_size=512
631		start_sector=32768
632		fs_size=$(( block_count*block_size ))
633		fs_sectors=$(( fs_size/sector_size ))
634		part_sectors=$(( ((fs_sectors-1)/2048+1)*2048 ))  # 1MB-aligned
635		end_sector=$(( start_sector+part_sectors-1 ))
636		secondary_gpt_sectors=33
637		fs_end=$(( (end_sector+secondary_gpt_sectors+1)*sector_size ))
638		image_size=$(( part_sectors*sector_size ))
639		truncate -s ${image_size} ${IMAGE}
640		e2fsck -fy ${IMAGE} >/dev/null 2>&1
641	fi
642
643	# Create final image
644	if [ $OVERWRITE -eq 1 ]; then
645		tmpimg=${OVERWRITE_IMAGE}
646	else
647		tmpimg=`mktemp`
648	fi
649	truncate -s ${fs_end} ${tmpimg}
650
651	# Create GPT
652	sgdisk -Z -a1 ${tmpimg}
653	sgdisk -a1 -n:1:64:8127 -t:1:8301 -c:1:loader1 ${tmpimg}
654	sgdisk -a1 -n:2:8128:8191 -t:2:8301 -c:2:env ${tmpimg}
655	sgdisk -a1 -n:3:16384:24575 -t:3:8301 -c:3:loader2 ${tmpimg}
656	sgdisk -a1 -n:4:24576:32767 -t:4:8301 -c:4:trust ${tmpimg}
657	sgdisk -a1 -n:5:32768:${end_sector} -A:5:set:2 -t:5:8305 -c:5:rootfs ${tmpimg}
658
659	losetup ${device} ${tmpimg}
660	partx -v --add ${device}
661
662	if [ ${FLAGS_p5} -eq ${FLAGS_TRUE} ]; then
663		dd if=${IMAGE} of=${devicep}5 bs=1M
664	fi
665fi
666if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ]; then
667	dd if=${idbloader} of=${devicep}1
668fi
669if [ ${FLAGS_p2} -eq ${FLAGS_TRUE} ]; then
670	dd if=${bootenv} of=${devicep}2
671fi
672if [ ${FLAGS_p3} -eq ${FLAGS_TRUE} ]; then
673	dd if=${ANDROID_BUILD_TOP}/external/u-boot/u-boot.itb of=${devicep}3
674fi
675if [ ${USE_IMAGE} -eq 1 ]; then
676	chown $SUDO_USER:`id -ng $SUDO_USER` ${tmpimg}
677	if [ $OVERWRITE -eq 0 ]; then
678		mv ${tmpimg} ${IMAGE}
679	fi
680	partx -v --delete ${device}
681	losetup -d ${device}
682fi
683