树莓派 4 U 引导在启动内核中挂起



我正在做一个项目,我想用U-Boot创建自己的嵌入式Linux。因此,我正在使用buildroot,我最近开始学习。成功创建自己的rasberrypi4_defconfig后,我目前正在努力解决问题,以使u-boot正常工作。

我正在使用哪些版本:

  1. RPI 4
  2. 构建根-2019.11
  3. U-boot(因此我每天都拉新的变化(

工作现状:

我建立在 Ubuntu(32 位(上。我用raspberrypi4_defconfig配置buildroot,并且没有更改。然后我为rpi_4_32b_defconfig制作一个 u-boot defconfig 并创建 u-boot.binmake CROSS_COMPILE=arm-linux-gnueabihf- u-boot.bin现在我的下一步是配置配置.txt并与以下内容交换内容:

enable_uart=1
kernel=u-boot.bin

此外,我将我的u-boot.bin复制到我的SD卡中。

我实际做的最后一步是使用以下内容构建自己的boot.scr.uimg

mmc dev 0
fatload mmc O:1 ${fdt_addr_r} bcm2711-rpi-4-b.dtb
fatload mmc 0:1 ${kernel_addr_r} zImage
setenv bootargs console=ttyS0,115200 
root=/dev/mmcblk0p2 rootfstype=ext4 rootwait rw
bootz ${kernel_addr_r} - ${fdt_addr_r}

问题到目前为止,我正在存档以访问 U-boot 菜单,但在启动时我卡在启动内核中 我实际上认为我的boot.scr.uimg可能不正确,但不明白。

环境

arch=arm
baudrate=115200
board=rpi
board_name=4 Model B
board_rev=0x11
board_rev_scheme=1
board_revision=0xC03111
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_efi_binary=if fdt addr ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr ${fdtcontroladdr};fi;load ${devty
pe} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootarm.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${f
dt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_syslinux_conf=extlinux/extlinux.conf
boot_targets=mmc0 mmc1 pxe dhcp
bootargs=console=ttyS0,115200 
root=/dev/mmcblk0p2 rootfstype=ext4 rootwait rw
bootcmd=run distro_bootcmd
bootcmd_dhcp=if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; if test -z "${f
dtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; setenv efi_old_vci ${bootp_vci};setenv efi_old_
arch ${bootp_arch};setenv bootp_vci PXEClient:Arch:00010:UNDI:003000;setenv bootp_arch 0xa;if dhcp ${kernel_addr_r}; then tftpboot $
{fdt_addr_r} dtb/${efi_fdtfile};if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r}; else bootefi ${kernel_addr_r
} ${fdtcontroladdr};fi;fi;setenv bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv efi_fdtfile;setenv efi_old_arch;s
etenv efi_old_vci;
bootcmd_mmc0=devnum=0; run mmc_boot
bootcmd_mmc1=devnum=1; run mmc_boot
bootcmd_pxe=dhcp; if pxe get; then pxe boot; fi
bootdelay=2
bootfstype=fat
cpu=armv7
dhcpuboot=usb start; dhcp u-boot.uimg; bootm
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
efi_dtb_prefixes=/ /dtb/ /dtb/current/
ethaddr=dc:a6:32:45:1f:d1
fdt_addr=2eff5d00
fdt_addr_r=0x02600000
fdt_high=ffffffff
fdtcontroladdr=3af6ac98
fdtfile=bcm2711-rpi-4-b.dtb
fileaddr=2600000
filesize=9e6f
initrd_high=ffffffff
kernel_addr_r=0x00080000
load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
loadaddr=0x00200000
mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
pxefile_addr_r=0x02500000
ramdisk_addr_r=0x02700000
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done; setenv devplist
scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootarm.efi; then echo Found EFI removable media binary efi/boot/bootarm.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x02400000
serial#=10000000f58b842c
soc=bcm283x
stderr=serial,vidconsole
stdin=serial,usbkbd
stdout=serial,vidconsole
usbethaddr=dc:a6:32:45:1f:d1
vendor=raspberrypi
Environment size: 3996/16380 bytes

引导日志

U-Boot 2020.01-rc4-00066-g7e5ee346fc (Dec 05 2019 - 16:55:27 +0100)
DRAM:  948 MiB
RPI 4 Model B (0xc03111)
MMC:   emmc2@7e340000: 0, mmcnr@7e300000: 1
Loading Environment from FAT... *** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot:  0 
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr.uimg
297 bytes read in 18 ms (15.6 KiB/s)
## Executing script at 02400000
switch to partitions #0, OK
mmc0 is current device
40559 bytes read in 29 ms (1.3 MiB/s)
5601344 bytes read in 1084 ms (4.9 MiB/s)
Kernel image @ 0x080000 [ 0x000000 - 0x557840 ]
## Flattened Device Tree blob at 02600000
Booting using the fdt blob at 0x2600000
Using Device Tree in place at 02600000, end 0260ce6e
Starting kernel ...

我在树莓派 4 上遇到了同样令人困惑的问题,最后我找到了解决方案。

  1. 确保"enable_uart=1"在配置中.txt在第一个分区中。

  2. 树莓派 4 支持 32 位和 64 位模式。固件配置.txt、u-boot 和内核应为相同的配置。

这是我的配置.txt适用于 64 位系统。

[pi4]
kernel=u-boot.bin
max_framebuffers=2
[all]
arm_64bit=1
enable_uart=1
dtparam=i2c=on
dtparam=spi=on
dtparam=act_led_trigger=heartbeat
dtparam=pwr_led_trigger=mmc0
dtparam=audio=on
device_tree_address=0x02000000
dtoverlay=vc4-fkms-v3d,cma-128

只需删除 32 位系统的"arm_64bit=1",使用 32 位 u-boot 以及内核和设备树二进制文件 (dtb(。

请确保为每个系统使用正确的工具链。

这是我的工具链,用于引导,内核和buildroot:

64-bit: gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu
32-bit: gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf
  1. 在 u-boot bootargs 中添加 "8250.nr_uarts=1"。然后你会得到完整的内核启动日志,它将帮助您找出它卡在哪里。

这是我在第二个分区上加载 rootfs 的引导参数。

setenv bootargs 8250.nr_uarts=1 console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait rw
  1. 加载内核和设备树,然后启动内核

对于 64 位系统

fatload mmc 0:1 ${kernel_addr_r} Image
fatload mmc 0:1 ${fdt_addr} bcm2711-rpi-4-b.dtb
booti ${kernel_addr_r} - ${fdt_addr}

对于 32 位系统

fatload mmc 0:1 ${kernel_addr_r} zImage
fatload mmc 0:1 ${fdt_addr} bcm2711-rpi-4-b.dtb
bootz ${kernel_addr_r} - ${fdt_addr}

请注意,我们需要使用 fdt_addr 而不是 fdt_addr_r,尽管fdt_addr_t也对我有用。请参阅 https://elinux.org/RPi_U-Boot 了解fdt_addr与fdt_addr_t。

  1. 尝试没有任何行延续 (( 的 bootargs,以确保您不会混淆 U-Boot。
  2. 这可能是 initrd 内容的问题(包括所有正确的驱动程序吗? 正确构建? 加载到内存中?
  3. 请参阅 https://stackoverflow.com/a/58832898/7158800 .dts/.dtb 文件中所选行的注释。 确定要指定的控制台设备后,请确保 .dtb 与 U-Boot 引导参数匹配。
  4. 如果你有一个JTAG调试器,确保你甚至可以在Linux中达到start_kernel((。 我之前在使用 grub 包装器时已经挂断了电话,所以你认为你正在将控制权转移到 Linux,但实际上你跳入了深空,或者至少是尚未准备好黄金时间的代码。如果您没有看到任何早期语句打印(即在物理 CPU 0x0 上启动Linux(,请确保您根本没有使用Linux。

最新更新