NanoPC-T2制作刷机包

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、 官方代码更新了,相应的脚本等等一些文件并没有及时更新,

已经很晚了,就不写了!有事不要找我,没事更不要找我!!!

posted @ 2019-04-21 01:05  goodboyyd  阅读(864)  评论(0编辑  收藏  举报