海思3516DV300 rootfs編譯及刷寫過程記錄

0x1. 簡單說幾句

前幾天某寶買了一個海思3516DV300小板子募闲,打算玩玩它的NNIE肴熏,這玩意1T的算力還算不錯了忽孽,值得玩下甥材。但是買來之后發(fā)現(xiàn)被坑了盯另,店家給刷寫的程序不帶那個telnetd,只能使用串口連接上去擂达,但是那個板子帶一個店家給的攝像頭應用土铺,它開機自啟還開了看門狗胶滋。串口登錄上去,會不停打印日志悲敷,停了之后又自動重啟究恤。這就非常難受。和店家問了下后德,只能自己從頭開始搞它的固件了部宿,作為一個算法工程師(劃掉,實際是搬磚工)瓢湃,我用我為數(shù)不多的嵌入式知識踩了不少坑理张,所以打算寫點啥記下來。
店家給了Uboot绵患、內(nèi)核的uImage雾叭、rootfs,由于這個板子硬件是店家開發(fā)的落蝙,需要對uboot和內(nèi)核做修改织狐,所以,這里直接用他們提供內(nèi)核還有uboot筏勒,然后偷梁換柱移迫,換個自己編譯的rootfs上去。

店家提供的文件

0x2. 準備

1.海思SDK

首先管行,得有海思的SDK厨埋,這里需要提前安裝好海思的編譯器arm-himix200-linux-*,并在終端里已經(jīng)配置了環(huán)境變量捐顷。編譯海思rootfs需要的文件荡陷,在 Hi3516CV500R001C02SPC020.rar這個壓縮包里

SDK位置

解壓了這個壓縮包后,執(zhí)行里面的sdk.unpack腳本套菜。海思3516DV300和3516CV500有很多東西是相同的亲善,所以在這個SDK里面,可以看到很多CV500的東西逗柴,但是實際上也給DV300用蛹头,這并不奇怪。
sdk.unpack

2. 安裝依賴戏溺、配置環(huán)境

安裝一些依賴渣蜗,我這里使用的是Ubuntu 18.04的環(huán)境。需要安裝如下的包旷祸,這些直接用apt-get install來安裝就可以了耕拷。

zlib1g-dev liblzo2-dev uuid-dev pkg-config libuuid1 bison
mtd-utils u-boot-tools libncurses5-dev libcrypto++-dev
binutils uuid uuid-dev gpref make gcc g++

海思的編譯,有一個坑托享,是文檔里需要安裝的依賴庫和實際上需要的并不相同

海思文檔

我很不明白骚烧,為啥浸赫,編譯一個rootfs,還要裝TeX的工具赃绊?難道是編譯的時候生成文檔既峡?還是要編譯的時候去寫論文?我沒裝這些也編譯過了氨滩椤运敢?還有一個,就是編譯gdb等海思芯片工具的時候忠售,有些依賴庫需要安裝传惠,但是并沒有在文檔里寫,比如bison和gpref稻扬。

3. 基礎的嵌入式Linux知識

這里需要對rootfs有一點點了解卦方。

rootfs

如上圖(摘自海思文檔Hi3516CV500╱Hi3516DV300╱Hi3516AV300 開發(fā)環(huán)境用戶指南),rootfs包含的內(nèi)容就是這樣的泰佳。嵌入式Linux系統(tǒng)啟動的時候愿汰,會從這個文件系統(tǒng)中,調(diào)用init這個程序乐纸,init作為Linux系統(tǒng)啟動的第一個進程,會從這里fork出很多其他的進程來摇予。Linux系統(tǒng)的啟動過程可以分為5個階段:內(nèi)核的引導汽绢、運行 init、系統(tǒng)初始化侧戴、建立終端宁昭、用戶登錄系統(tǒng)。在嵌入式環(huán)境下酗宋,由uboot來加載內(nèi)核积仗,然后內(nèi)核加載完成后,運行init蜕猫,這樣就完成了系統(tǒng)的啟動寂曹。
在這里,我們是用busybox來完成rootfs的編譯的回右。busybox是一個集成了一百多個最常用linux命令和工具的軟件,它集成了init隆圆、shell,甚至還集成了一個http服務器和一個telnet服務器翔烁,而所有這一切功能卻只占了很小的空間渺氧。

