Microcontroller Simulating Linux Auto Initialization Process

Follow+Star Public Account, don’t miss exciting content
Microcontroller Simulating Linux Auto Initialization Process
Source | Embedded Mixed Pot

Typically, when we write programs, we follow this pattern: executing one function after another in a logical sequence.

Microcontroller Simulating Linux Auto Initialization Process

If the logic is very complex and involves many modules, then this sequential execution code can become quite bulky, with tight coupling between modules. In the Linux kernel, with various peripheral drivers, it is almost impossible to execute in a sequential logical manner.

The kernel code can be so extensive yet organized, effectively separating various layers and modules, while a large amount of code is logically organized together. This has a crucial role in the initcall.

By mimicking this approach, we can ultimately clear the code in the main function shown in the image, separate this logic, and achieve the same functionality.

To realize this functionality, some background knowledge is needed:

1. Organization of program code

2. Knowledge related to linker scripts.

3. Application of function pointers.

Microcontroller Simulating Linux Auto Initialization Process

1. Code organization, as shown in the image, we need to know where the variables a, b, and function pointers f, f2 are stored in the program’s segments. You can refer to this article on STM32 startup code implementation | C language. The aforementioned a, f are stored in the bss segment, while b, f2 are stored in the data segment, as they have been given initial values. Implementing this initcall will place the data that needs to be automatically initialized into a custom segment, such as .initcall.

To place data into specific segments, we need to use the attribute((section)) keyword to change the data storage segment.

The current program compilation utilizes these segments, with the exception of .isr_vector, which is also added; the rest are defaults from the compiler.

Microcontroller Simulating Linux Auto Initialization Process

First, add segment code:

Microcontroller Simulating Linux Auto Initialization Process

Of course, this is not enough; we also need to tell the linker (LD) to link the .initcall segment into the program, so this modification is necessary.

Microcontroller Simulating Linux Auto Initialization Process

This segment is aligned to 8 bytes, defining two global variables, and links these data in order from 0-5. With these two modifications, let’s take a look at the status of each segment in the program.

As shown in the image:

Microcontroller Simulating Linux Auto Initialization Process

The newly added red box indicates the .initcalls segment, which totals 8 bytes, starting from 0x80005a8.

Now let’s examine the specifics of this segment using the readelf tool.

Microcontroller Simulating Linux Auto Initialization Process

It matches the size tool above, while the address in the green box is SystemInit(0x08000231, little-endian).

Microcontroller Simulating Linux Auto Initialization Process

Thus, by using attribute and modifying the linker script, we have placed the function pointer variables into the .initcall segment.

How do we call this function? Similar to the initialization of data segment data, we traverse this segment, retrieve the function address, forcibly convert the address in the segment to a function pointer, and then directly call it.

Microcontroller Simulating Linux Auto Initialization Process
Microcontroller Simulating Linux Auto Initialization Process

The implemented image shows that the function address is retrieved from the .initcall segment and called directly. It is very easy to confuse the function’s address with that of the function pointer variable.

Modifying the code this way allows for automatic initialization functions to be called, but writing a long line such as static initcall_t __ attribute__(( __ used__,__ section__(“.initcall.0.init”))) every time is not comfortable. In the Linux kernel, macros are used for modifications.

This is similar.

Microcontroller Simulating Linux Auto Initialization Process

Add macros to execute according to the program’s logical sequence:

0. low_level_init, for example, to initialize the basic system clock

1. arch_init, for example, to initialize CPU architecture and NVIC.

2. dev_init, for peripheral module initialization, such as i2c, flash, spi, etc.

3. board_init, to set specific hardware board settings.

4. os_init, for operating system settings like file systems, network stacks, etc.

5. app_init, to finally run user programs.

Modify your own program to use macros instead. By doing this, calling do_initcalls will execute in order from 0, 1 to 5.

Microcontroller Simulating Linux Auto Initialization Process
Microcontroller Simulating Linux Auto Initialization Process

Finally, let’s take a look at the initcall segment:

Microcontroller Simulating Linux Auto Initialization Process
Microcontroller Simulating Linux Auto Initialization Process
Microcontroller Simulating Linux Auto Initialization Process
Microcontroller Simulating Linux Auto Initialization Process

Now, as long as you add similar to dev_init(), app_init() for automatic initialization functions, they will be automatically called without needing to execute each one sequentially in the main function.

For example, the initialization controlled by i2c is placed in dev_init, and many i2c slaves are connected below. Each slave can be initialized using app_init, even if a new one comes along, it can also be initialized with app_init without changing the original, achieving a high degree of separation between modules.

This successfully simulates the Linux kernel initialization, and finally, the library is included.

https://gitee.com/android_life/stm32_freertos_opensource/tree/master/bareos/initcall

Those interested can take a look, as well as follow and share.

Original: https://www.toutiao.com/a6906858875912307203/?log_from=16f51be0430a9_1647178471075

Disclaimer: The materials in this article are sourced from the internet, and copyright belongs to the original author. If there are copyright issues, please contact me for deletion.

———— END ————

Microcontroller Simulating Linux Auto Initialization Process

● Column “Embedded Tools”

● Column “Embedded Development”

● Column “Keil Tutorials”

● Selected Tutorials for Embedded Column

Follow the public account reply “Join Group” to join the technical exchange group according to the rules, reply “1024” to see more content.

Microcontroller Simulating Linux Auto Initialization Process

Microcontroller Simulating Linux Auto Initialization Process

Click “Read Original” to see more shares.

Leave a Comment