UBoot binary file strcture and offsets - u-boot

I believe the UBoot binary image has a common format
, containing following fields:
------------------------------------------
| Header: UBoot version, code size, ... |
------------------------------------------
| code |
------------------------------------------
| A Queue maybe containing CRC |
------------------------------------------
Can you please help me find the offsets of each field ? The most important for me is the offsets of the header parameters (version, entry point, ...), so any documentation would be helpful.
I saw this structure in uboot code, but I am not sure if these are the correct header offsets since it is not matching with the uboot.bin generated in my case. Is it maybe platform dependent ?

To find the U-Boot version string you can use:
grep -a 'U-Boot [0-9][0-9][0-9][0-9]\.[0-9][0-9]' u-boot.bin
u-boot.bin is a raw file which is typically the concatenation of multiple files. The layout of the binaries is defined by linker scripts like arch/arm/cpu/armv8/u-boot.lds. Typically the entry point is on the first byte.

Related

cannot get c program to build, compiler doesn't find include files

When attempting to compile a c program it never finds the include files. In a program located in ~/hbc/channel (offending file is in ~/hbc/channel/channelapp/source/xml.c) I get the following error:
source/xml.c:8:18: fatal error: mxml.h: No such file or directory
my PATH is set as follows:
dan#htpc~/hbc/channel-$ export | grep DEVKIT
declare -x DEVKITARM="/home/dan/devkitpro/devkitARM"
declare -x DEVKITPPC="/home/dan/devkitpro/devkitPPC"
declare -x DEVKITPRO="/home/dan/devkitpro"
And the file is there with the include files in the devkit:
dan#htpc~/hbc/channel-$ find ~/ | grep mxml.h
/home/dan/devkitpro/devkitPPC/include/mxml.h
Since it would be insane to have to edit every single file to point to its required library or header, I really need to ask.
Is there something I'm missing out? How can I set these paths properly so that the compiler sees them? I couldn't find anything else regarding this question and the development environment is set correctly since I could compile simpler code. It's this code requiring external libraries that's failing to find them.
Thanks in advance.

What is difference between u-boot.bin and u-boot.rom

I have builded the U-boot for minnowboard max. I am seeing the files like uboot.rom uboot.bin etc.
what is the difference between uboot.rom and uboot.bin ? Which files I should flash to SPI NOR flash.
This is explained in doc/README.x86. In short, if you are going to be writing U-Boot to SPI NOR then you need to ensure that you have the correct binary blobs in the correct locations AND use BUILD_ROM=y so that u-boot.rom is generated as this is the file that is required on x86 to run on bare metal (rather than say as a coreboot payload).
Edit to address the comment:
The file 'u-boot' is the ELF object that is the result of building all of the U-Boot sources and linking them. This includes all of the extra sections and information an ELF file can contain. This is also by and large not bootable. The u-boot.bin file is the ELF u-boot but passed via objcopy to strip out (by and large, see the Makefile for the various flags or build with V=1) everything except for text/data sections so that we have only what is required to boot. Then u-boot.rom is the combination of objects and formatting that the x86 architecture requires in order to execute and run an image. Building with V=1 will show all of the details here.

How to print message to stdout from GNU ld script?

I have quite large ld link script for embedded platform which is low on RAM and ROM. I want to know how much memory is left available after I have relocated all the code. Actually, I want to print out the value
of location counter . to stdout.
How can I do it? Is there some magic command like print(.)?
I have a post-link step in my projects that dumps the size of stuff so I can see how close I'm getting. Just add something along the lines of:
arm-none-eabi-size binary_image.axf
That will get you output like:
text data bss dec hex filename
204808 704 23188 228700 37d5c Foo.axf
On my cortex-m3 chip, this would be text+data = flash usage, data+bss = ram usage. dec/hex are useless values.
And as Olaf says, use a map file for more specific memory consumption. I have this added to my link step:
-Xlinker -Map=Foo.map
Another solution might be to add the following command to the linker:
-Xlinker --print-memory-usage
This gives me the following output:
Memory region Used Size Region Size %age Used
m_interrupts: 576 B 576 B 100.00%
m_text: 22988 B 32192 B 71.41%
m_data: 26552 B 32 KB 81.03%
Read the manual. There are no such commands - there cannot be.
Linker "scripts" are actually more like configuration/descriptor files. They are not "executed" like a script. There is also not a single . (how could be for different memory areas?).
You can, however, output a map which might exactly be what you need. Try option -M. If you have set up the memory regions in the linker script correctly, the linker will warn if some memory area overflows, which is actually what you want for automatic builds.
Update: You could grep/filter the map file if you want to insist seeing the section sizes on each build.
You can't print the value of a symbol while the script is being executed, but you can create a symbol and the look it up afterwards with nm. Like this:
value_of_dot = .;
Then
nm my_file.elf | grep value_of_dot
Edit: If you really want it printed to stdout you would have to modify the linker. E.g. for lld, add printfs in LinkerScript.cpp in LinkerScript::assignSymbol().
For your particular use-case of checking how much memory is used, it is probably better to use size, as escrafford suggested, or objdump -section-headers.

Storing CRC into an AXF/ELF file

