精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

3天內不再提示

Tina Linux存儲開發指南

嵌入式Linux那些事 ? 來源:嵌入式Linux那些事 ? 作者:嵌入式Linux那些事 ? 2023-03-06 11:10 ? 次閱讀

Tina Linux 存儲開發指南

1 概述

1.1 編寫目的

介紹TinaLinux Flash,分區,文件系統等存儲相關信息,指導方案的開發定制。

1.2 適用范圍

Tina V3.0 及其后續版本。

1.3 相關人員

適用于TinaLinux 平臺的客戶及相關技術人員。

2 分區管理

2.1 分區配置文件

在全志平臺中,通過sys_partition.fex 文件配置分區。在Tina 中,可以在lunch 選擇方案后,通過命令cconfigs 快速跳轉到分區配置目錄,通常情況下,其路徑如下。

tina/device/config/chips/<芯片編號>/configs/<方案名>/linux/sys_partition.fex

tina/device/config/chips/<芯片編號>/configs/<方案名>/linux/sys_partition_nor.fex

#以上路徑不存在,則使用

tina/device/config/chips/<芯片編號>/configs/<方案名>/sys_partition.fex

?

說明 sys_partition_nor.fex 適用于nor。 sys_partition.fex 適用于rawnand/spinand/mmc。

2.2 分區配置格式

以rootfs 分區為例:

[partition]

name = rootfs

size = 20480

downloadfile = "rootfs.fex"

user_type = 0x8000

每個分區以[partition] 標識,分區屬性及其意義如下表。

屬性 含義 必選 備注
name 分區名 Y
size 分區大小 Y 單位:扇區(512B),注1
downlodefile 分區燒入的鏡像文件 N 注2
verify 量產后校驗標識 N (默認)1:使能;0:禁用,注3
user_type 分區屬性 N 注 4
keydata 量產時是否擦除本分區 N 0x8000:使用;其他無效

說明:

最后一個分區(UDISK),不設置size,表示分配所有剩余空間。

downloadfile 支持絕對路徑和相對路徑,相對于tina/out/<方案名>/image。

verify 決定是否校驗downloadfile 中指定的鏡像,若為ext4 稀疏鏡像,務必禁用。

歷史遺留,目前只對UBI 方案有效。bit0為1 時,表示創建靜態卷,反之為動態卷。

創建downloadfile 的資源鏡像包看章節分區資源鏡像文件。 [partition] 標識用戶空間的邏輯分區,在UBI 方案中,表現為UBI 卷。此外,在sys_partiton.fex中存在特殊的配置MBR,用于配置MBR 空間大小,此配置在UBI 方案中無效。例如:

[mbr]

size = 2048

MBR 分區以Kbyte 為單位,對用戶不可見,屬于隱藏空間,其大小也必須滿足對齊原則。

警告 一般情況下,不建議用戶修改mbr 分區的大小。

2.3 常見分區及其用途

分區名 用途 大小 備注
boot 內核鏡像分區 比實際鏡像等大或稍大即可
rootfs 根文件系統鏡像 比實際鏡像等大或稍大即可
extend 擴展系統鏡像 參考OTA 文檔 參考OTA 文檔僅小容量OTA 方案使用
recovery 恢復系統鏡像 參考OTA 文檔 僅限大容量OTA 方案使用
private 存儲SN、MAC 等數據 使用默認大小即可 量產時默認不丟失
misc 存儲系統狀態、刷機狀態 使用默認大小即可
env 存放Uboot 使用的數據 使用默認大小即可
pstore 內核奔潰日志轉存分區 使用默認大小即可
rootfs_data 根目錄覆蓋分區 根據需求配置 注1
UDISK 用戶數據分區 不需要配置大小 注2

說明:

rootfs_data 分區通過overlayfs 覆蓋根文件系統,以支持squashfs 根文件系統的可寫,此時對根文件系統寫入的數 據實際是保存到rootfs_data 分區,因此rootfs_data 分區的容量標識著根文件系統最大可寫數據量。

UDISK 作為最后一個分區,不需要設置size,表示分配剩余所有空間給UDISK。

2.4 分區大小與對齊

分區大小的對齊要求與不同介質(nor/nand/mmc)、不同存儲方案相關。不按對齊要求配置,可能出現文件系統異常,分區邊界數據丟失等現象。對齊規則如下表。

介質 對齊大小 備注
nor 64K 對齊物理擦除塊大小,注1
(nftl) spinand 驅動超級塊大小 注2
(ubi) spinand 2 × 物理塊- 2 × 頁 注3
rawnand 驅動超級塊大小 與物料相關,16M 對齊可基本兼容
emmc 16M 與物料相關,16M 對齊可基本兼容

說明

nor 的擦除塊常見為64K,即在sys_partition_nor.fex 中分區size 進行128 對齊。在id 表配置為4K 擦除且使能內核CONFIG_MTD_SPI_NOR_USE_4K_SECTORS 時,也可使用4K 對齊。推薦使用默認64K 對齊。

在常見的128M Spi Nand 中,為256K 對齊,即在sys_partition.fex 中分區size 進行512 對齊。

在常見的128M Spi Nand 中,需要和邏輯擦除塊(super block)對齊,1 個super block 包含兩個物理擦除塊,常見的物理擦除塊128K,1 個邏輯的超級塊為256K,但是需要使用每個物理塊的第一個page(2K)來作為ubi 所需的信息頭部,所以實際的為(256k-2*2k),為252K 對齊,即在sys_partition.fex 中分區size 進行504 對齊。

警告 如果分區不對齊,可能會出現以下情況。 ? nor/rawnand/spinand 可能會導致數據丟失。 ? mmc 不會造成數據丟失,但可能導致性能損失。

如果分區使用ubifs 文件系統,分區最小為5M ,否則大概率提示空間不夠。 如果分區使用ext4 文件系統,分區最小為3M ,否則無法形成日志,會有掉電變磚風險。

技巧

在ext4 與日志章節有描述判斷創建的ext4 文件系統是否支持日志的方法。

在分區資源鏡像文件章節指導如何創建帶文件系統的資源鏡像、分區大小、文件系統大小、文件大小更多內容,請參考總容量說明。

2.5 分區與文件系統

常見的分區與文件系統對應關系如下表。

分區名 默認文件系統 文件系統特性 備注
rootfs squashfs 壓縮、只讀 為了安全,根文件系統建議只讀
rootfs_data jffs2/ext4/ubifs 可寫 注1
UIDSK jffs2/ext4/ubifs 可寫 注1
boot vfat 裸數據分區,部分方案為vfat
private vfat 注2
misc none 裸數據分區
env none 裸數據分區
pstore pstore 轉存奔潰日志

說明

可寫的分區,nor 為jffs2;UBI 方案為ubifs;其他為ext4。

private 默認為裸數據,使用dragonSN 工具燒錄后會成為vfat 文件系統。

只讀文件系統推薦使用squashfs。可寫文件系統,nor 推薦jffs2,UBI 方案推薦ubifs,其他推薦ext4。更多文件系統信息,請參考文件系統支持情況。

2.6 分區資源鏡像文件

在sys_partition.fex中通過downloadfile 指定需要燒錄到分區的資源鏡像文件。大多數情況下,資源鏡像文件都構建在文件系統上,通過某些命令實現把系統需要的文件,例如音頻文件、視頻文件等資源,打包成一個帶文件系統的鏡像包,并在燒錄時把鏡像包燒寫入存儲 介質。 創建不同文件系統鏡像的命令不一樣,常見有以下幾種:

