小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Device Tree(一):背景介紹

 jiffes 2015-07-09
分類: linux相關(guān) 2014-06-28 14:16 763人閱讀 評論(0) 收藏 舉報

一、前言

作為一個多年耕耘在linux 2.6.23內(nèi)核的開發(fā)者,各個不同項目中各種不同周邊外設驅(qū)動的開發(fā)以及各種瑣碎的、扯皮的俗務占據(jù)了大部分的時間。當有機會下載3.14的內(nèi)核并準備學習的時候,突然發(fā)現(xiàn)linux kernel對于我似乎變得非常的陌生了,各種新的機制,各種framework、各種新的概念讓我感到閱讀內(nèi)核代碼變得舉步維艱。 還好,剖析內(nèi)核的熱情還在,剩下的就交給時間的。首先進入視線的是Device Tree機制,這是和porting內(nèi)核非常相關(guān)的機制,如果想讓將我們的硬件平臺遷移到高版本的內(nèi)核上,Device Tree是一個必須要掃清的障礙。

我想從下面三個方面來了解Device Tree:

1、為何要引入Device Tree,這個機制是用來解決什么問題的?(這是本文的主題)

2、Device Tree的基礎概念(請參考DT基礎概念

3、ARM linux中和Device Tree相關(guān)的代碼分析(請參考DT代碼分析

閱讀linux內(nèi)核代碼就像欣賞冰山,有看得到的美景(各種內(nèi)核機制及其代碼),也有埋在水面之下看不到的基礎(機制背后的源由和目的)。沉醉于各種內(nèi)核機制的代碼固然有無限樂趣,但更重要的是注入更多的思考,思考其背后的機理,真正理解軟件抽象。這樣才能舉一反三,并應用在具體的工作和生活中。

本文主要從下面幾個方面闡述為何ARM linux會引入Device Tree:

1、沒有Device Tree的ARM linux是如何運轉(zhuǎn)的?

2、混亂的ARM architecture代碼和存在的問題

3、新內(nèi)核的解決之道

 

二、沒有Device Tree的ARM linux是如何運轉(zhuǎn)的?

我曾經(jīng)porting內(nèi)核到兩個ARM-based的平臺上。一個是小的芯片公司的應用處理器,公司自己購買了CPU core,該CPU core使用ARM兼容的指令集(但不是ARM)加上各種公司自行設計的多媒體外設整合成公司的產(chǎn)品進行銷售。而我的任務就是porting 2.4.18內(nèi)核到該平臺上。在黑白屏幕的手機時代,那顆AP(application process)支持了彩屏、camera、JPEG硬件加速、2D/3D加速、MMC/SD卡、各種音頻加速(內(nèi)置DSP)等等特性,功能強大到無法直視。另外一次移植經(jīng)歷是讓2.6.23內(nèi)核跑在一個大公司的冷門BP(baseband processor)上。具體porting的方法是很簡單的:

1、自己撰寫一個bootloader并傳遞適當?shù)膮?shù)給kernel。除了傳統(tǒng)的command line以及tag list之類的,最重要的是申請一個machine type,當拿到屬于自己項目的machine type ID的時候,當時心情雀躍,似乎自己已經(jīng)是開源社區(qū)的一份子了(其實當時是有意愿,或者說有目標是想將大家的代碼并入到linux kernel main line的)。

2、在內(nèi)核的arch/arm目錄下建立mach-xxx目錄,這個目錄下,放入該SOC的相關(guān)代碼,例如中斷controller的代碼,時間相關(guān)的代碼,內(nèi)存映射,睡眠相關(guān)的代碼等等。此外,最重要的是建立一個board specific文件,定義一個machine的宏:

MACHINE_START(project name, "xxx公司的xxx硬件平臺") 
    .phys_io    = 0x40000000, 
    .boot_params    = 0xa0000100,   
    .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc, 
    .map_io        = xxx_map_io, 
    .init_irq    = xxx_init_irq, 
    .timer        = &xxx_timer, 
    .init_machine    = xxx_init, 
MACHINE_END

在xxx_init函數(shù)中,一般會加入很多的platform device。因此,伴隨這個board specific文件中是大量的靜態(tài)table,描述了各種硬件設備信息。

3、調(diào)通了system level的driver(timer,中斷處理,clock等)以及串口terminal之后,linux kernel基本是可以起來了,后續(xù)各種driver不斷的添加,直到系統(tǒng)軟件支持所有的硬件。

綜上所述,在linux kernel中支持一個SOC平臺其實是非常簡單的,讓linux kernel在一個特定的平臺上“跑”起來也是非常簡單的,問題的重點是如何優(yōu)雅的”跑”。

 

