伦伦影院久久影视,天天操天天干天天射,ririsao久久精品一区 ,一本大道香蕉大久在红桃,999久久久免费精品国产色夜,色悠悠久久综合88,亚洲国产精品久久无套麻豆,亚洲香蕉毛片久久网站,一本一道久久综合狠狠老

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

深入解析Linux內核debug_kinfo驅動:為Bootloader打造的內核信息備份方案

jf_44130326 ? 來源:Linux ? 作者:Linux ? 2026-03-12 08:11 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Android/GKI(Generic Kernel Image)等基于Linux內核的系統中,bootloader往往需要獲取內核的關鍵信息以完成調試、啟動校驗等操作。debug_kinfo驅動正是為解決這一需求而生——它將內核符號表、內存布局、編譯配置等核心信息封裝并寫入預留內存區域,供bootloader直接讀取。本文將從功能定位、代碼流程、核心設計三個維度,深度剖析debug_kinfo的實現邏輯,并通過流程圖直觀呈現其核心執行路徑。

一、debug_kinfo的核心功能

debug_kinfo驅動的核心目標是標準化內核關鍵信息的存儲與傳遞,具體實現了以下核心能力:

1.收集內核編譯配置(如KALLSYMS、CFI_CLANG等開關)、符號表元數據(符號數量、地址表物理地址等);

2.記錄內核內存布局(如_stext/_etext物理地址、模塊內存區間等);

3.提供用戶態接口,支持動態寫入build信息(如版本號、編譯時間);

4.將所有信息寫入設備樹指定的預留內存區域,保證bootloader可訪問;

5.生成校驗和,確保信息完整性。

該驅動主要依賴Linux平臺總線(platform_driver)和預留內存(reserved_mem)機制實現,適配了設備樹(DTB)驅動模型,具備良好的可移植性。

二、核心數據結構:信息封裝的載體

要理解debug_kinfo的工作邏輯,首先需掌握其定義的兩個核心結構體(位于debug_kinfo.h):

1. kernel_info:內核信息本體

