Dev/Embedded/FromScratch
Introduction
First of all, building your own system image for your board is a good idea.
This may feel a little bit confusing or difficult at first, but you'll find most information here and across this Wiki. It may not be exhaustive or up-to-date, but you'll have all the basics.
Building your own images is really important.
It means that :
- You have access to all the sources
- You do not depend on others to get what you want, update, or fix your system
- You will learn a lot
What do you need
In order to build your own system image you will need a few things :
- - A system running a Linux based distribution. It will be your "host" or "development" system. (Well, the "Linux based" is not mandatory, but it's the one I use).
I'm using a Devuan GNU/Linux system running on a x86_64 computer, but there are alternatives out there, for the distribution as well as for the hardware.
It's best if it has some powerfull processors and plenty of available RAM and storage, but even the smallest system will do the job, it will only take more time.
- - A (cross-)compiler toolchain. You'll find (most of) the information related to this part on my page dedicated to cross-compilation.
- - A way to fetch the sources of course.
- - A target system to run the binaries you'll build. Well you certainly have one, or you'll not be here, though it is also possible to use an emulator on your development system.
- - A way to connect to your target's serial console. It may be possible to do it differently, but it's way easier to have a serial link to connect to the system console (UART), and I'll consider you are using this solution.
- - Some time, curiosity and will. It's not very difficult, but you may enconter some problem as the systems you'll use are in constant evolution and may not behave the same as when I wrote these lines.
System content
All system images can be split in three parts :
- The bootloader
- The Linux kernel
- The userspace
These three parts may be split further, but it's the basics.
Bootloader
The bootloader is a small piece of software which is the first thing to run when the system is powered up.
The role of the Bootloader is to setup the hardware so that it can execute a bigger system : the Linux Kernel in our case.
Depending on your target hardware you may need more than one boatloader before you can get your Linux Kernel running. This is usually due to technical reasons, such as available memory or hardware security protections.
In most cases, the very first boatloader is a part you have no control over, and is usually called a "ROM bootloader" (or RBL), and is integrated in the ROM of the processor. This one will load your first stage bootloader from a given source, depending (most of the time) on the state of some configuration pins (boot selection or boot configuration) or internal fuses (e-fuses, which may be one-time programmable or not).
Depending on the hardware you'll use, this first stage bootloader can be :
- The only bootloader you'll need
- A smaller version of your bootloader : some processor will load the bootloader in the instruction cache of the processor, which may be too small for a full featured bootloader (tough if you manage to get everything you need in the available space, then you can get rid of the second stage bootloader and use only this one).
- A specific piece of firmware required for the processor, provided as source or binary : many recent ARM targets require an "ARM trusted firmware", now called "Trusted Firmware-A (TF-A)". Other may need other hadware specific bootloader to start.
When the first stage bootloader is not the only required one, it will load your second stage bootloader.
In order to know what can and cannot be done with a specific board you will need the board's documentation or schematics (and the processor's documentation).
ARM trusted firmware (or Trusted Firmware-A)
If you are building U-Boot for an arm64/aarch64 device, you need to include the "ARM trusted firmware" (ATF) or "Trusted Firmware-A" (TF-A).
- Get the sources :
You can get this either from the trustedfirmware.org git repository :
git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
or the arm-trusted-firmware git repository on github :
git clone https://github.com/ARM-software/arm-trusted-firmware.git
Note that both repository seems to have the same code, only some of the tags appear to be different.
- Configure :
There's no configuration stage for this part, though you'll need to know the "platform" name and the "target" name you want to build.
You can run "make help" to get the list of supported platform and the target names.
You can refer to the documentation for your SoC (processor) under "docs/plat" directory.
I'll indicate the right plaform and target on the pages dedicated to each board when I get my hands on them :)
- Compile :
To build this firmware part get to the root of the git tree and run:
platform= target= make CROSS_COMPILE=aarch64-linux-gnu- PLAT=${platform} DEBUG=1 ${target}
Set "platform" and "target" according to your needs as identified in the "Configure" section above