Pengdonglin
Email:[email protected]
Development Board: tiny4412adk+s700 4GB Flash
Host: Wind7 64-bit
Virtual machine: vmware+ubuntu12_04
U-boot:u-boot 2010.12
Linux kernel version: linux-3.0.31
Android version: android-4.1.2
Serial printing of kernel self-extracting period
When the kernel in the Zimage format is started, the kernel will be self-extracting, printing information as follows:
Uncompressing Linux ...
This sentence is in the ARCH/ARM/BOOT/COMPRESSED/MISC.C:
void Long Long Long int arch_id) { ... Putstr ("uncompressing Linux ... " ); ...}
Static voidPUTSTR (Const Char*ptr) { CharC; while((c = *ptr++)! =' /') { if(c = ='\ n') PUTC ('\ r'); PUTC (c); //According to the APCs rule, the value in C is passed to the register R0} flush ();}
Compiled misc.c are listed in Arch/arm/boot/compressed/.misc.o.cmd to depend on those files, where
DEPS_ARCH/ARM/BOOT/COMPRESSED/MISC.O: = ... Arch/arm/mach-exynos/include/mach/uncompress.h ... Arch/arm/plat-samsung/include/plat/uncompress.h ...
In MISC.C there are # include <mach/uncompress.h> refers to Arch/arm/mach-exynos/include/mach/uncompress.h
In the mach/uncompress.h: #include <plat/uncompress.h>, which means:
Arch/arm/plat-samsung/include/plat/uncompress.h
There are PUTC implementations in Arch/arm/plat-samsung/include/plat/uncompress.h:
Static voidPUTC (intch) { if(Uart_rd (S3c2410_ufcon) &S3c2410_ufcon_fifomode) { intLevel ; while(1) { level=uart_rd (S3c2410_ufstat); level&=Fifo_mask; if(Level <Fifo_max) Break; } } Else { /*Not using FIFOs*/ while((Uart_rd (s3c2410_utrstat) & s3c2410_utrstat_txe)! =S3c2410_utrstat_txe) barrier (); } /*write byte to transmission register*/uart_wr (S3C2410_UTXH, ch);}
Let's take a look at the implementation of UART_RD and UART_WR
Static__inline__voidUART_WR (unsignedintReg, unsignedintval) { volatileUnsignedint*ptr; PTR= (volatileUnsignedint*) (Reg +uart_base); *ptr =Val;}Static__inline__ unsignedintuart_rd (unsignedintreg) { volatileUnsignedint*ptr; PTR= (volatileUnsignedint*) (Reg +uart_base); return*ptr;}
As you can see, the inline function is used, and the underlying register is directly manipulated, so which UART does it operate on? We know that tiny4412 has two serial ports that can be used directly, corresponding to Uart0 and UART3 respectively. If you want to know this question, you need to see what is the value of the uart_base variable?
Or in this file:
#define Uart_base S3c_pa_uart + (S3c_uart_offset * config_s3c_lowlevel_uart_port)
Where S3c_pa_uart is the base address of the UART controller 0x13800000,exynos4412 there are altogether 5 UART, each UART accounts for S3c_uart_offset (0x10000) bytes, and a key macro config_s3c_ Lowlevel_uart_port, it specifies which UART to use, this macro can be configured when make menuconfig, here we set the
Config_s3c_lowlevel_uart_port=0
tiny4412 Serial Drive Analysis three---the kernel self-extracting in several stages of log printing