I've successfully used buildroot (v. 2019.05) to built u-boot and Kernel and was able to boot it together.
The problem is that, even though I selected Kernel compression mode to gzip, all I get is the uncompressed Image file.
In the output directory (and Linux as well) there is only Image file, while there should be Image.gz.
How to generate Image.gz from / instead of Image?
On arm64, Linux does not support self-extracting compression. It relies on the boot loader to do that.
The Linux build system does have an Image.gz (and Image.bz2 etc.) target, but it does nothing more than calling gzip on Image (compare this with zImage, which adds a self-extractor).
Since it is easy to do the compression outside of the kernel build system, and since there are so many different compressors possible, Buildroot doesn't provide options for them. However, it is possible to select a custom image name (BR2_LINUX_KERNEL_IMAGE_TARGET_CUSTOM) and then set BR2_LINUX_KERNEL_IMAGE_TARGET_NAME to Image.gz. Alternatively, you can do the compression in a post-build script.
Remember to make sure that the bootloader is able to decompress with that algorithm.
According to the Linux package configuration tool:
This selection will just ensure that the correct host tools are built.
The actual compression for the kernel should be selected in the kernel
configuration menu.
Make sure you select the compression option using make linux-menuconfig too.
In buildroot, besides selecting the compression mechanism you can also select the output format for the kernel image (uImage, zImage, vmlinux ...).
You should find on of those in your output/images/ or in the build directory of your kernel.
When using U-boot you probably want to use the uImage or the zImage. See this question. Both of them will be compressed if selected in the kernel configuration (CONFIG_KERNEL_GZIP).
During boot the uncompressed size of the kernel is logged in the beginning. You can compare it to the size on your filesystem.
## Booting kernel from Legacy Image at 10000000 ...
Image Name: Linux-4.14.73-ltsi
Created: 2019-05-14 11:55:16 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4684016 Bytes = 4.5 MiB
Load Address: 00008000
Entry Point: 00008000
...
Related
I am attempting to get initramfs working on an embedded linux device using buildroot and uboot. I have been following the guides have have initramfs set up in the buildroot and kernel config. However as far as I can tell it is not being built into the kernel, although a CPIO or the root FS is being included in the output.
My questions is twofold. First, from a high level standpoint, is my understanding of the boot process correct?
Stage 1 bootloader (Atmel/ARM specific) starts and hands off
Stage 2 bootloader (uboot) initializes a few things, loads the kernel into memory and runs it
The kernel places the CPIO archive into memory, makes that root and runs init in that enviornment
This means the image I flash onto the chip is an IMG with a boot and system partition, the system partition is ext4 and contains the CPIO archive within. I am not sure how to make item 3 actually happen from here.
Second, in terms of actual configurations, the Buildroot menuconfig has a number of options for filesystems
ext2/3/4 root filesystem (on by default)
cpio the root filesystem (for use as an initial RAM filesystem)
initial RAM filesystem linked into linux kernel
Then in the kernel config
General -> Initial RAM filesystem and RAM disk (initramfs/initrd) support
General -> Initramfs source files (set to the generated cpio file)
What is buildroot generating here? From my end it looks like I am getting duplicate images (CPIO and ext4) and the CPIO is being ignored.
For people who may have the same question, the best way forward is to become more familiar with uboot and it's options. In particular the role uboot-env.txt plays in the process.
My understanding of buildroot was wrong. The process is
Building kernel
Creating all root filesystems (ext and CPIO)
Rebuilding the kernel with the CPIO inside
Packaging the ext file as dictated by my genimage.cfg file
This may be of interest if the process is confusing to you.
Here is what the system was doing
Stage 1 bootloader (Atmel/ARM specific) starts and hands off
Stage 2 bootloader (uboot) initializes a few things, then behaves as dictated by as config, by writing the kernel to memory from the ext4 partition and running it
This kernel did not have the cpio so it did not run.
Better understanding the process and components I was able to restructure my img file and use the bootloader to load the kernel that was built with the cpio.
I want to build linux for zed board. When I look into zynq-common.h file in u-boot/include/configs directory, I see that kernel_load_address is 0x02080000.
Why kernel load address is 0x02080000?
What is the logic of it?
I am using version 2018.01.
Value that I mentioned is "kernel_load_address=0x2080000" in CONFIG_EXTRA_ENV_SETTINGS
I don't think that's the actual load address. UBoot should load it to 0x8000 by default. It could be modified, but you arn't going to want to do that through the header files.
(You shouldn't need to be looking at those files, especially not modifying them.)
If you want to build the kernel for the zedboard, I reccomend following either of these guides:
https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/software/linux/zynq_2014r2
https://highlevel-synthesis.com/2016/10/31/how-to-compile-xilinx-linux-kernel-for-zynq/
You will also need the toolchains from Xilinx if you don't want to build the kernel on platform which will take 4-6 or more hours (I have had to do it before, not fun).
Value that I mentioned is "kernel_load_address=0x2080000" in CONFIG_EXTRA_ENV_SETTINGS
That particular environment variable is not the mainline version of U-Boot. So apparently you are using a custom version.
The use of that env variable is likely to locate the kernel image with an input command in main memory. Since this is an ARM board the kernel image would be a zImage or uImage (which would contain a zImage).
The zImage is capable of uncompressing itself and relocating the kernel image to its proper load address for actual execution.
That final load address is typically the start of physical memory plus 0x8000. See Building kernel uImage using LOADADDR
Since the kernel will be relocated during decompression, this intermediate memory address used by U-boot for reading in the compressed kernel image is not crucial. The uncompression code attached to the zImage is position independent, so loading the zImage into memory is flexible. As long as the zImage resides in memory higher than the kernel's actual loadaddress, there is no issue (i.e. an extra relocation).
Kernel 3.19 (re-)introduced Device Tree Overlays. I am on Linux kernel 3.19.4, via Fedora (3.19.4-200.fc21.armv7hl).
I have an overlay file overlay.dts as described in the documentation.
overlay.c contains functions to work with overlays, including to functions to load an overlay.
Does the kernel check any paths for overlays to load? If so, where? If not, how can I load my overlay?
From my experience (3.8-3.14), DTB loading is actually the jurisdiction of the boot-loader, rather than the kernel itself. I've used u-boot for this - u-boot can load the compiled device-tree file (man dtc) from an EXT2-based filesystem to a known location in RAM, which is then specified in the kernel command line.
Which boot-loader are you using?
Consider a live GNU/Linux distro with the following constraints: all the software should be contained in an initrd image (which results in its huge size) and the kernel contains as few statically-compiled modules as possible.
Consider the bootup process of the described distro: the bootloader (e.g. grub or isolinux) loads the kernel, which then loads and extracts the initrd into the memory. During the extraction (which takes 20-30 seconds on old computers) nothing happens on the screen.
I was wondering, is there a ready-made solution of showing a splash screen during the initrd extraction process? If not, can you please comment on the following ideas:
Statically compile an e.g. 600x480x8bit image into the kernel and somehow flush it into the framebuffer while initrd is being extracted.
Do the same, but force a particular video driver to be loaded (e.g. VESA) and hack into its code, rather that kernel's framebuffer.
Thank you.
Perhaps you can make it simpler: Create 2 initrd files. The first one can be small. Then it can call Plymouth to show a splash screen while the real initrd is extracted.
You are wrong if you think, that the kernel loads the initrd image. It is done by the boot loader. If you want to show a splash screen you have to tell your boot loader to display an image. How to do this depends on your boot loader.
You might try creating a plain .ppm file and use LZMA compression for the Kernel Compression Mode. This might be done by using the boot logo option, but not sure if it will work for you.
First you need to enable support in your kernel for Bootup logo and Standard 224-color Linux Logo:
Device Drivers —> Graphics Support –>
Support for frame buffer devices
VESA VGA graphics support
Video mode selection support
Framebuffer Console support
Select compiled-in fonts
VGA 8×16 font
Bootup logo
Standard 224-color Linux log
Second,if supposed that you have a .png image named screen.png, you need to generate the appropiate .ppm file:
pngtopnm screen.png| ppmquant -fs 223 | pnmtoplainpnm > /usr/src/linux/drivers/video/logo/logo_linux_clut224.ppm
Then just compile, install, update your bootloader and check if it works for you.
According to this picture from The Kernel Boot Process:
The bulk of the kernel image is only ~1.5MB. I thought the kernel image should be a fairy large binary image file in order to support the hardware (or is this kernel module?) and various kernel functions, since the source is pretty large. Also, where's the initrd?
First the kernel is compressed. Then in most desktop environment, the kernel is built with a minimal set of statically linked modules. The initrd image is loaded from the hard drive, from the /boot folder (see your grub configuration) and is used to detect your desktop hardware to load the appropriate modules, to be able to mount a root file system. The initrd image contains this sets of modules. Imagine a RAID, LVM or an exotic file system that cannot be recognized by the bootloader. This is why the boot partition is most of time in ext2/3/(4?). Then when the right modules are loaded, the root file system is swapped from initrd image with the one on the hard drive (pivot_root). Then the rest of the hardware modules are loaded from the "none initrd" filesystem, mostly with the help of udev.
Hope this helps!
P.S. Correct me if I'm wrong!