0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核代碼60%都是驅(qū)動(dòng)?

嵌入式悅翔園 ? 來(lái)源:嵌入式悅翔園 ? 2023-07-11 11:48 ? 次閱讀

一、前言

為什么Linux內(nèi)核代碼60%都是驅(qū)動(dòng)? 如果每支持新的設(shè)備就加入驅(qū)動(dòng),內(nèi)核會(huì)不會(huì)變得越來(lái)越臃腫?

要先搞明白這個(gè)問(wèn)題,我們首先要明確(區(qū)分)兩個(gè)概念:內(nèi)核代碼和內(nèi)核,這是兩個(gè)完全不一樣的概念,我們通過(guò) git clone 命令從網(wǎng)上拉取下來(lái)的代碼叫做內(nèi)核代碼,如果增加新的設(shè)備內(nèi)核代碼確實(shí)會(huì)變得越來(lái)越臃腫,這點(diǎn)是肯定的,但是內(nèi)核并不會(huì)變得臃腫,具體原因我們接下里會(huì)進(jìn)行討論。說(shuō)了那么多內(nèi)核代碼,那內(nèi)核是什么呢?為什么內(nèi)核代碼變多了內(nèi)核卻不會(huì)變大?

內(nèi)核 是我們通過(guò)交叉編譯之后真正燒錄到板子里跑起來(lái)的代碼,而交叉編譯的時(shí)候,是有選擇的進(jìn)行編譯,這里面有頂尖的大神們的智慧結(jié)晶,與你硬件相關(guān)的才編譯,不相關(guān)的代碼則不會(huì)被編譯到內(nèi)核里,所以不是說(shuō)內(nèi)核里提交了一個(gè)設(shè)備的驅(qū)動(dòng)你的內(nèi)核就會(huì)變大,這要看你的硬件有沒(méi)有用到這個(gè)驅(qū)動(dòng)。

二、Linux中避免內(nèi)核臃腫的措施

我們上面知道了內(nèi)核是經(jīng)過(guò)我們交叉編譯裁剪之后的代碼,會(huì)有選擇性的將對(duì)我們有用的代碼編譯進(jìn)內(nèi)核中,不需要的將被舍棄,這是Linux內(nèi)核開(kāi)發(fā)者智慧的結(jié)晶,也是保證內(nèi)核不會(huì)變得臃腫的原因。那除了交叉編譯之外還有沒(méi)有其他的措施來(lái)保證內(nèi)核不會(huì)變的越來(lái)越大呢?下面就給大家分享幾個(gè)用來(lái)保證內(nèi)核不臃腫的措施。

2.1 交叉編譯及SDK包的裁剪

