日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

你知道kernel version的实现原理和细节吗

發布時間:2023/12/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 你知道kernel version的实现原理和细节吗 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

kernel 啟動時通常會看到下面第二行信息的內容,它們代表了當前 kernel 的版本、編譯工具版本、編譯環境等信息。

Booting?Linux?on?physical?CPU?0x0 Linux?version?5.4.124+?(funny@funny)?(gcc?version?6.5.0?(Linaro?GCC?6.5-2018.12))?#30?SMP?Sat?Sep?11?11:10:28?CST?2021 ......

要知道,系統啟動過程中的任何一條打印信息,都是經過了無數次討論和驗證才呈現在大家的面前。看似無關緊要的一條信息,但背后卻隱藏著非常有趣的故事。

為什么要打印version信息

當系統啟動之后有很多種方式能夠確定內核版本號信息,在嵌入式或安卓 kernel 系統下,查看版本信息:

  • uname

[root@cpu?]#?uname?-a Linux?cpu?5.4.124+?#30?SMP?Sat?Sep?11?11:10:28?CST?2021?armv7l?GNU/Linux [root@cpu?]#
  • proc/version

[root@cpu?]#?cat?/proc/version Linux?version?5.4.124+?(funny@funny)?(gcc?version?6.5.0?(Linaro?GCC?6.5-2018.12))?#30?SMP?Sat?Sep?11?11:10:28?CST?2021 [root@cpu?]#

在發行版 linux 系統環境下,還可以用下面的命令查看版本信息:

  • hostnamectl

funny@funny:~$?hostnamectlStatic?hostname:?funnyIcon?name:?computer-vmChassis:?vm...Virtualization:?vmwareOperating?System:?Ubuntu?16.04.7?LTSKernel:?Linux?4.15.0-142-genericArchitecture:?x86-64 funny@funny:~$
  • lsb_release

No?LSB?modules?are?available. Distributor?ID:?Ubuntu Description:????Ubuntu?16.04.7?LTS Release:????????16.04 Codename:???????xenial

以上方法都是系統啟動正常、加載完文件系統之后使用的。
那么,系統啟動過程中是否有必要打印內核版本信息呢?答案是完全有必要。


