]>
Commit | Line | Data |
---|---|---|
6b2f8290 SG |
1 | #!/bin/bash |
2 | # SPDX-License-Identifier: GPL-2.0+ | |
3 | # | |
4 | # Script to build an EFI thing suitable for booting with QEMU, possibly running | |
5 | # it also. | |
6 | ||
7 | # This just an example. It assumes that | |
8 | ||
9 | # - you build U-Boot in ${ubdir}/<name> where <name> is the U-Boot board config | |
10 | # - /mnt/x is a directory used for mounting | |
11 | # - you have access to the 'pure UEFI' builds for QEMU | |
12 | # | |
13 | # UEFI binaries for QEMU used for testing this script: | |
14 | # | |
15 | # OVMF-pure-efi.i386.fd at | |
16 | # https://drive.google.com/file/d/1jWzOAZfQqMmS2_dAK2G518GhIgj9r2RY/view?usp=sharing | |
17 | ||
18 | # OVMF-pure-efi.x64.fd at | |
19 | # https://drive.google.com/file/d/1c39YI9QtpByGQ4V0UNNQtGqttEzS-eFV/view?usp=sharing | |
20 | ||
ed10008b SG |
21 | bzimage_fname=/tmp/kernel/arch/x86/boot/bzImage |
22 | ||
6b2f8290 SG |
23 | set -e |
24 | ||
25 | usage() { | |
26 | echo "Usage: $0 [-a | -p] [other opts]" 1>&2 | |
27 | echo 1>&2 | |
28 | echo " -a - Package up the app" 1>&2 | |
ed10008b | 29 | echo " -k - Add a kernel" 1>&2 |
6b2f8290 SG |
30 | echo " -o - Use old EFI app build (before 32/64 split)" 1>&2 |
31 | echo " -p - Package up the payload" 1>&2 | |
32 | echo " -P - Create a partition table" 1>&2 | |
33 | echo " -r - Run QEMU with the image" 1>&2 | |
34 | echo " -s - Run QEMU with serial only (no display)" 1>&2 | |
35 | echo " -w - Use word version (32-bit)" 1>&2 | |
36 | exit 1 | |
37 | } | |
38 | ||
39 | # 32- or 64-bit EFI | |
40 | bitness=64 | |
41 | ||
42 | # app or payload ? | |
43 | type=app | |
44 | ||
45 | # create a partition table and put the filesystem in that (otherwise put the | |
46 | # filesystem in the raw device) | |
47 | part= | |
48 | ||
49 | # run the image with QEMU | |
50 | run= | |
51 | ||
52 | # run QEMU without a display (U-Boot must be set to stdout=serial) | |
53 | serial= | |
54 | ||
55 | # before the 32/64 split of the app | |
56 | old= | |
57 | ||
ed10008b SG |
58 | # package up a kernel as well |
59 | kernel= | |
60 | ||
6b2f8290 SG |
61 | # Set ubdir to the build directory where you build U-Boot out-of-tree |
62 | # We avoid in-tree build because it gets confusing trying different builds | |
63 | ubdir=/tmp/b/ | |
64 | ||
ed10008b | 65 | while getopts "akopPrsw" opt; do |
6b2f8290 SG |
66 | case "${opt}" in |
67 | a) | |
68 | type=app | |
69 | ;; | |
70 | p) | |
71 | type=payload | |
72 | ;; | |
ed10008b SG |
73 | k) |
74 | kernel=1 | |
75 | ;; | |
6b2f8290 SG |
76 | r) |
77 | run=1 | |
78 | ;; | |
79 | s) | |
80 | serial=1 | |
81 | ;; | |
82 | w) | |
83 | bitness=32 | |
84 | ;; | |
85 | o) | |
86 | old=1 | |
87 | ;; | |
88 | P) | |
89 | part=1 | |
90 | ;; | |
91 | *) | |
92 | usage | |
93 | ;; | |
94 | esac | |
95 | done | |
96 | ||
97 | run_qemu() { | |
98 | extra= | |
99 | if [[ "${bitness}" = "64" ]]; then | |
100 | qemu=qemu-system-x86_64 | |
101 | bios=OVMF-pure-efi.x64.fd | |
102 | else | |
103 | qemu=qemu-system-i386 | |
104 | bios=OVMF-pure-efi.i386.fd | |
105 | fi | |
106 | if [[ -n "${serial}" ]]; then | |
107 | extra="-display none -serial mon:stdio" | |
1f0cf892 SG |
108 | else |
109 | extra="-serial mon:stdio" | |
6b2f8290 SG |
110 | fi |
111 | echo "Running ${qemu}" | |
112 | # Use 512MB since U-Boot EFI likes to have 256MB to play with | |
113 | "${qemu}" -bios "${bios}" \ | |
114 | -m 512 \ | |
115 | -drive id=disk,file="${IMG}",if=none,format=raw \ | |
116 | -nic none -device ahci,id=ahci \ | |
117 | -device ide-hd,drive=disk,bus=ahci.0 ${extra} | |
118 | } | |
119 | ||
120 | setup_files() { | |
121 | echo "Packaging ${BUILD}" | |
122 | mkdir -p $TMP | |
123 | cat >$TMP/startup.nsh <<EOF | |
124 | fs0:u-boot-${type}.efi | |
125 | EOF | |
126 | sudo cp ${ubdir}/${BUILD}/u-boot-${type}.efi $TMP | |
127 | ||
128 | # Can copy in other files here: | |
129 | #sudo cp ${ubdir}/$BUILD/image.bin $TMP/chromeos.rom | |
130 | #sudo cp /boot/vmlinuz-5.4.0-77-generic $TMP/vmlinuz | |
131 | } | |
132 | ||
133 | # Copy files into the filesystem | |
134 | copy_files() { | |
135 | sudo cp $TMP/* $MNT | |
ed10008b SG |
136 | if [[ -n "${kernel}" ]]; then |
137 | sudo cp ${bzimage_fname} $MNT/vmlinuz | |
138 | fi | |
6b2f8290 SG |
139 | } |
140 | ||
141 | # Create a filesystem on a raw device and copy in the files | |
142 | setup_raw() { | |
143 | mkfs.vfat "${IMG}" >/dev/null | |
144 | sudo mount -o loop "${IMG}" $MNT | |
145 | copy_files | |
146 | sudo umount $MNT | |
147 | } | |
148 | ||
149 | # Create a partition table and put the filesystem in the first partition | |
150 | # then copy in the files | |
151 | setup_part() { | |
152 | # Create a gpt partition table with one partition | |
153 | parted "${IMG}" mklabel gpt 2>/dev/null | |
154 | ||
155 | # This doesn't work correctly. It creates: | |
156 | # Number Start End Size File system Name Flags | |
157 | # 1 1049kB 24.1MB 23.1MB boot msftdata | |
158 | # Odd if the same is entered interactively it does set the FS type | |
159 | parted -s -a optimal -- "${IMG}" mkpart boot fat32 1MiB 23MiB | |
160 | ||
161 | # Map this partition to a loop device | |
162 | kp="$(sudo kpartx -av ${IMG})" | |
163 | read boot_dev<<<$(grep -o 'loop.*p.' <<< "${kp}") | |
164 | test "${boot_dev}" | |
165 | dev="/dev/mapper/${boot_dev}" | |
166 | ||
167 | mkfs.vfat "${dev}" >/dev/null | |
168 | ||
169 | sudo mount -o loop "${dev}" $MNT | |
170 | ||
171 | copy_files | |
172 | ||
173 | # Sync here since this makes kpartx more likely to work the first time | |
174 | sync | |
175 | sudo umount $MNT | |
176 | ||
177 | # For some reason this needs a sleep or it sometimes fails, if it was | |
178 | # run recently (in the last few seconds) | |
179 | if ! sudo kpartx -d "${IMG}" > /dev/null; then | |
180 | sleep .5 | |
181 | sudo kpartx -d "${IMG}" > /dev/null || \ | |
182 | echo "Failed to remove ${boot_dev}, use: sudo kpartx -d ${IMG}" | |
183 | fi | |
184 | } | |
185 | ||
186 | TMP="/tmp/efi${bitness}${type}" | |
187 | MNT=/mnt/x | |
188 | BUILD="efi-x86_${type}${bitness}" | |
189 | IMG=try.img | |
190 | ||
191 | if [[ -n "${old}" && "${bitness}" = "32" ]]; then | |
192 | BUILD="efi-x86_${type}" | |
193 | fi | |
194 | ||
195 | setup_files | |
196 | ||
197 | qemu-img create "${IMG}" 24M >/dev/null | |
198 | ||
199 | if [[ -n "${part}" ]]; then | |
200 | setup_part | |
201 | else | |
202 | setup_raw | |
203 | fi | |
204 | ||
205 | if [[ -n "${run}" ]]; then | |
206 | run_qemu | |
207 | fi |