三、混亂的ARM architecture代碼和存在的問題

每次正式的linux kernel release之后都會有兩周的merge window,在這個窗口期間,kernel各個部分的維護者都會提交各自的patch,將自己測試穩(wěn)定的代碼請求并入kernel main line。每到這個時候,Linus就會比較繁忙,他需要從各個內(nèi)核維護者的分支上取得最新代碼并merge到自己的kernel source tree中。Tony Lindgren,內(nèi)核OMAP development tree的維護者,發(fā)送了一個郵件給Linus,請求提交OMAP平臺代碼修改,并給出了一些細節(jié)描述:

1、簡單介紹本次改動

2、關(guān)于如何解決merge conficts。有些git mergetool就可以處理,不能處理的,給出了詳細介紹和解決方案

一切都很平常,也給出了足夠的信息,然而,正是這個pull request引發(fā)了一場針對ARM linux的內(nèi)核代碼的爭論。我相信Linus一定是對ARM相關(guān)的代碼早就不爽了,ARM的merge工作量較大倒在其次,主要是他認為ARM很多的代碼都是垃圾,代碼里面有若干愚蠢的table,而多個人在維護這個table,從而導致了沖突。因此,在處理完OMAP的pull request之后(Linus并非針對OMAP平臺,只是Tony Lindgren撞在槍口上了),他發(fā)出了怒吼:

Gaah. Guys, this whole ARM thing is a f*cking pain in the ass.

負責ARM linux開發(fā)的Russell King臉上掛不住,進行了反駁:事情沒有那么嚴重,這次的merge conficts就是OMAP和IMX/MXC之間一點協(xié)調(diào)的問題,不能抹殺整個ARM linux團隊的努力。其他的各個ARM平臺維護者也加入討論:ARM平臺如何復雜,如何龐大,對于arm linux code我們已經(jīng)有一些思考,正在進行中……一時間,討論的氣氛有些尖銳,但總體是坦誠和友好的。

對于一件事情,不同層次的人有不同層次的思考。這次爭論涉及的人包括:

1、內(nèi)核維護者(CPU體系結(jié)構(gòu)無關(guān)的代碼)

2、維護ARM系統(tǒng)結(jié)構(gòu)代碼的人

3、維護ARM sub architecture的人(來自各個ARM SOC vendor)

維護ARM sub architecture的人并沒有強烈的使命感,作為公司的一員,他們最大的目標是以最快的速度支持自己公司的SOC,盡快的占領市場。這些人的軟件功力未必強,對linux kernel的理解未必深入(有些人可能很強,但是人在江湖身不由己)。在這樣的情況下,很多SOC specific的代碼都是通過copy and paste,然后稍加修改代碼就提交了。此外,各個ARM vendor的SOC family是一長串的CPU list,每個CPU多多少少有些不同,這時候#ifdef就充斥了各個源代碼中,讓ARM mach-和plat-目錄下的代碼有些不忍直視。

作為維護ARM體系結(jié)構(gòu)的人,其能力不容置疑。以Russell King為首的team很好的維護了ARM體系結(jié)構(gòu)的代碼?;旧希薽ach-和plat-目錄,其他的目錄中的代碼和目錄組織是很好的。作為ARM linux的維護者,維護一個不斷有新的SOC加入的CPU architecture code的確是一個挑戰(zhàn)。在Intel X86的架構(gòu)一統(tǒng)天下的時候,任何想正面攻擊Intel的對手都敗下陣來。想要擊倒巨人(或者說想要和巨人并存)必須另辟蹊徑。ARM的策略有兩個,一個是focus在嵌入式應用上,也就意味著要求低功耗,同時也避免了和Intel的正面對抗。另外一個就是博采眾家之長,采用license IP的方式,讓更多的廠商加入ARM建立的生態(tài)系統(tǒng)。毫無疑問,ARM公司是成功的,但是這種模式也給ARM linux的維護者帶來了噩夢。越來越多的芯片廠商加入ARM陣營,越來越多的ARM platform相關(guān)的代碼被加入到內(nèi)核,不同廠商的周邊HW block設計又各不相同……