structkernel_info {// Kallsyms相關編譯配置__u8 enabled_all;        // 是否開啟CONFIG_KALLSYMS_ALL__u8 enabled_base_relative;   // 是否開啟CONFIG_KALLSYMS_BASE_RELATIVE__u8 enabled_absolute_percpu;  // 是否開啟CONFIG_KALLSYMS_ABSOLUTE_PERCPU__u8 enabled_cfi_clang;     // 是否開啟CONFIG_CFI_CLANG// 符號表元數據__u32 num_syms;         // 符號總數(kallsyms_num_syms)__u16 name_len;         // 符號名最大長度(KSYM_NAME_LEN)__u16 bit_per_long;       // 內核long類型位數(BITS_PER_LONG)// 物理地址信息(供bootloader尋址)__u64 _addresses_pa;      // kallsyms_addresses物理地址__u64 _relative_pa;       // kallsyms_relative_base物理地址__u64 _stext_pa;        // 內核文本段起始物理地址__u64 _etext_pa;        // 內核文本段結束物理地址// 其他關鍵信息:線程棧大小、swapper頁表物理地址、build信息、模塊布局等__u32 thread_size;       // 線程棧大?。═HREAD_SIZE)__u8 build_info[BUILD_INFO_LEN];// 構建信息(256字節)__u64 module_start_va;     // 模塊虛擬地址起始__u64 module_end_va;      // 模塊虛擬地址結束} __packed;

關鍵設計:使用__packed屬性強制按字節對齊,避免不同架構下的內存對齊差異導致bootloader解析出錯。

2. kernel_all_info:帶校驗的完整信息包

structkernel_all_info {__u32 magic_number;       // 魔數(0xCCEEDDFF),用于合法性校驗__u32 combined_checksum;    // 校驗和(異或校驗)structkernel_info info;    // 內核核心信息} __packed;

魔數用于bootloader識別有效信息區域,校驗和則通過異或運算生成,確保信息未被篡改。

三、代碼執行流程:從驅動加載到信息寫入

debug_kinfo的核心邏輯集中在debug_kinfo.c,整體流程可分為驅動初始化(probe)、信息填充用戶態接口三個階段。為了更直觀理解,先呈現整體執行流程圖:

wKgZPGmyBYeAVCqDAANgVRY9JCA047.png

階段1:驅動probe——綁定設備并初始化內存

作為platform_driver,debug_kinfo的入口是debug_kinfo_probe函數,負責完成設備綁定、預留內存校驗、信息初始化:

步驟1:解析設備樹,獲取預留內存區域

mem_region= of_parse_phandle(pdev->dev.of_node,"memory-region",0);rmem= of_reserved_mem_lookup(mem_region);

驅動從設備樹節點中讀取memory-region屬性,找到預留給bootloader的內存區域(reserved_mem)。該內存區域由內核提前分配且不參與普通內存管理,確保bootloader可直接訪問。

步驟2:校驗預留內存合法性

if(!rmem->base|| !rmem->size)return-EINVAL;if(rmem->size 

檢查預留內存的基地址、大小是否有效,且需至少容納kernel_all_info結構體(避免信息截斷)。

步驟3:映射預留內存并初始化

all_info_addr = rmem->priv; // 獲取預留內存的虛擬地址memset(all_info_addr,0,sizeof(structkernel_all_info));// 清空內存

rmem->priv是預留內存的虛擬地址(內核已完成映射),驅動先清空該區域,為后續填充信息做準備。

階段2:填充內核核心信息

probe函數的核心邏輯是將內核關鍵信息寫入kernel_info結構體,對應流程圖中I-L步驟,主要分為以下幾類:

1.編譯配置信息(宏定義展開)

info->enabled_all = IS_ENABLED(CONFIG_KALLSYMS_ALL);info->enabled_cfi_clang = IS_ENABLED(CONFIG_CFI_CLANG);

通過IS_ENABLED宏讀取內核編譯時的配置(如是否開啟符號表、CFI校驗等),將布爾值轉為u8類型存儲。

2.符號表元數據(kallsyms相關)

info->num_syms = kallsyms_num_syms; // 符號總數if (!info->enabled_base_relative) {info->_addresses_pa = (u64)__pa_symbol(kallsyms_addresses); // 物理地址} else {info->_relative_pa = (u64)__pa_symbol(kallsyms_relative_base);info->_offsets_pa = (u64)__pa_symbol(kallsyms_offsets);}

?kallsyms_addresses:內核符號地址表,__pa_symbol將虛擬地址轉為物理地址(供bootloader訪問);

?若開啟CONFIG_KALLSYMS_BASE_RELATIVE,則存儲相對基地址和偏移量表,而非絕對地址表。

3.內核內存布局信息

info->_stext_pa = (u64)__pa_symbol(_stext); // 文本段起始物理地址info->_etext_pa = (u64)__pa_symbol(_etext); // 文本段結束物理地址info->_end_pa = (u64)__pa_symbol(_end);   // 內核鏡像結束物理地址info->swapper_pg_dir_pa = (u64)__pa_symbol(swapper_pg_dir);// 頁表物理地址

記錄內核核心段的物理地址,bootloader可通過這些地址定位內核鏡像位置。

4.模塊相關信息

#ifdefined(CONFIG_RANDOMIZE_BASE) && defined(MODULES_VSIZE)info->module_start_va = module_alloc_base;info->module_end_va = info->module_start_va + MODULES_VSIZE;#elifdefined(CONFIG_MODULES) && defined(MODULES_VADDR)info->module_start_va = MODULES_VADDR;info->module_end_va = MODULES_END;#elseinfo->module_start_va = VMALLOC_START;info->module_end_va = VMALLOC_END;#endif

根據內核配置,動態設置模塊的虛擬地址區間,適配不同的模塊加載策略(如地址隨機化、固定地址)。

5.生成校驗和

update_kernel_all_info(all_info);

調用update_kernel_all_info函數,通過異或運算計算kernel_info所有u32字段的校驗和,存入combined_checksum,同時設置魔數DEBUG_KINFO_MAGIC。

階段3:用戶態接口——動態寫入build信息

驅動提供了一個模塊參數build_info,支持用戶態動態寫入構建信息(如版本號、編譯時間),對應流程圖中O-S步驟:

1.定義參數操作接口

staticconststructkernel_param_opsbuild_info_op = {.set = build_info_set, // 設置函數};module_param_cb(build_info, &build_info_op,NULL,0200);

module_param_cb注冊一個回調型模塊參數,權限0200表示只有root可寫;用戶通過echo "build-info" > /sys/module/debug_kinfo/parameters/build_info即可寫入。

2.實現參數設置邏輯

staticintbuild_info_set(constchar*str,conststructkernel_param *kp){all_info = (structkernel_all_info *)all_info_addr;// 拷貝build信息(截斷過長內容)memcpy(&all_info->info.build_info, str,min(build_info_size -1,strlen(str)));update_kernel_all_info(all_info);// 重新計算校驗和// 過長時打印警告并返回錯誤if(strlen(str) > build_info_size) {pr_warn("Build info buffer can't hold entire stringn");return-ENOMEM;}return0;}

寫入build信息后,驅動會重新計算校驗和,確保bootloader讀取的信息完整性。

四、設計亮點與工程價值

1.跨階段通信的標準化

通過預留內存+固定結構體的方式,解決了內核與bootloader之間的信息傳遞問題——無需修改bootloader核心邏輯,只需按結構體解析即可獲取內核信息。

2.兼容性與可移植性

?基于platform_driver和設備樹,適配不同硬件平臺;

?使用__packed對齊、__pa_symbol地址轉換等內核通用接口,兼容不同架構(ARM/ARM64/x86);

?條件編譯適配不同內核配置(如模塊地址隨機化、KALLSYMS_BASE_RELATIVE)。

3.安全性與完整性

?魔數校驗:bootloader可通過magic_number快速識別有效信息區域;

?異或校驗和:防止內存數據被篡改,保證信息可信度。

4.可擴展性

?build_info字段支持動態寫入,適配不同場景的自定義信息需求;

?kernel_info結構體預留了擴展字段(如模塊布局偏移、percpu配置),可按需添加新信息。

五、總結

關鍵點回顧

1.debug_kinfo驅動核心是通過預留內存+標準化結構體,實現內核向bootloader傳遞關鍵信息,核心流程為“解析設備樹→校驗內存→填充信息→生成校驗→提供用戶態接口”;

2.核心設計亮點包括__packed對齊保證跨架構兼容、魔數+校驗和保證信息完整性、模塊參數支持動態寫入build信息;

3.該驅動是內核與bootloader跨階段通信的典型實現,為嵌入式系統調試、啟動校驗提供了標準化方案。

debug_kinfo驅動是Linux內核與bootloader之間的“信息橋梁”,其核心設計思路是將內核運行時的關鍵元數據標準化、物理化存儲,解決了跨執行階段的信息傳遞難題。從代碼實現來看,它充分利用了Linux內核的platform_driver、reserved_mem、模塊參數等機制,兼顧了兼容性、安全性和可擴展性。

對于嵌入式系統開發者而言,理解debug_kinfo的實現邏輯,不僅能掌握內核信息封裝的技巧,還能為定制化調試工具、bootloader適配提供參考——比如基于該驅動擴展更多內核狀態信息,或優化bootloader的內核信息解析邏輯,提升系統調試和啟動的可靠性。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    88

    文章

    11772

    瀏覽量

    219137
  • bootloader
    +關注

    關注

    2

    文章

    245

    瀏覽量

    48104
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Linux內核驅動開發的技術核心精要

    嵌入式Linux驅動開發是連接硬件與操作系統的關鍵環節。隨著內核演進(如Linux 6.13)和硬件復雜度提升,開發者需掌握并發控制、中斷分層、內存管理、設備樹、調試工具等核心知識。本
    發表于 03-10 13:56

    Linux內核的“心跳”:jiffies如何為系統計時?

    Linux 內核的世界里,有一個默默工作的 "計時器"——jiffies。它不像我們手機上的時鐘那樣顯示年月日,卻掌控著內核中絕大多數時間相關的操作:從進程調度到設備驅動的定時檢查
    的頭像 發表于 02-04 16:27 ?845次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內核</b>的“心跳”:jiffies如何為系統計時?

    深入RK3588內核:rockchip_linux_defconfig的作用與調試價值

    在 RK3588 芯片的 Linux 開發中,有一個文件始終是開發者繞不開的核心 ——kernel/arch/arm64/configs/rockchip_linux_defconfig。無論是首次
    的頭像 發表于 02-03 15:56 ?1187次閱讀
    <b class='flag-5'>深入</b>RK3588<b class='flag-5'>內核</b>:rockchip_<b class='flag-5'>linux</b>_defconfig的作用與調試價值

    深入解析rk平臺Android Bootloader核心代碼:從啟動流程到AVB驗證

    作為Android設備啟動的第一道“閘門”,Bootloader(以U-Boot為主)承擔著初始化硬件、加載內核、驗證鏡像完整性的核心職責。今天我們拆解Rockchip平臺
    的頭像 發表于 01-22 07:06 ?306次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>解析</b>rk平臺Android <b class='flag-5'>Bootloader</b>核心代碼:從啟動流程到AVB驗證

    【「Linux 設備驅動開發(第 2 版)」閱讀體驗】+讀深入理解Linux內核內存分配

    每個內存地址是虛擬的,不是直接指向RAM中的任何地址。當用戶訪問內存中的存儲單元時,都會進行地址轉換以匹配相應的物理內存。書籍的第10章討論了五個主題,對Linux內核內存分配進行詳細講解。 接著
    發表于 01-16 20:05

    【「Linux 設備驅動開發(第 2 版)」閱讀體驗】Linux內核開發基礎

    感謝電子發燒友論壇提供的《Linux設備驅動開發(第2版)》閱讀機會,測評將從Linux內核開發基礎、Linux
    發表于 01-12 22:45

    【「Linux 設備驅動開發(第 2 版)」閱讀體驗】+讀內核處理的核心輔助函數

    上周收到《Linux 設備驅動開發(第 2 版)》書籍,這是一本介紹Linux內核開發的指導性書籍。全面了解Linux
    發表于 01-10 22:08

    深入解析RK平臺Android/Linux Bootloader核心文件:android_bootloader.c

    Bootloader是Android設備啟動的第一道“關卡”,負責初始化硬件、加載系統鏡像并完成內核啟動的前置準備。在基于U-Boot的Android設備中,android_bootloader
    的頭像 發表于 01-09 10:58 ?1242次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>解析</b>RK平臺Android/<b class='flag-5'>Linux</b> <b class='flag-5'>Bootloader</b>核心文件:android_<b class='flag-5'>bootloader</b>.c

    深入Linux內核:進程調度的核心邏輯與實現細節

    ,背后都離不開內核調度算法的精準操控。今天,我們就從優先級、調度算法、時間片分配到底層實現,全方位拆解Linux內核進程調度的核心邏輯。 一、進程調度的“身份標識”:優先級與分類 要理解調度邏輯,首先得搞懂:進程憑什么“插隊”?
    的頭像 發表于 12-24 07:05 ?4362次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>Linux</b><b class='flag-5'>內核</b>:進程調度的核心邏輯與實現細節

    Linux內核日志玩明白了嗎?printk調試神器全解析

    前言:做Linux驅動開發或內核調試的朋友,一定對printk不陌生,但你真的會用它嗎?為什么同樣是調試RK3588內核,別人能精準捕捉關鍵錯誤,你卻被海量日志淹沒?今天就帶大家吃透p
    的頭像 發表于 12-19 08:32 ?895次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內核</b>日志玩明白了嗎?printk調試神器全<b class='flag-5'>解析</b>

    Linux內核模塊的加載機制

    ,比如當插入一個新設備時,udev會根據設備信息自動加載對應的驅動模塊。這是通過uevent事件和用戶空間的工具配合實現的,提高了設備的即插即用能力。 3、解析加載.ko文件 .ko文件
    發表于 11-25 06:59

    【迅工業RK3568穩定可靠】itop-3568開發板Linux驅動開發實戰:RK3568內核模塊符號導出詳解

    【迅工業RK3568穩定可靠】itop-3568開發板Linux驅動開發實戰:RK3568內核模塊符號導出詳解
    的頭像 發表于 11-21 13:25 ?1257次閱讀
    【迅<b class='flag-5'>為</b>工業RK3568穩定可靠】itop-3568開發板<b class='flag-5'>Linux</b><b class='flag-5'>驅動</b>開發實戰:RK3568<b class='flag-5'>內核</b>模塊符號導出詳解

    Linux內核printk日志級別全解析:從參數解讀到實操配置

    ,避免被無效信息淹沒。 二、先搞懂:什么是?printk?輸出等級? printk?是?Linux?內核
    的頭像 發表于 11-20 15:54 ?1737次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內核</b>printk日志級別全<b class='flag-5'>解析</b>:從參數解讀到實操配置

    Linux內核參數調優方案

    在高并發微服務環境中,網絡性能往往成為K8s集群的瓶頸。本文將深入探討如何通過精細化的Linux內核參數調優,讓你的K8s節點網絡性能提升30%以上。
    的頭像 發表于 08-06 17:50 ?984次閱讀

    RK3568開發板內核模塊實現-查看模塊信息

    驅動模塊加載之后,使用“modinfo helloworld.ko”命令可以獲得模塊的信息,包括模塊作者,模塊說明,模塊支持的參數等等。 lsmod 命令可以列出已經載入 Linux 內核
    發表于 05-16 11:18