Bin Meng | 7a0c834 | 2019-07-18 00:34:14 -0700 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | .. sectionauthor:: Bin Meng <bmeng.cn@gmail.com> |
| 3 | |
| 4 | QEMU x86 |
| 5 | ======== |
| 6 | |
| 7 | Build instructions for bare mode |
| 8 | -------------------------------- |
| 9 | |
| 10 | To build u-boot.rom for QEMU x86 targets, just simply run:: |
| 11 | |
| 12 | $ make qemu-x86_defconfig (for 32-bit) |
| 13 | $ make qemu-x86_64_defconfig (for 64-bit) |
| 14 | $ make all |
| 15 | |
| 16 | Note this default configuration will build a U-Boot for the QEMU x86 i440FX |
| 17 | board. To build a U-Boot against QEMU x86 Q35 board, you can change the build |
| 18 | configuration during the 'make menuconfig' process like below:: |
| 19 | |
| 20 | Device Tree Control ---> |
| 21 | ... |
| 22 | (qemu-x86_q35) Default Device Tree for DT control |
| 23 | |
| 24 | Test with QEMU for bare mode |
| 25 | ---------------------------- |
| 26 | |
| 27 | QEMU is a fancy emulator that can enable us to test U-Boot without access to |
| 28 | a real x86 board. Please make sure your QEMU version is 2.3.0 or above test |
| 29 | U-Boot. To launch QEMU with u-boot.rom, call QEMU as follows:: |
| 30 | |
| 31 | $ qemu-system-i386 -nographic -bios path/to/u-boot.rom |
| 32 | |
| 33 | This will instantiate an emulated x86 board with i440FX and PIIX chipset. QEMU |
| 34 | also supports emulating an x86 board with Q35 and ICH9 based chipset, which is |
| 35 | also supported by U-Boot. To instantiate such a machine, call QEMU with:: |
| 36 | |
| 37 | $ qemu-system-i386 -nographic -bios path/to/u-boot.rom -M q35 |
| 38 | |
| 39 | Note by default QEMU instantiated boards only have 128 MiB system memory. But |
| 40 | it is enough to have U-Boot boot and function correctly. You can increase the |
| 41 | system memory by pass '-m' parameter to QEMU if you want more memory:: |
| 42 | |
| 43 | $ qemu-system-i386 -nographic -bios path/to/u-boot.rom -m 1024 |
| 44 | |
| 45 | This creates a board with 1 GiB system memory. Currently U-Boot for QEMU only |
| 46 | supports 3 GiB maximum system memory and reserves the last 1 GiB address space |
| 47 | for PCI device memory-mapped I/O and other stuff, so the maximum value of '-m' |
| 48 | would be 3072. |
| 49 | |
| 50 | QEMU emulates a graphic card which U-Boot supports. Removing '-nographic' will |
| 51 | show QEMU's VGA console window. Note this will disable QEMU's serial output. |
| 52 | If you want to check both consoles, use '-serial stdio'. |
| 53 | |
| 54 | Multicore is also supported by QEMU via '-smp n' where n is the number of cores |
| 55 | to instantiate. Note, the maximum supported CPU number in QEMU is 255. |
| 56 | |
Joshua Watt | 00f237e | 2019-07-03 12:45:32 -0500 | [diff] [blame] | 57 | U-Boot uses 'distro_bootcmd' by default when booting on x86 QEMU. This tries to |
| 58 | load a boot script, kernel, and ramdisk from several different interfaces. For |
| 59 | the default boot order, see 'qemu-x86.h'. For more information, see |
Dario Binacchi | 5ef229a | 2023-01-09 12:52:40 +0100 | [diff] [blame] | 60 | 'doc/develop/distro.rst'. Most Linux distros can be booted by writing a uboot |
| 61 | script. |
Joshua Watt | 00f237e | 2019-07-03 12:45:32 -0500 | [diff] [blame] | 62 | For example, Debian (stretch) can be booted by creating a script file named |
| 63 | 'boot.txt' with the contents:: |
| 64 | |
| 65 | setenv bootargs root=/dev/sda1 ro |
| 66 | load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} /vmlinuz |
| 67 | load ${devtype} ${devnum}:${distro_bootpart} ${ramdisk_addr_r} /initrd.img |
| 68 | zboot ${kernel_addr_r} - ${ramdisk_addr_r} ${filesize} |
| 69 | |
| 70 | Then compile and install it with:: |
| 71 | |
| 72 | $ apt install u-boot-tools && \ |
| 73 | mkimage -T script -C none -n "Boot script" -d boot.txt /boot/boot.scr |
| 74 | |
Bin Meng | 7a0c834 | 2019-07-18 00:34:14 -0700 | [diff] [blame] | 75 | The fw_cfg interface in QEMU also provides information about kernel data, |
| 76 | initrd, command-line arguments and more. U-Boot supports directly accessing |
| 77 | these informtion from fw_cfg interface, which saves the time of loading them |
| 78 | from hard disk or network again, through emulated devices. To use it , simply |
| 79 | providing them in QEMU command line:: |
| 80 | |
| 81 | $ qemu-system-i386 -nographic -bios path/to/u-boot.rom -m 1024 \ |
| 82 | -kernel /path/to/bzImage -append 'root=/dev/ram console=ttyS0' \ |
| 83 | -initrd /path/to/initrd -smp 8 |
| 84 | |
| 85 | Note: -initrd and -smp are both optional |
| 86 | |
| 87 | Then start QEMU, in U-Boot command line use the following U-Boot command to |
| 88 | setup kernel:: |
| 89 | |
| 90 | => qfw |
| 91 | qfw - QEMU firmware interface |
| 92 | |
| 93 | Usage: |
| 94 | qfw <command> |
| 95 | - list : print firmware(s) currently loaded |
| 96 | - cpus : print online cpu number |
| 97 | - load <kernel addr> <initrd addr> : load kernel and initrd (if any) and setup for zboot |
| 98 | |
| 99 | => qfw load |
| 100 | loading kernel to address 01000000 size 5d9d30 initrd 04000000 size 1b1ab50 |
| 101 | |
| 102 | Here the kernel (bzImage) is loaded to 01000000 and initrd is to 04000000. Then, |
| 103 | 'zboot' can be used to boot the kernel:: |
| 104 | |
| 105 | => zboot 01000000 - 04000000 1b1ab50 |
| 106 | |
| 107 | To run 64-bit U-Boot, qemu-system-x86_64 should be used instead, e.g.:: |
| 108 | |
| 109 | $ qemu-system-x86_64 -nographic -bios path/to/u-boot.rom |
| 110 | |
| 111 | A specific CPU can be specified via the '-cpu' parameter but please make |
| 112 | sure the specified CPU supports 64-bit like '-cpu core2duo'. Conversely |
| 113 | '-cpu pentium' won't work for obvious reasons that the processor only |
| 114 | supports 32-bit. |
| 115 | |
Simon Glass | b985760 | 2023-07-30 11:16:07 -0600 | [diff] [blame] | 116 | Booting distros |
| 117 | --------------- |
| 118 | |
| 119 | It is possible to install and boot a standard Linux distribution using |
| 120 | qemu-x86_64 by setting up a root disk:: |
| 121 | |
| 122 | qemu-img create root.img 10G |
| 123 | |
| 124 | then using the installer to install. For example, with Ubuntu 2023.04:: |
| 125 | |
| 126 | qemu-system-x86_64 -m 8G -smp 4 -bios /tmp/b/qemu-x86_64/u-boot.rom \ |
| 127 | -drive file=root.img,if=virtio,driver=raw \ |
| 128 | -drive file=ubuntu-23.04-desktop-amd64.iso,if=virtio,driver=raw |
| 129 | |
| 130 | You can also add `-serial mon:stdio` if you want the serial console to show as |
| 131 | well as the video. |
| 132 | |
| 133 | The output will be something like this:: |
| 134 | |
| 135 | U-Boot SPL 2023.07 (Jul 23 2023 - 08:00:12 -0600) |
| 136 | Trying to boot from SPI |
| 137 | Jumping to 64-bit U-Boot: Note many features are missing |
| 138 | |
| 139 | |
| 140 | U-Boot 2023.07 (Jul 23 2023 - 08:00:12 -0600) |
| 141 | |
| 142 | CPU: QEMU Virtual CPU version 2.5+ |
| 143 | DRAM: 8 GiB |
| 144 | Core: 20 devices, 13 uclasses, devicetree: separate |
| 145 | Loading Environment from nowhere... OK |
| 146 | Model: QEMU x86 (I440FX) |
| 147 | Net: e1000: 52:54:00:12:34:56 |
| 148 | eth0: e1000#0 |
| 149 | Hit any key to stop autoboot: 0 |
| 150 | Scanning for bootflows in all bootdevs |
| 151 | Seq Method State Uclass Part Name Filename |
| 152 | --- ----------- ------ -------- ---- ------------------------ ---------------- |
| 153 | Scanning global bootmeth 'efi_mgr': |
| 154 | Hunting with: nvme |
| 155 | Hunting with: qfw |
| 156 | Hunting with: scsi |
| 157 | scanning bus for devices... |
| 158 | Hunting with: virtio |
| 159 | Scanning bootdev 'qfw_pio.bootdev': |
| 160 | fatal: no kernel available |
| 161 | Scanning bootdev 'virtio-blk#0.bootdev': |
| 162 | Scanning bootdev 'virtio-blk#1.bootdev': |
| 163 | 0 efi ready virtio 2 virtio-blk#1.bootdev.part efi/boot/bootx64.efi |
| 164 | ** Booting bootflow 'virtio-blk#1.bootdev.part_2' with efi |
| 165 | EFI using ACPI tables at f0060 |
| 166 | efi_install_fdt() WARNING: Can't have ACPI table and device tree - ignoring DT. |
| 167 | efi_run_image() Booting /efi\boot\bootx64.efi |
| 168 | error: file `/boot/' not found. |
| 169 | |
| 170 | Standard boot looks through various available devices and finds the virtio |
| 171 | disks, then boots from the first one. After a second or so the grub menu appears |
| 172 | and you can work through the installer flow normally. |
| 173 | |
| 174 | Note that standard boot will not find 32-bit distros, since it looks for a |
| 175 | different filename. |
| 176 | |
| 177 | Current limitations |
| 178 | ------------------- |
| 179 | |
| 180 | Only qemu-x86-64 can be used for booting distros, since qemu-x86 (the 32-bit |
| 181 | version of U-Boot) seems to have an EFI bug leading to the boot handing after |
| 182 | Linux is selected from grub, e.g. with `debian-12.1.0-i386-netinst.iso`:: |
| 183 | |
| 184 | ** Booting bootflow 'virtio-blk#1.bootdev.part_2' with efi |
| 185 | EFI using ACPI tables at f0180 |
| 186 | efi_install_fdt() WARNING: Can't have ACPI table and device tree - ignoring DT. |
| 187 | efi_run_image() Booting /efi\boot\bootia32.efi |
| 188 | Failed to open efi\boot\root=/dev/sdb3 - Not Found |
| 189 | Failed to load image 큀緃: Not Found |
| 190 | start_image() returned Not Found, falling back to default loader |
| 191 | Welcome to GRUB! |
| 192 | |
| 193 | The bochs video driver also seems to cause problems before the OS is able to |
| 194 | show a display. |
| 195 | |
Simon Glass | 9804e57 | 2023-09-01 12:08:23 -0600 | [diff] [blame] | 196 | The QEMU `-cdrom` option is intended to work with the original ISO-format |
| 197 | images, not the recently invented ISOHybrid image. |
| 198 | |
Simon Glass | b985760 | 2023-07-30 11:16:07 -0600 | [diff] [blame] | 199 | Finally, the use of `-M accel=kvm` is intended to use the native CPU's |
| 200 | virtual-machine features to accelerate operation, but this causes U-Boot to hang |
| 201 | when jumping 64-bit mode, at least on AMD machines. This may be a bug in U-Boot |
| 202 | or something else. |