![]() text segment contains the executable code so this is the actual starting address of the kernel after decompression. text segment (as output from the compiler) should be located. As the name says, this is where the kernel. Then the TEXT_OFFSET is added to the pointer to the start of physical memory. There are patches being made that would instead attempt to get this information from the device tree. This means that the kernel readily assumes that it has been loaded and executed in the first part of the first block of physical memory. On most modern platforms this is done with the Kconfig-selected code AUTO_ZRELADDR, which means a logical AND between the program counter and 0xf8000000. The decompression code then locates the start of physical memory. So now the kernel decompression code is executing from the physical address of the physical memory where it was loaded. It jumps over some magic numbers and saves the pointer to the ATAGs. (This is not immediately evident.) It begins with 8 or 7 NOP instructions for legacy reasons. If the kernel is compressed, execution begins in arch/arm/boot/compressed/head.S in the symbol start: a little bit down the file. (In this case r1 is ignored.) A DTB can also be appended to the kernel image, and optionally amended using the ATAGs from r2. On contemporary device tree kernels, r2 is repurposed as a pointer to the device tree blob (DTB) in physical memory. The boot loader then jumps to the kernel in supervisor mode, with all interrupts, MMUs and caches disabled. It can be executed from any address as long as the decompressed kernel fits. The kernel would be placed somewhere in this memory. The ATAGs would contain the location and size of the physical memory. The boot loader puts 0 into register r0, an architecture ID into register r1 and a pointer to the ATAGs in register r2. Russell King defined the ABI for booting the Linux kernel from a bootloader in 2002 in the Booting ARM Linux document. The bootloader, whether RedBoot, U-Boot or EFI places the kernel image somewhere in physical memory and executes it passing some parameters in the lower registers. All machines under arch/arm/* uses this method if they are booted using a compressed kernel, and most of them are using compressed kernels. This is intended as a comprehensive rundown of how the Linux kernel self-decompresses on ARM 32-bit legacy systems. For NAND flash controllers this can easily be the case. It is faster to load because the time it takes for the decompression to run is shorter than the time that it takes to transfer an uncompressed image from the storage media, such as flash.For example for the Gemini platform that I work on, the vmlinux uncompressed kernel is 11.8 MB while the compressed zImage is a mere 4.8 MB, we save more than 50% It saves space on the flash memory or other storage media holding the kernel, and memory is money.ARM traditionally uses compressed kernels.
0 Comments
Leave a Reply. |