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 17set -e 18set -u 19 20script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 21 22if [ -z $ANDROID_BUILD_TOP ]; then 23 echo "error: please run script after 'lunch'" 24 export ANDROID_BUILD_TOP=$(realpath "${script_dir}"/../../../..) 25 echo "error: set ANDROID_BUILD_TOP as ${ANDROID_BUILD_TOP}" 26fi 27 28source "${ANDROID_BUILD_TOP}/external/shflags/shflags" 29 30UBOOT_DIST= 31KERNEL_DIST= 32OUTPUT_IMAGE= 33 34FLAGS_HELP="USAGE: $0 [UBOOT_DIST] [KERNEL_DIST] [OUTPUT_IMAGE] [flags]" 35 36FLAGS "$@" || exit $? 37eval set -- "${FLAGS_ARGV}" 38 39for arg in "$@" ; do 40 if [ -z $UBOOT_DIST ]; then 41 UBOOT_DIST=$arg 42 elif [ -z $KERNEL_DIST ]; then 43 KERNEL_DIST=$arg 44 elif [ -z $OUTPUT_IMAGE ]; then 45 OUTPUT_IMAGE=$arg 46 else 47 flags_help 48 exit 1 49 fi 50done 51 52if [ -z "${KERNEL_DIST}" ]; then 53 OUTPUT_IMAGE="${UBOOT_DIST}" 54 UBOOT_DIST= 55fi 56 57if [ ! -e "${UBOOT_DIST}" ]; then 58 echo "No UBOOT_DIST, use prebuilts" 59 UBOOT_DIST="${ANDROID_BUILD_TOP}"/device/google/cuttlefish_prebuilts/bootloader/rockpi_aarch64 60fi 61if [ ! -e "${KERNEL_DIST}" ]; then 62 echo "No KERNEL_DIST, use prebuilts" 63 KERNEL_DIST=$(find "${ANDROID_BUILD_TOP}"/device/google/cuttlefish_prebuilts/kernel -name '*-arm64-rockpi' | sort | tail -n 1) 64fi 65 66WRITE_TO_IMAGE=`[ -z "${OUTPUT_IMAGE}" ] && echo "0" || echo "1"` 67 68if [ $WRITE_TO_IMAGE -eq 0 ]; then 69 init_devs=`lsblk --nodeps -oNAME -n` 70 echo "Reinsert device (to write to) into PC" 71 while true; do 72 devs=`lsblk --nodeps -oNAME -n` 73 new_devs="$(echo -e "${init_devs}\n${devs}" | sort | uniq -u | awk 'NF')" 74 num_devs=`echo "${new_devs}" | wc -l` 75 if [[ "${new_devs}" == "" ]]; then 76 num_devs=0 77 fi 78 if [[ ${num_devs} -gt 1 ]]; then 79 echo "error: too many new devices detected! aborting..." 80 exit 1 81 fi 82 if [[ ${num_devs} -eq 1 ]]; then 83 if [[ "${new_devs}" != "${mmc_dev}" ]]; then 84 if [[ "${mmc_dev}" != "" ]]; then 85 echo "error: block device name mismatch ${new_devs} != ${mmc_dev}" 86 echo "Reinsert device (to write to) into PC" 87 fi 88 mmc_dev=${new_devs} 89 continue 90 fi 91 echo "${init_devs}" | grep "${mmc_dev}" >/dev/null 92 if [[ $? -eq 0 ]]; then 93 init_devs="${devs}" 94 continue 95 fi 96 break 97 fi 98 done 99 # now inform the user 100 echo "Detected device at /dev/${mmc_dev}" 101fi 102 103bootenv_src=`mktemp` 104bootenv=`mktemp` 105cat > ${bootenv_src} << "EOF" 106bootdelay=2 107baudrate=1500000 108scriptaddr=0x00500000 109boot_targets=mmc1 mmc0 110bootcmd=run distro_bootcmd 111distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done 112bootcmd_mmc0=devnum=0; run mmc_boot 113bootcmd_mmc1=devnum=1; run mmc_boot 114mmc_boot=if mmc dev ${devnum}; then ; run scan_for_boot_part; fi 115scan_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; 116find_script=if test -e mmc ${devnum}:${distro_bootpart} /boot/boot.scr; then echo Found U-Boot script /boot/boot.scr; run run_scr; fi 117run_scr=load mmc ${devnum}:${distro_bootpart} ${scriptaddr} /boot/boot.scr; source ${scriptaddr} 118fastboot_raw_partition_raw1=0x0 0x2000000 119EOF 120echo "Sha=`${script_dir}/gen_sha.sh --uboot ${UBOOT_DIST} --kernel ${KERNEL_DIST}`" >> ${bootenv_src} 121mkenvimage -s 32768 -o ${bootenv} - < ${bootenv_src} 122rm -f ${bootenv_src} 123 124IMAGE=`mktemp` 125kernel_dist_dir=$(echo ${KERNEL_DIST}) 126kernel_dist_dir=$(realpath ${kernel_dist_dir}) 127if [ ! -d "${kernel_dist_dir}" ]; then 128 echo "error: running realpath on KERNEL_DIST fail" 129 echo KERNEL_DIST="${KERNEL_DIST}" 130 echo kernel_dist_dir="${kernel_dist_dir}" 131 exit 1 132fi 133${ANDROID_BUILD_TOP}/kernel/tests/net/test/build_rootfs.sh \ 134 -a arm64 -s bullseye-rockpi -n ${IMAGE} -r ${IMAGE}.initrd -e -g \ 135 -k ${kernel_dist_dir}/Image -i ${kernel_dist_dir}/initramfs.img \ 136 -d ${kernel_dist_dir}/rk3399-rock-pi-4b.dtb:rockchip 137if [ $? -ne 0 ]; then 138 echo "error: failed to build rootfs. exiting..." 139 rm -f ${IMAGE} 140 exit 1 141fi 142rm -f ${IMAGE}.initrd 143 144if [ ${WRITE_TO_IMAGE} -eq 0 ]; then 145 device=/dev/${mmc_dev} 146 devicep=${device} 147 148 # Burn the whole disk image with partition table 149 sudo dd if=${IMAGE} of=${device} bs=1M conv=fsync 150 151 # Update partition table for 32GB eMMC 152 end_sector=61071326 153 sudo sgdisk --delete=7 ${device} 154 sudo sgdisk --new=7:145M:${end_sector} --typecode=7:8305 --change-name=7:rootfs --attributes=7:set:2 ${device} 155 156 # Rescan the partition table and resize the rootfs 157 sudo partx -v --add ${device} 158 sudo resize2fs ${devicep}7 >/dev/null 2>&1 159else 160 # Minimize rootfs filesystem 161 rootfs_partition_start=$(partx -g -o START -s -n 7 "${IMAGE}" | xargs) 162 rootfs_partition_end=$(partx -g -o END -s -n 7 "${IMAGE}" | xargs) 163 rootfs_partition_num_sectors=$((${rootfs_partition_end} - ${rootfs_partition_start} + 1)) 164 rootfs_partition_offset=$((${rootfs_partition_start} * 512)) 165 rootfs_partition_size=$((${rootfs_partition_num_sectors} * 512)) 166 e2fsck -fy ${IMAGE}?offset=${rootfs_partition_offset} >/dev/null 2>&1 167 imagesize=`stat -c %s "${IMAGE}"` 168 rootfs_partition_tempfile=$(mktemp) 169 dd if="${IMAGE}" of="${rootfs_partition_tempfile}" bs=512 skip=${rootfs_partition_start} count=${rootfs_partition_num_sectors} 170 while true; do 171 out=`resize2fs -M ${rootfs_partition_tempfile} 2>&1` 172 if [[ $out =~ "Nothing to do" ]]; then 173 break 174 fi 175 done 176 dd if="${rootfs_partition_tempfile}" of="${IMAGE}" bs=512 seek=${rootfs_partition_start} count=${rootfs_partition_num_sectors} conv=fsync,notrunc 177 rm -f "${rootfs_partition_tempfile}" 178 truncate -s "${imagesize}" "${IMAGE}" 179 sgdisk -e "${IMAGE}" 180 e2fsck -fy ${IMAGE}?offset=${rootfs_partition_offset} || true 181 182 # Minimize rootfs file size 183 block_count=`tune2fs -l ${IMAGE}?offset=${rootfs_partition_offset} | grep "Block count:" | sed 's/.*: *//'` 184 block_size=`tune2fs -l ${IMAGE}?offset=${rootfs_partition_offset} | grep "Block size:" | sed 's/.*: *//'` 185 sector_size=512 186 start_sector=`partx -g -o START -s -n 7 "${IMAGE}" | xargs` 187 fs_size=$(( block_count*block_size )) 188 fs_sectors=$(( fs_size/sector_size )) 189 part_sectors=$(( ((fs_sectors-1)/2048+1)*2048 )) # 1MB-aligned 190 end_sector=$(( start_sector+part_sectors-1 )) 191 secondary_gpt_sectors=33 192 fs_end=$(( (end_sector+secondary_gpt_sectors+1)*sector_size )) 193 image_size=$(( part_sectors*sector_size )) 194 195 # Disable ext3/4 journal for flashing to SD-Card 196 tune2fs -O ^has_journal ${IMAGE}?offset=${rootfs_partition_offset} 197 e2fsck -fy ${IMAGE}?offset=${rootfs_partition_offset} >/dev/null 2>&1 198 199 # Update partition table 200 sgdisk --delete=7 ${IMAGE} 201 sgdisk --new=7:145M:${end_sector} --typecode=7:8305 --change-name=7:rootfs --attributes=7:set:2 ${IMAGE} 202fi 203 204# idbloader 205if [ ${WRITE_TO_IMAGE} -eq 0 ]; then 206 sudo dd if=${UBOOT_DIST}/idbloader.img of=${devicep}1 conv=fsync 207else 208 idbloader_partition_start=$(partx -g -o START -s -n 1 "${IMAGE}" | xargs) 209 dd if=${UBOOT_DIST}/idbloader.img of="${IMAGE}" bs=512 seek=${idbloader_partition_start} conv=fsync,notrunc 210fi 211# prebuilt 212# sudo dd if=${ANDROID_BUILD_TOP}/device/google/cuttlefish_prebuilts/uboot_bin/idbloader.img of=${devicep}1 conv=fsync 213 214# uboot_env 215if [ ${WRITE_TO_IMAGE} -eq 0 ]; then 216 sudo dd if=${bootenv} of=${devicep}2 conv=fsync 217else 218 ubootenv_partition_start=$(partx -g -o START -s -n 2 "${IMAGE}" | xargs) 219 dd if=${bootenv} of="${IMAGE}" bs=512 seek=${ubootenv_partition_start} conv=fsync,notrunc 220fi 221# uboot 222if [ ${WRITE_TO_IMAGE} -eq 0 ]; then 223 sudo dd if=${UBOOT_DIST}/u-boot.itb of=${devicep}3 conv=fsync 224else 225 uboot_partition_start=$(partx -g -o START -s -n 3 "${IMAGE}" | xargs) 226 dd if=${UBOOT_DIST}/u-boot.itb of="${IMAGE}" bs=512 seek=${uboot_partition_start} conv=fsync,notrunc 227fi 228# prebuilt 229# sudo dd if=${ANDROID_BUILD_TOP}/device/google/cuttlefish_prebuilts/uboot_bin/u-boot.itb of=${devicep}3 conv=fsync 230 231if [ ${WRITE_TO_IMAGE} -eq 1 ]; then 232 truncate -s ${fs_end} ${IMAGE} 233 sgdisk --move-second-header ${IMAGE} 234 mv -f ${IMAGE} ${OUTPUT_IMAGE} 235fi 236