I'm currently working on a C program in the LPCXpresso (eclipse-based) tool-chain on Windows 7, an IDE with gcc targeting the an NXP Cortex M3 microprocessor. It provides a simple way to compile-link-program the microprocessor over JTAG. The result of a build is an AXF file (ELF format) that is loaded by a debug configuration.
The loaded program resides in Flash memory from 0x00000 to 0x3FFFB. I'd like to include a 4-byte CRC-32 at 0x3FFFC to validate the program at start-up. I added another section and use the gcc __attribute__ directive to access that memory location.
uint32_t crc32_build __attribute__ ((section(".text_MFlashCRC")));
To compute and store the CRC-32 value, my plan was to use SRecord with the following post-build steps:
arm-none-eabi-size "${BuildArtifactFileName}"
arm-none-eabi-objcopy -O binary "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin"
checksum -p ${TargetChip} -d "${BuildArtifactFileBaseName}.bin"
../util/srec_cat "${BuildArtifactFileBaseName}.bin" -binary -crop 0 0x3FFFC -fill 0xFF 0x00000 0x3FFFC -crc32-b-e 0x3FFFC -o "${BuildArtifactFileBaseName}.crc.bin" -binary
echo ""
echo "CRC32:"
../util/srec_cat "${BuildArtifactFileBaseName}.crc.bin" -binary -crop 0x3FFFC 0x40000 -o - -hex-dump
This creates a binary with a checksum (necessary for bootloader) and then computes the CRC over the used Flash memory, storing the CRC value at 0x3FFFC.
However, I don't think I can load the binary file using the debugger. There is a built in programming utility with LPCXpresso that can load the modified binary file, however, that doesn't let me debug. I believe I can then try to start a debugging session with the original AXF file using "attach-only" mode, however, this becomes cumbersome.
I've been able to use readelf to inspect the crc32_build variable in the AXF file. Is there a way to edit the variable in the AXF file? Is there an industry-standard approach to inserting a CRC as a post-build step?
There is no industry standard that I am aware of. There are various techniques to do this. I would suggest that you use the crc32_build as an extern in 'C' and define it via a linker script. For instance,
$ cat ld.script
.text : {
_start_crc_region = .;
*(.text);
_end_crc_region = .;
crc32_build = .;
LONG(CALC_CRC);
}
You pass the value CALC_CRC as zero for a first invocation and then relink with the value set. For instance,
$ ld --defsym=CALC_CRC=0 -T ld.script *.o -o phony.elf
$ objcopy -j sections phony.elf -o phony.bin # sections means checksum 'areas'
$ ld --defsym=CALC_CRC=`crc32 phony.bin` -T ld.script *.o -o target.elf
I use this technique to add digital signing to images; it should apply equally well to crc values. The linker script allows you to position the variable, which is often important for integrity checks like a CRC, but wouldn't matter for a simple checksum. A linker script also allows you to define symbols for both the start and end of the region. Without a script, you need some elf introspection.
You can of course extend the idea to include init data and other allocated sections. At some point you need to use objcopy to extract the sections and do the integrity check at build time. The sections may have various alignment constraints and you need to mimic this (in phony.bin above) on the host when doing the build time crc calculation.
As a bonus, everything is already done when you generate an srec file.
If you have trouble with --defsym, you can just pre-process the ld.script with sed, awk, perl, python, etc and substitute text with a hex value where CALC_CRC is.

Getting link errors with CMake

I'm getting multiple definition link errors after conditionally compiling platform-specific code.
My project is laid out like this:
/
|__+ include/
| |__+ native/
| | |__ impl.h
| |
| |__ general.h
|
|__+ src/
|__+ native/
| |__ impl.linux.c
| |__ impl.win32.c
|
|__ general.c
At the top of the general.c file:
#if defined(LIBRARY_PLATFORM_LINUX)
#include "native/impl.linux.c"
#elsif defined(LIBRARY_PLATFORM_WIN32)
#include "native/impl.win32.c"
#endif
I set up introspection in CMake in order to detect the operating system and define the corresponding constants. The thing is, I didn't want to maintain one CMakeLists.txt file in every directory, so I simply globbed all the .c files as suggested in this answer:
file(GLOB_RECURSE LIBRARY_SOURCE_FILES "${PROJECT_SOURCE_DIR}/src/*.c")
Apparently, this is what is causing the problem. It seems to be compiling the code #included in general.c as well as the individual src/native/impl.*.c files.
CMakeFiles/lib.dir/src/native/impl.linux.c.o: In function `declared_in_impl_h':
impl.linux.c:(.text+0x0): multiple definition of `declared_in_impl_h'
CMakeFiles/lib.dir/src/general.c.o:general.c:(.text+0x0): first defined here
How can I untangle this situation?
The best practice for that sort of cross-platform situation is to create two libraries, one for linux and one for windows and stop doing conditional includes. Each platform only compiles and links the relevant library.
The recommended way to do that with cmake is to stop globbing and just include each file. There are some situations where it can get confused and not realize that it needs to recompile. You can make an argument that non-changing legacy code won't have that problem.
If you really want to avoid doing either of these things, I would put the included code in a header instead of a c file. You don't really want the include guards so that people don't get it confused for something that should be used like a regular header. Put a bunch of comments in the file to warn them off of said behavior as well.

Resources