0x3. rootfs編譯與打包

1. Makefile的全部編譯目標

這里,我們看海思提供的Makefile蹬屹,在osdrv下的這一個侣背。我們可以看下白华,這個Makefile可以編譯什么東西。在剛才的make all 的過程中贩耐,可以看到弧腥,整個系統(tǒng)的編譯是分為幾個部分的。這里憔杨,我們分別來看每個部分鸟赫。


編譯的目標

其中,紅圈是我們需要的消别,看名字就可以知道它是干啥的了抛蚤,通過hiboardtool、hipctool是編譯我們需要板子寻狂、電腦上的工具岁经,包括在板子上調(diào)試代碼的gdb、電腦上打包rootfs用的mkyaffs2image100等蛇券;hibusybox是編譯busybox的缀壤,hirootfs是打包編譯完成的busybox到可用的rootfs鏡像的。

2. 按照官方說明編譯全部內(nèi)容(可選)

這一步的目的是為了了解海思編譯的過程纠亚,然后塘慕,后面編譯工作可以更順利,當然也可以手動執(zhí)行這些操作。此外,通過make all可以檢查依賴庫是否安裝正確幅慌,然后編譯出我們需要的工具來,這樣后面就不用再考慮工具的事情了蛤织。
網(wǎng)上有些博主說,直接在海思osdrv那個文件夾下執(zhí)行make all鸿染,會有坑指蚜,容易編譯不過。其實涨椒,這都是海思文檔的鍋摊鸡,那個文檔并不全面。在osdrv下的那個Makefile文件丢烘,里面內(nèi)容非常多柱宦,不過有大坑,如果可以讀懂那個Makefile播瞳,并做出合適的修改掸刊,后面構建rootfs等操作就會非常順利。
這里赢乓,按照那個readme_cn.txt忧侧,下載了那些開源代碼的源碼文件石窑,放到相應的位置,就可以開始編譯了蚓炬。直接執(zhí)行make all就可以了松逊,這樣默認編譯出來的是3516DV平臺的文件。這里首先跑一遍make all肯夏,來編譯全部的東西经宏,包括電腦上用的那些工具,后面就可以只編譯一部分了驯击。我的電腦是AMD R5 2600X的CPU烁兰,編譯一次大約10分鐘。如果報錯徊都,那就是依賴庫的問題沪斟。
完成編譯后,可以看到已經(jīng)按照默認配置生成了一些rootfs文件暇矫、uImage還有uboot文件主之。這個uImage和uboot是沒修改過的,不一定可以用李根。這里只看它生成的rootfs文件槽奕。

編譯結果

此外,在osdrv/pub/bin下房轿,會編譯出板子和PC上用的工具史翘,包括鏡像制作工具、GDB調(diào)試工具等冀续,在hi3516dv300_spi_smp_image_glibc下,是編譯出的uboot必峰、uImage和rootfs洪唐。

3. 修改rootfs然后編譯

如果用make all編譯出的rootfs鏡像,是不方便的吼蚁,因為這里沒把NNIE之類的驅動打包進去凭需,同時,并沒有為板子上設置/tmp分區(qū)肝匆,而且粒蜈,編譯的busybox里面有相當多的冗余的東西。所以這里需要對編譯的過程進行修改旗国,然后手動編譯并將驅動放進去枯怖。
我們的目標是build出帶有驅動、相關配置的可以直接用的rootfs來能曾。這里我們先看busybox的部分度硝。

busybox編譯