例如下面列出的幾種應用場景:

  • SoC 芯片的 kernel 適配

  • 可裝載驅動程序調試

  • 多分支內核版本加載

  • 內核偽裝

  • kernel version實現原理

    kernel version這條打印信息來源于start_kernl()中的linux_banner字符串。

    asmlinkage?__visible?void?__init?start_kernel(void) { ...boot_cpu_init();page_address_init();pr_notice("%s",?linux_banner); ...

    這里的banner好比是ubuntu系統里的ssh登錄橫幅一樣,呈現了系統的一些基本信息。

    Welcome?to?Ubuntu?16.04.7?LTS?(GNU/Linux?4.15.0-142-generic?x86_64)*?Documentation:??https://help.ubuntu.com*?Management:?????https://landscape.canonical.com*?Support:????????https://ubuntu.com/advantage*?Super-optimized?for?small?spaces?-?read?how?we?shrank?the?memoryfootprint?of?MicroK8s?to?make?it?the?smallest?full?K8s?around.https://ubuntu.com/blog/microk8s-memory-optimisation ...

    banner字符串的定義位于init/version.c中,注意,它是一個只讀字符串,不要去修改它。

    const?char?linux_banner[]?="Linux?version?"?UTS_RELEASE?"?("?LINUX_COMPILE_BY?"@"LINUX_COMPILE_HOST?")?("?LINUX_COMPILER?")?"?UTS_VERSION?"\n";

    由以下幾部分組成:

    • UTS_RELEASE
      對應"5.4.124+"

    • LINUX_COMPILE_BY
      對應"funny",我的編譯機funny

    • LINUX_COMPILE_HOST
      對應"funny",我的編譯機Host是funny

    • LINUX_COMPILER
      對應"gcc version 6.5.0 (Linaro GCC 6.5-2018.12"

    • UTS_VERSION
      對應"#30 SMP Sat Sep 11 11:10:28 CST 2021"
      UTS:Unix Time Stamp,從這個名字可以看出linux中的UNIX印記。

    接下來對這些字符串逐條進行解析

    上面這些宏的第一級定義位于./scripts/mkcompile_h文件中。

    {?echo?/\*?This?file?is?auto?generated,?version?$VERSION?\*/if?[?-n?"$CONFIG_FLAGS"?]?;?then?echo?"/*?$CONFIG_FLAGS?*/";?fiecho?\#define?UTS_MACHINE?\"$ARCH\"echo?\#define?UTS_VERSION?\"`echo?$UTS_VERSION?|?$UTS_TRUNCATE`\"echo?\#define?LINUX_COMPILE_BY?\"`echo?$LINUX_COMPILE_BY?|?$UTS_TRUNCATE`\"echo?\#define?LINUX_COMPILE_HOST?\"`echo?$LINUX_COMPILE_HOST?|?$UTS_TRUNCATE`\"echo?\#define?LINUX_COMPILER?\"`$CC?-v?2>&1?|?grep?'?version?'?|?sed?'s/[[:space:]]*$//'`\" }?>?.tmpcompile

    UTS_VERSION

    UTS_VERSION="#$VERSION" CONFIG_FLAGS="" if?[?-n?"$SMP"?]?;?then?CONFIG_FLAGS="SMP";?fi if?[?-n?"$PREEMPT"?]?;?then?CONFIG_FLAGS="$CONFIG_FLAGS?PREEMPT";?fi if?[?-n?"$PREEMPT_RT"?]?;?then?CONFIG_FLAGS="$CONFIG_FLAGS?PREEMPT_RT";?fi UTS_VERSION="$UTS_VERSION?$CONFIG_FLAGS?$TIMESTAMP"

    LINUX_COMPILE_BY
    LINUX_COMPILE_HOST
    LINUX_COMPILER

    if?test?-z?"$KBUILD_BUILD_USER";?thenLINUX_COMPILE_BY=$(whoami?|?sed?'s/\\/\\\\/')elseLINUX_COMPILE_BY=$KBUILD_BUILD_USERfiif?test?-z?"$KBUILD_BUILD_HOST";?thenLINUX_COMPILE_HOST=`hostname`elseLINUX_COMPILE_HOST=$KBUILD_BUILD_HOSTfi

    UTS_RELEASE --- 重點分析這個宏的來源
    這是一個在kernel頂層Makefile中定義的一個宏,如下:

    uts_len?:=?64 define?filechk_utsrelease.hif?[?`echo?-n?"$(KERNELRELEASE)"?|?wc?-c?`?-gt?$(uts_len)?];?then?\echo?'"$(KERNELRELEASE)"?exceeds?$(uts_len)?characters'?>&2;????\exit?1;?????????????????????????????????????????????????????????\fi;???????????????????????????????????????????????????????????????\echo?\#define?UTS_RELEASE?\"$(KERNELRELEASE)\" endef

    提高make的打印等級可以看到,上面的腳本內容經過翻譯之后如下:

    if?[?`echo?-n?"5.4.124+"?|?wc?-c?`?-gt?64?];?then?echo?'"5.4.124+"?exceeds?64?characters'?>&2;?exit?1;?fi;?echo?\#define?UTS_RELEASE?\"5.4.124+\";?}

    現在可以確定KERNELRELEASE就是從kernel.release文件中獲取到的。打開kernel.release確認一下:

    其中KERNELRELEASE對應5.4.124+。


    KERNELRELEASE又是怎么來的呢?
    KERNELRELEASE同樣也是在Makefile中定義的、自動生成的字符串,它可以在多個地方被修改。在Makefile中查找KERNELRELEASE字符串,看見它是由下面這條命令生成的。

    KERNELRELEASE?=?$(shell?cat?include/config/kernel.release?2>?/dev/null)

    這條命令里的2>/dev/null的含義是:若cat失敗即沒有取到文件內容,那么將錯誤信息輸出到黑洞文件。
    通過下面命令驗證:

    funny@funny:~$?cat?funny.txt funny??yeah funny@funny:~$?B=$(cat?funny.txt?2>?/dev/null) funny@funny:~$?echo?$B funny??yeah funny@funny:~$

    一切準備就緒之后,通過下面的代碼將UTS_RELEASE更新到utsrelease.h中。

    1195?include/generated/utsrelease.h:?include/config/kernel.release?FORCE 1196?????????$(call?filechk,utsrelease.h)

    其中filechk的定義位于scripts/Kbuild.include

    define?filechk$(Q)set?-e;?????????????????????????????????????????????\mkdir?-p?$(dir?$@);?????????????????????????????????????\trap?"rm?-f?$(dot-target).tmp"?EXIT;????????????????????\{?$(filechk_$(1));?}?>?$(dot-target).tmp;???????????????\if?[?!?-r?$@?]?||?!?cmp?-s?$@?$(dot-target).tmp;?then???\$(kecho)?'??UPD?????$@';????????????????????????\mv?-f?$(dot-target).tmp?$@;?????????????????????\fi endef

    而utsrelease.h中內容如下:

    linux$?cat?./obj/include/generated/utsrelease.h #define?UTS_RELEASE?"5.4.124+" linux$

    這就是我們內核啟動過程中打印出來的kernel version信息。


    推薦閱讀:

    專輯|Linux文章匯總

    專輯|程序人生

    專輯|C語言

    我的知識小密圈

    關注公眾號,后臺回復「1024」獲取學習資料網盤鏈接。

    歡迎點贊,關注,轉發,在看,您的每一次鼓勵,我都將銘記于心~

    嵌入式Linux

    微信掃描二維碼,關注我的公眾號

    總結

    以上是生活随笔為你收集整理的你知道kernel version的实现原理和细节吗的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。