]> git.ipfire.org Git - thirdparty/u-boot.git/blob - scripts/build-efi.sh
Merge patch series "configs: ti: Enable basic settings for SystemReady ACS"
[thirdparty/u-boot.git] / scripts / build-efi.sh
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
21 bzimage_fname=/tmp/kernel/arch/x86/boot/bzImage
22
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
29 echo " -k - Add a kernel" 1>&2
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
58 # package up a kernel as well
59 kernel=
60
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
65 while getopts "akopPrsw" opt; do
66 case "${opt}" in
67 a)
68 type=app
69 ;;
70 p)
71 type=payload
72 ;;
73 k)
74 kernel=1
75 ;;
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"
108 else
109 extra="-serial mon:stdio"
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
136 if [[ -n "${kernel}" ]]; then
137 sudo cp ${bzimage_fname} $MNT/vmlinuz
138 fi
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