anoPC-T2製作刷機包 前提:到友善的wiki中,仔細看編譯uboot、內核、製作刷機包的教程。 準備工作: 1、 虛擬機Ubuntu安裝,並安裝n多軟體可以支撐編譯內核等等。 2、 安裝交叉編譯器,參考wiki-8.1。 3、 下載友善修改好的uboot、內核源代碼,debian_nanopi ...
anoPC-T2製作刷機包
前提:到友善的wiki中,仔細看編譯uboot、內核、製作刷機包的教程。
準備工作:
1、 虛擬機Ubuntu安裝,並安裝n多軟體可以支撐編譯內核等等。
2、 安裝交叉編譯器,參考wiki-8.1。
3、 下載友善修改好的uboot、內核源代碼,debian_nanopi2、sd-fuse_nanopi2等製作刷機包的腳本,友善有兩套代碼:
Uboot2014,和linux-3.4.y是配套使用,沒有使用設備樹.
Uboot2016和linux-4.4.y是配套使用,使用設備樹.
4、 下載友善已經製作好的刷機包,也可以使用sd-fuse_nanopi2自己製作(最好使用這種方法,裡面有東西後面用到)。
我使用的源碼版本是uboot2014和linux-3.4.y,文件系統是busybox-1.30.0,具體分析就不多說了,直接來操作:
第一步-編譯:
到友善的git上去下載對應得源碼包(最好使用git拉取,直接下載好像會出錯,選好分支不然編譯會失敗)
以上只用到了部分,全是用git拉取後,壓縮的包,備份起來,下載是真的慢。
解壓出來(具體命令自己百度)
分別是文件系統,kernel,刷機包工具、uboot
進入uboot_nanopi2目錄下,直接編譯,大概不到一分鐘,就ok了,具體命令wiki上有,
進入linux-3.4.y目錄下,直接編譯,時間大概5分鐘,具體命令wiki上有,
make nanopi2_linux_defconfig
make uImage -j12 (PC機cpu多核可以使用jn 的命令)
進入busybox目錄下,直接編譯,時間大概10分鐘,可以百度下具體做法。
make menuconfig
設置完交叉工具鏈的首碼後,保存退出,直接make,
執行make install
至於剩下的拷貝庫文件,創建各種文件等等,就自行百度就可以解決, 或者直接看韋東山老師的教程,寫的很詳細。其中一點:腳本裡面的串口設備名稱是ttyAMA0,不要寫錯了,要不然會出錯。
第二步-分析官方的二進位文件分佈
進入sd-fuse_s5p4418目錄下,文件和文件夾如下:
fusing.sh mkimage.sh prebuilt README.md tools,最好先看下readme,先瞭解下。
首先執行腳本mkimage.sh,跟一個參數android(也可以是其他的,分析下腳本就知道了)
./mkimage.sh android
虛擬機必須聯網,因為需要下載一些東西,我提前下載好了,也可以把腳本中的鏈接複製到迅雷中下載,然後再拷到虛擬機解壓在當前目錄下,也是可以的。android-lollipop-images.tgz,解壓在當前文件夾。
進入文件夾,可以看到很多文件:
2ndboot.bin bootloader env.conf partmap.txt userdata.img
boot.img cache.img info.conf system.img
其中2ndboot.bin是s5p4418官方的,看不到源碼,猜測就是一個自舉文件。
bootloader 就是uboot生成的文件
boot.img 是kernel和類似於ramdisk的小文件系統。
Cache.img system.img userdata.img是安卓的文件,我暫時沒有去管它。
剩下兩個.conf文件是一些環境變數,最後一個文件partmap.txt對我們有很大的參考價值
# sd0 partition map
# flash= <device>.<dev no>:<partition>:<fstype>:<start>,<length>
# support device : eeprom, nand, mmc
# support fstype : 2nd, boot, raw, fat, ext4, ubi
#
flash=mmc,0:2ndboot:2nd:0x200,0x7e00:2ndboot.bin;
flash=mmc,0:bootloader:boot:0x8000,0x77000:bootloader;
flash=mmc,0:boot:fat:0x000100000,0x004000000:boot.img;
flash=mmc,0:system:ext4:0x04100000,0x2F200000:system.img;
flash=mmc,0:cache:ext4:0x33300000,0x1AC00000:cache.img;
flash=mmc,0:misc:emmc:0x4E000000,0x00800000;
flash=mmc,0:recovery:emmc:0x4E900000,0x01600000;
flash=mmc,0:userdata:ext4:0x50000000,0x0:userdata.img;
文件直接把刷機包的分區和地址寫好了,但是我們不知道bootloader是否和我們編譯好的完全一樣,其中的boot.img又是由那些文件組成的?我們就需要分析這些。
腳本執行完畢後,會生成一個s5p4418-android-lollipop-20190420.img文件,我們需要分析這個文件,看下官方是怎麼做的。
把剛做好的刷機包、android-lollipop-images.tgz解壓出來的文件、我們編譯好的uboot和uImage拷貝到PC上,對比文件,看下有那些差異。
首先看刷機包,使用分區助手看下分區情況:
Boot分區,有uImage,root.img.gz,ramdisk-recovery.img等等文件
System分區和其他分區是安卓文件系統,對我們沒什麼價值,就不看了。
分析分區,我們知道第一個分區放的是kernel和ramdisk這樣的文件系統,第二個分區放的是文件系統。可以對比下boot分區下的uImage和我們編譯的有什麼大的差異(其實官方僅僅把它放在裡面而已)
接下來對比uboot,發現BootLoader就是uboot,沒有什麼大的差異。
從上面的分析,可以得出友善官方規劃的刷機包分區其實和partmap.txt中的分區是一一對應的,那麼我們是不是可以測試下,看是否可以成功做出最小的刷機包512M(可以參考下韋東山老師關於友善neo的視頻(免費),裡面講的比較好)。
截取partmap.txt中和我們相關的分區部分,我規划了一個分區,沒裝visio,不能畫圖,只有寫下來
flash=mmc,0:2ndboot:2nd:0x200,0x7e00:2ndboot.bin;
flash=mmc,0:bootloader:boot:0x8000,0x77000:bootloader;
flash=mmc,0:boot:fat:0x000100000,0x004000000:boot.img;
flash=mmc,0:system:ext4:0x04100000,0x2F200000:system.img;
SD卡的一個小知識:SD卡的分區信息放在前512B中,而一般SD卡的最小擦除單元剛好是512B=0x200=1 sector;(也可能不是sector)
2ndboot.bin 0x200 = 1 sector
Bootloader 0x8000 =64 sector
boot.img 第一個分區-格式fat 20M
文件系統 第二個分區-格式ext4 256-20M(我們暫時先分區,等內核可以跑起來再說)
進入我們的linux目錄下,新建build目錄,把2ndboot.bin,我們自己編譯的u-boot.bin,uImage拷貝到build目錄下。
一下操作可以百度下它的意思,我就不細說了,註意空格:
dd if=/dev/zero of=fs_nanopc_256M.img bs=1M count=256
losetup /dev/loop0 fs_nanopc_256M.img
fdisk /dev/loop0 //參看分區表,直接按回車代表預設屬性,+20M代表第一個分區是20M,第二個分區直接回車代表剩餘空間全部分配給第二個分區,最好w,代表寫入分區表,
可以輸入p查看分區情況
分區完後,寫入分區文件系統格式:
partprobe /dev/loop0
mkfs.fat /dev/loop0p1
mkfs.ext4 /dev/loop0p2
拷貝文件到img文件中:
dd if=2ndboot.bin of=/dev/loop0 bs=512 seek=1
dd if=u-boot.bin of=/dev/loop0 bs=512 seek=64
現在我們的uboot已經放入到刷機包中,我們可以把這個刷機包燒寫到SD卡中測試了,文件只有512M,燒寫不超過1分鐘,預計uboot可以啟動。然而我們發現,串口輸出可以預估的不一樣,如下:
串口列印出這些信息,說明2ndboot.bin已經執行了,但是uboot沒啟動。
分析可能:
我們下載的android目錄下的bootloader和我們編譯的一樣,是不是腳本執行過程中往裡面添加了一些東西???
看下腳本,但是感覺友善這個腳本寫的有點亂,也沒看出什麼來,所以我接直接粗暴的方式對比文件:到0x8000的位置,看使用官方的腳本製作的刷機包s5p4418-android-lollipop-xxx.img,和我們的uboot有什麼不一樣
發現uboot並不是放在0x8000的地址上,而是放在0x8200的地址上,而且0x8000-0x8200之間還有一些數據,暫時不知道具體含義。
使用粗暴的做法,直接創建一個bin文件,把0x8000-0x8200的內容放到裡面,
再次修改我們的分區信息:
2ndboot.bin 0x200 = 1 sector
head.bin 0x8000 = 64 sector
Bootloader 0x8200 =65 sector
boot.img 第一個分區-格式fat 20M
文件系統 第二個分區-格式ext4 256-20M(我們暫時先分區,等內核可以跑起來再說)
修改我們的刷機包:
dd if=2ndboot.bin of=/dev/loop0 bs=512 seek=1
dd if=head.bin of=/dev/loop0 bs=512 seek=64
dd if=u-boot.bin of=/dev/loop0 bs=512 seek=65
順便把內核也放到裡面:
mount /dev/loop0p1 /mnt
cp uImage /mnt
umount /mnt
重新燒寫SD卡,啟動:
Uboot正常啟動,但是內核沒有載入,看下預設的環境變數,有很多設置不符合我們現在的情況,修改如下
setenv bootdelay 5
setenv kernel uImage
setenv bootargs console=ttyAMA0,115200n8 root=/dev/mmcblk1p2 rootfstype=ext4 rootwait init=/sbin/init loglevel=7 printk.time=1 consoleblank=0 bootdev=2
setenv bootcmd $bloader 0x48000000 $bootfile
set bloader ext4load mmc 0:1
但是我們發現設置後,無法載入ext2文件系統,我們在分區時,boot的文件系統是fat的,但是uboot並沒有支持fat文件系統,我們在分區助手裡面看到boot分區也是ext4的,所以我們應該修改boot分區的文件系統為ext4
再次製作:
losetup -d /dev/loop0 //首先卸載設備
rm fs_nanopc_256M.img //刪除未完善的刷機包
重覆剛纔的步驟:
dd if=/dev/zero of=fs_nanopc_256M.img bs=1M count=256
losetup /dev/loop0 fs_nanopc_256M.img
fdisk /dev/loop0
partprobe /dev/loop0
mkfs.ext4 /dev/loop0p1
mkfs.ext4 /dev/loop0p2
把所有需要的文件全部寫入到刷機包中
dd if=2ndboot.bin of=/dev/loop0 bs=512 seek=1
dd if=head.bin of=/dev/loop0 bs=512 seek=64
dd if=u-boot.bin of=/dev/loop0 bs=512 seek=65
mount /dev/loop0p1 /mnt //掛載第一個分區到
cp uImage /mnt
umount /mnt
mount /dev/loop0p2 /mnt //掛載第二個分區
cp ../imgForNanopi2/fs_nanopi2/* -rfd /mnt/ //複製文件系統到第二個分區,使用rfd的參數
umount /mnt
losetup -d /dev/loop0
重新燒寫測試:
設置環境變數:
setenv bootdelay 5
setenv kernel uImage
setenv bootargs console=ttyAMA0,115200n8 root=/dev/mmcblk1p2 rootfstype=ext4 rootwait init=/sbin/init loglevel=7 printk.time=1 consoleblank=0 bootdev=2
setenv bootcmd $bloader 0x48000000 $bootfile
set bloader ext4load mmc 0:1
因為控制台設置環境變數不能有分號,所以,現在不能自動啟動內核,需要我們手動
run bootcmd
bootm
進入了熟悉的界面,說明我們只做刷機包已經成功了。關於uboot環境變數的設置,最好修改uboot源碼,修改巨集定義。
但是實際操作中,並沒有這麼順利,還是有很多問題:
1、 uboot的環境變數,有些官方寫死了,就算是我們修改了,重啟就恢復了
2、 boot分區下的ramdisK文件系統,有什麼用?我暫時沒去管它
3、 官方代碼更新了,相應的腳本等等一些文件並沒有及時更新,
已經很晚了,就不寫了!有事不要找我,沒事更不要找我!!!