不知道從何時 Linux Kernel 開始使用 Device Tree Blob. 在 Rockchip Project 裡 Device Tree Blob 被打包於 resource.img . 筆者這篇文章在此介紹如何打包/解包這 Rockchip 之 resource.img.
Build Rockchip Resource_tool
Rockchip resource_tool 原始碼位於 u-boot-rockchip Project 中 ( u-boot-rochchip/tools/resource_tool/ ) . 我們使用 git 把它 clone 下來.
$ git clone https://github.com/linux-rockchip/u-boot-rockchip ... $ make Arch=arm -C u-boot-rochchip/tools/resource_tool/ ...
如果編譯有誤, 用以下的方式修改 makefile 再編譯一次試試. 應該可以編譯成功.
$ sudo apt-get install gcc-arm-linux-gnueabihf ... $ sudo apt-get install g++-arm-linux-gnueabihf ...
$ sed "s/= gcc$/= gcc -I\/usr\/include\/x86_64-linux-gnu/" u-boot-rockchip/tools/resource_tool/Makefile > u-boot-rockchip/tools/resource_tool/makefile $ make -C u-boot/tools/resource_tool/ clean $ make -C u-boot/tools/resource_tool/ -f makefile ... gcc -I/usr/include/x86_64-linux-gnu -c -o resource_tool.o resource_tool.c -fshort-wchar -m32 -ffunction-sections -Os resource_tool.c: In function ‘get_file_size’: resource_tool.c:333:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 6 has type ‘__off_t’ [-Wformat=] LOGD("path:%s, size:%d", path, st.st_size); ^ gcc -I/usr/include/x86_64-linux-gnu -c -o common.o common.c -fshort-wchar -m32 -ffunction-sections -Os gcc -I/usr/include/x86_64-linux-gnu -c -o tests.o tests.c -fshort-wchar -m32 -ffunction-sections -Os gcc -I/usr/include/x86_64-linux-gnu -o resource_tool resource_tool.o common.o tests.o -fshort-wchar -m32 -ffunction-sections -Os -Wl,--gc-sections -static strip -s --remove-section=.note --remove-section=.comment resource_tool make: Leaving directory `/home/jasonc/rk30-linux/u-boot/tools/resource_tool' $ $ sudo cp u-boot-rockchip/tools/resource_tool/resource_tool /usr/local/bin/ ...
Device Tree Compiler (DTC)
再來我們需要準備好 Device Tree Compiler. 在編譯 kernel 完成後, 可以找到 dtc 這個編譯器.
$ make ARCH=arm rk30x6_mini_defconfig ... $ make ARch=arm rk3066a-marsboard.img ...
$ find kernel -name dtc kernel/scripts/dtc kernel/scripts/dtc/dtc $ $ sudo cp kernel/scripts/dtc/dtc /usr/local/bin/
Unpack Resource.img
Kernel 編譯完成後會產生 kernel.img 以及 resource.img . 我們使用剛剛編譯好的 resource_tool 來 unpack 這個 resource.img , 如下:
$ mkdir -p out $ resource_tool --verbose --unpack --image=kernel/resource.img Dump header: partition version:0.0 header size:1 index tbl: offset:1 entry size:1 entry num:3 Dump Index table: entry(0): path:rk-kernel.dtb offset:4 size:33431 D/dump_file(192): try to dump entry:rk-kernel.dtb D/mkdirs(180): mkdir:out entry(1): path:logo.bmp offset:70 size:170326 D/dump_file(192): try to dump entry:logo.bmp D/mkdirs(180): mkdir:out entry(2): path:logo_kernel.bmp offset:403 size:19160 D/dump_file(192): try to dump entry:logo_kernel.bmp D/mkdirs(180): mkdir:out Unack upgrade_rk3066/Image/resource.img to out successed! $
可以看到 resource.img 裡面包含了 logo.bmp , logo_kernel.bmp 以及 rk-kernel.dtb (Device Tree Blob) .
$ ls out $ logo.bmp logo_kernel.bmp rk-kernel.dtb
Device Tree 反編譯
接下來我們使用 Device Tree Compiler (dtc) 反編譯這個 rk-kernel.dtb . `dtc` 這個指令如何使用, 請敲一下 `--help` 看一下.
$ dtc -help ...
$ dtc -I dtb -O dts out/rk-kernel.dtb -o out/rk-kernel.dts
反組譯後我們可以得到 `rk-kernel.dts` 檔案. 這個檔案就是 Device Tree Source File. 它的內容大概如下.
$ vi out/rk-kernel.dts ... /dts-v1/; / { #address-cells = <0x1>; #size-cells = <0x1>; interrupt-parent = <0x1>; compatible = "chipspark,rayeager-px2", "rockchip,rk3066a"; model = "Rayeager PX2"; chosen { bootargs = "console=ttyS2,1500000 androidboot.selinux=disabled init=/init initrd=0x62000000,0x00800000 root=/dev/rknand_rootfs rw rootwait mtdparts=rk29xxnand:0x00000800@0x00000800(misc),0x00004000@0x00001000(recovery),0x00000800@0x00005000(boot),0x00000800@0x00005800(resource),0x00002800@0x00006000(kernel),0x00007000@0x00008800(rootfs),0x0001E000@0x0000F800(rom),0x00004000@0x0002D800(emulator),-@0x00031800(data)"; }; aliases { i2c0 = "/i2c@2002d000"; i2c1 = "/i2c@2002f000"; i2c2 = "/i2c@20056000"; i2c3 = "/i2c@2005a000"; i2c4 = "/i2c@2005e000"; mshc0 = "/dwmmc@1021c000"; mshc1 = "/dwmmc@10214000"; mshc2 = "/dwmmc@10218000"; serial0 = "/serial@10124000"; serial1 = "/serial@10126000"; serial2 = "/serial@20064000"; serial3 = "/serial@20068000"; spi0 = "/spi@20070000"; spi1 = "/spi@20074000"; }; ...
Device Tree 編譯
已知 `rk-kernel.dts` or `rk3066a-marsboard.dts` , 要產生 Device Tree Blob, 可以使用下述命令:
$ dtc -I dts -O dtb out/rk-kernel.dts -o out/rk-kernel.dtb
或者我們有原始的 kernel Source Code,
$ make ARCH=arm -C kernel rk3066a-marsboard.dtb ... $ ls kernel/arch/arm/boot/dts/*.dtb $ kernel/arch/arm/boot/dts/rk3066a-marsboard.dtb ... $ /bin/cp kernel/arch/arm/boot/dts/rk3066a-marsboard.dtb out/rk-kernel.dtb
Pack Resource.img
已知 `logo.bmo` , `logo_kernel.bmp` 以及 `rk-kernel.dtb` , 要產生 resource.img . 我們使用下述命令:
$ resource_tool --verbose --pack out/logo.bmp out/logo_kernel.bmp out/rk-kernel.dtb resource.img && /bin/mv ./resource.img out/ D/main(112): try to pack 4 files. D/write_header(375): try to write header... D/write_index_tbl(391): try to write index table... D/get_file_size(327): try to get size(out/rk-kernel.dtb)... D/get_file_size(333): path:out/rk-kernel.dtb, size:33431 D/write_file(338): try to write file(out/rk-kernel.dtb) to offset:4... D/get_file_size(327): try to get size(out/rk-kernel.dtb)... D/get_file_size(333): path:out/rk-kernel.dtb, size:33431 D/write_index_tbl(409): try to write index entry(out/rk-kernel.dtb)... D/write_index_tbl(427): mod fdt path:out/rk-kernel.dtb -> rk-kernel.dtb... D/get_file_size(327): try to get size(out/logo_kernel.bmp)... D/get_file_size(333): path:out/logo_kernel.bmp, size:19160 D/write_file(338): try to write file(out/logo_kernel.bmp) to offset:70... D/get_file_size(327): try to get size(out/logo_kernel.bmp)... D/get_file_size(333): path:out/logo_kernel.bmp, size:19160 D/write_index_tbl(409): try to write index entry(out/logo_kernel.bmp)... D/get_file_size(327): try to get size(out/logo.bmp)... D/get_file_size(333): path:out/logo.bmp, size:170326 D/write_file(338): try to write file(out/logo.bmp) to offset:108... D/get_file_size(327): try to get size(out/logo.bmp)... D/get_file_size(333): path:out/logo.bmp, size:170326 D/write_index_tbl(409): try to write index entry(out/logo.bmp)... Pack to resource.img successed! $
Pack Recovery.img
筆者之前的文章其實已經介紹了如何 pack & repack recovery.img. 這邊我再簡單地重複一下:
DefConfig:
$ make ARCH=arm -C kernel rk30x6_mini_defconfig ...
zImage:
$ make ARCH=arm -C kernel zImage ...
DTB:
$ make ARCH=arm -C kernel rk3066a-marsboard.dtb ...
Pack Recovery.img:
$ cat kernel/arch/arm/boot/zImage arch/arm/boot/dts/rk3066a-marsboard.dtb > kernel/dkernel $ mkbootimg --kernel kernel/dkernel --ramdisk build/recovery/ramdisk-recovery.img --output out/recovery.img
Repack Recovery.img
Cpio & Unzip:
$ cd build/recovery/ $ mkdir -p unpacked-recovery $ cat ramdisk-recovery.img | gunzip | cpio -i ...
$ ls acct d drmboot.ko fstab.rk30board.bootmode.unknown init.rc property_contexts sdcard service_contexts tmp bugreports data etc fstab.unknown mnt res seapp_contexts storage ueventd.rc charger default.prop file_contexts.bin init oem rk30xxnand_ko.ko selinux_version sys ueventd.rk30board.rc config dev fstab.rk30board.bootmode.emmc init.bootmode.unknown.rc proc sbin sepolicy system vendor $
$ find . | cpio -o -H newc | gzip > ../ramdisk-recovery.img ; cd .. ...
$ mkbootimg --kernel kernel/dkernel --ramdisk build/recovery/ramdisk-recovery.img --output out/recovery.img
以 Linux Expect Script 自動輸入密碼 Fetch Remote Remote Repository
Remote Repository
假設 我的 Remote Projcet 如下:
$ git config --global user.email "lexra@example.com" $ git config --global user.name "Lexra Chang" $ repo init --repo-url ssh://git@www.rockchip.com.cn/repo/rk/tools/repo -u ssh://git@www.rockchip.com.cn/linux/rk/platform/manifests -b linux -m rk3288_linux_release.xml ...
Bin/Repo-Sync.exp
筆者之前碰到的問題是這樣:
repo init 兩個 --repo-url 似乎使得 repo sync 需要輸入兩次 Passphrase ; 而這兩次 Passphrase 常常來不及輸入.
$ .repo/repo/repo sync --force-sync kernel Enter passphrase for key '/home/jasonc/.ssh/id_rsa': Enter passphrase for key '/home/jasonc/.ssh/id_rsa':
因此筆者設計了一個 Expect Script 自動輸入密碼. 這 Expect Script (bin/repo-sync.exp) 的內容如下:
$ vi bin/repo-sync.exp
$ set timeout -1 set PARAM [lindex $argv 0] spawn .repo/repo/repo sync --force-sync $PARAM set times 0 while { $times < 9 } { expect { "Enter passphrase for key '/home/jasonc/.ssh/id_rsa':" { log_user 0; send "mypassword\r"; log_user 1; exp_continue } eof { exit } } set times [ expr $times + 1] } exit
Expect Bin/Repo-Sync.exp Kernel
這個 Expect Script 需要一個參數.
jasonc@bebop:~/rk30-linux$ expect bin/repo-sync.exp kernel spawn .repo/repo/repo sync --force-sync kernel Enter passphrase for key '/home/jasonc/.ssh/id_rsa': Enter passphrase for key '/home/jasonc/.ssh/id_rsa': perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = "en_US:en", LC_ALL = (unset), LC_PAPER = "zh_TW.UTF-8", LC_ADDRESS = "zh_TW.UTF-8", LC_MONETARY = "zh_TW.UTF-8", LC_NUMERIC = "en_US.UTF-8", LC_TELEPHONE = "zh_TW.UTF-8", LC_MESSAGES = "en_US.UTF-8", LC_IDENTIFICATION = "zh_TW.UTF-8", LC_MEASUREMENT = "zh_TW.UTF-8", LC_CTYPE = "en_US.UTF-8", LC_TIME = "zh_TW.UTF-8", LC_NAME = "zh_TW.UTF-8", LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C"). Fetching project rk/kernel perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = "en_US:en", LC_ALL = (unset), LC_PAPER = "zh_TW.UTF-8", LC_ADDRESS = "zh_TW.UTF-8", LC_MONETARY = "zh_TW.UTF-8", LC_NUMERIC = "en_US.UTF-8", LC_TELEPHONE = "zh_TW.UTF-8", LC_MESSAGES = "en_US.UTF-8", LC_IDENTIFICATION = "zh_TW.UTF-8", LC_MEASUREMENT = "zh_TW.UTF-8", LC_CTYPE = "en_US.UTF-8", LC_TIME = "zh_TW.UTF-8", LC_NAME = "zh_TW.UTF-8", LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C"). Fetching projects: 100% (1/1), done. jasonc@bebop:~/rk30-linux$
Expect Bin/Repo-Sync.exp Sources/Meta-Openembedded
jasonc@bebop:~/rk30-linux$ expect bin/repo-sync.exp sources/meta-openembedded spawn .repo/repo/repo sync --force-sync sources/meta-openembedded Enter passphrase for key '/home/jasonc/.ssh/id_rsa': perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = "en_US:en", LC_ALL = (unset), LC_PAPER = "zh_TW.UTF-8", LC_ADDRESS = "zh_TW.UTF-8", LC_MONETARY = "zh_TW.UTF-8", LC_NUMERIC = "en_US.UTF-8", LC_TELEPHONE = "zh_TW.UTF-8", LC_MESSAGES = "en_US.UTF-8", LC_IDENTIFICATION = "zh_TW.UTF-8", LC_MEASUREMENT = "zh_TW.UTF-8", LC_CTYPE = "en_US.UTF-8", LC_TIME = "zh_TW.UTF-8", LC_NAME = "zh_TW.UTF-8", LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C"). Fetching project meta-openembedded Enter passphrase for key '/home/jasonc/.ssh/id_rsa': Fetching projects: 100% (1/1), done. jasonc@bebop:~/rk30-linux$
Expect Bin/Repo-Sync.exp Sources/Meta-Rockchip
jasonc@bebop:~/rk30-linux$ expect bin/repo-sync.exp sources/meta-rockchip spawn .repo/repo/repo sync --force-sync sources/meta-rockchip Enter passphrase for key '/home/jasonc/.ssh/id_rsa': Enter passphrase for key '/home/jasonc/.ssh/id_rsa': perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = "en_US:en", LC_ALL = (unset), LC_PAPER = "zh_TW.UTF-8", LC_ADDRESS = "zh_TW.UTF-8", LC_MONETARY = "zh_TW.UTF-8", LC_NUMERIC = "en_US.UTF-8", LC_TELEPHONE = "zh_TW.UTF-8", LC_MESSAGES = "en_US.UTF-8", LC_IDENTIFICATION = "zh_TW.UTF-8", LC_MEASUREMENT = "zh_TW.UTF-8", LC_CTYPE = "en_US.UTF-8", LC_TIME = "zh_TW.UTF-8", LC_NAME = "zh_TW.UTF-8", LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C"). Fetching project linux/yocto/meta-rockchip perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = "en_US:en", LC_ALL = (unset), LC_PAPER = "zh_TW.UTF-8", LC_ADDRESS = "zh_TW.UTF-8", LC_MONETARY = "zh_TW.UTF-8", LC_NUMERIC = "en_US.UTF-8", LC_TELEPHONE = "zh_TW.UTF-8", LC_MESSAGES = "en_US.UTF-8", LC_IDENTIFICATION = "zh_TW.UTF-8", LC_MEASUREMENT = "zh_TW.UTF-8", LC_CTYPE = "en_US.UTF-8", LC_TIME = "zh_TW.UTF-8", LC_NAME = "zh_TW.UTF-8", LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C"). Fetching projects: 100% (1/1), done. jasonc@bebop:~/rk30-linux$
Git Branch --Set-Upstream-To
jasonc@bebop:~/rk30-linux/kernel-dmc$ git branch ...
jasonc@bebop:~/rk30-linux/kernel-dmc$ git checkout -b develop ...
jasonc@bebop:~/rk30-linux/kernel-dmc$ git checkout develop ...
jasonc@bebop:~/rk30-linux/kernel-dmc$ git branch --set-upstream-to=origin/develop develop ...
jasonc@bebop:~/rk30-linux/kernel-dmc$ git pull ...
jasonc@bebop:~/rk30-linux/kernel-dmc$ git status ...
jasonc@bebop:~/rk30-linux/kernel-dmc$ git push origin develop ...
之後只要 PULL PUSH, 這樣 develop branch 同步應該就不會有問題了.
丁噹 我還是一樣 作詞:陳奕勤&黃婷 作曲:陳奕勤 編曲:呂聖斐 @ 威幅音樂 說好卻沒一起到的地方 只剩下模糊的想像 總說日子還很長 還記得當時你嚮往的模樣 過去像是破舊的遊樂場 零碎的歡樂最難忘 畫面一直在回放 當初我們是如此愛著對方 你聊起你的流浪 很客氣地分享 你有沒有看穿我還是一樣 淡然應付窘狀 為何還是好難 而你已比從前寬廣 我說著我的近況 儘是無關痛癢 工作依然頻繁我還是一樣 偶爾也會孤單 無數失眠的夜晚 想念你的舊創 也一樣 記憶深處殘存了些盼望 時不時在我腦海蕩 你留給我的影響 多年以後還在我身上頑強 你眉宇還是飛揚 笑聲還是爽朗 愛情走了多遠我難以想像 回不去的時光 落下往日的夕陽 我還有什麼能 不一樣