1. 程式人生 > >開啟Linux核心啟動早期的log

開啟Linux核心啟動早期的log



開啟Linux核心啟動早期的log

有時會遇到當在u-boot中執行完bootm後,打印出start kernel後串列埠就沒有再輸出任何資訊了。此時就需要開啟核心早期的log

makemenuconfig

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

對於earlyprintk,還需要在bootargs

中新增引數earlyprintk才能生效,有了上面這幾個配置,會有下面幾個巨集生效:

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

關於earlyprintk的解析在檔案arch/arm/kernel/early_printk.c中:

1: extern void printch(int)

;

2:

3:static voidearly_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 __initsetup_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);

其中printch都是通過組合語言實現的。

arch/arm/Kconfig.debug中可以看到:

configDEBUG_LL
bool "Kernel low-level debuggingfunctions (read help!)"
depends on DEBUG_KERNEL
help
Say Y here to include definitions of printascii,printch, printhexin the kernel.This is helpful if you aredebugging code that executes beforethe console is initialized.

configDEBUG_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 printroutines to direct
their output to UART 0. The portmust have been initialised by the boot-loaderbefore use.

configDEBUG_LL_INCLUDE
string
…… default "debug/exynos.S" ifDEBUG_EXYNOS_UART

configEARLY_PRINTK
bool "Early printk"
depends on DEBUG_LL
help
Say Y here if you want to have an earlyconsole using the
kernel low-level debuggingfunctions. Addearlyprintk to your kernel parametersto enable this console.

從上面的資訊我們可以知道:

·在串列埠終端尚未註冊時,核心定義了printasciiprintch以及printhex用於除錯;

·early console使用的也是上面定義的函式,需要在傳遞給核心的引數中新增earlyprintk引數

·Linux核心早期的print函式的輸出串列埠要跟u-boot下使用的一致,即核心不再負責初始化了,讓u-boot來做,所以二者一定要一致,否則那些print函式以及earlyprintk都沒法輸出資訊;

·可以參考arch/arm/kernel/debug.Sprintasciiprintch以及printhex都是在這裡定義的;

·kernel進入C函式(start_kernel)後可以呼叫early_print來列印資訊,它是在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: }

可以看到,early_print也會呼叫printasciiprintk,意思是用early_print列印的資訊可能會重複出現在終端上(printk會緩衝一部分,bootconsole註冊後,會將printk緩衝區中的內容輸出)。

上面所說的列印函式只能在核心自解壓後的函式中才能使用,那麼核心自解壓過程中的資訊是不是也可以列印呢?可以,核心自解壓相關的檔案在arch/arm/boot/compressed/下面,我們所熟知的:

Uncompressing Linux... done, booting the kernel.

就是這個目錄下的程式碼打印出來的,具體程式碼如下:

arch/arm/boot/compressed/misc.c

1: void

2: decompress_kernel(unsigned long output_start, unsigned longfree_mem_ptr_p,

3:unsigned longfree_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: }

其中,putstr的定義如下:

1: static void putstr(const char *ptr)

2: {

3:char c;

4:

5:while ((c = *ptr++) != '\0') {

6:if (c =='\n')

7:putc('\r');

8:putc(c);

9:}

10:

11:flush();

12: }

putc是彙編實現的,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:movpc, lr

9: ENDPROC(putc)

10:

11:

其中addruart的實現因soc的不同而不同,對於exynos4412,它的實現是(arch/arm/include/debug/exynos.S):

1: .macro addruart, rp, rv, tmp

2:mrcp15, 0, \tmp, c0, c0, 0

3:and\tmp, \tmp, #0xf0

4:teq\tmp, #[email protected]@ A15

5:ldreq\rp, =EXYNOS5_PA_UART

6:movne\rp, #EXYNOS4_PA_UART @@ EXYNOS4

7:ldr\rv, =S3C_VA_UART

8: CONFIG_DEBUG_S3C_UART != 0

9:add\rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)

10:add\rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)

11:if

12: .endm

這個函式的目的就是獲得控制除錯uart的暫存器的物理基地址(rp)和虛擬基地址(rv),這裡也沒有初始化uart的程式碼,所以必須跟u-boot使用的串列埠一致。

相關推薦

開啟Linux核心啟動早期log

 開啟Linux核心啟動早期的log 有時會遇到當在u-boot中執行完bootm後,打印出start kernel後串列埠就沒有再輸出任何資訊了。此時就需要開啟核心早期的log: makemenuconfig Kernel hacking--->

如何調整Linux核心啟動中的驅動初始化順序-驅動載入優先順序

轉載自:http://zhidao.baidu.com/link?url=adCsiTiI7i3QVYrTx19jkt_FvBV2VlQ4NV18pEu6Kdi4Yhv0ryauD3LHj1pxGE-YP8M_PxZnHNy-hVKBvzJOkPfqehZmR9CQm5GZ5XZDx-O Lin

Linux核心啟動過程分析(十)-----RTC驅動分析

參考https://blog.csdn.net/xuao20060793/article/details/46433263這篇博文 RTC驅動分析: Class.c (drivers\rtc):subsys_initcall(rtc_init); static int __init

Linux核心啟動第二階段之setup_arch函式分析

轉自:http://blog.chinaunix.net/uid-20672257-id-2383451.html 執行setup_arch()函式 回到start_kernel當中,569行,呼叫setup_arch函式,傳給他的引數是

Linux核心啟動流程分析(一)

