FriendlyCore 定制固件

硬件环境 Nanopi neo core2 .

定制系统固件 ## 整体流程概述
1. 从友善官网下载emmc版本的固件。 2. 将官方固件写进TF卡。并copy出最后一个分区的emmc固件内容 -> friendlycore-xenial_4.14_arm64 目录。 3. 修改相关分区镜像。并覆盖TF卡的内容。 4. 将TF卡插入硬件,将EMMC固件烧进EMMC。 完成。
---- ### friendlycore-xenial_4.14_arm64 目录
| 文件                                   | 内容                                 | | ----                                   | ----                                | | partmap.txt                           | 分区表。                              | | info.conf                             |                                      | | sunxi-spl.bin                         | uboot 第一阶段                        | | u-boot.itb                            | uboot 第二阶段                        | | boot.img                              | 引导分区,存 kernel、dtb、ramdisk.img  | | rootfs.img                            | 根目录分区、overlayFs lower dir,只读分区。 | | userdata.img                          | 根目录分区、overlayFs upper dir,读写分区。  |
备注:友善的文件系统使用 overlayFs 。可以通过重置 userdata.img 恢复出厂设置。  
---- # 动驱动
## 知识储备 ### 启动过程 sunxi-spl.bin 是指定到固定地址的。cpu 上电会从固定地址读取程序进行启动。   sunxi-spl.bin 被执行。初始化时钟、初始化ddr、初始化 sdio/emmc 驱动器。     加载 uboot.itb 并执行。   uboot.itb 被执行。初始化串口等必要外设。     命令行操作。(如果有)     加载 kernel dtb ramdisk 到内存。     引导内核启动(会传递参数给内核)。   内核启动,最后启动第一个用户进程。(在ramdisk内的/init)   ramdisk 是个临时的简易 rootfs。 里面有一些基本的linux命令。以及 overlayFS 挂载过程。       ramdisk 内 /init 脚本得到执行。       init 脚本调用 mountroot 方法。    (mountroot 在 /script/local 文件内。)         mountroot 调用 local_mount_overlay 方法。           local_mount_overlay 内执行  mount -t overlay.....   挂载 overlayfs。           此时,emmc 的分区正式被挂载。 ramdisk 被覆盖。 /script 目录将不可见。 也就找不到挂载 overlayfs 相关的代码了。           系统启动后是找不到挂载代码的。
overlayFS 的参数来自于 uboot 传递。   cat /proc/cmdline 可以看到参数内容是:console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait fsck.repair=yes panic=10 fbcon=map:0  data=/dev/mmcblk0p3 snd-soc-core.pmdown_time=3600000    
引导启动过程大概如此。  
### 驱动相关
驱动有两种存在形式。   1. 编译进内核。 (boot.img 内)   2. 以内核模块(.ko格式) 存在于 /lib/modules/&{内核版本} 目录下。(rootfs.img 内)   也可以存在于 ramdisk.img 内,但是友善没这么做。应该是做通用 ramdisk.img 考虑。  
### .img 相关
可以通过 file 命令进行查看。 boot.img    FAT 分区镜像。  可以直接使用 sudo mount boot.img /mnt/boot 挂载进行修改。 rootfs.img  Android 稀疏镜像格式。内部是 EXT4 分区。 是个难点。  
资料: https://segmentfault.com/a/1190000004363645
// sparse image 转化成为 ext4 的 raw imge   Usage: simg2img  rootfs.img  rootfs.ext4   
// 挂载分区到 /mount/rootfs sudo mount rootfs.ext4  /mount/rootfs
// 创建一个目录,将 rootfs 文件整个拖出来。   mkdir rootfsDir   sudo cp /mnt/rootfs/* rootfsDir -rd
修改后使用友善 sd-fuse_h5/build_rootfs.sh 脚本将 rootfsDir 文件夹直接打包成 sparse image 的 img 并生成 partmap.txt   // out 是目录,会存放 rootfs.img 和 partmap.txt 两个文件   sudo ./build_rootfs.sh rootfsDir out  
---- ## 增加驱动、或增加内核模块
编译内核,并且编译驱动。 更新 boot.img 、rootfs.img。  
所需文件   内核代码:linux.tar.bz2  (git clone https://github.com/friendlyarm/linux.git -b sunxi-4.14.y --depth 1)   交叉编译工具链:gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu.tar.xz  (友善官方云盘下载)   制作镜像工具:sd-fuse_h5.tgz  (git clone https://github.com/friendlyarm/sd-fuse_h5)  
编译内核参考友善官方 http://wiki.friendlyarm.com/wiki/index.php/Building_U-boot_and_Linux_for_H5/H3/H2%2B/zh#.E7.BC.96.E8.AF.91Linux.E5.86.85.E6.A0.B8  
编译内核最终文件: |文件名                                                 |描述                   | 存放位置    | |----                                                  |----                   |----        | | arch/arm64/boot/Image                                | 内核                   | boot.img  | | arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi*.dtb  | dtb 设备树bin文件      | boot.img   | | 各个目录的.ko                                         | 内核模块。 加密或者驱动 | rootfs.img |
### 需要修改的文件
选择4G/5G模块需要的驱动模块。修改结果存在 .config 文件。  
#### U9300C 4G 模块
需要启用的内核模块有:   CONFIG_USB_SERIAL=y   CONFIG_USB_SERIAL_GENERIC=y   CONFIG_USB_SERIAL_OPTION=y   CONFIG_USB_USBNET=y   CONFIG_USB_NET_RNDIS_HOST=y   CONFIG_USB_NET_CDCETHER=y   可以直接用 vim .comfig 修改,也可以通过 make menuconfig ARCH=arm64 进行图形化修改。  
需要修改的 CONFIG_USB_SERIAL_OPTION 模块实际.c文件   /driver/usb/serial/option.c   static const struct usb_device_id option_ids[] 数组内添加一项: 
{ USB_DEVICE(0x1c9e, 0x9b3c) }, /* ULONG U9300C */  
### 打包 .img
参考 《知识储备》 《.img 相关》 部分。
#### boot.img
挂载 boot 分区。   Image 和 dtb 文件直接 copy 到 mount 挂载出来的 boot 文件夹。   卸载 boot 分区。  完成。
#### rootfs.img
解压 rootfs.img 到目录。 在 linux 源码目录下执行: make modules_install INSTALL_MOD_PATH=/rootfsDir/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-   将新内核模块安装到 rootfsDir 相关目录。
重新打包 rootfs.img 并获得 分区描述文件 partmap.txt 
完成修改。
---- # 预装系统软件/文件
预装系统软件只需要动 rootfs.img   打包系统镜像等完全参考驱动方面。
## 原理
直接修改 rootfs 文件,即预装软件。   由于 cpu 架构不同,rootfs 内的相关软件不能直接在PC上执行,需要一个模拟器。用于执行 rootfsDir 内的软件。   执行相关软件同样需要虚拟一个根目录。  
## 操作 ### 修改文件
直接修改,注意权限即可。
### 预装软件
PC 主机安装模拟器: sudo apt-get install qemu-user-static   PC 主机安装虚拟根目录软件: sudo apt-get install debootstrap  
debootstrap 内包含 chroot 命令。这是虚拟根目录的软件。  
// 从 PC 主机内 copy 刚安装的模拟器到 虚拟根目录下。 sudo cp /usr/bin/qemu-arm64-static rootfsDir/usr/bin/  
// 进入需要需要虚拟成根目录的目录下。 cd rootfsDir
// 所有指令都需要下列打头。   // sudo 需要 PC 机的 root 权限执行。   // LC_ALL=C LANGUAGE=C 基础环境变量。必须。   // chroot . 将当前目录虚拟成根目录。并执行后面的命令。   sudo LC_ALL=C LANGUAGE=C LANG=C chroot . 
// 例如:配置 dpkg   sudo LC_ALL=C LANGUAGE=C LANG=C chroot . dpkg --configure -a  
// 例如:安装 htop
sudo LC_ALL=C LANGUAGE=C LANG=C chroot . apt-get install htop
上一篇:构建调试Linux内核网络代码的环境MenuOS系统


下一篇:linux