本內容的驗證使用的盈鵬飛嵌入式CoM-335x核心模塊及評估板EAC-335X,簡要介紹如下:
產品特性
?采用TI公司Cortex-A8 AM335X處理器,運行最高速度為1GHZ;
?支持128M-512M DDR3 SDRAM;
?支持128-1G字節 SLC電子盤或者EMMC 4G-32G大容量電子盤,可啟動;
?最多可支持兩路千兆以太網,支持IEEE1588;
?支持兩路高速USB OTG;
?支持最多六路串口,雙路CAN BUS;
?支持分辨率最高的1360*768顯示接口,可支持SGX530 3D引擎;
?板載DS1339的RTC時鐘,國內獨家設計,保證系統時鐘同步;
?支持GPMC擴展總線,可擴展FPGA或者 DSP應用;
?穩定的操作系統的支持,可預裝Ubuntu 16.04或者Preempt Linux 4.14;ANDROID 4.2可根據項目定制;
超小體積,郵票孔設計,160pins, 尺寸為:45*45MM
EAC-335X產品功能圖:
1 概述
本手冊主要介紹AM335x系列核心模塊的衍生產品——包括EVB-335x(Linux 3.2.0)與HMI-T335(Linux 4.14.67)基于UBIFS的使用,旨在解決防止用戶文件(數據)丟失問題。
早前,用戶文件與根文件系統保存在同一MTD分區,若文件系統發生不可修復的損壞,用戶文件也可能隨之丟失。分離根文件系統與用戶文件,使得二者擁有不同分區,可有效規避此問題。這好比PC有系統分區專用于安裝系統,還有其他分區用于存儲用戶文件(例如:文檔、相片、音樂等),當系統發生不可修復的故障時,重新安裝系統只會丟失系統分區的文件并不會導致其他分區的文件丟失。
內容梗概:
第2章:介紹nand分區表,這些分區是典型的應用——即用戶文件與根文件系統存儲在同一分區。
第3章:介紹在u-boot源碼中添加新分區,包括兩個版本:u-boot 201404與u-boot 2018.01,其中u-boot 201404用于引導Linux 3.2.0、u-boot 2018.01引導Linux 4.14.67。
第4章:介紹在Linux源碼中添加新分區。 Linux 3.2.0在mach-xxx文件中添加分區,Linux 4.14.67則在dts中添加,注意兩者的區別。
第5章:提出一些注意事項,包括:u-boot與Linux內核分區大小應保持一致;注意區別燒錄鏡像文件不同;驗證新分區是否生效。
第6章:介紹在用戶空間如何掛載ubi分區;如何制作UBI鏡像以及燒錄;如何實現自動掛載ubi分區。
附錄1 :簡單介紹ubi工具
基于以下條件,貫穿手冊中的每一章節,最終實現UBI分區掛載(user spacemount或automaticmount)。其流程參考本章的流程圖:
① 主板:EVB-335x,其中Nand flash page size 為2048 byte(mkfs.ubifs工具需要傳遞正確的page size 參數,否則導致UBI鏡像掛在失敗),容量512MB;
軟件:u-boot 2014.04,Linux 3.2.0;
UBI分區:新添加373MB的userdata分區。
② 主板:HMI-335,其中Nand flash page size 為4096 byte,容量512MB;
軟件:u-boot 2018.01,Linux 4.14.67;
UBI分區:添加“ubi_volume”分區,容量100MB;添加“userdata”分區,使用剩余容量。
對于分區,u-boot與內核的容量是固定的。如果您需要添加新分區用于保存用戶文件,保留足夠的rootfs空間,剩余的則可劃分為新分區。
2nand 分區介紹
nand 分區是將某個設備的存儲空間切割成段,根據地址規劃一定大小空間。在u-boot命令行執行:mtdparts,查看當前分區,如下圖所示:
圖中的“parts = 9”,表示共有9個分區,各分區的起始地址及大小在列。需要注意的是,rootfs分區使用nand的剩余空間,對于不同容量的nand,rootfs分區的大小不同。在u-boot 2014.04-rc2(引導Linux 3.2.0)分區表中,出廠默認劃分如下:
添加userdata后的分區表如下:
在u-boot 2018.01(引導Linux 4.14.67)分區表,由于Linux4.14.67內核的板級代碼采用dtb,所以會看到u-boot包括dtb分區,出廠默認劃分如下:
添加ubi_volume與userdata后的分區表如下:
說明:
① 分區表中的容量是計算得來的理論值,由于nand壞塊原因,實際可使用空間比理論值小。特別是格式化成UBIFS的分區,某些block或page用于存儲UBI的屬性標記,實際容量比分區小。
② 對于不同容量的nand,rootfs或用戶分區大小不同,表中列出3種不同容量的分區示例。
3 U-Boot 修改nand 分區
EVB-335x(內核版本Linux 3.2.0),配套u-boot 2014.04-rc2;HMI-T335(內核版本 Linux 4.14.67),配套u-boot 2018.01。兩個版本u-boot修改分區的方式不一樣,分別介紹:
3.1?EVB-335x修改nand分區
[if !supportLists]1、?[endif]輸入命令:tar -jxvf u-boot-2014.04-rc2-00037-gbaecd31.tar.bz2,將光盤linux\bootloader中
u-boot-2014.04-rc2-00037-gbaecd31.tar.bz2解壓到PC機 linux下,如下圖所示:
進入u-boot-2014.04-rc2-00037-gbaecd31目錄,如下圖所示:
2、輸入命令:vi include/configs/com335x.h,打開com335x.h文件
3、定位到#define MTDPARTS_DEFAULT宏定義,這個宏定義決定u-boot對nand的分區,如將rootfs
分區改為128M,再在rootfs分區后添加一個userdata分區,則修改如下圖所示:
注意:修改分區大小時,不要忘記單位(m), 如128m(rootfs)。另要使用逗號將每個分區分開,最后一個分區后沒有逗號。
4、保存退出,編譯u-boot,編譯過程請參考Linux CoM335X 開發指南。
3.2 HMI-T335修改nand分區
新版本的u-boot在defconfig修改分區。假設,需要在hmi-t335-nand-800x480_defconfig添加ubi_volume與userdata分區,操作如下:
1、使用文檔編輯工具(例如vim、gedit等)打開configs/hmi-t335-nand-800x480_defconfig文件;
2、找到配置項“CONFIG_MTDPARTS_DEFAULT”,添加ubi_volume與userdata,分區之間用“,”間隔,如下:
注:
① 分區格式為:容量(分區名),如100m(ubi_volume)表示ubi_volume分區的容量為100m。最后一個分區的容量用“-”,表示分配全部的剩余容量。
② 未添加新分區前,nand的剩余容量都分配給rootfs,添加ubi_volume與userdata分區,同時修改rootfs分區的容量,示例中改為128m。
3、修改nand分區完成后,保存退出,重新編譯u-boot,可參考以下操作:
host# make distclean
host# make ARCH=arm hmi-t335-nand-800x480_defconfig
host# make?ARCH=arm CROSS_COMPILE=/opt/hmi-t335-linux-sdk/bin/arm-linux-gnueabihf- -j32
4、正常編譯結束后,在u-boot源碼頂級目錄生成MLO、u-boot.img,這兩個文件最終要燒錄到nand中。
4、Linux內核修改nand分區
EVB-335x使用Linux 3.2.0,HMI-T335使用Linux 4.14.67。Linux 3.2.0無device tree,有關板級的代碼在mach-xxx中添加;Linux 4.14.67板級代碼在dts中添加。以下分別介紹:
4.1、EVB-335x 修改nand分區
1、輸入命令:tar -jxvf linux-3.2-evb335x.tar.bz2,將光盤linux\kernel\?linux-3.2-evb335x.tar.bz2解壓到PC機linux系統下,如下圖所示
紅色框內linux-3.2-evb335x為解壓生成的目錄。
進入linux-3.2-evb335x目錄,如下圖所示:
2、輸入命令:vi arch/arm/mach-omap2/board-com335x.c,打開板級初始化文件,如下圖所示:
3、定位到static struct mtd_partition com335x_nand_partitions[],此結構數組為內核對nand 分區,
如將文件系統分區劃分128M,添加分區userdata,userdata分區占用剩余空間,如下圖所示:
其中:
name :為分區的名字
offset :為分區開始的偏移地址
MTDPART_OFS_APPEND:表示緊接著上一個分區,MTD Core會自動計算和處理分區地址
Size:為分區的大小,在最后一個分區我們設為MTDPART_SIZ_FULL,表示這個NADN剩下的所有部分。
SZ_128K:代表128k,nand flash以block為單位擦除,而K9F2G08U0B 或K9F4G08U0B每個block大小為128K,所以在內核分區計算中以SZ_128為最小單位。
4、保存退出后,編譯內核,編譯過程請參考CoM335X Linux 開發指南。
4.2、HMI-T335修改nand分區
說明:HMI-T335的Linux內核集成到buildroot當中,所有修改均在“buildroot-2018.02.12”目錄下進行。
以在board/hmi-t335/hmi-t335-nand-800x480.dts中添加“ubi_volume”與“userdata”分區為例,步驟如下:
1、使用文本編輯工具打開,找到“&gpmc”node,修改“partition@10”的容量,在此改為128MB;
2、添加“ubi_volume”分區,容量100MB;添加“userdata”分區,使用剩余容量。
3、保存退出,重新編譯內核。
host# make linux-rebuild
注:partition的“label”屬性為分區名稱;“reg”屬性為容量,其格式為<offset size>,reg的size為0表示使用剩余容量。
5? nand分區注意事項
1、u-boot分區應與內核分區大小保持一致;
2、修改分區后,重新編譯u-boot與Linux內核,并更新到目標板。通常使用TF卡更新,EVB-335x與HMI-T335的 系統鏡像區分如下:
3、更新系統鏡像前,先執行擦除操作,以確保清除nand中的舊數據,再更新。擦除整個nand,執行:nand erase.chip如下圖:
網絡燒寫系統可參考CoM335X更新linux系統手冊。
4.4、驗證分區是否生效,在u-boot命令行執行mtdpats,在shell中執行cat /proc/mtd,如下列圖片所示:
從以上兩圖中看出u-boot與Linux內核修改后的分區,調整后的rootfs為128MB(0x08000000 byte),新增的userdata分區為373MB(0x17580000 byte)。
從以上兩圖中看出u-boot與Linux內核修改后的分區,調整后的rootfs為128MB(0x08000000 byte),新增的分區ubi_volume為100MB(0x6400000 byte)、userdata為373MB(0x17580000 byte)。
6 MTD設備用戶空間操作
創建分區參考前文所述,以下內容將闡述:
1、如何掛載MTD分區;
2、如何將用戶文件壓制成UBI鏡像;
3、應用舉例。
應用舉例,涉及兩個不同版本的Linux kernel以及u-boot,應當注意當前所使用的版本。
6.1?如何掛載MTD分區
MTD設備分區后,還不能直接用作存儲空間,需要經過格式化、關聯UBI、掛載操作。以userdata分區(/dev/mtd9)掛載到/mnt目錄為例,步驟如下:
① 格式化MTD分區,如下圖所示:
EVB-335x# ubiformat /dev/mtd9
② 關聯UBI設備,如下圖所示:
EVB-335x# ubiattach /dev/ubi_ctrl -m 9
注:正常關聯設備,打印設備相關信息,如:物理擦除快、邏輯擦除塊、容量等。留意console中的信息“UBI: attached mtd9 to ubi1”,創建UBI卷時會用到。
③ 創建一個UBI卷,使用部分容量或全部容量。如下圖所示:
?使用部分,例如創建10MB的卷、卷標為ubifs_volume
EVB-335x# ubimkvol /dev/ubi1 -N ubifs_volume ?-s 10MiB
?使用全部容量,例如使用全部容量、卷標為userdata
EVB-335x# ubimkvol /dev/ubi1 -N userdata -m
④ 掛載MTD分區,掛載時可指定設備節點或者卷標
?設備節點掛載的方式,例如掛載/dev/ubi1_0到/mnt
EVB-335x# mount -t ubifs /dev/ubi1_0 /mnt/
?卷標掛載的方式,例如ubi1的卷標為userdata,將其掛載/mnt
EVB-335x# mount -t ubifs ubi1:userdata /mnt/
注:正常掛載,console中輸出卷標、容量等信息。亦可通過df指令查看,如下圖所示:
6.2 制作UBI鏡像
Linux應用程序或數據庫等可能時常需要升級,傳統的辦法是直接拷貝到運行的系統或者重新制作根文件系統再燒錄。拷貝的工作量與設備數量成正比,當有很多設備時,顯然這不是高效的方法。重新制作根文件系統,再燒錄,需要停止運行Linux且燒寫時間較長。如果不是生產燒錄,不建議直接燒錄根文件系統,直接燒錄講求的是一步到位。
針對以上兩個問題,將用戶文件壓制成UBI鏡像并燒錄在一定程度上解決升級的問題。大致流程為:制作UBI鏡像、基于用戶空間燒錄或u-boot燒錄UBI鏡像。
6.2.1 制作UBI鏡像
假設,以userdata目錄為UBI鏡像的源,userdata目錄下包含一個test.txt文件,步驟如下:
1、host# mkfs.ubifs -F -q -r userdata -m 2048 -e 126976 -c 2987 -o userdata_ubifs.img
2、host# ubinize -o userdata.ubi -m 2048 -p 128KiB -s 512 -O 2048 userdata_ubinize.cfg
userdata_ubinize.cfg內容如下:
host#?cat userdata_ubinize.cfg
注:制作容量為373MB、page size為2048 byte的UBI鏡像。
1、host# mkfs.ubifs -F -q -r ubi_volume -m 4096 -e 253952 -c 399 -o ubivolume_ubifs.img
2、host# ubinize -o ubi_volume.ubi -m 4096 -p 256KiB -s 1024 -O 4096 ubivolume.cfg
host # cat ubivolume.cfg
注:制作容量為100MB、page size為4096 byte的UBI鏡像。
6.2.2 燒錄UBI鏡像
將UBI鏡像燒錄指定分區,可在Linux shell中完成,或者在u-boot中單獨燒錄UBI鏡像以及u-boot源碼中添加自動燒寫的指令。當應用程序升級,而根文件系統與內核不升級時,可選擇單獨燒錄UBI鏡像。
1、Linux shell使用指令燒錄;
① 燒寫UBI鏡像,如下圖所示:
EVB-335x# ubiformat /dev/mtd9 -f userdata.ubi
② 掛載分區鏡像,掛載完成后,查看UBI 鏡像的文件,如下圖所示:
EVB-335x?# ubiattach /dev/ubi_ctrl -m 9
EVB-335x?# mount -t ubifs /dev/ubi1_1 /mnt/
UBI鏡像中文件的文件內容與制作UBI鏡像的源文件一致,鏡像燒寫成功。
注意:4096 byte page size的nand燒寫UBI image時,提示offsets不符的warning,如下圖所示。
當選擇y,繼續格式化。然后關聯UBI設備,報錯如下圖所示:
此時,需要指定sub-page與VID header(volume identifier header),指令如下:
HMI-T335# ubiformat /dev/mtd11 -s 1024 -O 4096 -f ubi_volume.ubi
如果由于VID與指定的不一樣,提示“libscan: warning!: inconsistent VID header offset: was 4096, but is 1024 in eraseblock 399”,選擇y繼續。如下圖所示:
關聯設備,也需要指定VID header執行:
HMI-335# ubiattach /dev/ubi_ctrl -m 11 -O 4096
2、在u-boot命令行中燒寫UBI鏡像,首先將鏡像文件(userdata.ubi)保存到TF卡根目錄,然后通過fatload指令讀到RAM的某個地址,再寫入Nand Flash的userdata分區。
U-Boot# mw.b 0x82000000 0xFF
U-Boot# mmc rescan
U-Boot# fatload mmc 0 0x82000000 userdata.ubi
U-Boot# nand erase.part userdata
U-Boot# nand write 0x82000000 userdata ${filesize}
3、u-boot自動燒錄,其原理與u-boot命令行燒錄一樣。自動燒錄,少了人工干預,燒錄工作交由u-boot完成。要想完成自動燒錄,需在board/eac/com335x/board.c文件中,添加如下代碼:
將UBI鏡像(usedata.ubi)保存到TF卡根目錄,連同其他系統鏡像一并燒錄。待系統啟動后,執行以下指令掛載UBI分區,同時可以看到分區中文件,如下圖所示:
EVB-335x?# ubiattach /dev/ubi_ctrl -m 9
EVB-335x?# mount -t ubifs ubi1:userdata /mnt
注:步驟3自動燒錄的代碼,EVB-335x在文件中添加?u-boot-2014.04-rc2-00037-gbaecd31/board/eac/com335x/board.c;HMI-T335在u-boot-2018.01/board/embfly/hmi-t335/board.c文件中添加。
6.3 自動掛載UBI分區
本節介紹基于Linux 3.2.0以及4.14.67版本的內核,分別實現自動掛載UBI分區方法。
6.3.1 Linux 3.2.0 應用舉例
假設,要實現UBI device 1、volume 0、userdata卷標的UBI分區掛載到/mnt目錄。使用前文中分區,UBI最大的可用容量為373MB。
1、在include/configs/com335x.h文件中#define CONFIG_EXTRA_ENV_SETTINGS?定義處,添加黑體字部分的變量,該變量傳遞給Linux kernel,但不會自動掛載,這樣做可減少UBI設備關聯。如下圖所示:
注意:Nand Flash的page size為 2048 byte。
2、在內核中打開arch/arm/mach-omap2/board-com335x.c文件,找到?“static struct mtd_partition com335x_nand_partitions[]”函數,添加”user data”分區。注意同時修改rootfs分區的容量。如下:
3、重新編譯u-boot、Linux 內核,并燒寫到EVB-335x主板。
4、將以下指令寫入腳本:
注:按照/etc/init.d/rcS的命名規則(S??),保存到/etc/init.d目錄(例如:/etc/init.d/S81mountubi.sh),每次都會自動運行掛載userdata分區。
5、分區正常掛載、容量接近UBI鏡像所指定的、且分區內的文件與源一致,則表明UBI鏡像掛載成功。如下圖所:
6.3.2 Linux 4.14.67 應用舉例
512MB、page size為4096 byte的Nand Flash新建2個分區,其中一個為空分區(卷標為userdata),另一個(卷標為ubi_volume)用于燒寫UBI鏡像。假設userdata掛載到/mnt,ubi_volume掛載到/opt。
1、在include/configs/hmi-t335.h文件的#define CONFIG_EXTRA_ENV_SETTINGS?處添加以下環境變量,該變量傳遞給Linux kernel,但不會自動掛載,這樣做可減少UBI設備關聯。
注意:Nand Flash的page size為4096 byte。
2、在configs/hmi-t335-nand-800x480_defconfig文件中添加新分區及指定容量(黑體字部分):
3、在board/hmi-t335/hmi-t335-nand-800x480.dts文件中添加新分區:
注:原rootfs分區的容量改為128MB。
4、重新編譯u-boot、Linux內核,并燒錄到目標設備。啟動日志信息中打印關聯(attach)過程,如下圖。
將掛載指令寫成腳本,并保存到目標板的/etc/init.d/目錄,系統每次運行都會執行這些腳本。腳本的內容如下:
HMI-T335# cat /etc/init.d/S82mountubivolume.sh
HMI-T335?# cat /etc/init.d/S81mountuserdata.sh