看紅圈的部分肿轨,有沒有感覺不太對?這是海思的另一個坑蕊程,編譯完了椒袍,做出修改之后重新編譯,相當于沒修改藻茂。所以驹暑,我們手動編譯這些東西。此外辨赐,使用這個編譯出來的rootfs优俘,busybox是有不少多余的東西的,通過手動配置肖油,可以更加精簡兼吓。這里,我們把紅圈的內(nèi)容都注釋掉森枪,然后在osdrv/opensource/busybox/busybox-1.26.2下视搏,直接執(zhí)行cp config_v200_a7_softfp_neon .config && make menuconfig,然后進入配置界面县袱。
busybox config

這里浑娜,我把Print Utilities下的所有內(nèi)容關了,把shells下的hush關了式散,這些可以根據(jù)自己的想法來配置筋遭。配置完成后保存并退出,再執(zhí)行make -j && make install來編譯busybox暴拄,這時候漓滔,編譯的結果在_install文件夾下,我們已經(jīng)完成了busybox的編譯乖篷。

4. 添加驅動响驴、配置啟動設置

系統(tǒng)在啟動的時候,需要加載驅動撕蔼,然后配置網(wǎng)絡豁鲤,所以需要修改配置項,然后讓系統(tǒng)可以自動完成驅動加載等任務鲸沮。
這里琳骡,我只需要開發(fā)NNIE的應用,可能用到TDE讼溺、IVE等模塊楣号。驅動在這里


驅動

海思提供了一個rootfs的框架(也可以看做是一個類似于模板的東西吧),我們可以在這個的基礎上進行配置,把編譯的busybox復制進去(實際上make all的時候竖席,也是使用的這個模板)耘纱。這里,我們要在這個模板的基礎上毕荐,把驅動和相關配置添加進去束析。

prepare

在hirootfs_prepare的這里,把rootfs_scripts/rootfs.tgz的內(nèi)容解壓到pub這里了憎亚,而這個rootfs.tgz员寇,就是海思提供的rootfs的模板。海思提供的Makefile會把這個rootfs.tgz解壓第美,然后復制到目標位置蝶锋,那么我們就仿照著它,把驅動什往、配置也都復制到目標位置扳缕。
把ko文件夾復制到osdrv/rootfs_scripts下。在makefile的第313行添加如下內(nèi)容别威,這樣躯舔,就可以在打包rootfs的時候把驅動打包進去。
komod

有了驅動省古,還需要在系統(tǒng)啟動的時候加載驅動粥庄。所以這里需要設置啟動腳本。解壓rootfs_scripts/rootfs.tgz豺妓,然后把其中的/etc文件夾移動到rootfs_scripts文件夾下惜互。修改etc/init.d/rcS,在文件結尾添加3行琳拭,具體內(nèi)容如下

#! /bin/sh

/bin/mount -a

echo "
            _ _ _ _ _ _ _ _ _ _ _ _
            \  _  _   _  _ _ ___
            / /__/ \ |_/
           / __   /  -  _ ___
          / /  / /  / /
  _ _ _ _/ /  /  \_/  \_ ______
___________\___\__________________
"
for initscript in /etc/init.d/S[0-9][0-9]*
do
    if [ -x $initscript ] ;
    then
        echo "[RCS]: $initscript"
        $initscript
    fi
done
cd /komod
./load3516dv300 -i -osmem 512 -total 1024
telnetd &

以上三行命令含義為训堆,進入/komod加載驅動,加載時設置DV300板子有1G的內(nèi)存白嘁,其中為系統(tǒng)分配512MB蔫慧,剩余的為MMZ內(nèi)存,最后啟動telnetd服務权薯,這樣可以使用telnet來連接板子。
除了加載驅動睡扬,這時候板子是沒有設置網(wǎng)絡的盟蚣,需要為板子設置一個網(wǎng)絡連接。這里使用的是靜態(tài)IP卖怜。在osdrv/rootfs_scripts文件夾下屎开,修改etc/init.d/S80Network文件。打開這個文件马靠,修改前面幾行即可奄抽。

