Opened 3 years ago

Closed 15 months ago

#13284 closed enhancement (fixed)

ARM image installer

Reported by: kallisti5 Owned by: bonefish
Priority: low Milestone: Unscheduled
Component: Build System Version: R1/Development
Keywords: arm Cc:
Blocked By: Blocking:
Has a Patch: no Platform: arm

Description

Fedora is doing something interesting with their ARM releases.

  1. User downloads a generic Fedora armhfp release
    1. (raw disk image compressed with xz) https://arm.fedoraproject.org/
  2. User installs fedora-arm-image-install tool package to system
  3. User runs fedora-arm-image-install --image=downloaded-release.img.xz --target=cubieboard --media=/dev/sdf
  4. Tool writes the generic image to the SD card, then customizes it as needed based on binaries within the downloaded os image.
  5. user boots sd card on ARM device.
  • All supported Device Trees are included in the os image
  • All u-boot images are included in os image

https://pagure.io/arm-image-installer

Since we already have device trees, we could start building a generic image that our tool could write to an sd card and then prep for boot.

We could do one ARM build (arm v7 likely), then be able to quickly test it on multiple devices without rebuilding over and over.

Change History (7)

comment:1 by pulkomandy, 3 years ago

A single image for all ARM devices is the goal, but we are not quite there yet:

  • our device tree is not used enough, for example, in the bootloader and early kernel, we hardcode various RAM addresses depending on the target hardware. Fixing that would make porting to new ARM devices MUCH easier (no need to rewrite the mmu init code for each of them, breaking the other ones).
  • our SD images already include the bootloaders and stuff. It may be possible to make some kind of "anyboot" style image there, with a big FAT partition with all early loaders and u-boots for different devices. There probably will be some clashes between different devices when doing that however, so the Fedora approach of preparing the image on the user side may make sense. Also possible would be a jigdo-like system, where a script on the server side assembles the image as the user downloads it. Allows us to keep a single BFS image and just prepend the MBR + boot FAT partition to it on download.

in reply to:  1 comment:2 by kallisti5, 3 years ago

Replying to pulkomandy:

A single image for all ARM devices is the goal, but we are not quite there yet:

  • our device tree is not used enough, for example, in the bootloader and early kernel, we hardcode various RAM addresses depending on the target hardware. Fixing that would make porting to new ARM devices MUCH easier (no need to rewrite the mmu init code for each of them, breaking the other ones).

I actually fixed the u-boot hardcoded addresses a while ago:

http://cgit.haiku-os.org/haiku/commit/build/jam/board/rpi2/BoardSetup?id=b8dff21b5aa8498698904f2fe2a08c71f67b1899 http://cgit.haiku-os.org/haiku/tree/build/jam/board/rpi2/BoardSetup#n36

There are variables you can pass to u-boot which are set by the individual u-boot builds. (default sane memory locations for fdt's, etc. per board)

The only real custom thing in that u-boot script anymore is the FDT location, however that is easy to fix

<boot partition>/board.fdt (copied from <boot partition>/fdts/<board>.fdt by the haiku-arm-image-writer tool)

I think we might have one or two hard-coded addresses around in the sources, but most of these were converted to being loaded from the FDT...

http://cgit.haiku-os.org/haiku/tree/src/system/boot/platform/u-boot/start.cpp#n232 http://cgit.haiku-os.org/haiku/commit/src/system/kernel/platform/u-boot/fdt_serial.cpp?id=c6a4fee57959c986091fcd52f2096b28b98456e2

http://cgit.haiku-os.org/haiku/tree/src/system/kernel/arch/arm/soc_omap3.cpp#n184

http://cgit.haiku-os.org/haiku/tree/src/system/kernel/arch/arm/soc_pxa.cpp#n141

We do still have some hard-coded framebuffer stuff that needs converted to fdt: http://cgit.haiku-os.org/haiku/tree/src/system/boot/platform/u-boot/video.cpp#n104

  • our SD images already include the bootloaders and stuff. It may be possible to make some kind of "anyboot" style image there, with a big FAT partition with all early loaders and u-boots for different devices. There probably will be some clashes between different devices when doing that however, so the Fedora approach of preparing the image on the user side may make sense.

Yup. We already have 90% of this as well which helps. The haiku-arm-image-install tool already finds the fat mmc partition and (re) populates it based on a json manifest...

https://github.com/kallisti5/haiku-arm-image-installer/blob/master/haiku-arm-installer#L128

I still need to write the alternative "hard-coded" SPL offset stuff though for things like the Allwinner chipsets.

Also possible would be a jigdo-like system, where a script on the server side assembles the image as the user downloads it. Allows us to keep a single BFS image and just prepend the MBR + boot FAT partition to it on download.

Interesting idea. Sounds a lot more complex to write though :-)

