Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use U-Boot for the Raspberry Pi 4-specific image #97883

Merged
4 commits merged into from Dec 31, 2020

Conversation

samueldr
Copy link
Member

@samueldr samueldr commented Sep 13, 2020

This is part of the effort to slowly move the Raspberry Pi 4 support to the mainline-based generic AArch64 image.

With this change, the image is now structurally compatible with the mainline AArch64 image. This means that when mainline Linux has been verified to work on the Raspberry Pi 4 enough for the end-user to gain a foothold into ARM-land, we can finally remove the Raspberry Pi 4-specific SD image.

The idea being that if mainline is not working well enough for specific use cases, or incompatible with the Raspberry Pi Foundation's ecosystem of hardware, drivers and software, the user now has the ability to either switch the running kernel and rebuild, or even now build AArch64 packages. The Raspberry Pi 4 might be that user's first and only way to build AArch64 things!

With this change, we should be able to somewhat reduce the difficulties in supporting, and answering questions about the Raspberry Pi 4. It should work, structurally speaking, just like the Raspberry Pi 3 images.

One last change, for the rpi-5.4.y kernel branch, we need to drop the cma= parameter from the kernel command line. The kernel command line takes precedence from the pre-configured CMA set in the FDT; which in turn allocates in an area that VC cannot read. The pre-configured CMA value works just fine. Using the configuration option (1) clears up the kernel command-line a bit, and (2) fixes that issue since it has lower precedence.

This includes changes from:

This changes nothing for existing Raspberry Pi 4B users. Only images made from the moment this change lands are going to be different.

Should this get backported? Well, the main part of this PR, changing to U-Boot for the Raspberry Pi 4 image, does not apply as there is no Raspberry Pi 4 image on stable. The kernel update might be relevant, but might bring breaking changes.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

cc #63720

@samueldr
Copy link
Member Author

Since I'm including modified changes from @matthewbauer and keeping authorship, I'd like for him to review at least that part of the changes.

# We previously defined it on the kernel command line as cma=
# The kernel command line will override a platform-specific configuration from its device tree.
# https://github.com/torvalds/linux/blob/856deb866d16e29bd65952e0289066f6078af773/kernel/dma/contiguous.c#L35-L44
CMA_SIZE_MBYTES = freeform "32";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the platform specific config is not always good. At least on rpi3, I had to set it to 256M to get plymouth to display properly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, though this becomes the default, which was previously set on the command-line. The command-line still has precedence over this value.

It is actually hard to know what value should be used! It seems basically no one is in agreement.

So for the time being I only moved the value so the Raspberry Pi 4B can use whatever the device tree defines.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you can reclaim cma not in use, a higher value may be a good idea. I wish rpi published defaults for it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, multiple angles on that:

  1. Each board vendors should provide a device tree entry with what is needed to make them useful. Probably through an overlay. This is because some boards have issues that are specific! E.g. here the Pi4 can't use CMA higher than 1GiB!
  2. We can provide known useful values per-board in some manner. As it seemingly can't be universal (see previous issue)
  3. What even is a good universal value to use here?