#!/bin/sh

ipaddr=192.168.1.123
bootp=
gateway=192.168.1.1
netmask=255.255.255.0
hostname=
netdev=eth0
autoconf=

如果想使用/tmp分區(qū)蔼两,則需要在etc/fstab中設置tmp掛載。在osdrv/etc/fstab中逞度,添加這一行

tmpfs           /tmp            tmpfs   defaults,size=20m 0 0

以上配置完成后额划,同樣需要在構建rootfs鏡像時把配置文件添加進去。編輯osdrv/Makefile档泽,在第314行添加如下內(nèi)容:


添加配置到rootfs

完成以上內(nèi)容后俊戳,在make hirootfs_prepare的時候就會自動完成相關文件的添加。

5.打包rootfs

在上面馆匿,我們已經(jīng)完成了busybox的修改與編譯抑胎,也完成配置驅動、運行庫渐北、環(huán)境變量等工作了阿逃。這時,使用上面得到的內(nèi)容來打包rootfs赃蛛。

由于上面已經(jīng)在makefile里把重新編譯busybox的內(nèi)容注釋掉了恃锉,在make hibusybox的時候會跳過重新編譯而只是把之前手動編譯的結果復制到目標位置,所以這里我們可以直接使用這個makefile來完成打包焊虏。
在Makefile的第402行左右淡喜,可以找到打包的命令。

打包rootfs

在這里诵闭,我們可以發(fā)現(xiàn)炼团,海思提供的makefile編譯rootfs,實際上分了5個步驟:準備疏尿、編譯busybox瘟芝、編譯板子的工具、編譯PC的工具褥琐、打包rootfs锌俱,這個hirootfs_notools_build里,就是調(diào)用mkyaffs2image100之類的工具來打包鏡像敌呈。在上面make all的時候贸宏,已經(jīng)完成了工具的編譯,所以磕洪,我們在第445行附近吭练,仿照hirootfs_build添加一行,讓它不編譯工具析显,只進行復制文件鲫咽、打包的操作:
添加一行

然后執(zhí)行make hirootfs_pack,這樣,就可以看到分尸,我們需要的rootfs鏡像已經(jīng)生成了锦聊。
rootfs

在這一步中,是打包一個文件夾里的文件到rootfs鏡像箩绍,然后這個文件夾里的內(nèi)容又被壓縮到pub/rootfs_glibc.tgz中孔庭,最后這個文件夾被刪掉,可以解壓這個壓縮包看下里面有什么東西伶选。

rootfs

完成以上步驟后史飞,就得到了海思DV300上使用的rootfs。最后一步仰税,就是把它刷到板子上构资。

0x4. rootfs的刷寫

我買的這個板子,配的是128MB的nand flash陨簇,型號為W25N01G吐绵,頁大小為2K,ECC為4bit河绽。

SPI Nand Flash

這個板子的rootfs使用的是yaffs2的分區(qū)格式己单,正好,海思的工具已經(jīng)生成了2k4bit的yaffs格式的rootfs文件耙饰,直接把它刷進去就行纹笼。
刷固件需要使用tftp和串口。在Linux上苟跪,串口可以使用picocom或者minicom廷痘。這里我使用的是picocom。運行
sudo picocom /dev/ttyUSB0 -b 115200即可打開串口件已。這里tftp使用的是tftpd-hpa笋额。tftp服務器的配置參考這個文章http://blog.chinaunix.net/uid-23065002-id-5203089.html
把上面的rootfs文件放到tftpd文件夾下,然后打開串口篷扩,給板子上電兄猩,隨便按鍵進入uboot命令行。執(zhí)行printenv鉴未,看下當前uboot的環(huán)境設置枢冤。
uboot