內(nèi)核維護者是真正對操作系統(tǒng)內(nèi)核軟件有深入理解的人,他們往往能站在更高的層次上去觀察問題,發(fā)現(xiàn)問題。Linus注意到每次merge window中,ARM的代碼變化大約占整個ARCH目錄的60%,他認為這是一個很明顯的符號,意味著ARM linux的代碼可能存在問題。其實,60%這個比率的確很夸張,因為unicore32是在2.6.39 merge window中第一次全新提交,它的代碼是全新的,但是其代碼變化大約占整個ARCH目錄的9.6%(需要提及的是unicore32是一個中國芯)。有些維護ARM linux的人認為這是CPU市場占用率的體現(xiàn),不是問題,直到內(nèi)核維護者貼出實際的代碼并指出問題所在。內(nèi)核維護者當然想linux kernel支持更多的硬件平臺,但是他們更愿意為linux kernel制定更長遠的規(guī)劃。例如:對于各種繁雜的ARM平臺,用一個kernel image來支持。

經(jīng)過爭論,確定的問題如下:

1、ARM linux缺少platform(各個ARM sub architecture,或者說各個SOC)之間的協(xié)調(diào),導致arm linux的代碼有重復。值得一提的是在本次爭論之前,ARM維護者已經(jīng)進行了不少相關(guān)的工作(例如PM和clock tree)來抽象相同的功能模塊。

2、ARM linux中大量的board specific的源代碼應該踢出kernel,否則這些垃圾代碼和table會影響linux kernel的長期目標。

3、各個sub architecture的維護者直接提交給Linux并入主線的機制缺乏層次。

 

四、新內(nèi)核的解決之道

針對ARM linux的現(xiàn)狀,最需要解決的是人員問題,也就是如何整合ARM sub architecture(各個ARM Vendor)的資源。因此,內(nèi)核社區(qū)成立了一個ARM sub architecture的team,該team主要負責協(xié)調(diào)各個ARM廠商的代碼(not ARM core part),Russell King繼續(xù)負責ARM core part的代碼。此外,建立一個ARM platform consolidation tree。ARM sub architecture team負責review各個sub architecture維護者提交的代碼,并在ARM platform consolidation tree上維護。在下一個merge window到來的時候,將patch發(fā)送給Linus。

針對重復的代碼問題,如果不同的SOC使用了相同的IP block(例如I2C controller),那么這個driver的code要從各個arch/arm/mach-xxx中獨立出來,變成一個通用的模塊供各個SOC specific的模塊使用。移動到哪個目錄呢?對于I2C或者USB OTG而言,這些HW block的驅(qū)動當然應該移動到kernel/drivers目錄。因為,對于這些外設,可能是in-chip,也可能是off-chip的,但是對于軟件而言,它們是沒有差別的(或者說好的軟件抽象應該掩蓋底層硬件的不同)。對于那些system level的code呢?例如clock control、interrupt control。其實這些也不是ARM-specific,應該屬于linux kernel的核心代碼,應該放到linux/kernel目錄下,屬于core-Linux-kernel frameworks。當然對于ARM平臺,也需要保存一些和framework交互的code,這些code叫做ARM SoC core architecture code。OK,總結(jié)一下:

1、ARM的核心代碼仍然保存在arch/arm目錄下

2、ARM SoC core architecture code保存在arch/arm目錄下

3、ARM SOC的周邊外設模塊的驅(qū)動保存在drivers目錄下

4、ARM SOC的特定代碼在arch/arm/mach-xxx目錄下

5、ARM SOC board specific的代碼被移除,由Device Tree機制來負責傳遞硬件拓撲和硬件資源信息。

OK,終于來到了Device Tree了。本質(zhì)上,Device Tree改變了原來用hardcode方式將HW 配置信息嵌入到內(nèi)核代碼的方法,改用bootloader傳遞一個DB的形式。對于基于ARM CPU的嵌入式系統(tǒng),我們習慣于針對每一個platform進行內(nèi)核的編譯。但是隨著ARM在消費類電子上的廣泛應用(甚至桌面系統(tǒng)、服務器系統(tǒng)),我們期望ARM能夠象X86那樣用一個kernel image來支持多個platform。在這種情況下,如果我們認為kernel是一個black box,那么其輸入?yún)?shù)應該包括:

1、識別platform的信息

2、runtime的配置參數(shù)

3、設備的拓撲結(jié)構(gòu)以及特性

對于嵌入式系統(tǒng),在系統(tǒng)啟動階段,bootloader會加載內(nèi)核并將控制權(quán)轉(zhuǎn)交給內(nèi)核,此外,還需要把上述的三個參數(shù)信息傳遞給kernel,以便kernel可以有較大的靈活性。在linux kernel中,Device Tree的設計目標就是如此。


原創(chuàng)文章,轉(zhuǎn)發(fā)請注明出處。蝸窩科技,www.。

轉(zhuǎn)自:http://www./linux_kenrel/why-dt.html

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多