Platform introduction
Development board: tiny4412ADK + S700 + 4GB Flash
Kernel version to be transplanted: Linux-4.4.0 (supports device tree)
u-boot version: U-Boot 2010.12 that comes with Friendly Arm (some changes have been made to support uImage startup)
busybox version: busybox 1.25
Cross-compilation tool chain: arm-none-linux-gnueabi-gcc
(gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29))
Notice
Continue above.
So far, the board is up and running, and then the driver can be transplanted according to the board's conditions. I’ll do this later. Here’s some knowledge I gained during the tossing process to share.
1. Device tree decompilation
When we execute make dtbs in the kernel directory, some .dtb files will be generated under arch/arm/boot/dts. So what is in this file? We can use the dtc command to decompile these dtb files. The executable program dtc here has been provided in the Linux kernel source code. The specific path is: scripts/dtc/. You can use the following command to compile this tool from the Linux source code:
make CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm scripts
This will generate the executable program dtc under scripts/dtc.
Of course, if you do not have the Linux source code, you can also use the apt-get command to install this tool. The command is as follows:
sudo apt-get install device-tree-compiler
The following takes exynos4412-tiny4412.dtb as an example:
Order:
dtc -I dtb -O dts -o tiny4412.dts arch/arm/boot/dts/exynos4412-tiny4412.dtb
Then the decompiled file tiny4412.dts will be generated, part of which is as follows:
/dts-v1/;
/ {
#address-cells = <;0x1>;
#size-cells = <;0x1>;
interrupt-parent = <;0x1>;
compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
model = "FriendlyARM TINY4412 board based on Exynos4412";
chosen {
stdout-path = "/serial@13800000";
bootargs = "root=/dev/ram0 rw rootfstype=ext4 console=ttySAC0,115200 init=/linuxrc earlyprintk";
};
aliases {
spi0 = "/spi@13920000";
spi1 = "/spi@13930000";
spi2 = "/spi@13940000";
i2c0 = "/i2c@13860000";
i2c1 = "/i2c@13870000";
i2c2 = "/i2c@13880000";
i2c3 = "/i2c@13890000";
i2c4 = "/i2c@138A0000";
i2c5 = "/i2c@138B0000";
i2c6 = "/i2c@138C0000";
i2c7 = "/i2c@138D0000";
i2c8 = "/i2c@138E0000";
csis0 = "/camera/csis@11880000";
csis1 = "/camera/csis@11890000";
fimc0 = "/camera/fimc@11800000";
fimc1 = "/camera/fimc@11810000";
fimc2 = "/camera/fimc@11820000";
fimc3 = "/camera/fimc@11830000";
serial0 = "/serial@13800000";
serial1 = "/serial@13810000";
serial2 = "/serial@13820000";
serial3 = "/serial@13830000";
pinctrl0 = "/pinctrl@11400000";
pinctrl1 = "/pinctrl@11000000";
pinctrl2 = "/pinctrl@03860000";
pinctrl3 = "/pinctrl@106E0000";
fimc-lite0 = "/camera/fimc-lite@12390000";
fimc-lite1 = "/camera/fimc-lite@123A0000";
mshc0 = "/mmc@12550000";
};
memory {
device_type = "memory";
reg = <0x40000000 0x40000000>;
};
clock-controller@03810000 {
compatible = "samsung,exynos4210-audss-clock";
reg = <0x3810000 0xc>;
#clock-cells = <;0x1>;
linux,phandle = <;0x2>;
phandle = <;0x2>;
};
i2s@03830000 {
This method is very helpful for learning device trees.
2. Print information in u-boot
In many files in u-boot, debug(...) is used to print information. By default, these logs cannot be printed. The definition of this function is in include/common.h:
#ifdef DEBUG
#define debug(fmt,args...) printf (fmt ,##args)
#define debugX(level,fmt,args...) if (DEBUG>=level) printf(fmt,##args);
#else
#define debug(fmt,args...)
#define debugX(level,fmt,args...)
#endif /* DEBUG */
So you can add #define DEBUG at the top of the C file that calls the debug function. This method is also commonly used in the Linux kernel and Android.
3. Open the early log of Linux kernel startup
Sometimes, after bootm is executed in u-boot, the serial port does not output any information after the start kernel is printed. At this time, you need to open the early kernel log:
make menuconfig
Kernel hacking --->
[*] Kernel low-level debugging functions (read help!)
Kernel low-level debugging port (Use Samsung S3C UART 0 for low-level debug)
[*] Early printk
For earlyprintk, you need to add the parameter earlyprintk in bootargs to take effect. With the above configurations, the following macros will take effect:
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_S3C_UART0=y
CONFIG_DEBUG_LL_INCLUDE="debug/exynos.S"
CONFIG_DEBUG_UNCOMPRESS=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_EARLY_PRINTK=y
The analysis of earlyprintk is in the file arch/arm/kernel/early_printk.c:
1: extern void printch(int);
2:
3: static void early_write(const char *s, unsigned n)
4: {
5: while (n-- >; 0) {
6: if (*s == 'n')
7: printch('r');
8: printch(*s);
9: s++;
10: }
11: }
12:
13: static void early_console_write(struct console *con, const char *s, unsigned n)
14: {
15: early_write(s, n);
16: }
17:
18: static struct console early_console_dev = {
19: .name = "earlycon",
20: .write = early_console_write,
21: .flags = CON_PRINTBUFFER | CON_BOOT,
22: .index = -1,
23: };
24:
25: static int __init setup_early_printk(char *buf)
26: {
27: early_console = &;early_console_dev;
28: register_console(&;early_console_dev);
29: return 0;
30: }
31:
32: early_param("earlyprintk", setup_early_printk);
Among them, printch is implemented through assembly language.
You can see this in arch/arm/Kconfig.debug:
config DEBUG_LL
bool "Kernel low-level debugging functions (read help!)"
depends on DEBUG_KERNEL
help
Say Y here to include definitions of printascii, printch, printhex
in the kernel. This is helpful if you are debugging code that
executes before the console is initialized.
config DEBUG_S3C_UART0
depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 0 for low-level debug"
help
Say Y here if you want the debug print routines to direct
their output to UART 0. The port must have been initialised
by the boot-loader before use.
config DEBUG_LL_INCLUDE
string
……
default "debug/exynos.S" if DEBUG_EXYNOS_UART
config EARLY_PRINTK
bool "Early printk"
depends on DEBUG_LL
help
Say Y here if you want to have an early console using the
kernel low-level debugging functions. Add earlyprintk to your
kernel parameters to enable this console.
From the above information we can know:
When the serial port terminal has not been registered, the kernel defines printascii, printch and printhex for debugging;
The early console also uses the function defined above. You need to add the earlyprintk parameter to the parameters passed to the kernel.
The output serial port of the early print function of the Linux kernel must be consistent with that used under u-boot, that is, the kernel is no longer responsible for initialization and lets u-boot do it, so the two must be consistent, otherwise the print functions and earlyprintk will not work. Output information;
You can refer to arch/arm/kernel/debug.S, printascii, printch and printhex are all defined here;
After the kernel enters the C function (start_kernel), you can call early_print to print information. It is defined in arch/arm/kernel/setup.c:
1: void __init early_print(const char *str, ...)
2: {
3: extern void printascii(const char *);
4: char buf[256];
5: va_list ap;
6:
7: va_start(ap, str);
8: vsnprintf(buf, sizeof(buf), str, ap);
9: va_end(ap);
10:
11: #ifdef CONFIG_DEBUG_LL
12: printascii(buf);
13: #endif
14: printk("%s", buf);
15: }
As you can see, early_print will also call printascii and printk, which means that the information printed with early_print may appear repeatedly on the terminal (printk will buffer part of it, and when bootconsole is registered, the content in the printk buffer will be output).
The printing function mentioned above can only be used in functions after kernel self-decompression. So can the information during the kernel self-decompression process also be printed? Yes, the files related to kernel self-extraction are under arch/arm/boot/compressed/, which we are familiar with:
Uncompressing Linux... done, booting the kernel.
It is printed by the code in this directory. The specific code is as follows:
arch/arm/boot/compressed/misc.c
1: void
2: decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
3: unsigned long free_mem_ptr_end_p,
4: int arch_id)
5: {
6: ......
7: putstr("Uncompressing Linux...");
8: ret = do_decompress(input_data, input_data_end - input_data,
9: output_data, error);
10: ......
11: putstr(" done, booting the kernel.n");
12: }
Among them, putstr is defined as follows:
1: static void putstr(const char *ptr)
2: {
3: char c;
4:
5: while ((c = *ptr++) != '') {
6: if (c == 'n')
7: putc('r');
8: putc(c);
9: }
10:
11: flush();
12: }
putc is implemented in assembly, arch/arm/boot/compressed/debug.S:
1: #include CONFIG_DEBUG_LL_INCLUDE
2:
3: ENTRY(putc)
4: addruart r1, r2, r3
5: waituart r3, r1
6: senduart r0, r1
7: busyuart r3, r1
8: mov pc, lr
9: ENDPROC(putc)
10:
11:
The implementation of addruart varies depending on the SOC. For exynos4412, its implementation is (arch/arm/include/debug/exynos.S):
1: .macro addruart, rp, rv, tmp
2: mrc p15, 0, tmp, c0, c0, 0
3: and tmp, tmp, #0xf0
Previous article:Linux kernel transplantation based on tiny4412 (supports device tree) (2)
Next article:Linux kernel transplantation based on tiny4412--DM9621NP network card driver transplantation (4)
Recommended ReadingLatest update time:2024-11-16 08:36
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- 【Running posture training shoes】No.005-Posture recognition and step frequency calculation
- 【TMS320 frequency measurement】Newbie's second post! TMS320F28379D Launchpad environment configuration
- CC1310 switching rate method
- Experience in using arrays, strnpy functions, and atoi functions in DSP projects
- Continuous integration plus self-shielding-5G RF focus
- The location of the essence chapter affects its use
- [NUCLEO-L552ZE review] + HLK-V20 speech recognition module experiment
- [Zhongke Bluexun AB32VG1 RISC-V board "run into" RTT evaluation] ADC
- dxp
- How to timestamp ZigBee mac layer data