On Mon, 05 Aug 2013 12:39:03 -0600 Stephen Warren swarren@wwwdotorg.org wrote:
On 08/03/2013 01:11 AM, Dennis Gilmore wrote:
Hi all,
I wanted to start a discussion on defining a unified feature set that makes it simpler for the different distros to support ARM systems using u-boot. I have based a lot of my thoughts on how calxeda ship their systems configured as it works fairly well, recently i sent in a patch implementing most of what I would like to see for the wandboard[1]
right or wrong we want things to be simple for the user and to largely look like a linux system on x86 would. The user and distro should never need to worry about memory locations
I agree. I'd certainly like to see various distros have regular "PC-style" installers for Tegra boards.
I have attempted to write the "bootcmd" in upstream U-Boot for Tegra devices in a way that helps this. More on that below.
so this would mean similar partitioning. i.e. /boot on ext4 root and swap on lvm or as raw partitions. people should be able to have just / on ext4 also. Down the road xfs /boot support would be a nice to have.
That's only partially relevant for U-Boot. Two things U-Boot needs to support:
- Filesystem read for whatever filesystem /boot is part of (it could
very well be the / filesystem too, but U-Boot doesn't care, except for / vs. /boot in path names). This is a matter of adding the right flags to each board's U-Boot config file.
right, but at the least it needs to be ext4 not all boards today read ext4, btrfs may be something down the road also. u-boot doesnt need to care too much. it just needs to look in / and /boot
- Some way of determining which partition it should load things from.
For this point, I'd suggest MBR's bootable flag, or GPT's similar flags. I always intended to implement a sub-command of U-Boot's "part" command that read the partition flags and picked the correct partition to use based on those flags...
The rest of the stuff (swap, LVM, ...) seems entirely related to the distro itself and/or whatever gets put into the initrd.
Mostly i was trying to show that where the other bits live doesn't matter.
bootz and raw initrd support. not having to wrap kernels and initrds really is a must. raw initrd support means that its much simpler for a user to rebuild an initramfs if needed and bootz means we do not need to worry about making sure that we specify the correct addresses to load the kernel to when calling mkimage.
+1 from me.
when it comes to memory addressing a distro and user shouldn't need to know anything. Ideally u-boot will auto allocate addresses based on the size of loaded objects. starting with a base address internal to u-boot you load a kernel, when loading an initramfs u-boot automatically calculates an address that ensures it does not overlap with the kernel. same for a fdt if loaded. I say auto calculated because what we think today will be enough room may not be tomorrow, dynamically calculating gives the flexibility for whatever may come.
The way I've approached this for Tegra is to have the default environment define certain standard environment variables that U-Boot scripts can use, without a care. For example, the kernel should be loaded at ${kernel_addr_r}, initrd at ${ramdisk_addr_r}, DTB at ${fdt_addr_r}, etc.
I really don't want to need to deal with variable names either. I really want to just say load a kernel initramfs and here is some arguments and have the rest just work.
I chose the values of those variables in the Tegra environment to support reasonable max sizes. The kernel itself has a max size based on practicality and the ARM ISA and jump range. There's no reason the compressed kernel should be larger than the uncompressed kernel, etc.
another perfectly valid way to do it. a initramfs should be able to be non existant or 200mb big and just work. I suggested dynamically allocated solely because something we consider outrageous today may be necessary tomorrow.
fdt will be automatically loaded and provided fedora ships dtbs in /boot/dtb-<kernelver>/ I am not sure where other distros provide them, however u-boot should automatically load dtb and provide access to a fdt in a ${fdt_addr} variable that can be used by pxe_cmd but still allows the user to specify their own in extlinux.conf if desired. ideally the devicetree files need to be decoupled from the kernel, along the lines of what is being discussed in the kernel now[2]. Distros should agree on a single location for the dtbs to be placed. /boot/dtb/ or /boot/dtbs/ are probably good locations. u-boot can then look in the path with and without /boot
The model I chose on Tegra is slightly different.
For credit, I was heavily inspired by the default bootcmd from downstream TrimSlice U-Boot and I think also the upstream Calxeda U-Boot.
Tegra's U-Boot searches all known boot devices for /boot/boot.scr (and some other filenames), sets up some variables to record where it was found, loads the file into RAM, and treats that as a U-Boot script. The boot script then determines everything else that happens at boot; loading the kernel/initrd/DTB, and booting it.
This lets boot.scr control e.g.:
While i think its a noble goal I really don't think that boot.scr is really very suitable for distros. I do not know of a great way to setup menus its why i want to use the sysboot command provided by pxe boot and load a extlinux style config file. uboot handles all the details of the devices and memory locations behind the scenes. users get confused anytime they need to run mkimage. I really want to take it out of the equation.
- Whether the distro wraps zImage into a uImage or not, since the
distro-supplied script determines whether bootz or bootm is executed.
- Whether the distro has an initrd or not (I currently don't use one
typically).
- The filename of the initrd and DTB, since the location/name/... of
these is probably somewhat distro-specific.
I think that distros should be able to agree on a common location. names are defined upstream. omap has a quite nice way to work out the filename of the dtb you just need to know/workout where to load it.
- Whatever extra kernel command-line parameters the distro cares to
pass to the kernel, without having to add them to the U-Boot environment, but rather just to boot.scr, which is a much more accessible file in a regular file-system.
In other words, I've tried to define a "boot interface" between U-Boot and the distro (which is to simply load/execute boot.scr, and provide some data to boot.scr in environment variables), rather than making U-Boot have complete knowledge of how to boot the distro.
Also, I have set up all boards so that they define standard U-Boot environment variables ${soc}, ${board} that define which HW the code is running on. This can be used to automatically construct the DTB filename, and hence makes boot.scr pretty much HW-agnostic.
An example boot.scr that I use is shown below, with some extra comments for the purposes of this email:
========== # I anticipate replacing this hard-coded assignment with e.g.: # part find-bootable ${devtype} ${devnum} rootpart setenv rootpart 1
# Find partition UUID (not fs UUID) at run-time, so script adapts to # whatever is there without regenerating it part uuid ${devtype} ${devnum}:${rootpart} uuid
# Here is the use of ${uuid} from aboe # bootargs_extra allows the user to interrupt boot and add to the # kernel command-line setenv bootargs ... root=PARTUUID=${uuid} ${bootargs_extra}
# You could load a "uEnv.txt" here too, which could set some variables # that e.g. get added to bootargs etc., if you want plain-text disk- # based configuration of this boot script.
# Complete generic... load ${devtype} ${devnum}:${rootpart} ${kernel_addr_r} /boot/zImage
load ${devtype} ${devnum}:${rootpart} ${ramdisk_addr_r} /boot/initrd.gz # So that we don't need to regenerate script when initrd size changes ramdisk=${ramdisk_addr_r}:0x${filesize} # :-( setenv initrd_high 0xffffffff
load ${devtype} ${devnum}:${rootpart} ${fdt_addr_r} \ /boot/${soc}-${board}.dtb
bootz ${kernel_addr_r} ${ramdisk} ${fdt_addr_r}
While this is a step forward, its still much more than we need to do if we enable pxe support and use sysboot to load a config file the says load this kernel and initramfs and pass these bootargs. My initial post had a fully working example.
For specifics in the code, see the definition of CONFIG_EXTRA_ENV_SETTINGS in U-Boot's include/configs/tegra-common-post.h, and work backwards from there.
Note that I'm also in the process of pushing a project to github that creates a few boot.scr that fit into this model. I've written the code, and hope to have IP approval to upload it very soon. Aside from the example above, it also supports netboot, initrd being optional, hard-coding various extra stuff into bootargs, etc.
You can also see some hard-coded boot scripts that I hope to get added to the Ubuntu installer image generator at:
https://code.launchpad.net/~srwarren/debian-installer/tegra/+merge/175967
(I'd love to have similar support added to other distros; I just had to pick one to work on first)
It is not likely to get into fedora's installer. we currently have extlinux support which is really simple and arm-boot-config at: https://git.fedorahosted.org/cgit/arm-boot-config.git its a mostrosity of hush scripting to enable menus and configuration options. but it does require board specific knowledge to enable support for new systems. but i definetly want to enable people to use boot.scr if they choose to
What this gets us in the end is that with a unified kernel, device tree and u-boot implementing the system specific knowledge, supporting new ARM systems is along the same lines as supporting new x86 systems. Get the drivers and platform support in the mainline kernel and as long as the Distro enables it it will just work in the next OS release. The one part then that we as Distro's need to do is to ensure we install u-boot into the disk correctly for the board in question if it is a system that does not ship with some kind of storage for u-boot. If it is a system with NOR, Nand, SPI storage for u-boot it is then entirely in the vendors hand, and assuming that they implement everything, all distros will be able to simply support them. Giving users and vendors more choice in what to run on their hardware.
At least for Tegra, the U-Boot binary won't (ever?) be part of the file-system, but is rather always somewhere dedicated (eMMC boot sectors rather than the main user area, SPI, or NAND for example). As such, the model I'd like to push for Tegra is that you use HW-specific tools to install U-Boot, then use a distro installer SD card, USB device, or even CD-/DVD-ROM image to install the distro, and that the distro doesn't have to know anything at all about the bootloader, except to install a hopefully entirely HW-agnostic boot.scr that I detailed above.
need to add pxe support in there. there is no reason we couldnt make installer isos, we dont because we do not know of any hardware supporting it. but a installer sdcard or usb stick are things we want to support as well as network installing using pxe booting.
I know that some other SoCs store U-Boot etc. on storage-partitions/filesystems instead. Perhaps distros should always assume that the "U-Boot partition" is sacred, and just large enough for the firmware, and put all their files on other partitions. The only difference between Tegra and OMAP then would be an extra partition, and hence the distro's / or /boot would be either partition 1 or 2:
Tegra: Boot flash: U-Boot storage partition 1: / (boot.scr, DTB, zImage, etc.)
(p1 marked bootable)
OMAP: storage partition 1: U-Boot storage partition 2: / (boot.scr, DTB, zImage, etc.)
(p2 marked bootable)
for fedora 20 i plan to use raw MLO support for OMAP and have it load the u-boot.img from the first bootable partition. SuSE are doing this today but the patch they have enabling it needs some work to support all the different ways things are setup today. for fedora 19 we used a 20mb vfat partiton that contains MLO u-boot.img and a uEnv.txt loading a boot.scr from /boot/ on the 3rd partition partition 1: 20mb for u-boot mounted at /boot/uboot partition 2: 512mb swap partition 3: /
but overall i like the idea,
I may not be entirely clear here and there may be things I am missing, I feel it is a good place to start the discussion.
I like where I think you're going!
Thank you, I am open to feedback and options to achieve our goals that will help all distros and not break things for use cases that are not our primary interest.
Dennis