文件系統 創建鏡像命令
vfat mkfs.vfat
ext4 make_ext4fs
ubifs mkfs.ubifs
squashfs mksquashfs4

為了最大程度利用空間,一般會使文件系統等于物理分區大小,即創建文件系統時使用分區表劃定的分區大小來創建。

如果不希望硬編碼大小,則可在打包時從分區表獲得大小,再傳給文件系統創建工具,具體的實現可以參考tina/scripts/pack_img.sh 中的make_data_res() 和make_user_res() 等函數。

2.6.1 創建squashfs 鏡像

生成squashfs 的命令,可參考編譯過程的log 得到,或者在網上搜索squashfs 生成方式。 例如在scripts/pack_img.sh 中定義一個函數

function make_user_squash()

{

local SOURCE_DATE_EPOCH=$(${PACK_TOPDIR}/scripts/get_source_date_epoch.sh)

# 這一行指定要打包到文件系統的數據

local USER_PART_FILE_PATH=${PACK_TOPDIR}/target/allwinner/方案名字/user_sq

local USER_PART_SQUASHFS=${PACK_TOPDIR}/out/${PACK_BOARD}/image/user_sq.squashfs

local USER_PART_DOWNLOAD_FILE=${PACK_TOPDIR}/out/${PACK_BOARD}/image/user_sq.fex

cd ${ROOT_DIR}/image

[ -e $USER_PART_FILE_PATH ] && {

#這里用了gzip,需要更高壓縮率可改成xz

${PACK_TOPDIR}/out/host/bin/mksquashfs4 $USER_PART_FILE_PATH $USER_PART_SQUASHFS

-noappend -root-owned -comp gzip -b 256k

-processors 1 -fixed-time $SOURCE_DATE_EPOCH

dd if=${USER_PART_SQUASHFS} of=${USER_PART_DOWNLOAD_FILE} bs=128k conv=sync

}

cd -

}

找個地方調用下即可。 這里不用傳入分區表的原因是,制作squashfs 不需要指定文件系統大小,只讀的文件系統大小完全取決于文件內容。

2.6.2 創建vfat 鏡像

mkfs.vfat <輸出鏡像> -C <文件系統大小>

