8
votes

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?

2
What board are your using? A Versatile board or a custom board? What SRAM are you talking about?sessyargc.jp
The board is a at91sam9g45 and it is actually DDR2-SDRAM.user1357493
Upvote just for knowing how to correctly spell U-Boot.sawdust
You already have to have a chunk of ram that you use to place the linux kernel, optionally place the root file system, within that space you also place the ATAGs and/or device tree then pass that address in to the kernel. Not sure why you would "allocate" that space, you are a bootloader you OWN all the chip resources including ram. what you dont use for the bootloader is all free space for the above items. Plus as desired you can use more of that space to pass whatever else you feel you need to.old_timer

2 Answers

3
votes

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.

0
votes

If you want to go by the global-variable approach in How to detect cold boot versus warm boot on an ARM processor? :

You can force that global variable to be in a specific ELF section (see http://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Variable-Attributes.html) , and then in the linker script set that section to a specific address.

If you have good ld-script skills, you could even get the linker to initialize all bss sections except that one :)