]> git.sesse.net Git - debian-xu4/blob - mkimage.sh
Minor cleanup.
[debian-xu4] / mkimage.sh
1 #! /bin/bash
2
3 # Install a bog-standard Debian bootable for ODROID XU3/XU4.
4 # Note that this will only work for SD cards; MMC devices
5 # have a different layout. See
6 # /usr/share/doc/u-boot-exynos/README.odroid.gz for more details.
7 #
8 # Note: You will need u-boot-exynos >= 2016.05~rc3+dfsg1-1,
9 # which at the time of writing is in experimental (it will
10 # probably eventually hit stretch).
11 #
12 # Beware: This will ERASE ALL DATA on the target SD card.
13 #
14 #
15 # Copyright 2016 Steinar H. Gunderson <steinar+odroid@gunderson.no>.
16 # Licensed under the GNU GPL, v2 or (at your option) any later version.
17
18 set -e
19
20 DEVICE=
21 BOOTPART_MB=256
22 SUITE=stretch
23
24 while getopts "b:s:" opt; do
25         case $opt in
26                 b)
27                         BOOTPART_MB=$OPTARG
28                         ;;
29                 s)
30                         # Sorry, jessie won't work; the kernel doesn't support XU3/XU4.
31                         SUITE=$OPTARG
32                         ;;
33                 :)
34                         echo "Option -$OPTARG requires an argument."
35                         exit 1
36                         ;;
37         esac
38 done
39 shift $((OPTIND - 1))
40
41 DEVICE=$1
42 if [ ! -b "$DEVICE" ]; then
43         echo "Usage: $0 [-b BOOTPARTITION_SIZE] [-s SUITE] DEVICE [OTHER_DEBOOTSTRAP_ARGS...]"
44         echo "DEVICE is an SD card device, e.g. /dev/sdb."
45         exit 1
46 fi
47 shift
48
49 set -x
50
51 # Prerequisites.
52 dpkg --add-architecture armhf
53 apt update
54 apt install git parted dosfstools e2fsprogs binfmt-support qemu qemu-user-static debootstrap zerofree u-boot-exynos:armhf
55
56 # Get first stages of bootloader. (BL1 must be signed by Hardkernel,
57 # and TZSW comes without source anyway, so we can't build these ourselves)
58 # This is the only part that doesn't strictly need root.
59 if [ ! -d u-boot ]; then
60         git clone https://github.com/hardkernel/u-boot -b odroidxu3-v2012.07
61 fi
62
63 # Partition the device.
64 parted ${DEVICE} mklabel msdos
65 parted ${DEVICE} mkpart primary fat32 2MB $(( BOOTPART_MB + 2 ))MB
66 parted ${DEVICE} set 1 boot on
67 parted ${DEVICE} mkpart primary ext2 $(( BOOTPART_MB + 2))MB 100%
68
69 # Figure out if the partitions are of type ${DEVICE}1 or ${DEVICE}p1.
70 if [ -b "${DEVICE}1" ]; then
71         DEVICE_STEM=${DEVICE}
72 elif [ -b "${DEVICE}p1" ]; then
73         DEVICE_STEM=${DEVICE}p
74 else
75         echo "Could not find device files for partitions of ${DEVICE}. Exiting."
76         exit 1
77 fi
78
79 # Put the different stages of U-Boot into the right place.
80 # The offsets come from README.odroid.gz.
81 dd if=u-boot/sd_fuse/hardkernel_1mb_uboot/bl1.bin.hardkernel of=${DEVICE} seek=1 conv=sync
82 dd if=u-boot/sd_fuse/hardkernel_1mb_uboot/bl2.bin.hardkernel.1mb_uboot of=${DEVICE} seek=31 conv=sync
83 dd if=/usr/lib/u-boot/odroid-xu3/u-boot-dtb.bin of=${DEVICE} seek=63 conv=sync
84 dd if=u-boot/sd_fuse/hardkernel_1mb_uboot/tzsw.bin.hardkernel of=${DEVICE} seek=2111 conv=sync
85
86 # Clear out the environment.
87 dd if=/dev/zero of=${DEVICE} seek=2560 count=32 bs=512 conv=sync
88
89 # Create a /boot partition. Strictly speaking, almost everything could be loaded
90 # from ext4, but using FAT is somehow traditional and less likely to be broken
91 # at any given time. (It doesn't support symlinks, though, which breaks flash-kernel,
92 # but we don't use that anyway.)
93 BOOT_PART=${DEVICE_STEM}1
94 mkfs.vfat -F 32 ${BOOT_PART}
95
96 # Put an LVM on the other partition; it's easier to deal with when expanding
97 # partitions or otherwise moving them around.
98 vgchange -a n odroid || true  # Could be left around from a previous copy of the partition.
99 pvcreate -ff ${DEVICE_STEM}2
100 vgcreate odroid ${DEVICE_STEM}2
101 lvcreate -l 100%FREE -n root odroid
102
103 # And the main filesystem.
104 mkfs.ext4 /dev/odroid/root
105
106 # Mount the filesystem and debootstrap into it.
107 # isc-dhcp-client is, of course, not necessarily required, especially as
108 # systemd-networkd is included and can do networking just fine, but most people
109 # will probably find it very frustrating to install packages without it.
110 mkdir -p /mnt/xu4/
111 mount /dev/odroid/root /mnt/xu4
112 mkdir /mnt/xu4/boot/
113 mount ${BOOT_PART} /mnt/xu4/boot
114 debootstrap --include=linux-image-armmp-lpae,grub-efi-arm,lvm2,isc-dhcp-client --foreign --arch armhf ${SUITE} /mnt/xu4 "$@"
115
116 # Run the second stage debootstrap under qemu (via binfmt_misc).
117 cp /usr/bin/qemu-arm-static /mnt/xu4/usr/bin/
118 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot /mnt/xu4 /debootstrap/debootstrap --second-stage
119 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot /mnt/xu4 dpkg --configure -a
120
121 # Enable security updates, and apply any that might be waiting.
122 if [ "$SUITE" != "unstable" ] && [ "$SUITE" != "sid" ]; then
123         echo "deb http://security.debian.org $SUITE/updates main" >> /mnt/xu4/etc/apt/sources.list
124         DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot /mnt/xu4 apt update
125         DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot /mnt/xu4 apt dist-upgrade
126 fi
127
128 # Create an fstab (this is normally done by partconf, in d-i).
129 BOOT_UUID=$( blkid -s UUID -o value ${BOOT_PART} )
130 cat <<EOF > /mnt/xu4/etc/fstab
131 # /etc/fstab: static file system information.
132 #
133 # Use 'blkid' to print the universally unique identifier for a
134 # device; this may be used with UUID= as a more robust way to name devices
135 # that works even if disks are added and removed. See fstab(5).
136 #
137 # <file system> <mount point>   <type>  <options>       <dump>  <pass>
138 /dev/odroid/root / ext4 errors=remount-ro 0 1
139 UUID=${BOOT_UUID} /boot vfat defaults 0 2
140 EOF
141
142 # Set a hostname.
143 echo odroid > /mnt/xu4/etc/hostname
144
145 # Work around Debian bug #824391.
146 echo ttySAC2 >> /mnt/xu4/etc/securetty
147
148 # Install GRUB, chainloaded from U-Boot via UEFI.
149 mount --bind /dev /mnt/xu4/dev
150 mount --bind /proc /mnt/xu4/proc
151 chroot /mnt/xu4 /usr/sbin/grub-install --removable --target=arm-efi --boot-directory=/boot --efi-directory=/boot
152
153 # Get the device tree in place (we need it to load GRUB).
154 # flash-kernel can do this (if you also have u-boot-tools installed),
155 # but it also includes its own boot script (which has higher priority than
156 # GRUB) and just seems to lock up.
157 cp $( find /mnt/xu4 -name exynos5422-odroidxu4.dtb ) /mnt/xu4/boot/
158
159 # update-grub does not add “devicetree” statements for the
160 # each kernel (not that it's copied from /usr/lib without
161 # flash-kernel anyway), so we need to explicitly load it
162 # ourselves. See Debian bug #824399.
163 cat <<EOF > /mnt/xu4/etc/grub.d/25_devicetree
164 #! /bin/sh
165 set -e
166
167 # Hack added by prepare.sh when building the root image,
168 # to work around Debian bug #824399.
169 echo "echo 'Loading device tree ...'"
170 echo "devicetree /exynos5422-odroidxu4.dtb"
171 EOF
172 chmod 0755 /mnt/xu4/etc/grub.d/25_devicetree
173
174 # Work around Debian bug #823552.
175 sed -i 's/\(GRUB_CMDLINE_LINUX_DEFAULT=".*\)"/\1 loglevel=4"/' /mnt/xu4/etc/default/grub 
176
177 # Now we can create the GRUB boot menu.
178 chroot /mnt/xu4 /usr/sbin/update-grub
179
180 # Set the root password. (It should be okay to have a dumb one as default,
181 # since there's no ssh by default. Yet, it would be nice to have a way
182 # to ask on first boot, or better yet, invoke debian-installer after boot.)
183 echo root:odroid | chroot /mnt/xu4 /usr/sbin/chpasswd
184
185 # Zero any unused blocks on /boot, for better packing if we are to compress the
186 # filesystem and publish it somewhere. (See below for the root device.)
187 echo 'Please ignore the following error about full disk.'
188 dd if=/dev/zero of=/mnt/xu4/boot/zerofill bs=1M || true
189 rm -f /mnt/xu4/boot/zerofill
190
191 # All done, clean up.
192 rm /mnt/xu4/usr/bin/qemu-arm-static
193 umount /mnt/xu4/dev
194 umount /mnt/xu4/proc
195 umount /mnt/xu4/boot
196 umount /mnt/xu4
197
198 # The root file system is ext4, so we can use zerofree, which is
199 # supposedly faster than dd-ing a zero file onto it.
200 zerofree -v /dev/odroid/root
201
202 vgchange -a n odroid