*tldr; I would like to generally understand how the world of linux / embedded linux works. What do I need to do to take the Linux mainline and compile/deploy it on a board with different processors and peripherals, from scratch.
How I currently See It Working:
Steps to get Linux running on arbitrary board:
- Get sources for uBoot (for embedded) or GRUB (desktop/x86 SOM)
- Modify uBoot or GRUB for specific system, write code to init specific chip and get required interfaces for memory and console up and running
- Modify uBoot/GRUB config.txt to configure code written above
- compile these and deploy to board, verify that bootloader console comes up and can interact with it
- Get kernel mainline sources
- "make config" to select drivers and modules that will be available (At this point these selections will change the source - wherever these settings are stored will no longer match a git clone from the mainline) (Track this .config file in source control for future reference)
- Get tools such as Busybox or desktop alternative? Install in source directories
- Get ucLibc or other libraries and install in source directories
- Compile kernel source using cross compiler toolchain for specific chip
- Create device tree files .dtb for board (both embedded/desktop? or desktop does not use?) This connects drivers to physical pins
- Use Uboot/GRUB and TFTP/serial console or memory card etc to load compiled kernel image.
- Boot up and verify shell access through serial/SSH etc depending on drivers and device tree config
- Modify uEnv.txt (embedded) or mysteryfile.txt (desktop) for board specific configurations? This is essentially a script that blocks or adds kernel startup steps? What is the desktop equivalent?
- apt-get desired packages and drivers
- write drivers and application code and test (manually loading drivers)
- Add device tree files to account for hardware and drivers implemented above (these are separate from the intial BSP one created)
- To include these in kernel image build the kernel and create the file structure with all of these sources and config file mods in the folder strcuture (additions/mods to Linux mainline)
- Could have a separate folder for Linux mainline and mods, copy mods directly overwritting/adding files to mainline in a third staging folder. This will allow all additions and non-mainline mods to be source controlled separate.
If you can get a base system that you can SSH into, and at this point you have drivers for all the common components (Video, USB, mouse etc) then you can pretty much do anything at this point (install X11 server, LXDE, networking etc)? Which drivers need to be handled by the bootloader/bios and which ones are purely in the kernel domain?
There are Kconfig files for configuring the kernel build. This makes sense and the kernel module development docs that I have seen seem to describe this well.
There are also files like uEnv.txt and config.txt that handle the run time configuration and which devices should be loaded. There are also device tree blobs which also determine which devices should be loaded?
How do the magic strings in these files tie into the kernel, are these modifications done to the mainline for a specific board? Something has to read these to determine if HDMI should be enabled or not, and this can't be the exact same code as what is on the desktop version of Linux.
Once drivers are in the mainline are they still developed independently from the mainline? For example I have been using a couple of drivers but there are notes they are now included in the mainline, does this mean that it is no longer possible to download directly on its own? The steps I have followed downloaded the headers for my board, the source and then compiled it and installed it. If it is in the mainline do I need to pull it from there now instead?
Background and Specific Thoughts
I am an EE and have experience with Microcontrollers and Windows development, but do not have much Linux experience. The framing of my question is "If I started off with this arbitrary (with linux compiler available) processor, and these peripherals how do I (and what are my options) for building a linux release"
I have been able to find RPI2 and BBB (Beaglebone Black) specific documentation and how-to's but when you get into more advanced topics like the bootloader there are only a few crumbs to vaguely describe what is going on. For example the RPI2 has a 3 stage bootloader (of which from reading it does not sound like it is totally uBoot based) and the BBB has a more "traditional" uBoot based bootloader. Now the new BBx15 has jumpers where you can select where you want to boot from.
The desktop systems use GRUB (IIRC) and embedded systems typically use uBoot. I have read that the RPI uses the GPU during boot and reads the first stage bootloader off of a separate ROM. And that is all the information available. If you wanted to spin your own version of the board (for discussions sake, this is not really practical) then in addition to uBoot what is going on? Doesn't uBoot for the BBx15 have extra modifications to allow for the jumper boot selection?
Does Linux know anything about the staging of booting or is it oblivious to this once it is running? The BBB uses uBoot to load the image off the eMMC into RAM, the RPI2 uses the 3 stage bootloader. I am guessing that the BBB uses the ARM processor to do this but the RPI2 uses the GPU. I thought on power up that the ARM processor starts executing, what would they have to modify to stage these load procedure? Does the GPU hold the ARM in reset until it has completed its ROM code? Since the GPU is part of the boot procedure does that mean the code it executes is taken out of the uBoot code, that other systems without this GPU would have to then run in the uBoot code? This whole procedure implies to me that if you modify the second or third stage bootloader that you could run Linux entirely off the GPU alone (if the kernel was compiled with the GPU toolchain)?
Is the third stage bootloader and config.txt actually just uBoot?
Regarding the headers for the board in use. Are these just the headers from the mainline with the drivers that have been overlayed included or is there something more to this. The "headers" are just the mainline headers if that is what you have started running with?
For embedded microcontroller development I am used to having a HAL layer. The HAL has function stubs where you setup the peripherals and then point the drivers to those resources. The board support package typically have these HAL stubs already coded for the board in question. I am sure there has to be some parallels here to Linux development but I can't quite see where these divisions are.
There are packages such as Buildroot and Yocto. Are these just the Linux mainline with an interface to automate selecting the ARM processor and drivers to include?