mcopy -s -v -i <輸出鏡像> <資源文件所在文件夾>/* ::

可參考pack_img.sh(在其中搜索mkfs.vfat 找到相關代碼)。

2.6.3 創建ext4 鏡像

使用tina/out/host/bin/make_ext4fs 創建ext4 鏡像,推薦的使用方法如下:

make_ext4fs -l <文件系統大小> -b <塊大小> -m 0 -j <日志塊個數> <輸出的鏡像保存路徑> <資源文件所在文件

夾>

其中, ? -m 0: 表示不需要要為root 保留空間。 ? -j < 日志塊個數>: 日志總大小為塊大小* 日志塊個數。

例如:

make_ext4fs -l 20m -b 1024 -m 0 -j 1024 ${ROOT_DIR}/img/data.fex ${FILE_PATH}

如果空間不夠大,會顯示類似如下的錯誤日志:

$ ./bin/make_ext4fs -l 10m -b 1024 -m 0 -j 1024 data.fex ./bin

Creating filesystem with parameters:

Size: 10485760

Block size: 1024

Blocks per group: 8192

Inodes per group: 1280

Inode size: 256

Journal blocks: 1024

Label:

Blocks: 10240

Block groups: 2

Reserved blocks: 0

Reserved block group size: 63

error: ext4_allocate_best_fit_partial: failed to allocate 7483 blocks, out of space?

上述錯誤中,資源文件達到100+M,但是創建的鏡像-l 指定的大小只有10M,導致空間不夠而報錯。只需要擴大鏡像大小即可。 如需使用分區大小作為文件系統大小,可參考pack_img.sh(在其中搜索make_ext4fs 找到相關代碼)。

技巧 鏡像大小可以根據分區大小設置,也可以根據資源大小設置,后通過稀疏和resize 處理,即可保證最短燒錄時間和動態匹配分區大小。見稀疏ext4 鏡像和動態resize 章節。

2.6.3.1 稀疏ext4 鏡像

如果資源文件只有10M,但創建了100M 的鏡像文件,導致燒錄100M 的文件拖慢了燒錄速度。此時可以采用稀疏ext4 鏡像。

tina/out/host/bin/img2simg <原鏡像> <輸出鏡像>

稀疏鏡像的原理,類似與把文件系統沒用到的無效數據全刪掉,把文件系統壓縮。可參考pack_img.sh 中的函數sparse_ext4() 的實現與運用。

2.6.3.2 動態resize

如果擔心創建鏡像時指定的大小與實際的分區大小不匹配,可以在設備啟動后執行resize2fs 動態調整文件系統的大小。 例如:

resize2fs /dev/by-name/UDISK

命令后不指定大小,則默認為分區大小。通過這方法可以讓打包鏡像創建的文件系統大小匹配分區大小。 此命令可直接寫入啟動腳本,在掛載前執行。每次啟動都執行一遍不會有不良影響。

2.6.4 創建ubifs 鏡像

使用tina/out/host/bin/make.ubifs 創建ubifs 鏡像,推薦的使用方法如下:

mkfs.ubifs -x <壓縮方式> -b <超級頁大小> -e <邏輯擦除塊大小> -c <最大邏輯擦除塊個數> -r <資源文件所在 文件夾> -o <輸出的鏡像保存路徑> 壓縮方式可選none lzo zlib, 壓縮率zlib > lzo > none 對常見的128MB spinand,1 page = 2048 bytes, 1 block = 64 page, 則 超級頁大小為2048 * 2 = 4096 邏輯擦除塊大小為2048 * 2 * 64 = 262144 最大邏輯擦除塊個數,可簡單設置為一個較大的值,例如128MB / ( 2048 bytes * 2 * 64) = 512 則最終的命令為: mkfs.ubifs -x zlib -b 4096 -e 262144 -c 512 -r ${FILE_PATH} -o ${ROOT_DIR}/img/data_ubifs. fex

2.7 根文件系統改用ubifs

使用suqashfs + overlayfs(ubifs) 方案實現根目錄可寫,但是ubifs 會占用大量的空間存放元數據,造成空間浪費。理論上,UBIFS 可直接作為根文件系統,其穩定性和可壓縮性足夠保證安全和提高空間利用率。

警告 請謹慎使用,UBIFS 作為根文件系統只是理論安全,全志暫無量產方案佐證。

修改步驟如下:

執行cdevice ,修改跳轉目錄下的Makefile 在FEATURES 變量中添加ubifs 和nand

執行make menuconfig 使能在Target Image 頁面下使能ubifs 在Utilities->mtdutils 頁面中使能mtd-utils-mkfs.ubifs

執行cconfigs ,修改跳轉目錄下的env-XXX.cfg 把rootfstype 值改為ubifs 在對應 存儲介質的setargs_XXX 的root 值改為root=ubi0_X ,其中X 表示對應的第幾個分區;刪除 ubi.block 項。

執行make kernel_menuconfig,取消使能overlayfs

在sys_partition.fex 中刪除rootfs_data 分區

2.8 總容量說明

在全志的驅動中,會預留一部分空間存儲特殊數據,因此提供給用戶分區空間不等于實際Flash總容量。

分區表可用空間= flash總容量- 保留空間

不同存儲介質,其保留空間會有差異。

存儲介質 保留空間 備注
nor 512K 對應bootloader 分區,包含分區表,boot0,uboot
(nftl) nand 總容量的1/10~1/8 注1,注2
(UBI) spinand
mmc 20M 包含boot0,uboot 等

最新spinor 的存儲分布, 隱藏空間1MB,其中mbr 占用16KB,mbr 往前共占用1008KB,uboot 往前共占用64KB,其中包括boot0 和uboot 中間4KB 的預留區域,這段區域用于存放flash 的spi 采樣點等信息。

|boot0|4kb|uboot|mbr |分區表可見的用戶分區|

說明

(nftl) nand 的隱藏空間對用戶不可見,包含分區表MBR 分區,boot0,uboot, 磨損算法、壞塊保留等。對128M 的 spinand 來說,用戶可用空間一般為108M。

由于出廠壞塊的存在,可能會導致每一顆Flash 呈現的用戶可用總容量不同,但全志(nftl) nand 保證總容量不會隨著使 用過程出現壞塊而導致可用容量減少。

UBI 方案中,除了必要的mtd 物理分區之外(boot0/uboot/pstore 等),其余空間劃分到一個mtd 物理分區。在此 mtd 物理分區中根據sys_partition.fex 的劃分構建ubi 卷。UBI 的機制,每個塊都需要預留1~2 個頁作為EC/VID 頭。因此可用容量會小于mtd 物理分區容量。

對于非ubi 方案,用戶空間可通過下面的命令查看用戶可用分區大小,大小單位為KB。

# cat /proc/partitions major minor #blocks name 93 0 112384 nand0 93 1 256 nand0p1 93 2 5120 nand0p2 93 3 10240 nand0p3 93 4 10240 nand0p4 93 5 7168 nand0p5 93 6 64 nand0p6 93 7 512 nand0p7 93 8 256 nand0p8 93 9 76463 nand0p9

如例子中的結果,nand0 分為多個分區,每個nand0px 對應一個分區表中的分區。對于ubi 方案,整個nand 分為若干mtd。可使用以下命令查看

# cat /proc/mtd dev: size erasesize name mtd0: 00100000 00040000 "boot0" mtd1: 00300000 00040000 "uboot" mtd2: 00100000 00040000 "secure_storage" mtd3: 00080000 00040000 "pstore" mtd4: 07a80000 00040000 "sys"

如例子中的結果,整個nand 分為5 個mtd。 ? mtd0 存放boot0, size 1 MB ? mtd1 存放uboot, size 3 MB ? mtd2 存放secure_storage, size 1 MB ? mtd3 存放pstore, size 512 KB ? mtd4 則會進一步分為多個ubi 卷,占用剩余所有空間

以上所有mtd 的size 相加,應該恰好等于flash 總size。分區表中定義的每個邏輯分區,會對應mtd sys 上的ubi 卷。可使用以下命令查看

# ubinfo -a UBI version: 1 Count of UBI devices: 1 UBI control device major/minor: 10:51 Present UBI devices: ubi0 ubi0 Volumes count: 12 Logical eraseblock size: 258048 bytes, 252.0 KiB Total amount of logical eraseblocks: 489 (126185472 bytes, 120.3 MiB) Amount of available logical eraseblocks: 0 (0 bytes) Maximum count of volumes 128 Count of bad physical eraseblocks: 1 Count of reserved physical eraseblocks: 19 Current maximum erase counter value: 3 Minimum input/output unit size: 4096 bytes Character device major/minor: 247:0 Present volumes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 Volume ID: 0 (on ubi0) Type: static Alignment: 1 Size: 1 LEBs (258048 bytes, 252.0 KiB) Data bytes: 258048 bytes (252.0 KiB) State: OK Name: mbr Character device major/minor: 247:1 ----------------------------------- Volume ID: 1 (on ubi0) Type: dynamic Alignment: 1 Size: 2 LEBs (516096 bytes, 504.0 KiB) State: OK Name: boot-resource Character device major/minor: 247:2 ----------------------------------- ... #此處省略若干卷 ----------------------------------- Volume ID: 11 (on ubi0) Type: dynamic Alignment: 1 Size: 242 LEBs (62447616 bytes, 59.6 MiB) State: OK Name: UDISK Character device major/minor: 247:12

如例子中的結果 ? volume 0 為mbr, 占1 LEBs(252 KB),對應分區表本身 ? volume 1 為boot-resource, 占2 LEBs(504 KB),對應分區表中第一個分區 ? … ? volume 11 為UDISK, 占242 LEBs(59.8 MB),對應分區表中最后一個分區 常見的關于容量的疑惑與解答。

問:df 查看UDISK 分區大小,明明分區有50M,怎么顯示總大小只有40+M? 答:df 顯示的是文件系統的大小,文件系統本身需要額外的空間存儲元數據,導致實際可用空間 會比分區大小略少。

問:df 查看boot 分區大小,為什么顯示的大小比實際分區大? 答:boot 分區是通過鏡像燒寫的形式格式化的fs,創建鏡像時設置的文件系統的大小并不等于分 區實際大小,導致此時文件系統大小并不能體現實際分區大小。

問:df 查看squashfs 使用率總是100%? 答:squashfs 是只讀壓縮文件系統,文件系統大小取決于總文件大小,使用率總是100%,跟分 區大小無關。

說明

文件大小 我們常說的文件大小,指的是文件內容有多少字節。但在一個文件系統中,空間分配以塊為單位,必然會造成內部碎片。假 設塊為4K,如果文件大小為1K,文件系統依然為其分配4K 的塊,就會造成3K 的空間浪費。

文件系統大小 文件系統大小,指的是文件系統元數據中標識的可用大小。形象來說,是df 命令或者statfs() 函數反饋的大小。文件系 統大小不一定等于分區大小,既可大于分區大小,也可小于分區大小。

分區大小 在劃分分區時規定的大小,往往是sys_partition.fex 中指定的大小。

2.9 特殊隱藏空間

不管是nor,nand 還是mmc,都需要一些隱藏空間存儲特殊數據,例如boot0/uboot/dtb/sys_config。用戶無法使用這些隱藏空間。 此外,nand 驅動還需要額外的空間以實現磨損平衡、壞塊管理算法,因此nand 的隱藏空間更大。

隱藏空間大小見總容量說明。

3 系統掛載

Tina 目前支持兩種啟動方式,分別是busybox 和procd,不同啟動方式,其自動掛載的配置不同。 此處的自動掛載指開機冷掛載以及熱插拔掛載,其中冷掛載指啟動時掛載,熱掛載指TF/U 盤等插拔設備時的掛載。

3.1 塊設備節點

Tina 中設備節點都在/dev 目錄下,對于不同存儲介質,生成的設備節點會不一樣。

存儲 介質設備 節點備注
nand /dev/nand{a,b,c…} MBR 分區表
nand /dev/nand0p{1,2,3…} GPT 分區表
mmc /dev/mmcblk0p{1,2,3…}
nor /dev/mtdblock{0,1,2…}
TF 卡/dev/mmcblk{0,1}p{1,2…} 注1
U 盤 /dev/sda{1,2…}
SATA 硬盤/dev/sda{1,2…}

說明

若使用mmc 做內部存儲介質,由于mmc 占用了mmcblk0的設備名,此時TF 卡的設備名序號遞增為mmcblk1,否則生 成mmcblk0的設備名。因此配置fstab 時尤其注意TF 設備名是否正確。 對sys_partition.fex 中設置的內部存儲介質的設備節點,會自動動態在/dev/by-name 中創建軟鏈 接。例如:

root@TinaLinux:/# ll /dev/by-name/ drwxr-xr-x 2 root root 220 Mar 1 15:05 . drwxr-xr-x 7 root root 3060 Mar 1 15:05 .. lrwxrwxrwx 1 root root 12 Mar 1 15:05 UDISK -> /dev/nand0p9 lrwxrwxrwx 1 root root 12 Mar 1 15:05 boot -> /dev/nand0p2 lrwxrwxrwx 1 root root 12 Mar 1 15:05 env -> /dev/nand0p1 lrwxrwxrwx 1 root root 12 Mar 1 15:05 misc -> /dev/nand0p6 lrwxrwxrwx 1 root root 12 Mar 1 15:05 private -> /dev/nand0p8 lrwxrwxrwx 1 root root 12 Mar 1 15:05 pstore -> /dev/nand0p7 lrwxrwxrwx 1 root root 12 Mar 1 15:05 recovery -> /dev/nand0p5 lrwxrwxrwx 1 root root 12 Mar 1 15:05 rootfs -> /dev/nand0p3 lrwxrwxrwx 1 root root 12 Mar 1 15:05 rootfs_data -> /dev/nand0p4

因此,在fstab 也可以使用/dev/by-name/XXXX的形式匹配設備。塊設備如果有分區,會形成分區設備節點,以mmc、U 盤為例介紹設備節點名與分區的關系:

設備節點名 含義
/dev/mmcblk0 表示整個mmc 空間,包含所有分區
/dev/mmcblk0p1 表示mmc 中的第1 個分區
/dev/mmcblk0p2 表示mmc 中的第2 個分區
/dev/sda 表示整個U 盤,包含所有分區
/dev/sda1 表示U 盤內的第1 個分區
/dev/sda2 表示U 盤內的第2 個分區

熱插拔塊設備分區有以下特殊情況。

塊設備沒有分區 有一些特殊的TF 卡/U 盤沒有分區,而是直接使用整個存儲,表現為只有/dev/mmcblk1 和 /dev/sda ,而沒有分區節點/dev/mmcblk1p1 和/dev/sda1 。此時需要直接掛載整個存儲 設備,Tina 大部分方案都支持這種特殊情況。

塊設備有多個分區 有一些特殊的TF 卡/U 盤被分為多個分區,表現為存在多個/dev/mmcblk1p{1,2…} 和 /dev/sda{1,2…}。默認情況下,Tina 的fstab 配置為只支持掛載熱插拔存儲設備的第一個 分區到/mnt/SDCARD 或者/mnt/exUDISK。

3.2 掛載點

3.2.1 默認掛載設備目錄

Tina 中對常見的分區和熱插拔塊設備,有默認的掛載點。

存儲介質 掛載節點 設備節點 備注
nor/nand/mmc /mnt/UDISK /dev/by-name/UDISK 注1
TF 卡 /mnt/SDCARD 或/mnt/extsd /dev/mmcblk{0,1}p1 注2
U 盤 /mnt/exUDISK /dev/sda1 注3
SATA 磁盤 /mnt/exUDISK /dev/sda1 注3

說明

/dev/by-name/UDISK 為sys_partition.fex 的UDISK 分區的軟連接。

當無分區時,默認掛載整個TF 卡; 當有1 個或多個分區時,只掛載第一分區。

當無分區時,默認掛載整個設備(/dev/sda),當有1 個或多個分區時,只掛載第一個分區。

3.2.2 新建掛載點

掛載文件系統需要有掛載點。 如果掛載點所在目錄可寫,則在掛載之前先創建目錄即可。

mkdir -p xxx

若掛載點所在目錄為只讀,則需要在制作文件系統時提前創建好。 如創建非空目錄,則在對應方案的base-files 目錄創建。

procd-init: target/allwinner/方案/base-files busybox-init: target/allwinner/方案/busybox-init-base-files

如創建空目錄,由于git 不管理空目錄,因此需在Makefile 中動態創建,可仿照現有Makefile中創建UDISK 目錄的寫法。

procd-init: package/base-files/Makefile busybox-init: package/busybox-init-base-files/Makefile

3.3 procd 啟動下的掛載

procd 啟動時,自動掛載由procd、fstools、fstab 配合完成。如果需要修改冷/熱掛載規則,只需要修改fstab 配置文件即可。 SDK 中,配置文件位于:

tina/target/allwinner/<方案名>/base-files/etc

若只是調試或臨時修改掛載規則,只需要修改小機端的配置文件:

/etc/config/fstab

3.3.1 fstab 編寫格式

fstab 由多個config 組成,每個config 的基本格式示例如下:

config ‘xxxx’ option xxxx ‘xx’ option xxxx ‘xx’ option xxxx ‘xx’

config 有3 種類型,分別是mount|global|swap 。Tina SDK 中沒使用swap,在本文中不做介紹。

3.3.2 global 類型config

global 類型的config 是全局配置,示例如下。

config 'global' option anon_swap '0' option anon_mount '0' option auto_swap '1' option auto_mount '1' option delay_root '5' option check_fs '1'

配置項的意義如下表:

配置名稱 可選值 意義
anon_mount 0/1 注1
anon_swap 0/1 swap 使用,此處省略
auto_mount 0/1 只適用于設置熱插拔是否自動掛載塊設備
auto_swap 0/1 swap 使用,此處忽略
check_fs 0/1 建議配置為1,注2
delay_root 1,2,3… 注3

說明

anon_mount: 當fstab 中無匹配要掛載設備的uuid/label/device 屬性的配置節時, 是否采用默認掛載為 /mnt/“$device-name”。

check_fs: 是否在掛載前用/usr/sbin/e2fsck 檢查文件系統一致性(只適用于ext 系統)。

delay_root: 對應fstab 中target 為”/” 或”/overlay” 的設備節點不存在時,最長等待delay_root 秒。

3.3.3 mount 類型config

mount 類型的config 是具體的設備掛載配置,示例如下

config 'mount' option target '/mnt/UDISK' option device '/dev/by-name/UDISK' option options 'rw,sync' option enabled '1'

配置項的意義如下表:

配置名稱 意義 備注
target 掛載點 必須是絕對路徑,必須有效
device 設備名 通過設備名指定待掛載的設備,注1
uuid 設備UUID 通過fs 的UUID 指定待掛載的設備,注1
label 設備label 通過fs 的label 指定待掛載的設備,注1
enabled 是否使能 該節點是否有效(0/1)
options 掛載屬性 例如只讀掛載等,注2

device/uuid/label 是匹配掛載的設備,三者中至少要有一個有效。

默認掛載支持的屬性如下表:

配置名稱 意義 缺省值
ro / rw 只讀/ 可讀寫 rw
nosuid / suid 忽略suid/sgid 的文件屬性 suid
nodev / dev 不允許/允許訪問設備文件 dev
noexec / exec 不允許/允許執行程序 exec
sync / async 同步/異步寫入 async
mand / nomand 允許/不允許強制鎖 nomand
irsync 同步更新文件夾 無效
noatime / atime 不更新/更新訪問時間(atime) atime
nodiratime / diratime 不更新/更新目錄訪問時間(atime) diratime
relatime / norelatime 允許/不允許根據ctime/mtime 更新actime n orelatime
strictatime 禁止根據內核行為來更新atime, 但允許用戶空間修改 無效

3.4 busybox 啟動下的掛載

busybox 啟動時,通過pseudo_init 和rcS 完成大部分默認的掛載工作。

存儲節點 掛載路徑 用途
/dev/by-name/UDISK /mnt/UDISK 用戶數據
/dev/by-name/rootfs_data /overlay 作為overlay 使得rootfs 可寫
/dev/mmcblk{0,1}p1 /mnt/SDCARD 或/mnt/extsd TF 卡
/dev/sda1 /mnt/exUDISK U 盤

busybox 啟動使用默認掛載配置即可,如果需要修改,需要自行修改腳本。

tina/package/busybox-init-base-files/busybox-init-base-files/usr/bin/hotplug.sh

3.5 掛載文件系統

在分區表中增加的分區默認是空分區,如需掛載成文件系統使用,則首先需要在分區中寫入一個文件系統。 方式一,在PC 端預先生成好一個文件系統,并在分區表中指定為download_file,則啟動后可直接掛載。例如rootfs 分區就是在PC 端制作好文件系統,燒錄時寫入rootfs 分區。 方式二,在小機端進行格式化。例如UDISK 分區就是在第一次啟動時,由啟動腳本進行格式化。客戶可自行在某一啟動腳本或應用中調用格式化工具(mkfs.xxx)進行格式化。如需參考,可仿照UDISK 分區的格式化:

procd-init: package/base-files/files/lib/preinit/79_format_partition busybox-init: package/busybox-init-base-files/files/pseudo_init

3.5.1 注意事項

一些格式化工具并未默認選中,需要時請自行在make menuconfig 界面配置。部分文件系統對分區大小有最低要求,如ext4,ubifs,如果在小機端調用格式化分區時報錯,可根據報錯信息提示增大分區。 對于private 分區默認為空,使用DragonSN 工具寫號后,則為vfat 格式的文件系統。對于ubi 方案來說,如果需要使用基于塊設備的文件系統,則需要在ubi 之上模擬塊設備。在用戶空間可調用ubiblock 工具完成,注意這樣模擬出的塊設備是只讀的,如需可寫建議直接使用 ubifs。

詳見后文ubi 方案特殊說明。

4 文件系統支持情況

存儲介質 jffs2 squashfs ext4 vfat ntfs exfat ubifs
(NFTL) nand N Y Y Y Y N N
(UBI) spinand N Y Y(ro) Y(ro) Y(ro) N Y
mmc N Y Y Y Y N N
nor Y Y N N N N N
TF 卡 N N Y Y Y N N
U 盤 N N Y Y Y N N

說明

(ro) 表示只能實現只讀: ubi 卷可通過模擬塊設備,實現塊文件系統的讀,但不支持寫。

vfat(fat32)使用內核原生的支持,exfat 需要在Linux-5.7 后社區才正式支持,因此此處標注為不支持。

ntfs 依賴于第三方工具ntfs-3g。

TF 卡/U 盤等,建議使用vfat 實現Window/Linux/MacOS 的最大兼容參考文章《多平臺大型文件系統比較》。

vfat/ntfs/exfat 等Window 文件系統,不建議用做嵌入式存儲,除非您能保證其掉電安全和移植文件系統修復工具。

警告 關于文件系統的選擇,有以下幾點需要注意:

全志NFTL nand 可使用塊文件系統(ext4) 全志在驅動中實現磨損平衡和壞塊管理,向上呈現為塊設 備。因此可支持ext4,不需要且不支持常見的flash 文件系統(jffs2/yaffs/ubifs 等)。

為了保證掉電不變磚,根文件系統務必只讀(squashfs),或者ext4 掛載為ro 模式。

ext4/ubifs 等文件系統分區大小必須足夠大,以確保能正確創建日志塊,否則有掉電變磚風險分區大小 請參考章節分區大小與對齊。

4.1 ext4 與日志

4.1.1 ext4 的日志

與服務器等長期穩定供電的情況不同,嵌入式設備隨時有掉電的可能。不管在任意時間掉電,文件系統都需要保持一致性,換句話說,保證文件不會因為掉電丟失。如果文件系統只讀,則不需要日志。日志只是確保寫的安全。

說明 什么是文件系統的一致性? 文件系統元數據塊記錄了有什么文件,數據塊則保存了實際的文件內容。一致性則表示,元數據塊記錄了存在某個文件,必定存 在對應的數據塊,換句話說,就是保證元數據和數據的一致。 如果出現,元數據記錄文件A 存在,但文件A 的數據塊是無效的,或者明明數據塊是有效的,但元數據并沒任何記錄,導致系 統并不知道文件存在,就出現了文件系統的不一致。

警告 保證文件不丟失,只保證之前寫入的文件數據正常,而非正在寫,且因為掉電導致沒寫完整的文件。對大多數文 件系統而言,更多時候會直接丟棄這沒寫完整的文件以保證一致性。

ext4 通過日志的形式保證文件系統一致性。其支持3 種日志模式:

日志模式 原理 特點
journal 元數據與數據都寫入日志 最安全,但性能最慢
writeback 只有元數據寫入日志,但不保證數據先落盤 性能最快,但最不安全
ordered 只有元數據寫入日志,且保證數據先落盤,元數據后落盤 折中,默認方案

考慮安全和性能的折中,建議使用ordered 的日志模式。系統默認使用的就是ordered 模式。我們在mount 命令中顯示的掛載參數可顯示使用的哪種日志。

$mount /dev/by-name/UDISK on /mnt/UDISK type ext4 (rw,....,data=ordered)

4.1.2 分區大小與日志

有時候分區太小,系統會默認把日志功能關閉。可以通過以下方法判斷:

$dumpe2fs <分區or 鏡像文件> ... Filesystem features: has_journal ... ... Journal backup: inode blocks Journal features: (none) 日志大小: 1024k Journal length: 1024 Journal sequence: 0x00000001 Journal start: 0 ...

在Filesystem features 中有has_journal 的標志表示支持日志。在Jorunal 片段中也詳細描述了日志塊的大小等信息。 如果創建的文件系統沒有日志,對大多數用戶而言,擴大分區大小是最簡單的做法。專業的做法可以通過縮小塊大小,取消預留塊等方式為日志騰挪出空間。 按以往經驗,對小容量(<100M) 的存儲而言,在資源文件之外預留3-5M 的空間用于文件系統的元數據即可。

4.1.3 修復ext4

ext4 文件系統每次重啟后,建議都進行一次修復,確保文件系統穩定。 修復可以參考以下命令:

e2fsck -y <分區>

4.1.4 修復fat

TF 卡掛載fat 文件系統,fat 文件系統不是日志型文件系統,在掉電、帶電插拔等場景下不能保證文件系統數據的安全,所以建議啟動都進行一次修復。修復可以參考以下命令:

fsck_msdos -pfS /dev/mmcblk0p1

如章節global 類型config中描述,如果使用procd 引導啟動,在fstab 中使能check_fs,也可實現在掛載前自動修復。

5 UBI VS. NFTL

對nand 存儲介質,全志有兩套解決方案,分別是NFTL spi/raw nand 和UBI spi nand。UBI 存儲方案常用于小容量spinand,其實現原理跟NFTL 存儲方案完全不同。

5.1 NFTL Nand

這是全志實現的不開源的Nand 驅動,NFTL 全稱為NAND Flash Translation Layer,其可實現屏蔽Nand 的特性,對上呈現為塊設備。 我們常見的mmc 設備也是塊設備,可以簡單理解為,MMC = Nand Flash + 控制器+NFTL。所以通過全志的NFTL nand 驅動后,我們可以像mmc 設備一樣,以塊設備操作Nand。 例如,上層可以直接裸讀寫塊設備,常見的ota 更新也是基于這樣的實現:

dd if=boot.fex of=/dev/by-name/boot

技巧

詳細的OTA 方法,請參見OTA 相關文檔。

全志的NFTL Nand 驅動中,預留一部分空間做算法和關鍵數據保存。預留空間大致為1/10 ~1/8 的可用空間。這里的可用空間是指剔除出廠壞塊之外的空間。由于每一顆Flash 的出廠壞塊數量不盡相同,因此最終呈現給用戶的可用空間不盡相同。用戶也不需要擔心使用過程中出現的壞塊導致用戶可用空間變小,在算法實現中,使用壞塊會體現在預留空間而不是用戶空間。 此外,Nand 的磨損平衡、壞塊管理等特性全由NFTL 驅動實現。換句話說,驅動保證用戶數據的穩定,用戶可將其按塊設備使用。

5.2 UBI (spi) Nand

當前UBI 方案僅適用于小容量spinand。 UBI 方案是社區普遍使用的Flash 存儲方案,其構建在mtd 設備之上,由UBI 子系統屏蔽Nand 特性,對接UBIFS 文件系統。其層次結構由上往下大致如下:

層次 層級 功能
0 (最上層) UBIFS ubifs 文件系統
1 UBI 子系統 Nand 特性管理
2 MTD 子系統 封裝Flash,向上提供統一接口
3 (最下層) Flash 具體的Flash 驅動

我們把MTD 分區稱為物理分區,把UBI 卷(分區) 成為邏輯分區,因為 ? MTD 分區是按Flash 的物理地址區間劃分分區 ? UBI 卷(分區) 是動態映射的區間 全志的UBI 方案中,創建了這些MTD 物理分區:

分區名 大小 作用
boot0 4/8 個物理塊 存放boot0
uboot 4/20M 存放uboot
secure storage 8 個物理塊 存放關鍵數據
pstore 512K 奔潰日志轉存
sys 剩余空間 提供給ubi 子系統劃分邏輯分區

驅動會在sys 的MTD 物理分區上根據sys_partition.fex構建UBI 邏輯分區(卷)。 UBI 設備向上呈現為字符設備,無法直接使用諸如ext4 這樣基于塊設備的文件系統。但UBI 子系統支持模擬只讀的塊設備,即把UBI 邏輯卷模擬成只讀的塊設備。基于此,可以做到根文件系統依然使用squashfs 這樣的塊文件系統。 社區為UBI 設備專門設計了ubifs 文件系統。經過驗證,其配合UBI 子系統可保證數據掉電安全以及提供通用文件系統所有功能,甚至還提供文件系統壓縮功能。 除此之外,UBI 設備更新(OTA 更新)也不能直接裸寫設備,需要通過ubiupdateval 命令更新。 技巧:詳細的OTA 方法,請參見OTA 相關文檔。

5.3 ubi 相關工具

5.3.1 ubinfo

輸出指定ubi 設備信息。 例子:

ubinfo /dev/by-name/rootfs #查看rootfs卷的信息 ubinfo -a #查看所有卷的信息

可參考總容量說明

5.3.2 ubiupdatevol

更新指定卷上的數據。 例子:

ubiupdatevol -t /dev/by-name/boot #清除boot卷的數據 ubiupdatevol /dev/by-name/boot /tmp/boot.img #將/tmp/boot.img寫到boot卷,卷上原有數據會完全丟失

可參考總容量說明

可參考模擬塊設備

5.3.3 ubiblock

基于一個ubi 卷,生成模擬的只讀塊設備 例子:

ubiblock -c /dev/by-name/test #將test卷生成一個塊設備節點

可參考模擬塊設備

5.3.4 其他

在tina 方案上,燒錄固件時已經完成mtd 和ubi 卷的創建,啟動時自動attach 并掛載對應的分區,無需再自行處理。因此以下命令一般不會用到。 ubiformat: 將裸mtd 格式化成ubi ubiattach: 將mtd 關聯到ubi ubidetach: 將ubi 與mtd 解除關聯ubimkvol: 創建ubi 卷 ubirmvol: 移除ubi 卷

6 rootfs_data 及UDISK

6.1 overlayfs 簡介

Tina 默認根文件系統格式使用squashfs 格式,這是一種只讀壓縮的文件系統。很多應用則需要文件系統可寫,特別是/etc 等存放較多配置文件的目錄,為了滿足可寫的需求,Tina 默認使用overlayfs 技術。overlayfs 是一種堆疊文件系統,可以將底層文件系統和頂層文件系統的目錄進行合并呈現。

6.2 使用rootfs_data 作為overlayfs

Tina 常用的方式是專門劃分一個rootfs_data 分區, 先格式化成可寫的文件系統(如ext4/ubifs), 再進一步掛載為overyfs, 成為新的根, 讓上層應用認為rootfs 是可寫的。 rootfs_data 分區的大小就決定了應用能修改多少文件。具體原理和細節請參考網上公開資料,此處僅舉簡單例子輔助理解。

底層(即rootfs 分區的文件系統)不存在文件A,應用創建A,則A 只存在于上層(即 rootfs_data 分區)。

底層存在文件B,應用刪除B,則B 仍然存在于底層,但上層會創建一個特殊文件屏蔽掉,導 致對應用來說B 就看不到了,起到刪除的效果。

底層存在文件C,上層修改C,則C 會先被整個拷貝到上層,C 本身多大就需占用多大的上 層空間,在這個基礎上應用對上層的C 進行修改。 基于以上理解,可按需配置rootfs_data 的大小。一般開發期間會配置得較大,量產時可減小 (考慮實際只會修改少量配置文件)甚至去除(需要確認所有應用均不依賴rootfs 可寫)。

6.3 使用UDISK 作為overlayfs

如果希望overlayfs 的空間盡可能較大,也可考慮直接使用UDISK 分區作為上層文件系統空間。 可將target/allwinner/xxx/base-files/etc/config/fstab 中的rootfs_data 分區及UDISK 分區的掛載配置disable 掉。

config 'mount' option target '/overlay' option device '/dev/by-name/rootfs_data' option options 'rw,sync,noatime' option enabled '0' #此行改成0 config 'mount' option target '/mnt/UDISK' option device '/dev/by-name/UDISK' option options 'rw,async,noatime' option enabled '0'

再新增一個配置,將UDISK 直接掛載到/overlay 目錄。

config 'mount' option target '/overlay' option device '/dev/by-name/UDISK' option options 'rw,sync,noatime' option enabled '1'

6.4 如何清空rootfs_data 和UDISK

出于恢復出廠設置或其他需要,有時需要清空rootfs_data 和UDISK。 一般不建議在文件系統仍處于掛載狀態時直接操作對應的底層分區,因此建議需要清空時,不要直接操作對應塊設備,而是先設置標志并重啟,再在掛載對應分區前的啟動腳本中檢測到對應標志后,對分區進行重新格式化。 當前79_format_partition 中實現了一個clean_parts 功能, 會檢測env 分區中的parts_clean 變量并清空對應分區的頭部。清空后,rootfs_data 和UDISK 分區會自動重新觸發格式化。

# to clean rootfs_data and UDISK, please run fw_setenv parts_clean rootfs_data:UDISK reboot

具體實現請查看

package/base-files/files/lib/preinit/79_format_partition

7 關鍵數據保護

設備上保存的一些關鍵的數據,例如mac,SN 號等,一般要求在重新刷機時不丟失。以下介紹刷機數據不丟失的解決方案。

7.1 邏輯分區保護方案

7.1.1 分區設置

此處的邏輯分區,是指在分區表(sys_partition.fex/sys_partition_nor.fex) 中定義的分區。名字為private 的分區會特殊處理,默認刷機數據不丟失。 其他名字的分區,如果指定keydata=0x8000 屬性,則刷機數據不丟失。對于private 分區或設置了keydata=0x8000 屬性的分區,請勿設置downloadfile。

7.1.2 實現原理

對private 分區(配置了keydata=0x8000 屬性同理) 保護的方式是,擦除之前先申請一片內存,然后根據flash 中的舊分區表,讀出private 分區內容。 接著進行擦除,然后再按照新的分區表,將private 分區內容寫回flash 上新分區所在位置。

7.1.3 常見用法

使用全志的DragonSN 工具,選擇私有key 模式,將key 寫入private 分區。寫入后private分區默認會是一個vfat 文件系統,啟動后掛載/dev/by-name/private,即可讀出key。DragonSN 的具體用法請參考工具自帶文檔。

不使用DragonSN 工具, 由應用自行負責寫入數據和讀出數據, 直接在用戶空間操作/dev/by-name/private 節點即可。量產時可自行開發PC 端工具,通過adb 命令來完成key 的寫入。

7.1.4 ubi 方案特殊說明

7.1.4.1 模擬塊設備

對于nand nftl 方案,emmc 方案,nor 方案,邏輯分區是對應到一個塊設備,即對于private分區,可以直接讀寫/dev/by-name/private 節點,也可以借助DragonSN 工具制作成一個vfat文件系統,再掛載使用,掛載后文件系統是可讀寫的。 但對于nand ubi 方案,邏輯分區是對應到ubi 卷,由于ubi 的特性,無法再直接寫數據到/dev/by-name/private 節點,需要通過ubiupdatevol 工具來更新卷,或者自行在應用中按照ubi 卷更新步驟操作。 當基于ubi 卷構建vfat 文件系統時,需要先基于ubi 卷模擬塊設備,且掛載上的vfat 文件系統是只讀的。操作示例如下。

#查看private分區對應的ubi節點 root@TinaLinux:/# ll /dev/by-name/private lrwxrwxrwx 1 root root 11 Jan 1 00:00 /dev/by-name/private -> /dev/ ubi0_4 #創建模擬的塊設備 root@TinaLinux:/# ubiblock -c /dev/ubi0_4 block ubiblock0_4: created from ubi0:4(private) #掛載 root@TinaLinux:/# mkdir /tmp/private root@TinaLinux:/# mount -t vfat /dev/ubiblock0_4 /tmp/private/ #可以讀取內容 root@TinaLinux:/# ls /tmp/private/ ULI magic.bin #查看掛載情況,為ro root@TinaLinux:/# mount | grep private /dev/ubiblock0_4 on /tmp/private type vfat (ro,relatime,fmask=0022,dmask=0022,codepage=437, iocharset=iso8859-1,shortname=mixed,errors=remount-ro)

7.1.4.2 在設備端制作vfat 鏡像

由于ubifs 需占用17 個LEB,比較占空間,對于只在工廠一次性寫入信息,后續只讀的場景,一種可考慮的方案是使用vfat 文件系統。 首先選上kernel 的loopback 支持:

make kernel_menuconfig 選上Device Drivers --> [*] Block Devices --> <*>Loopback device support

分區表中建立分區,假設為test 分區隨后可以在小機端準備一個vfat 鏡像:

dd if=/dev/zero of=/mnt/UDISK/test.img bs=1M count=1 mkfs.vfat /mnt/UDISK/test.img mkdir -p /tmp/test mount /mnt/UDISK/test.img /tmp/test 此時可向/tmp/test 寫入文件 umount /tmp/test

將鏡像寫入卷中:

ubiupdatevol /dev/by-name/test /mnt/UDISK/test

后續按上文介紹的方法,使用模擬塊設備掛載,注意使用模擬塊設備掛載后就是只讀的了。

7.1.5 可能造成數據丟失的情況

出現以下情況,會導致private 分區數據丟失。

配置了強制擦除,例如sys_config.fex 中配置了eraseflag = 0x11。

無法讀取flash 上的分區表或private 分區。這個可能的原因包括flash 上的數據被破壞了 等。

新的分區表不包含private 分區。

在燒錄過程中掉電。如上所述,燒錄時是讀出-> 擦除-> 寫回,在擦除之后,寫回之前掉電,則數據丟失。 檢測到private 分區,開始執行保護private 分區的代碼,但執行過程中出錯,如malloc 失敗,private 無法讀取等,則會導致燒錄失敗。出現malloc 失敗問題一般是因為板子上燒錄了Android固件。因為安卓的private 分區比較大,而tina 的uboot 分配給malloc 的空間比較小。 這個時候,需要打包一份不保護private 分區的tina 固件先進行一次燒錄,即可解決問題。具體的:將sys_config.fex 的eraseflag 改為0x11,強制擦除。或者臨時移除sys_partition.fex中的private 分區。

7.2 物理區域保護方案

另一種保護數據不丟失的思路是,在flash 上劃定一塊物理區域,燒錄時默認不擦除。在Tina 上實現的secure storage 區域即具有這種特性。secure storage 區域用于保存key,可代替private 分區,理論上更為安全(被燒錄時誤擦除和被別的應用誤寫的可能性較低)。

7.2.1 nand nftl 方案實現

nand nftl 方案中,預留了一塊物理區域,用于secure storage。這塊區域不是邏輯分區,用戶空間不可見。燒錄時不會擦除這塊區域。在用戶空間讀寫secure storage 需要使用ioctl,由內核nand 驅動來協助完成。

7.2.2 nand ubi 方案實現

nand ubi 方案中,預留了一塊物理區域,用于secure storage,對上表現為一個mtd 分區。用戶空間可見。燒錄時不會擦除這塊區域。在用戶空間讀寫secure storage 需要使用ioctl,由內核來協助完成。理論上也可以直接讀寫mtd 設備節點,但不推薦,使用這種方式應用需要自行處理壞塊等問題。

7.2.3 emmc 方案實現

預留了一塊物理區域,默認是偏移6M-6.25M 的區域,作為secure storage。在用戶空間讀寫,可以直接通過mmcblk0 節點讀寫指定偏移。

7.2.4 nor 方案實現

暫未實現。

7.2.5 常見用法

使用全志的DragonSN 工具,選擇安全key 模式,將key 寫入secure storage 區域。啟動后在用戶空間調用庫讀出key。DragonSN 的具體用法請參考工具自帶文檔。

不使用DragonSN 工具,由應用自行在用戶空間調用庫寫入數據和讀出數據。量產時可自行開發PC 端工具,通過adb 命令來完成key 的寫入。

7.2.6 secure storage 格式

secure storage 有預設的格式,簡單總結如下 ? secure storage 總大小為256KB,因為有備份,所以實際能用128KB。 ? 128KB 分為32 個item, 即每個item 是4KB。 ? item0 用作secure_sotrage_map,所以用戶能用的實際為31 個item。 ? 每個item 內部為鍵值對的格式,包含CRC 校驗,其中用戶可存儲的key 長度最多為3KB。 ? secure_storage_map 中是以“name:length” 的格式保存所有item 的信息,所以所有item的“name:length” 字符串長度總和不能超過secure_storage_map 中data 的長度。一般而言,31 個3KB 的key 可以滿足需求,如果無法滿足,例如需要更多數量的key,則一種解決方式是上層應用自行將多個key 拼接起來,只要總大小不超過3KB 即可當成一個key 寫入 secure storage。讀出時應用自行反向解析出目標key 即可。

7.2.7 在uboot 中讀寫

基于以上介紹的格式,uboot 中封裝了pst 命令。

pst - read data from secure storageerase flag in secure storage Usage: pst pst read|erase [name] pst read, then dump all data pst read name, then dump the dedicate data pst write name, string, write the name = string pst erase, then erase all secure storage data pst erase key_burned_flag, then erase the dedicate data

7.2.8 在用戶空間讀寫

Tina 提供了讀寫庫。

make menuconfig 選中Allwinner --> <*> libsec_key --> [*] Enable secure storage key support

如果選上demo,則會編譯出demo 程序sec_key_test。

root@TinaLinux:/# sec_key_test -h -w : write key to sst and private -r : read key from sst or private -t 0: write some key to secure storage -t 1: repetitve read + verify some key from secure storage -t 2: repetitve write + verify some key from secure storage -t 3: verify some key from secure storage -t 4: write some key to private -t 5: repetitve read + verify some key from private -t 6: repetitve write + verify some key from private -t 7: verify some key from private -l : list -d : printf hex -h : help

更詳細的使用方式請參考:

tina/package/allwinner/libkey/readme.txt

7.3 secure storage 區域與private 分區比較

刷機不丟失的特性: ? private 分區每次刷機,是先讀出到dram,擦除flash,再寫入flash。刷機中途掉電可能丟失 ? secure storage 則是刷機過程完全不會擦除。理論上secure storage 的數據更安全。

用戶空間誤操作的可能: ? private 分區可以用常規分區更新命令清除掉。 ? secure storage 需要通過ioctl 專用接口訪問。

數據格式: ? private 分區可以裸分區讀寫,也可以格式化成文件系統。 ? secure storage 已限制為鍵值對,key 的長度也有限制。

存放位置: ? private 分區大小由分區表配置,是一個可見的普通分區。 ? secure storage 是flash 上的保留區域,大小固定,分區表中不可見。

? private 分區沒有備份,請避免寫入時掉電。或者自行在private 分區中構建備份。 ? secure storage 默認是雙備份。

在uboot 訪問: ? private 分區,uboot 通過通用的讀寫flash 接口或文件系統接口訪問,取決于數據格式。 ? sectre storage 區域,有固定格式,通過uboot 提供的secure storage 專用接口訪問。

校驗: ? private 分區如果是裸數據,是否校驗由應用自行處理。如果是文件系統,則由文件系統特性決定。 ? secure storage 格式中帶了crc 校驗。

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

    關注

    13

    文章

    4265

    瀏覽量

    85675
  • Linux
    +關注

    關注

    87

    文章

    11230

    瀏覽量

    208933
  • 開發指南
    +關注

    關注

    0

    文章

    34

    瀏覽量

    7531
  • Tina
    +關注

    關注

    2

    文章

    45

    瀏覽量

    16957
收藏 人收藏

    評論

    相關推薦

    Tina_Linux系統裁剪開發指南

    Tina_Linux系統裁剪開發指南1 概述2 Tina系統裁剪簡介2.1 boot0裁剪2.2 uboot裁剪2.3 內核裁剪2.3.1 刪除不使用的功能2.3.2 刪除不使用的驅動2.3.3
    的頭像 發表于 03-06 09:52 ?1515次閱讀

    EAC0945 linux開發指南

    EAC0945 linux開發指南
    發表于 09-28 12:40

    EAC0945 linux開發指南

    `EAC0945 linux開發指南`
    發表于 10-31 12:18

    Rockchip Linux SDK uboot logo開發指南

    arm嵌入式vs-rk3399 板卡uboot logo 開發指南概述:本文檔主要介紹 rockchip linux sdk uboot logo 顯示的相關功能、配置以及開發過程中的注意事項。適用于 rockhip
    發表于 10-09 08:12

    Tiny6410 Linux開發指南詳解

    Tiny6410 Linux 開發指南
    發表于 07-08 17:12 ?210次下載
    Tiny6410 <b class='flag-5'>Linux</b><b class='flag-5'>開發指南</b>詳解

    A64開發板LCD開發指南

    A64開發板LCD開發指南,驅動開發指南
    發表于 06-21 17:02 ?0次下載

    彩光燈開發指南

    彩光燈開發指南
    發表于 12-29 20:15 ?0次下載

    Linux的平臺下Mini210S裸機程序開發指南

    Linux的平臺下Mini210S裸機程序開發指南
    發表于 10-29 10:52 ?59次下載
    <b class='flag-5'>Linux</b>的平臺下Mini210S裸機程序<b class='flag-5'>開發指南</b>

    Rockchip Linux SDK的開發指南的詳細資料說明

    本文檔的主要內容詳細介紹的是Rockchip Linux SDK的開發指南的詳細資料說明。
    發表于 01-10 17:17 ?74次下載
    Rockchip <b class='flag-5'>Linux</b> SDK的<b class='flag-5'>開發指南</b>的詳細資料說明

    Tina_Linux_系統軟件開發指南

    Tina_Linux_系統軟件開發指南
    的頭像 發表于 03-02 15:25 ?1776次閱讀
    <b class='flag-5'>Tina_Linux</b>_系統軟件<b class='flag-5'>開發指南</b>

    Tina Linux配置開發指南

    Tina Linux配置開發指南
    的頭像 發表于 03-02 15:28 ?1.6w次閱讀
    <b class='flag-5'>Tina</b> <b class='flag-5'>Linux</b>配置<b class='flag-5'>開發指南</b>

    Linux NOR開發指南

    Linux NOR開發指南
    的頭像 發表于 03-06 09:55 ?925次閱讀
    <b class='flag-5'>Linux</b> NOR<b class='flag-5'>開發指南</b>

    Tina Linux圖形系統開發指南

    本文檔將介紹 Allwinner Tina Linux 中已經移植好的窗口系統,以及怎么使用,包括 MiniGUI、QT5、EFL、GTK+(WebkitGtk、Midori)、DirectFB、Wayland,整體結構 。
    的頭像 發表于 03-06 11:00 ?3055次閱讀
    <b class='flag-5'>Tina</b> <b class='flag-5'>Linux</b>圖形系統<b class='flag-5'>開發指南</b>

    Tina Linux音頻開發指南

    介紹Tina平臺音頻模塊的使用方法。
    的頭像 發表于 03-06 11:02 ?6254次閱讀
    <b class='flag-5'>Tina</b> <b class='flag-5'>Linux</b>音頻<b class='flag-5'>開發指南</b>

    Tina Linux PMU開發指南

    介紹使用Tina PMU 驅動的使用方法。
    的頭像 發表于 03-06 11:05 ?2016次閱讀
    <b class='flag-5'>Tina</b> <b class='flag-5'>Linux</b> PMU<b class='flag-5'>開發指南</b>