Книга: Embedded Linux Primer: A Practical, Real-World Approach
16.2.2. Customizing Kernel Initialization
16.2.2. Customizing Kernel Initialization
Now that we have a baseline kernel source tree from which to start, let's determine where to begin customizing for our particular board. We discovered that for the PowerPC architecture, the board-specific files reside in a directory called .../arch/ppc/platforms. Of course, this is not strictly necessary, but if you ever intend to submit your patches to the Linux kernel development community for consideration, proper form and consistency matter!
We find in the platforms directory a file called lite5200.c. It's a fairly simple file, containing two data structures and five functions. Listing 16-3 presents the functions from this file.
Listing 16-3. Functions from 5200 Platform File
lite5200_show_cpuinfo() /* Prints user specified text string */
lite5200_map_irq() /* Sets h/w specific INT logic routing */
lite5200_setup_cpu() /* CPU specific initialization */
lite5200_setup_arch() /* Arch. specific initialization */
platform_init() /* Machine or board specific init */
Let's look at how these functions are used. We briefly examined the low-level kernel initialization in Chapter 5. Here we look at the details for a particular architecture. Details differ between architectures, but when you can navigate one, the others will be easier to learn.
From Chapter 5, we saw the early flow of control on power-up. The bootloader passed control to the kernel's bootstrap loader, which then passed control to the Linux kernel via the kernel's head.o module. Here the platform-specific initialization begins. Listing 16-4 reproduces the pertinent lines from .../arch/ppc/kernel/head.S.
Listing 16-4. Calling Early Machine Initialization
...
/*
* Do early bootinfo parsing, platform-specific initialization,
* and set up the MMU.
*/
mr r3,r31
mr r4,r30
mr r5,r29
mr r6,r28
mr r7,r27
bl machine_init
bl MMU_init
...
Here you can see the assembly language call to machine_init. Of particular significance is the setup of the registers r3 through r7. These registers are expected to contain well-known values, which you will see momentarily. They were stored away very early in the boot sequence to the PowerPC general-purpose registers r27 through r31. Here they are reloaded from these stored values.
The machine_init() function is defined in a C file called setup.c, in the same architecture-specific kernel directory: .../arch/ppc/kernel/setup.c. The start of this routine is reproduced here in Listing 16-5.
Listing 16-5. Function machine_init() in setup.c
void __init machine_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) {
#ifdef CONFIG_CMDLINE
strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
#endif /* CONFIG_CMDLINE */
#ifdef CONFIG_6xx
ppc_md.power_save = ppc6xx_idle;
#endif
#ifdef CONFIG_POWER4
ppc_md.power_save = power4_idle;
#endif
platform_init(r3, r4, r5, r6, r7);
if (ppc_md.progress)
ppc_md.progress("id mach(): done", 0x200);
}
There is some very useful knowledge in this simple function. First, notice that the parameters to machine_init() represent the PowerPC general-purpose registers r3 through r7.[107] You saw that they were initialized just before the machine language call to machine_init. As you can see from Listing 16-5, these register values are passed unmodified to platform_init(). We need to modify this function for our platform. (We have more to say about that in a moment.)
Listing 16-5 also contains some machine-specific calls for power-management functions. If your kernel is configured for PowerPC 6xx support (CONFIG_6xx defined in your .config file), a pointer to a machine-specific power-management function (ppc6xx_idle) is stored in a structure. Similarly, if your kernel is configured for a PowerPC G5 core (CONFIG_POWER4), a pointer to its machine-specific power-management routine is stored in the same structure member. This structure is described in Section 16.3.3, "Machine-Dependent Calls."
- Initialization and association
- Kernel setup
- 3.4.2 RTOS Initialization
- Kernel Address Space
- Loading the Linux Kernel
- Understanding init Scripts and the Final Stage of Initialization
- Using the BIOS and Kernel to Tune the Disk Drives
- Kernel
- CHAPTER 36 Kernel and Module Management
- The Linux Kernel
- Types of Kernels
- Kernel Versions