(這部分稍微有些啰嗦,主要為了讓初學(xué)者更好的理解,老工程師可以直接跳過(guò)啦?。┙徊婢幾g是指在一種平臺(tái)上編譯生成在另一種不同平臺(tái)上運(yùn)行的可執(zhí)行程序。在Linux中,常見(jiàn)的情況是在PC主機(jī)(Ubuntu系統(tǒng))上編譯生成適用于嵌入式設(shè)備或其他架構(gòu)的目標(biāo)程序。

437e73d2-1f9d-11ee-962d-dac502259ad0.png

通過(guò)上面的介紹我們已經(jīng)知道了內(nèi)核代碼是會(huì)通過(guò)交叉編譯來(lái)進(jìn)行選擇性的將對(duì)我們有用的代碼編譯進(jìn)內(nèi)核的,但是交叉編譯到底是如何工作的呢?我們應(yīng)該怎么去配置交叉編譯以讓我們的內(nèi)核能過(guò)夠在穩(wěn)定運(yùn)行的基礎(chǔ)上盡量小巧呢?

做過(guò)嵌入式Linux的應(yīng)該都清楚,我這里的介紹也主要針對(duì)嵌入式Linux來(lái)講解,一般嵌入式Linux的交叉編譯工具鏈都是由SDK包提供商(一般是芯片廠)提供,所以一般不需要我們進(jìn)行編寫(xiě)和設(shè)計(jì),只需要針對(duì)自己開(kāi)發(fā)板的實(shí)際情況進(jìn)行裁剪即可。

其實(shí)Linux代碼到你燒錄到板子中的內(nèi)核代碼是經(jīng)過(guò)了下面的過(guò)程:

43a6c684-1f9d-11ee-962d-dac502259ad0.png

上面的圖是我對(duì)于一套代碼從Linux開(kāi)源代碼一步一步的被裁剪和適配后最終到達(dá)用戶(hù)手中過(guò)程的理解,當(dāng)然不同的廠商這個(gè)過(guò)程可能有所不同。

所以回到我們的問(wèn)題,看完上面圖片中的過(guò)程,你覺(jué)得Linux內(nèi)核中提交了新設(shè)備的驅(qū)動(dòng)代碼會(huì)被燒錄到最終燒錄到板子中嗎?

這里分幾種情況來(lái)討論:

如果這個(gè)新設(shè)備在該款芯片上完全不會(huì)用到,那么芯片廠提供的SDK包中就不會(huì)包含這個(gè)驅(qū)動(dòng);

如果這個(gè)新設(shè)備芯片是支持的,但是我這款開(kāi)發(fā)板不支持,那么板廠就不會(huì)同步這個(gè)設(shè)備的驅(qū)動(dòng);

如果這個(gè)新設(shè)備在開(kāi)發(fā)板上也是支持的,但是作為用戶(hù)完全不會(huì)用到該設(shè)備,那么該設(shè)備的驅(qū)動(dòng)也會(huì)被裁剪;

所以不是說(shuō)Linux內(nèi)核代碼中新提交一個(gè)設(shè)備驅(qū)動(dòng),該設(shè)備驅(qū)動(dòng)就會(huì)最終到開(kāi)發(fā)板中,中間是會(huì)經(jīng)過(guò)很多篩選的,只有真正對(duì)用戶(hù)有用的代碼才會(huì)被同步編譯和燒錄。

這里用戶(hù)可能會(huì)有疑問(wèn),講了半天代碼包的裁剪,代碼裁剪和交叉編譯有什么關(guān)系呢?這里還要明確一點(diǎn),代碼的裁剪并不是你想象的直接把代碼從代碼包中刪除了,更多時(shí)候是把代碼從編譯中刪除掉,即該設(shè)備的驅(qū)動(dòng)并不會(huì)被編譯到內(nèi)核中,但是源代碼你還是可以看到的。

2.2 設(shè)備樹(shù)

設(shè)備樹(shù)的由來(lái)想必大家應(yīng)該都有所耳聞:

ARM社區(qū)一貫充斥的大量垃圾代碼導(dǎo)致Linus盛怒,因此社區(qū)在2011年到2012年進(jìn)行了大量的工作。ARM Linux開(kāi)始圍繞Device Tree展開(kāi),Device Tree有自己的獨(dú)立的語(yǔ)法,它的源文件為.dts,編譯后得到.dtb,Bootloader在引導(dǎo)Linux內(nèi)核的時(shí)候會(huì)將.dtb地址告知內(nèi)核。之后內(nèi)核會(huì)展開(kāi)Device Tree并創(chuàng)建和注冊(cè)相關(guān)的設(shè)備,因此arch/arm/mach-xxx和arch/arm/plat-xxx中大量的用于注冊(cè)platform、I2C、SPI板級(jí)信息的代碼被刪除,而驅(qū)動(dòng)也以新的方式和.dts中定義的設(shè)備結(jié)點(diǎn)進(jìn)行匹配。

在設(shè)備樹(shù)出現(xiàn)之前,內(nèi)核代碼中包含了大量與硬件設(shè)備相關(guān)的配置信息和初始化操作。隨著硬件數(shù)量和多樣性的增加,內(nèi)核代碼變得越來(lái)越復(fù)雜,難以管理和維護(hù)。設(shè)備樹(shù)將硬件描述從內(nèi)核代碼中分離出來(lái),使得內(nèi)核代碼更加清晰簡(jiǎn)潔,并且與具體硬件解耦。

使用設(shè)備樹(shù)可以在運(yùn)行時(shí)動(dòng)態(tài)地配置硬件設(shè)備,而無(wú)需修改內(nèi)核源代碼。這點(diǎn)對(duì)于代碼的調(diào)試非常方便,我們自需要重新編譯設(shè)備樹(shù)文件放到開(kāi)發(fā)板中即可,而不用重新燒錄整個(gè)內(nèi)核。設(shè)備樹(shù)中的硬件描述信息可以根據(jù)實(shí)際硬件配置進(jìn)行自由組合和調(diào)整,從而達(dá)到更好的兼容性和靈活性。

2.3 模塊化

Linux內(nèi)核采用的是模塊化設(shè)計(jì),通過(guò)將功能劃分為獨(dú)立的模塊,可以提高代碼的可復(fù)用性和靈活性。內(nèi)核模塊是一段可以被動(dòng)態(tài)加載到內(nèi)核中并擴(kuò)展其功能的代碼。它相對(duì)獨(dú)立于內(nèi)核的其他部分,在需要時(shí)可以加載或卸載。

除了動(dòng)態(tài)的加載將通用的功能封裝成獨(dú)立的模塊,可以被多個(gè)子系統(tǒng)或驅(qū)動(dòng)程序共享和復(fù)用,避免了重復(fù)編寫(xiě)相同的代碼,提高了開(kāi)發(fā)效率。如果看過(guò)I2C驅(qū)動(dòng)的話(huà)大家應(yīng)該清楚I2C驅(qū)動(dòng)分為設(shè)備驅(qū)動(dòng)和核心驅(qū)動(dòng),Linux內(nèi)核已經(jīng)將I2C驅(qū)動(dòng)的公用代碼封裝到核心代碼中了,其實(shí)I2C設(shè)備驅(qū)動(dòng)代碼只需要簡(jiǎn)單的調(diào)用I2C核心驅(qū)動(dòng)中的接口即可,而不用從0開(kāi)始完成一個(gè)I2C的驅(qū)動(dòng)代碼,這樣代碼的復(fù)用率會(huì)變高,內(nèi)核驅(qū)動(dòng)的代碼量和代碼復(fù)雜度也會(huì)變小。

2.4 硬件抽象層

硬件抽象層(Hardware Abstraction Layer,HAL)是一種軟件層,用于將底層硬件設(shè)備的詳細(xì)實(shí)現(xiàn)細(xì)節(jié)與上層應(yīng)用程序隔離開(kāi)來(lái),提供一組統(tǒng)一的接口和功能,以簡(jiǎn)化對(duì)硬件的訪問(wèn)和操作。

43c67f42-1f9d-11ee-962d-dac502259ad0.png

硬件抽象層起到了在不同硬件平臺(tái)之間建立標(biāo)準(zhǔn)化接口的作用,使得應(yīng)用程序可以以相似的方式進(jìn)行硬件訪問(wèn)和控制,而無(wú)需關(guān)心具體硬件的細(xì)節(jié)。通過(guò)使用硬件抽象層,開(kāi)發(fā)人員可以更加方便地編寫(xiě)跨平臺(tái)或可移植的應(yīng)用程序,而不需要針對(duì)每個(gè)具體硬件設(shè)備進(jìn)行獨(dú)立的編程。

總的來(lái)說(shuō)硬件抽象層提供了一種中間層的軟件抽象,將底層硬件設(shè)備的具體實(shí)現(xiàn)細(xì)節(jié)與上層應(yīng)用程序解耦,為開(kāi)發(fā)人員提供簡(jiǎn)化的硬件訪問(wèn)接口和功能,以提高應(yīng)用程序的可移植性和跨平臺(tái)性。

三、嵌入式Linux的裁剪

其實(shí)本文默認(rèn)說(shuō)的Linux內(nèi)核都是說(shuō)的嵌入式Linux,因?yàn)閷?duì)于像Ubuntu這種系統(tǒng)我也不太清楚。對(duì)于嵌入式Linux的裁剪我們上面已經(jīng)介紹了整個(gè)代碼包的流程,想必大家已經(jīng)明白了我們燒錄進(jìn)去的內(nèi)核是已經(jīng)通過(guò)交叉編譯精簡(jiǎn)過(guò)的,所以理論上來(lái)說(shuō)燒錄進(jìn)去的已經(jīng)是最精簡(jiǎn)的了。

