How can I reserve a portion of SDRAM, say 4 bytes, to pass a flag between U-Boot and the Linux kernel so that this reserved memory location is not initialized by the linker and the value preserved after a warm boot? I'm trying to avoid using bootargs to minimize wear of the NAND flash used in an embedded application. My question could be considered an extension to the solution provided by: How to detect cold boot versus warm boot on an ARM processor?
I have built u-boot.lds with the linker script below and built it with: -fno-zero-initialized-in-bss without success.
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm926ejs/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
_U_BOOT_FLAG = .; . = . + 4;
.bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
_end = .;
}
Any ideas?
In other words, U-Boot should run the nfscmd script to boot the system. In turn, this environment variable is a set of commands of its own. First, it sets the bootargs environment variable, which U-Boot passes to the kernel as its boot parameters, and then uses the bootm command to boot the kernel located at $ (kernel_addr).
For example, uboot wants to read the kernel partition from the nand flash to the memory address 0x30007FC0 and start the kernel. You can use the following command: bootm 0x30007FC0. The key to starting the kernel is the bootm command.The implementation of the bootm command is in the do_bootm () function in uboot:
This step is implemented in the do_bootm_linux () function. Through a function pointer, thekernel () takes three arguments and jumps to the kernel (zImage) entry point to execute. At this point, the u-boot task has been completed and control is completely passed to the kernel (zImage).The specific implementation of the function is in bootm.c
Once the kernel is loaded, you can use the bootm command to boot that kernel. This can also be automated by setting the autostart environment variable to yes. In that case, diskboot will automatically boot the kernel it loads:
There is already a method to pass data between U-Boot and the Linux ARM kernel. It's called the ATAG memory list. Information such as usable memory regions, and board information are passed from U-Boot to the Linux ARM kernel using this data list. You could define a custom ATAG for your data. In U-Boot, add your routine to build your ARM tag in lib_arm/armlinux.c
. Then ATAGs are processed in arch/arm/kernel/setup.c
.
For documentation see Section 8 of this or this alt site.
ADDENDUM
Links to the referenced ATAG documentation are tenuous (even Google has a bad link).
Try searching for the actual name of the document, which is "Booting ARM Linux" by Vincent Sanders.
Currently there's a copy in Google's cache of the simtec site, and a broader search turned up a translation in Korean(?).
Another or an earlier version (?) (but seems to have been updated) by Russel King on ARM booting is here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With