I am using the U-boot "go" command to start my code, and clearly that does no more that what it says, namely it "jumps" to some address, remaining in EL2. So what is different about how linux gets started?
Well, linux doesn't get started by "go". Typically the "bootm"
(actually the more up to date "booti") command gets used.
I want to try this.
I want to learn how to get U-boot to start my code using
booti. I see mention of an "mkimage" utility.
I also see a boot header compiled into the linux image by
digging through the linux source code.
(I found this in linux-git/arch/arm64/kernel/head.S
I interrupt U-boot (which is easy), then type:
run distro_bootcmdIt finds a U-boot script /boot/boot.scr, reads the script (3180 bytes) then executes it at 0050_0000. The boot fails. I had hopes that I could get linux running and then examing boot.scr. I won't be able to do that without setting up a bootable SD card. I dig out my other RK3399, but there is no SD card in the slot.
run linux (which does bootflow scan)This darn board won't boot linux either, but I remember why. I only have U-boot on this SD card.
I find my card with Debian, and indeed it boots up. Along the way, I see:
Booting bootflow 'mmc@ff500000.bootdev.part_2' with scriptThis is booting Debian "forky" with root password "er3nae"
I look in /boot and find boot.cmd (and boot.scr)
It does this:
load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} /boot/vmlinuz-6.17.8+deb14-arm64
booti ${kernel_addr_r} ${ramdisk_addr_r}:${ramdisk_size} ${fdtcontroladdr}
I copy the vmlinuz file to my big desktop machine for study.
ls -l vmlinuz-6.17.8+deb14-arm64 -rw-r--r-- 1 tom tom 42233792 Dec 21 21:05 vmlinuz-6.17.8+deb14-arm64 file vmlinuz-6.17.8+deb14-arm64 vmlinuz-6.17.8+deb14-arm64: Linux kernel ARM64 boot executable Image, little-endian, 4K pages 00000000 4d5a 40fa 3bf0 8014 0000 0000 0000 0000 MZ@ ; 00000010 0000 9402 0000 0000 0a00 0000 0000 0000 00000020 0000 0000 0000 0000 0000 0000 0000 0000 00000030 0000 0000 0000 0000 4152 4d64 4000 0000 ARMd@ 00000040 5045 0000 64aa 0200 0000 0000 0000 0000 PE d 00000050 0000 0000 a000 0602 0b02 0214 0000 1302 00000060 0000 8000 0000 0000 9067 0e02 0000 0100 g 00000070 0000 0000 0000 0000 0000 0100 0002 0000 00000080 0000 0000 0300 0000 0000 0000 0000 0000 00000090 0000 9402 0000 0100 b9a6 8402 0a00 0001 000000a0 0000 0000 0000 0000 0000 0000 0000 0000The fact that the filename is vmlinuz indicates that the kernel image is compressed. It is supposed to have the required decompression code at the head.
Once again, Mike has been there before me.
Next I interrupt U-boot and type:
dhcp booti 02000000I get this:
> booti 02000000 Image lacks image_size field, assuming 16MiB Moving Image from 0x2000000 to 0x280000, end=0x1280000 Working FDT set to 0 FDT and ATAGS support not compiled in resetting ...
cmd/booti.c boot/bootm.cSearching on the first message we see yields:
arch/arm/lib/image.c: puts("Image lacks image_size field, assuming 16MiB\n");
Searching on the last message yields:
arch/arm/lib/bootm.c: panic("FDT and ATAGS support not compiled in\n");
Note that this is a panic, hence the reset, which had nothing to do with our code running.
The "Moving Image" message is from
boot/bootm.c: printf("Moving Image from 0x%lx to 0x%lx, end=0x%lx\n",
This document discusses booting Aarch64 Linux:
=> booti 0x02000000 - 03000000 Moving Image from 0x2000000 to 0x200000, end=0x201604 ERROR: Did not find a cmdline Flattened Device Tree Could not find a valid device treeFor whatever reason, it does shift my image to a lower location in memory, which should work OK -- but it wants to find a valid device tree.
See the next page for what device trees are all about.
We generate a minimal dtb, then try this:
dhcp tftpboot 03000000 bogus.dtb booti 0x02000000 - 03000000This works!
=> booti 0x02000000 - 03000000 Moving Image from 0x2000000 to 0x200000, end=0x201604 ## Flattened Device Tree blob at 03000000 Booting using the fdt blob at 0x3000000 Working FDT set to 3000000 Loading Device Tree to 000000003cf05000, end 000000003cf08069 ... OK Working FDT set to 3cf05000 Starting kernel ... Int is 4 bytes on aarch64 Long is 8 bytes on aarch64 SPSR_el2 = AABBCCDDDEADBEEF SPSR_el2 = 00000000DEADBEEF SPSR_el2 = 0000DEADBEEF0000 Running at EL 2 MPidr_el1 = 80000000 Core 0 CurrentEL reg = 00000008 CurrentEL = 2 Midr_el1 = 410FD034 This is an A53 core (00000D03) HCR_el2 = 00000022 HCR_el2 = 0000000000000022 SPSR_el2 = 1E252A06 SPSR_el2 = 000000001E252A06 VBAR_el2 = 3FF2B800 Blinking ...It runs my code, and I see all the expected messages. It is blinking very very slowly (so the CPU clock is much less than when I run my demo using "go"). I now get a 45 second delay where I previously got about 1/2 second -- so the clock is reduced by about 90.
But this is the least of our problems. The big disappointment is that we are running at EL2. We had hoped that having "booti" launch our code would provoke U-boot into running us at EL1.
Tom's electronics pages / tom@mmto.org