可以看到,uboot的啟動參數(shù)如圖铜秆,這里有配置啟動的時候nand flash的分區(qū)設置淹真、內(nèi)存劃分、串口終端等信息羽峰,也配置了從flash加載數(shù)據(jù)內(nèi)存的地址和大小。
uboot nand

參考nand命令,可以判斷出梅屉,啟動時從flash中值纱,跳過1MB后讀取了3MB的內(nèi)容到內(nèi)存的0x81000000,這就是加載內(nèi)核坯汤。結合bootargs和bootcmd虐唠,我們知道了flash的rootfs寫入偏移量為1MB+3MB,既0x400000惰聂。
現(xiàn)在可以開始刷寫rootfs疆偿。首先從內(nèi)存中清空一塊空間,用于保存tftp下載的rootfs文件搓幌,這塊空間一定要比下載的rootfs文件大杆故。我這里rootfs是20.7MB,我準備了25MB來存rootfs溉愁。然后再寫入处铛,寫入的時候也是先從nand flash中把相應的空間擦除,然后再寫拐揭。命令如下:

 mw.b 81000000 ff 2500000;tftp 0x81000000 rootfs_hi3516dv300_2k_4bit.yaffs2
 nand erase 400000 2500000;nand write.yaffs 81000000 400000 14a8400 #注意:14a8400為rootfs文件實際大谐敷 (16進制)

tftp下載rootfs

紅色框即為rootfs文件16進制的大小。
使用以上操作即可完成海思平臺的rootfs編譯堂污、驅動的加載家肯、IP配置等操作。有的時候盟猖,如果遇到找不到init導致的kernel panic讨衣,那么,可以把整個nand flash清空扒披,然后重新寫uboot值依、uImage、rootfs碟案,當然愿险,這個操作就比較危險了,如果真的把uboot寫沒了又沒及時恢復進去价说,那么只能用HiTool的HiBurn來寫了辆亏。
每個店家賣的板子都不一樣,我的板子是這個配置的鳖目,當然也有emmc等存儲芯片的板子扮叨,這個就需要參考海思的官方文檔來寫入了,當然领迈,編譯rootfs的方法都是一樣的彻磁。

最后放兩張重新編譯打包的rootfs在板子上跑的截圖

通過telnet連上去查看nnie狀態(tài)

查看mmz狀態(tài)

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碍沐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子衷蜓,更是在濱河造成了極大的恐慌累提,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件磁浇,死亡現(xiàn)場離奇詭異斋陪,居然都是意外死亡,警方通過查閱死者的電腦和手機置吓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門无虚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人衍锚,你說我怎么就攤上這事友题。” “怎么了构拳?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵咆爽,是天一觀的道長。 經(jīng)常有香客問我置森,道長斗埂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任凫海,我火速辦了婚禮呛凶,結果婚禮上,老公的妹妹穿的比我還像新娘行贪。我一直安慰自己漾稀,他們只是感情好,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布建瘫。 她就那樣靜靜地躺著崭捍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啰脚。 梳的紋絲不亂的頭發(fā)上殷蛇,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音橄浓,去河邊找鬼粒梦。 笑死,一個胖子當著我的面吹牛荸实,可吹牛的內(nèi)容都是我干的匀们。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼准给,長吁一口氣:“原來是場噩夢啊……” “哼泄朴!你這毒婦竟也來了重抖?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤祖灰,失蹤者是張志新(化名)和其女友劉穎仇哆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夫植,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年油讯,在試婚紗的時候發(fā)現(xiàn)自己被綠了详民。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡陌兑,死狀恐怖沈跨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情兔综,我是刑警寧澤饿凛,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站软驰,受9級特大地震影響涧窒,放射性物質發(fā)生泄漏。R本人自食惡果不足惜锭亏,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一纠吴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慧瘤,春花似錦戴已、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至怔匣,卻和暖如春握联,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背劫狠。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工拴疤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人独泞。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓呐矾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親懦砂。 傳聞我的和親對象是個殘疾皇子蜒犯,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355