簡介
本文介紹一個IPQ4019的MTD分區信息是如何從配置文件一步步傳遞到linux內核的。這個過程有幾個部分組成,分區信息在編譯過程中的傳遞;升級時寫入flash區;設備上電時linux如何得到分區信息。
上電後linux打印的MTD分區如下圖。
分區信息在編譯過程中的傳遞
原始的配置文件
BOOT.BF.3.1.1/boot_images/build/ms/bin/40xx/misc/tools/config/nor-partition.xml等文件中。
打開以後是如下xml內容。
<partition_versionlength="4">0x4</partition_version>
<partitions>
<partition>
<name length="16"type="string">0:SBL1</name>
<size_kblength="4">256</size_kb> //256KB
<pad_kblength="2">0</pad_kb>
<which_flashlength="2">0</which_flash>
<attr>0xFF</attr>
<attr>0xFF</attr>
<attr>0x00</attr>
<attr>0xFF</attr>
<img_nametype="string">sbl1_nor.mbn</img_name>
</partition>
<partition>
<namelength="16" type="string">0:MIBIB</name>
<size_kblength="4">128</size_kb>
<pad_kblength="2">0</pad_kb>
<which_flashlength="2">0</which_flash>
<attr>0xFF</attr>
<!-- Specify flashblock size in KB -->
<attr>64</attr>
<!-- Specify flash density in MB -->
<attr>32</attr>
<attr>0xFF</attr>
<img_nametype="string">nor-user-partition-ipq40xx.bin</img_name>
</partition>
<partition>
<namelength="16" type="string">0:QSEE</name>
<size_kblength="4">384</size_kb>
<pad_kblength="2">0</pad_kb>
<which_flashlength="2">0</which_flash>
<attr>0xFF</attr>
<attr>0xFF</attr>
<attr>0x00</attr>
<attr>0xFF</attr>
<img_nametype="string">tz.mbn</img_name>
</partition>
生成二進制mibib
使用如下命令
/BOOT.BF.3.1.1/boot_images/build/ms/bin/40xx/misc/tools目錄下
pythonnand_mbn_generator.py config/nor-partition.xml x.bin
生成一個二進制文件。此二進制文件的內容如下:
hexdump -C x.bin
00000000 9a 1b 7d aa bc 48 7d 1f 04 00 00 00 0b 00 00 00 |..}..H}.........|
00000010 30 3a 53 42 4c 31 00 00 00 00 00 00 00 00 00 00 |0:SBL1..........|
00000020 00 01 00 00 00 00 00 00 ff ff 00 ff 30 3a 4d 49 |............0:MI|
00000030 42 49 42 00 00 00 00 00 00 00 00 00 80 00 00 00 |BIB.............|
00000040 00 00 00 00 ff 40 20 ff 30 3a 51 53 45 45 00 00 |.....@ .0:QSEE..|
00000050 00 00 00 00 00 00 00 00 80 01 00 00 00 00 00 00 |................|
00000060 ff ff 00 ff 30 3a 43 44 54 00 00 00 00 00 00 00 |....0:CDT.......|
00000070 00 00 00 00 40 00 00 00 00 00 00 00 ff ff 00 ff |....@...........|
00000080 30 3a 44 44 52 50 41 52 41 4d 53 00 00 00 00 00 |0:DDRPARAMS.....|
00000090 40 00 00 00 00 00 00 00 ff ff 00 ff 30 3a 41 50 |@...........0:AP|
000000a0 50 53 42 4c 45 4e 56 00 00 00 00 00 40 00 00 00 |PSBLENV.....@...|
000000b0 00 00 00 00 ff ff 00 ff 30 3a 41 50 50 53 42 4c |........0:APPSBL|
000000c0 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 |................|
000000d0 ff ff 00 ff 30 3a 41 52 54 00 00 00 00 00 00 00 |....0:ART.......|
000000e0 00 00 00 00 40 00 00 00 00 00 00 00 ff ff 00 ff |....@...........|
000000f0 30 3a 48 4c 4f 53 00 00 00 00 00 00 00 00 00 00 |0:HLOS..........|
00000100 00 10 00 00 00 00 00 00 ff ff 00 ff 72 6f 6f 74 |............root|
00000110 66 73 00 00 00 00 00 00 00 00 00 00 00 58 00 00 |fs...........X..|
00000120 00 00 00 00 ff ff 00 ff 61 64 64 5f 6e 65 77 5f |........add_new_|
00000130 70 61 72 74 00 00 00 00 40 00 00 00 00 00 00 00 |part....@.......|
00000140 ff ff 00 ff 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
這個add_new_part是我自己手動增加的。
這個文件不會被編譯過程動態生成,如需要修改,則要人工生成。這個文件最後會放入mibib區,我們就叫它mibib文件。
已經制件好的mibib文件在BOOT.BF.3.1.1/boot_images/build/ms/bin/40xx/[ nor nor-plus-emmc nor-plus-nand emmc]
這些目錄下。
如BOOT.BF.3.1.1/boot_images/build/ms/bin/40xx/nor/nor-system-partition-ipq40xx.bin
編譯打包
在編譯過程中,大家可以看到如下日誌。Image1位置打包的文件就是norplussemmc-systerm-partition-ipq40xx.bin。它的來源就是上面的目錄的文件。
升級時寫入flash區
使用uboot升級或是sysupgrade升級,會把mibib文件寫入mibib的MTD區。
這個區內容非常重要,如果不正確,則系統連uboot也進不去。
設備上電時linux如何得到分區信息
高通MSM系列芯片上電過程。
APPSBL是我們的uboot區。
從串口日誌可知在uboot輸出日誌前的日誌如下:這部分日誌是SBL程序輸出的。
Format: Log Type - Time(microsec) - Message- Optional Info
Log Type: B - Since Boot(Power OnReset), D - Delta, S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.BF.3.1.1-00096
S - IMAGE_VARIANT_STRING=DAABANAZA
它的程序放到了0:SBL1區。它會讀取mibib區,如果讀不正確,則SBL程序會掛死。本人親測。
SBL把分區信息傳給UBOOT
Uboot修改FDT信息
Uboot讀取mtd[0]區上的信息
從nandinfo[nand_env_device]讀取數據,其中nand_env_device = 0.
取parts信息
Smem_getpart
Smem_getpart從smem的全局變量中找出 parts的名稱,size等信息。其中一些size信息保存在了nand_info中。
Setenv mtdparts並安裝到設備樹
FDT = flat device tree.
Fdt_node_set_part_info就是用來修改partition信息的函數,它把partition信息加入了FDT中。
Ft_board_setup -> Ipq_fdt_fixup_mtdparts->fdt_node_set_part_info.
Linux讀取過程
Mtdparts的兩種解析方式,一是ofpart,二是cmdpart,ARM使用第一種,lsdk使用第二種。
在spi總線被註冊以後,會掃描下面的設備,它會了解到下面有一個m25p80的flash.
在m25p80驅動加載時,會按dev->of_node的信息(這是設備樹解析成功後的結構)調用mtdparts的解析方式一步步加載分區。
在加載spi總線註冊之前,設備樹就已經都建立成功。設備樹的源文件在:
qsdk/qca/src/linux/arch/arm/boot/dts
相關dts文件不包含MTD分區信息。
最後在設備樹下的結果如下:
cd/proc/device-tree/soc/spi@78b5000/m25p80@0/
[root@Abloomy:m25p80@0]# ls-lat
-r--r--r-- 1 root root 4 Apr 21 05:23#address-cells
-r--r--r-- 1 root root 4 Apr 21 05:23#size-cells
-r--r--r-- 1 root root 11 Apr 21 05:23compatible
-r--r--r-- 1 root root 4 Apr 21 05:23density
-r--r--r-- 1 root root 18 Apr 21 05:23linux,modalias
-r--r--r-- 1 root root 7 Apr 21 05:23name
dr-xr-xr-x 2 root root 0 Apr 21 05:23partition@0
dr-xr-xr-x 2 root root 0 Apr 21 05:23partition@170000
dr-xr-xr-x 2 root root 0 Apr 21 05:23 partition@180000
dr-xr-xr-x 2 root root 0 Apr 21 05:23partition@40000
dr-xr-xr-x 2 root root 0 Apr 21 05:23partition@580000
dr-xr-xr-x 2 root root 0 Apr 21 05:23partition@60000
dr-xr-xr-x 2 root root 0 Apr 21 05:23partition@c0000
dr-xr-xr-x 2 root root 0 Apr 21 05:23partition@d0000
dr-xr-xr-x 2 root root 0 Apr 21 05:23partition@e0000
dr-xr-xr-x 2 root root 0 Apr 21 05:23 partition@f0000
-r--r--r-- 1 root root 4 Apr 21 05:23reg
-r--r--r-- 1 root root 4 Apr 21 05:23sector-size
-r--r--r-- 1 root root 4 Apr 21 05:23spi-max-frequency
-r--r--r-- 1 root root 0 Apr 21 05:23use-default-sizes
dr-xr-xr-x 12 root root 0 Apr 21 05:23 .
dr-xr-xr-x 3 root root 0 Apr 21 05:23 ..
[root@Abloomy:m25p80@0]#
參考
http://blog.csdn.net/modianwutong/article/details/46353301
http://blog.chinaunix.net/uid-9185047-id-5001947.html
UBOOT的fdt命令
這說明uboot可以修改fdt.
其中一個重要的命令是fdtmknode 它對於應的函數:fdt_add_subnode