comment:3 by pulkomandy, 3 years ago

The problem we had with the beagle-xM is that the RAM physical addresses are all in the kernel space (0x8000000 onwards). I think it is not the case in the other ARM devices. This makes a significant difference in the bootloader, which starts with physcal RAM addresses (no MMU), then sets up an identity mapping (all virtual addresses point to the matching physical address), enables the MMU, and then sets up the kernel space for runtime. By doing so, on the beagle xM it will unmap the RAM it is running from. Oops!

I think this is the main thing we should solve. Once we have that part working reliably in all cases, anyone can take the Haiku kernel and loader, stick them on a FAT drive, and try to boot them on any ARM device to see what comes out of it (and write all missing drivers).

comment:4 by kallisti5, 3 years ago

A little more investigation into how Fedora does it. Here is the kernel uImage from the Fedora arm release:

$ file /media/kallisti5/__boot/uImage
/media/kallisti5/__boot/uImage: u-boot legacy uImage, 4.8.6-300.fc25.armv7hl, Linux/ARM, OS Kernel Image (Not compressed), 5919120 bytes, Tue Nov 15 20:15:27 2016, Load Address: 0x00008000, Entry Point: 0x00008000, Header CRC: 0x31394551, Data CRC: 0x2EB17346

It looks like the base image targets raspberry pi 2 or 3 out of the box. The fedora-arm-image-installer doesn't actually do anything modification under those platforms.

I wish there was a single source comparing the memory maps on all the arm boards out there :-| We might be able to target a "common configuration" to maximize our board support.

comment:5 by kallisti5, 3 years ago

From what I can tell, the 0x00008000 entry point / load address in the Fedora linux kernel uImage seems to work on all of these boards: https://pagure.io/arm-image-installer/blob/master/f/boards.d

It lists omap3-beagle, but that doesn't seem to be making any kind of 'adjustments' to the 0x00008000.

Most of the memory maps we could pick up from the fdt.

comment:6 by pulkomandy, 3 years ago

I wouldn't count on a common memory map on the physical side. I think even with raspberry pi + beagle xM, we already have no overlapping RAM areas.

However, this does not matter to our kernel. Our kernel starts with MMU already enabled and it is mapped in 0x80000000. This address is fixed (it is opposite to Linux where the kernel side starts at 0 and userland at 80000000).

The work to get that set up is in haiku_loader. It is the one that enables the mmu and maps the kernel at the appropriate place.

So, the kernel is not a problem. The FDT can be used to discover hardware, etc.

What we need to do is either:

  • Write a custom haiku_loader for each board (annoying, but easy)
  • Write an haiku_loader that can figure out by itself a way to perform that mmu mapping, depending on the physical RAM layou (more work, but more generic).

Unless the plan is now to remove haiku_loader and use u-boot to load the kernel directly? I'm not sure that's the way to go, as we would loose our nice boot menu with blacklist packages, booting old system versions, etc.

comment:7 by kallisti5, 15 months ago

Resolution: fixed
Status: newclosed

This issue is mostly solved. We went with a generic haiku_loader.ub and using u-boot to choose the FDT

The design requires an external tool to "write haiku to the boot media, then 'prepare' the boot partition per board"

I whipped up a tool in Rust that does just this. The tool can write directly to FAT filesystems and inject the needed boot binaries.

It reads a json manifest from here: https://github.com/haiku/firmware/blob/master/manifest.json

and lets the end user "prepare" their SD card with haiku + board-centric items.

The Rust code is here: https://gitlab.com/kallisti5/rune-image

Currently, however, all of this is now blocked by #14313

Note: See TracTickets for help on using tickets.