Right now I really only moved the current value to a location where it has the least precedence. Let's leave changing the value to a further PR. I don't want this change set to start breaking things :) (even though I'm pretty sure it would be fine).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding another note about cma. Through the device tree it's entirely possible that multiple CMA ranges are allocated, and needed for some devices. I haven't looked at it in details, but I saw that transpire in a Mobile NixOS device.

Copy link
Contributor

@mohe2015 mohe2015 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good although I don't know a lot about the inner workings. Tested in on my Raspberry Pi 4 - seems to work pretty well.

@lovesegfault
Copy link
Member

I spent most of my weekend testing these changes with @samueldr's help on IRC. Here is what I've found:

  • U-Boot works fine, no issues there
  • hardware.deviceTree doesn't work with the traditional bootloader
  • Kernel 5.4 works fine on the RPi4, however you must not set the cma flag, otherwise it fails to find the sd card and everything breaks.
  • Kernel 4.9 should not be removed from the tree, as there are a number of RPi-specific things that still rely on that older kernel. The display I use, for example, requires a dtbo which simply refuses to load using 5.4.
  • Kernel 5.4 should be the default, but users need a mechanism to use the old 4.9 kernel when required.

I am now testing whether hardware.deviceTree works using U-Boot + 4.9 kernel

@lovesegfault
Copy link
Member

Another noticed side-effect of this: USB ports on the Pi4 don't work at all when you boot with U-boot

@colemickens
Copy link
Member

Raspberry Pi 4 USB works for me after also upgrading to u-boot 2020.10.

@domenkozar
Copy link
Member

So this just needs an update?

@OPNA2608
Copy link
Contributor

FWIW I rebased this PR locally on current master by dropping the raspberrypifw commit (master has a newer version) and fixing the conflict in all-packages.nix. SD image built fine & boots fine, installed system has been running fine afaict.

@blitz
Copy link
Contributor

blitz commented Nov 26, 2020

@samueldr Can you rebase this PR?

Comment on lines +323 to +327
ubootRaspberryPi4_64bit = buildUBoot {
defconfig = "rpi_4_defconfig";
extraMeta.platforms = ["aarch64-linux"];
filesToInstall = ["u-boot.bin"];
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking today at similar changes b/c this never got merged to master. I found this (unified) config file for RPi 3 & 4 (arm64 == aarch64): https://github.com/u-boot/u-boot/blob/0817daa7606ec55ba551acb0208eaba33a548804/configs/rpi_arm64_defconfig. Would it be worth merging these two configurations to reduce code overhead? I know that'll make this PR take slightly longer b/c more to review, so that might be a second step.

There's also an updated UBoot for Raspberry Pi 3B+: https://github.com/u-boot/u-boot/blob/0817daa7606ec55ba551acb0208eaba33a548804/configs/rpi_3_b_plus_defconfig. Complete speculation, but might fix some of the issues tracked in #66960

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be easy for anyone to use these configs already with a custom buildUBoot. If it turns out there is a big difference, we can still switch to them or provide additional builds.

@ghost ghost force-pushed the feature/raspberrypi4-with-u-boot branch 2 times, most recently from b194225 to cb998a2 Compare December 31, 2020 14:00
@ghost
Copy link

ghost commented Dec 31, 2020

Rebased (which made the linux-rpi update obsolete), updated armstubs to 2020-10-08

This includes setting up everything for the mainline Raspberry Pi 4
image.

In fact, the only difference left in the Raspberry Pi 4-specific image
is the kernel from the vendor.
As per the in-line comment, this is where distros should configure it.
Not via kernel command line parameters.

As found by looking at the implementation, while exploring the cause of
a bug on the Raspberry Pi 4, it was found that `cma=` on the command
line parameters will overwrite the values a device tree will have
configured for a given platform.

With this, the more recent 5.4 vendor kernel boots just fine on the
Raspberry Pi 4 using our common configuration.
@ghost ghost force-pushed the feature/raspberrypi4-with-u-boot branch from cb998a2 to c673c5e Compare December 31, 2020 15:42
@ghost ghost merged commit 4e75a31 into NixOS:master Dec 31, 2020
@samueldr samueldr deleted the feature/raspberrypi4-with-u-boot branch December 31, 2020 20:46
@misuzu
Copy link
Contributor

misuzu commented Jan 7, 2021

nixos.sd_image_raspberrypi4.aarch64-linux does not boot on my rpi4 8g:

PM_RSTS: 0x00000020
RPi: BOOTLOADER release VERSION:45291ce6 DATE: Jul 16 2020 TIME: 16:15:51 BOOTMODE: 0x00000006 part: 0 BUILD_TIMESTAMP=1594912546 0x53eb7634 0x00d03114
uSD voltage 3.3V
Initialising SDRAM 'Micron' 32Gb x2 total-size: 64 Gbit 3200
Boot mode: SD (01) order f4
SD HOST: 250000000 CTL0: 0x00000000 BUS: 100000 Hz actual: 100000 HZ div: 2500 (1250) status: 0x1fff0000 delay: 1080
SD HOST: 250000000 CTL0: 0x00000f00 BUS: 100000 Hz actual: 100000 HZ div: 2500 (1250) status: 0x1fff0000 delay: 1080
CID: 0002544d53413332472425f51c0100fc
CSD: 400e00325b590000e74f7f800a400000
SD: bus-width: 4 spec: 2 SCR: 0x02358003 0x01000000
SD HOST: 250000000 CTL0: 0x00000f04 BUS: 50000000 Hz actual: 41666666 HZ div: 6 (3) status: 0x1fff0000 delay: 2
MBR: 0x00004000,   61440 type: 0x0b
MBR: 0x00013000, 5351024 type: 0x83
MBR: 0x00000000,       0 type: 0x00
MBR: 0x00000000,       0 type: 0x00
lba: 16384 oem: 'mkfs.fat' volume: '  V       ^ '
rsc 4 fat-sectors 60 c-count 15321 c-size 4 r-dir 1 r-sec 32
PM_RSTS: 0x00000020
Partition: 0
lba: 16384 oem: 'mkfs.fat' volume: '  V       ^ '
rsc 4 fat-sectors 60 c-count 15321 c-size 4 r-dir 1 r-sec 32
Read config.txt bytes      650 hnd 0x00000035 hash '56f54a69c71c5a3c'
recover4.elf not found (6)
recovery.elf not found (6)
Read start4.elf bytes  2213312 hnd 0x000005f2 hash '19bbfbc3ec1da69d'
Read fixup4.dat bytes     5428 hnd 0x0000003a hash '5481e23d9a139ecb'
0x00d03114 0x00000000 0x0000003f
MEM GPU: 76 ARM: 948 TOTAL: 1024
Starting start4.elf @ 0xfec00200 partition 0


U-Boot 2020.10 (Oct 05 2020 - 15:15:32 +0000)

DRAM:  7.9 GiB
RPI 4 Model B (0xd03114)
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from FAT... *** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@7d580000
PCIe BRCM: link up, 5.0 Gbps x1 (SSC)
starting USB...
Bus xhci_pci: probe failed, error -110
No working controllers found
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:2...
Found /boot/extlinux/extlinux.conf
Retrieving file: /boot/extlinux/extlinux.conf
829 bytes read in 18 ms (44.9 KiB/s)
1:      NixOS - Default
Retrieving file: /boot/extlinux/../nixos/lsj0ndrcb660zp76nfwbwrwbl3ccb533-initrd-linux-5.4.79-1.20201201-initrd
8195099 bytes read in 367 ms (21.3 MiB/s)
Retrieving file: /boot/extlinux/../nixos/vw8c6pmm21rqyi78zmrb9r00x493n6a2-linux-5.4.79-1.20201201-Image
"Synchronous Abort" handler, esr 0x96000004
elr: 00000000000a2dac lr : 00000000000a2de8 (reloc)
elr: 000000003b37bdac lr : 000000003b37bde8
x0 : ffffffffffffffe0 x1 : 0000000000000000
x2 : 000000003af54e50 x3 : 0000000000000015
x4 : b900001f58000540 x5 : 0000000000000015
x6 : 000000003b3d3118 x7 : 000000003b3d3118
x8 : 0000000000000001 x9 : 0000000000000008
x10: 0000000000000006 x11: 000000003af6c820
x12: 000000000002ef90 x13: 0000000000000001
x14: 0000000000080000 x15: 000000003af48fd0
x16: 000000003b385128 x17: 0000000000000000
x18: 000000003af54d90 x19: 0000000000000000
x20: 0000000000001d28 x21: 0000000000000006
x22: 0000000000000000 x23: 000000003af46248
x24: 000000003b3bb720 x25: 0000000000000eda
x26: 0000000000000000 x27: 000000003b3ec348
x28: 000000000001a268 x29: 000000003af461c0

Code: eb02003f 54000061 d2800000 d65f03c0 (f9400401)
Resetting CPU ...

resetting ...

Edit: fixed by including these lines to config:

{
  boot.kernelParams = [
    # hangs on "Starting kernel ..." without this
    "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1 bcm2708_fb.fbwidth=0 bcm2708_fb.fbheight=0 bcm2708_fb.fbswap=1 smsc95xx.macaddr=DC:A6:32:BB:43:C3 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x4000000"
  ];

  nixpkgs.overlays = [
    (self: super:
    {
      # downgrade u-boot to fix "Synchronous Abort"
      ubootRaspberryPi4_64bit = super.buildUBoot rec {
        defconfig = "rpi_4_defconfig";
        extraMeta.platforms = [ "aarch64-linux" ];
        filesToInstall = [ "u-boot.bin" ];
        version = "2020.07";
        src = super.fetchurl {
          url = "ftp://ftp.denx.de/pub/u-boot/u-boot-${version}.tar.bz2";
          sha256 = "0sjzy262x93aaqd6z24ziaq19xjjjk5f577ivf768vmvwsgbzxf1";
        };
      };
    })
  ];
}

@samueldr
Copy link
Member Author

samueldr commented Jan 7, 2021

@misuzu have you tried upgrading u-boot too?

I haven't looked at all, but maybe the regression was fixed for the next stable version?

If it wasn't, we'd need to investigate, first confirming whether it's 8GB specific or not.

As an additional thing to try (but not a fix), have you tried editing config.txt to set total_mem to something like 4096? It was a valid method to work around the CMA issues, and confirm issues. If setting total_mem to a lower value works, it would really help confirm it's related to the RAM amount and not to something else coincidental.

@samueldr
Copy link
Member Author

samueldr commented Jan 7, 2021

Disregard trying with total_mem, @makefu on IRC reported (coincidentally) the same issue on a 4GB variant.

I suspect something other than the memory amount.

Though, a new thought (I shared with @makefu on IRC) is that it could be related to the firmware installed to the eeprom. I don't know which version I have, but I did confirm that it boots on my setup. I know that an arbitrary date in the past I updated the eeprom, so I only know that it's not the one it shipped with, and not the latest.

@misuzu
Copy link
Contributor

misuzu commented Jan 8, 2021

@misuzu have you tried upgrading u-boot too?

2021.01-rc5 is working, but it still hangs on "Starting kernel ..." without that kernel cmdline from #97883 (comment) even with total_mem=4096 in config.txt.

@samueldr
Copy link
Member Author

samueldr commented Jan 8, 2021

Oh, so is it the kernel command-line that fixes the issue, and not changing the u-boot version?

(I really don't know what is going on here. And I cannot reproduce and test due to some difference in setups.)

@misuzu
Copy link
Contributor

misuzu commented Jan 8, 2021

Oh, so is it the kernel command-line that fixes the issue, and not changing the u-boot version?

(I really don't know what is going on here. And I cannot reproduce and test due to some difference in setups.)

It's both. u-boot-2020.10 is broken and that kernel command-line is required to boot.

@samueldr
Copy link
Member Author

samueldr commented Jan 8, 2021

Given that 2021.01-rc5 works with the cmdline, and they're most probably releasing next week, we'll sit on that until next week, where we'll be able to update u-boot and fix part of the issue.

Do you know which command-line parameter is required? Or is it a combination of some? All? Sorry again for the harsh interrogation. I'd like to say it didn't work on mine either.

@samueldr
Copy link
Member Author

samueldr commented Jan 9, 2021

Testing a bit more, with the same build, headless, actually headless, HDMI ports both unpopulated, I can say that 8250.nr_uarts=1 makes the serial work, otherwise it "hangs" at "Starting kernel ...".

Looks like this is approx. equivalent to using uart1-overlay.

Added it to the raspberry pi 4 nixos on arm wiki page.

So I figure that the "no serial console" issue is solved via the command-line parameter, but we still have that odd U-Boot failing to boot. (Until the next stable release, soon enough.)

@ghost
Copy link

ghost commented Jan 9, 2021

I'm so sorry I can't be more helpful here. I only have the 8GB version and I don't have an HDMI cable or equipment to use the serial port. I tested this in a headless setup so I couldn't see many of the issues you are having.

@samueldr
Copy link
Member Author

samueldr commented Jan 9, 2021

@petabyteboy It seems the issue here happens, too, in a headless situation. And don't worry, I can't reproduce it either, though I'm sure something makes the error happen. And thanks for your input, it's useful to know it's not necessarily an 8GB version issue.

Now it'd be nicer if we could figure out what is the issue. It seems that the revision of the board itself doesn't matter, as [@makefu / I] have a 4GB 1.1 board, it works for me, fails for him; both of you [@petabyteboy / @misuzu] have an 8GB board (1.4 obligatory) and works for one of you, fails for the other.

I have personally tested:

  • plugged to an HDMI capture card
  • headless with UART

Both situation didn't produce a "Synchronuous abort". The image booted fine. Though I can confirm that in Linux, something needs to be done for UART to work, one solution is 8250.nr_uarts=1 on the cmdline. I would be willing to bet there are other ways.

@misuzu
Copy link
Contributor

misuzu commented Jan 9, 2021

Though I can confirm that in Linux, something needs to be done for UART to work, one solution is 8250.nr_uarts=1 on the cmdline.

Adding only 8250.nr_uarts=1 indeed fixes my issue. The weird part is that network doesn't work without it.

@happysalada
Copy link
Contributor

@misuzu what do you mean network doesn't work?
I'm asking, because I have the weirdest problem related to the network.
On nixos configuration.nix I've got networking.firewall.allowPing = true; (anyway the default is true)
but the raspberry pi doesn't respond to ping, so undectectable by nmap. I can ssh into it fine, but for some reason, ping doesn't work.
Not only that, but I've tried enabling

services = {
    avahi = {
      enable = true;
      publish = {
        enable = true;
        addresses = true;
        workstation = true;
      };
};

To no avail.
My raspberry pi is connected over ethernet cable, I haven't tried connecting to wifi.

@misuzu
Copy link
Contributor

misuzu commented Jan 10, 2021

@misuzu what do you mean network doesn't work?

There are no DHCP requests over ethernet from my rpi4 when started without 8250.nr_uarts=1. I suspect the kernel just not starting.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
NixOS on ARM
Awaiting triage
Development

Successfully merging this pull request may close these issues.

None yet