linux内核earlyprink,内核启动参数机制学习笔记
前兩天把內(nèi)核關(guān)于內(nèi)核啟動(dòng)參數(shù)的一些知識(shí)徹底地分析了一遍《Linux內(nèi)核源碼分析--內(nèi)核啟動(dòng)命令行的傳遞過程(Linux-3.0 ARMv7)》,發(fā)現(xiàn)了一些以前沒有注意的細(xì)節(jié)問題,這里總結(jié)如下:
一、2.6.32以后的內(nèi)核不再對(duì)cmdline中的未知參數(shù)輸出警告信息
以前在移植內(nèi)核的時(shí)候,如果cmdline中有未知的參數(shù),內(nèi)核一般會(huì)打印如下警告:
Unknown boot option `**********': ignoring? ? 但是這次我在uboot的bootargs中添加了內(nèi)核未知的參數(shù),比如“hello_linux.tekkaman=ninja”,但是在內(nèi)核啟動(dòng)信息和dmesg中一點(diǎn)錯(cuò)誤信息都沒有,我感覺很奇怪,然后我又在同事的板子上試了下,一樣沒有任何錯(cuò)誤信息。我查了下代碼,按照邏輯,是不會(huì)有錯(cuò)誤信息輸出。哪以前怎么會(huì)有錯(cuò)誤信息?
后來我通過Git查找了內(nèi)核針對(duì)這方面的修改,發(fā)現(xiàn)了如下提交:
commit f066a4f6df68f03b565dfe867dde54dfeb26576e
Author: Rusty Russell
Date: Tue Dec 1 14:56:44 2009 +1030
param: don't complain about unused module parameters.
參數(shù):不抱怨未使用的模塊參數(shù)。
Jon confirms that recent modprobe will look in /proc/cmdline, so these
cmdline options can still be used.
喬恩證實(shí):新的modprobe會(huì)讀取/proc/cmdline,所以這些
命令行選項(xiàng)仍然可能被使用。
See
Reported-by: Adam Williamson
Cc: stable@kernel.org
Signed-off-by: Rusty Russell
Signed-off-by: Linus Torvalds
也就是說由于新版本的module-init-tool中的modprobe可以在掛外部.ko模塊的時(shí)候讀取/proc/cmdline(也就是內(nèi)核啟動(dòng)參數(shù)cmdline的備份)中的參數(shù),所有在內(nèi)核啟動(dòng)的時(shí)候還暫時(shí)未知的參數(shù)可能在系統(tǒng)運(yùn)行起來,掛載模塊的時(shí)候被使用。所以在啟動(dòng)的時(shí)候提出警告實(shí)屬不必要。所有這個(gè)警信代碼被刪除了。
這個(gè)提交的補(bǔ)丁如下:
$ git diff f066a4f6df^..f066a4f6df
diff --git a/init/main.c b/init/main.c
index 5988deb..4051d75 100644
--- a/init/main.c
+++ b/init/main.c
@@ -251,7 +251,7 @@ early_param("loglevel", loglevel);
/*
* Unknown boot options get handed to init, unless they look like
- * failed parameters
+ * unused parameters (modprobe will find them in /proc/cmdline).
*/
static int __init unknown_bootoption(char *param, char *val)
{
@@ -272,14 +272,9 @@ static int __init unknown_bootoption(char *param, char *val)
if (obsolete_checksetup(param))
return 0;
- /*
- * Preemptive maintenance for "why didn't my misspelled command
- * line work?"
- */
- if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
- printk(KERN_ERR "Unknown boot option `%s': ignoring\n", param);
+ /* Unused module parameter. */
+ if (strchr(param, '.') && (!val || strchr(param, '.') < val))
return 0;
- }
if (panic_later)
return 0;
這個(gè)提交在2.6.32發(fā)布前被并入主線:
$ git tag --contains f066a4f6df
v2.6.32
v2.6.33
v2.6.33-rc1
v2.6.33-rc2
v2.6.33-rc3
v2.6.33-rc4
v2.6.33-rc5
v2.6.33-rc6
v2.6.33-rc7
v2.6.33-rc8
就這個(gè)問題在:
點(diǎn)擊(此處)折疊或打開
From?2009-09-11 16:28:54
When passing a kernel parameter of the type:
radeon.modeset=0
the kernel will throw a warning message that says "Unknown boot option
'radeon.modeset=0'. Ignoring..." However, the parameter is not ignored, it is
passed to (and parsed by) the radeon module.
We (Fedora QA/BugZappers) find people are often confused or worried by this
message when we ask them to use such a parameter, and worry that it is not
being applied correctly. The kernel should not print this warning/error message
when the parameter is of a format that will cause it to be passed to a kernel
module.
-------Comment??From?2009-09-22 02:50:17-------
Is this because modern modprobe is scraping these options from /proc/cmdline?
If so, yes, we should suppress those messages altogether.
CC'd Jon, he'd know.
-------Comment??From?2009-09-22 04:51:52-------
I don't know how it's implemented, exactly, that may well be how it works. I
just know that you can pass any module parameter as a kernel command line
parameter in that format (modulename.moduleparameter=value) and it gets passed
on somehow.
-------Comment??From?2009-11-26 17:43:30-------
ping? this still regularly causes confusion for users when we're trying to
debug various issues, see
for a recent example: it's a 'cosmetic' bug but with unfortunate effects.
-------Comment??From?2010-03-21 12:03:01-------
Yea, exactly that's what happens. Modprobe pulls out those arguments and
processes them.
I don't know why I missed this bug, but that should be fixed now. I even have
daily reminders setup and should get CC'd on every module issue from now on.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
二、使用modprobe掛載.ko模塊可以從cmdline中獲取參數(shù)
從上面的發(fā)現(xiàn)又牽出了一個(gè)新的發(fā)現(xiàn),原來單獨(dú)編譯的內(nèi)核模塊參數(shù)是可以用modprobe掛載的時(shí)候從內(nèi)核的cmdline中獲得的。這個(gè)是我以前沒有注意到的。于是我做了個(gè)實(shí)驗(yàn):寫一個(gè)簡單的模塊(僅在init函數(shù)中打印模塊參數(shù)),然后在內(nèi)核啟動(dòng)參數(shù)中增加這個(gè)參數(shù)的初始化。經(jīng)幾次實(shí)驗(yàn),證實(shí)了這個(gè)功能。
其實(shí)通過模塊掛載的原理和模塊的二進(jìn)制結(jié)構(gòu)的了解(詳見《深入Linux內(nèi)核構(gòu)件》 第七章 模塊),可以知道:其實(shí)這個(gè)功能是modprobe實(shí)現(xiàn)的。所以實(shí)現(xiàn)這個(gè)功能的必要條件是modprobe工具必須支持從/proc/cmdline讀取字符串,并通過格式(模塊名).(變量名)=(值)過濾出參數(shù)。
這個(gè)大家特別注意一下參數(shù)的格式 :
(模塊名).(變量名)=(值)
在嵌入式中,高版本的busybox是支持的,現(xiàn)在最新的肯定支持,但是注意了,要配置busybox的時(shí)候不能選擇"簡化版的掛載工具",要配置為編譯全功能的modprobe。
在PC系統(tǒng)下也是支持的,在grub的內(nèi)核啟動(dòng)參數(shù)中添加?hello_linux.tekkaman=ninja ,再用modprobe掛載模塊。用dmesg看內(nèi)核信息就可以看到實(shí)驗(yàn)結(jié)果。實(shí)驗(yàn)用的PC信息如下:
Linux Amethyst 3.2.12-gentoo #1 SMP Mon Apr 16 14:16:04 CST 2012 i686 AMD Athlon(tm) 64 X2 Dual Core Processor 4800+ AuthenticAMD GNU/Linuxmodule-init-tools version 3.16
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
嵌入式實(shí)驗(yàn)現(xiàn)象如下:
# busybox modprobe hello_linux
Hello, Linux !
(0) Hello, ninja
# cat /proc/cmdline
console=ttyO2,115200n8 root=/dev/nfsroot nfsroot=10.10.10.2:/media/6a55c5a3-f467-4b31-a56a-73b57c5cd2a2/C6A816x/development/targetfs,nolock rw mem=176M@0x80000000 mem=39M@0x9BD00000 vram=90M notifyk.vpssm3_sva=0xBF900000 ip=10.10.10.10:10.10.10.2:0.0.1:255.255.255.0::eth0:off noinitrd earlyprink hello_linux.tekkaman=ninja實(shí)驗(yàn)代碼如下:?test_module_i686.zip
總結(jié)
以上是生活随笔為你收集整理的linux内核earlyprink,内核启动参数机制学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 3.10 内核,升级linu
- 下一篇: linux查看jvm内存被使用情况,Li