其實(shí)內(nèi)核裁剪不是我們想象的那么簡(jiǎn)單,只有道行深的工程師才敢進(jìn)行內(nèi)核的裁剪。Linux內(nèi)核裁剪我也沒(méi)有做過(guò),所以這部分我留給大佬來(lái)補(bǔ)充吧!

四、總結(jié)

所以回歸最開(kāi)始的問(wèn)題,Linux內(nèi)核代碼60%都是驅(qū)動(dòng)?驅(qū)動(dòng)代碼不會(huì)造成內(nèi)核臃腫嗎?我認(rèn)為答案是不會(huì),如果你認(rèn)為會(huì)變得越來(lái)越臃,可以一起交流一下哦!





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    601

    瀏覽量

    28136
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    317

    瀏覽量

    22078

原文標(biāo)題:Linux內(nèi)核代碼60%都是驅(qū)動(dòng)?驅(qū)動(dòng)代碼不會(huì)造成內(nèi)核臃腫嗎?

文章出處:【微信號(hào):嵌入式悅翔園,微信公眾號(hào):嵌入式悅翔園】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 0人收藏

    評(píng)論

    相關(guān)推薦

    Linux內(nèi)核代碼

    Linux內(nèi)核代碼本章講述在L i n u x內(nèi)核源碼中,應(yīng)該從何處開(kāi)始查找特定的內(nèi)核函數(shù)。本書(shū)并不要求讀者具有C語(yǔ)言編程能力,也不要求讀
    發(fā)表于 02-09 15:24 ?36次下載

    Linux內(nèi)核代碼漫游

    Linux內(nèi)核代碼漫游 本章試圖以順序的方式來(lái)解釋Linux代碼,以幫助讀者對(duì)源代碼的體系
    發(fā)表于 02-09 15:27 ?26次下載

    Linux 內(nèi)核代碼

    Linux 內(nèi)核代碼 實(shí)模式setup階段setup用于體系結(jié)構(gòu)相關(guān)的硬件初始化工作,在arch目錄中的各個(gè)系統(tǒng)結(jié)構(gòu)的平臺(tái)相關(guān)都有類(lèi)似功能的代碼。在32位的x86平臺(tái)中,s
    發(fā)表于 02-10 13:45 ?28次下載

    嵌入式LINUX內(nèi)核網(wǎng)絡(luò)棧(源代碼)

    本文選擇 LINUX-1.2.13 內(nèi)核所包含的網(wǎng)絡(luò)部分代碼分析(注意網(wǎng)絡(luò)部分代碼內(nèi)核代碼的演
    發(fā)表于 05-12 10:39 ?57次下載
    嵌入式<b class='flag-5'>LINUX</b><b class='flag-5'>內(nèi)核</b>網(wǎng)絡(luò)棧(源<b class='flag-5'>代碼</b>)

    基于Linux內(nèi)核輸入子系統(tǒng)的驅(qū)動(dòng)研究

    Linux因其完全開(kāi)放的特性和穩(wěn)定優(yōu)良的性能深受歡迎,當(dāng)推出了內(nèi)核輸入子系統(tǒng)后,更方便了嵌入式領(lǐng)域的驅(qū)動(dòng)開(kāi)放。介紹了Linux的設(shè)備驅(qū)動(dòng)基礎(chǔ)
    發(fā)表于 09-12 16:38 ?23次下載

    Linux內(nèi)核代碼感悟

    直接訪問(wèn)校內(nèi)外的 lxr 網(wǎng)站)的。如果在 windows 下也可以用 source insight。以下的當(dāng)前路徑為內(nèi)核代碼路徑,通常為/usr/src/linux內(nèi)核版本為 2
    發(fā)表于 09-11 17:01 ?18次下載
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>代碼</b>感悟

    怎樣去讀Linux內(nèi)核代碼

    怎樣去讀Linux內(nèi)核代碼
    發(fā)表于 10-25 10:15 ?13次下載
    怎樣去讀<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>源<b class='flag-5'>代碼</b>

    Linux內(nèi)核輸入子系統(tǒng)的驅(qū)動(dòng)研究

    Linux內(nèi)核輸入子系統(tǒng)的驅(qū)動(dòng)研究
    發(fā)表于 10-31 14:41 ?14次下載
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>輸入子系統(tǒng)的<b class='flag-5'>驅(qū)動(dòng)</b>研究

    Linux內(nèi)核與Android的關(guān)系

    Android雖然建立在Linux內(nèi)核之上,但是他對(duì)內(nèi)核進(jìn)行了一些擴(kuò)展,增加了一些驅(qū)動(dòng)。比如Binder,loger等等驅(qū)動(dòng)??梢阅肁ndr
    發(fā)表于 09-09 09:10 ?4693次閱讀

    LINUX內(nèi)核代碼情景分析下冊(cè)PDF電子書(shū)免費(fèi)下載

    ?!?b class='flag-5'>LINUX內(nèi)核代碼情景分析》(下)則分基于Socket的進(jìn)程間通訊、設(shè)備驅(qū)動(dòng)、多處理器 SMP系統(tǒng)結(jié)構(gòu)以及系統(tǒng)引導(dǎo)和初始化四章。
    發(fā)表于 10-12 16:09 ?107次下載

    如何使用Linux內(nèi)核實(shí)現(xiàn)USB驅(qū)動(dòng)程序框架

    Linux內(nèi)核提供了完整的USB驅(qū)動(dòng)程序框架。USB總線(xiàn)采用樹(shù)形結(jié)構(gòu),在一條總線(xiàn)上只能有唯一的主機(jī)設(shè)備。 Linux內(nèi)核從主機(jī)和設(shè)備兩個(gè)角度
    發(fā)表于 11-06 17:59 ?20次下載
    如何使用<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>實(shí)現(xiàn)USB<b class='flag-5'>驅(qū)動(dòng)</b>程序框架

    關(guān)于Linux內(nèi)核代碼風(fēng)格

    從編碼風(fēng)格錯(cuò)誤開(kāi)始 曾經(jīng)在開(kāi)發(fā)Linux內(nèi)核驅(qū)動(dòng)的時(shí)候,創(chuàng)建了一個(gè)補(bǔ)丁文件,但是在把補(bǔ)丁打到主分支的時(shí)候提示很多編碼風(fēng)格的錯(cuò)誤問(wèn)題,后來(lái)重做了補(bǔ)丁才解決了問(wèn)題,這也是沒(méi)有嚴(yán)格按照的Linux
    的頭像 發(fā)表于 04-25 14:50 ?1951次閱讀

    linux內(nèi)核代碼詳解

     在安裝好的Linux系統(tǒng)中,內(nèi)核的源代碼位于/ust/src/linux.如果是從GNU網(wǎng)站下載的Linux
    發(fā)表于 09-06 17:01 ?4次下載

    Linux內(nèi)核如何使用結(jié)構(gòu)體和函數(shù)指針?

    我將結(jié)合具體的Linux內(nèi)核驅(qū)動(dòng)框架代碼來(lái)展示Linux內(nèi)核如何使用結(jié)構(gòu)體和函數(shù)指針。
    的頭像 發(fā)表于 09-06 14:17 ?1219次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>如何使用結(jié)構(gòu)體和函數(shù)指針?

    linux驅(qū)動(dòng)程序如何加載進(jìn)內(nèi)核

    ,需要了解Linux內(nèi)核的基本概念和API。以下是一些關(guān)鍵概念: 1.1 內(nèi)核模塊:Linux內(nèi)核模塊是一種動(dòng)態(tài)加載和卸載的
    的頭像 發(fā)表于 08-30 15:02 ?854次閱讀

    電子發(fā)燒友

    中國(guó)電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品