1. 依據arch/arm/kernel/vmlinux.lds 生成linux核心原始碼根目錄下的vmlinux,這個vmlinux屬於未壓縮,帶除錯資訊、符號表的最初的核心,大小約23MB;  命令:arm-linux-gnu-ld -o vmlinux -T a

linux核心啟動中的初始化

                轉自 http://blog.csdn.net/mayaoyao11/article/details/6636977 【問題】 此處我要實現的是將晶片的ID用於網絡卡MAC地址,網絡卡驅動是enc28j60_init。 但是,讀取晶片ID的函式,在as352x_afe

開啟linux核心自帶的模擬i2c-gpio模組過程

首先我們要知道核心的makefile是根據配置檔案,也就是kconfig來決定是否編譯一個檔案的。 如果沒有配置核心編譯它,就不會生成.o檔案。 自然就不會開啟這個模組了。 如下是Kconfig 檔

omapl138移植uboot系列之修改移植TI官方移植的Linux核心(啟動核心第二篇)

修改Linux核心原始碼     實際上,剛剛我們已經成功的啟動了TI移植過的Linux核心,但是從串列埠控制檯的現象來看,“Starting Kernel”之後什麼資訊都沒有輸出,這就需要我們在TI移植過的核心原始碼之上進行相應修改,以適合我們的639A板卡。

Android 8.0 系統啟動流程之Linux核心啟動--kernel_init程序(三)

    在上一篇文章中詳細的分析了kthreadd程序的啟動,init程序也是有idle程序去觸發啟動的,init程序分為前後兩部分,前一部分是在核心啟動的,主要是完成建立和核心初始化工作,內容都是跟Linux核心相關的;後一部分是在使用者空間啟動的,主要完成A

linux 核心啟動錯誤和selinux引數 Kernel panic -not syncing:Attempted to kill init

今天在裝某個軟體的時候,修改了selinux引數。修改selinux 的某個引數值為Disable。導致 linux系統不能啟動。出現如下錯誤 Kernel panic -not syncing:Attempted to kill init! 後經過向群友請教和

國嵌視訊學習---linux核心啟動流程

一、核心檔案uImage的構成 uImage:Uboot header和zImage zImage:解壓程式碼和壓縮後的vmlinux映象 二、zImage核心的構成 其中解壓程式碼由Head.s和misc.s組成。 三、vmlinux核心構成 1.啟動程式碼部分:

Linux核心啟動資訊能過串列埠輸出

只需要在GRUB的配置檔案中加上核心引數 console=tty0 console=ttyS0,115200,如下 linux    /boot/vmlinuz-3.0.0-15-generic root=UUID=eb9f0676-556e-42c2-9681-52d7c

Linux核心啟動過程概述 Linux核心啟動過程概述

Linux核心啟動過程概述    版權宣告:本文原創,轉載需宣告作者ID和原文連結地址。     Hi!大家好,我是CrazyCatJack。今天給大家帶來的是Linux核心啟動過程概述。希望能夠幫助大家更好的理解Linux核心的啟動,並且創造出自己的核

用Source Insight開啟linux核心原始碼

用Source Insight開啟linux核心原始碼 2008-01-09 19:06 Linux的核心原始碼可以從很多途徑得到。一般來講,在安裝的linux系統下,/usr/src/linux目錄下的東西就是核心原始碼。另外還可以從互連網上下載,解壓縮後文件一般也都位於linux目錄下。核心原始碼有很多

使用gdb跟蹤Linux核心啟動過程

孫業毅 原創作品 轉載請註明出處 第三講構造一個簡單的Linux系統MenuOS  @2015.03 1. 背景介紹 這節課的實驗是使用gdb除錯執行一個簡單的Linxu系統,使用的實驗樓提供的虛擬機器環境(http://www.shiyanlou.com/cou

linux 核心啟動流程(涉及到根檔案系統的問題)

Linux核心啟動及檔案系統載入過程 當u-boot開始執行bootcmd命令。就進入Linux核心啟動階段,與u-boot類似,普通Linux核心的啟動過程也能夠分為兩個階段,但針對壓縮了的核心如uImage就要包含核心自解壓過程了。本文以linux-2.6.37版原始

Linux 核心啟動資訊的列印 --- dev_driver_string函式/dev_name函式

核心啟動時,常會打印出一些資訊:開頭是 "驅動模組的名字: + 具體的資訊"如:在執行的linux系統裝置上,插入滑鼠,就會打印出滑鼠的相關資訊;[ 402.134068] input: USB Optical Mouse as /devices/soc0/soc/2100

linux 核心啟動除錯

使用printascii() 函式 除錯啟動資訊printascii輸出 1.配置核心除錯 DEBUG_LL 2在需要的地方增加函式外部宣告及引用 /****************************************/ 在booting the kernel 之後Kernel 最先執行的是st

控制Linux核心啟動中的列印

如果正常配置了輸入輸出終端,則核心啟動過程中會將很多資訊輸出到控制檯上。這些資訊中有些表示嚴重錯誤,有些只是一般的提示資訊。 在平臺成熟後,繼續保留這些資訊既不美觀,也會影響啟動速度(串列埠的波特率很低)。因此要儘量遮蔽不重要的資訊。這需要對核心進行一些改造。

Linux Kernel Boot Parameters(Linux核心啟動引數)

The following is a consolidated list of the kernel parameters as implemented (mostly) by the __setup() macro and sorted into English D