- 加载/ 启动linux内核脚本
下面就是如何如何通过Usb加载运行编译出来的kernel及ramdisk.img了(脚本:Android-Q/nanopi-neo/boot/run.sh):
#! /bin/bash set -e -x RAMDISK=../../out/target/product/nanopi/ramdisk.img SIZE_RAMDISK=`printf '0x%x' $(stat -c %s ${RAMDISK})` cat << EOF > boot.cmd # Recompile with: mkimage -C none -A arm -T script -d boot.cmd boot.scr # CPU=H3 # OS=friendlycore/ubuntu-oled/ubuntu-wifiap/openwrt/debian/debian-nas... echo "running boot.scr" setenv ramdisk ramdisk.img setenv kernel zImage setenv env_addr 0x43100000 setenv kernel_addr 0x46000000 setenv ramdisk_addr 0x47000000 setenv dtb_addr 0x48000000 setenv ramdisk_size ${SIZE_RAMDISK} fdt addr \${dtb_addr} # setup MAC address fdt set ethernet0 local-mac-address \${mac_node} # setup XR819 MAC address if test \$board = nanopi-duo; then fdt set xr819 local-mac-address \${wifi_mac_node}; fi # setup boot_device fdt set mmc\${boot_mmc} boot_device <1> setenv fbcon map:0 #setenv hdmi_res drm_kms_helper.edid_firmware=HDMI-A-1:edid/1280x720.bin video=HDMI-A-1:1280x720@60 setenv extra androidboot.hardware=nanopi androidboot.selinux=permissive androidboot.serialno=621415251279 setenv bootargs console=ttyS0,115200 earlyprintk panic=10 fbcon=\${fbcon} printk.devkmsg=on ignore_loglevel \${extra} bootz \${kernel_addr} \${ramdisk_addr}:\${ramdisk_size} \${dtb_addr} EOF ../u-boot/tools/mkimage -C none -A arm -T script -d boot.cmd boot.scr ../sunxi-tools/sunxi-fel -p -v uboot ../u-boot/u-boot-sunxi-with-spl.bin \ write 0x43100000 boot.scr \ write 0x48000000 ../../kernel-common/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dtb \ write 0x46000000 ../../kernel-common/arch/arm/boot/zImage \ write 0x47000000 ${RAMDISK}
从这里可以看到,这个脚本:
1。首先会在当前路径下创建一个名为boot.cmd(Android-Q/nanopi-neo/boot/boot.cmd)的文件
2。再通过mkimage转换成u-boot可以识别的boot.scr(Android-Q/nanopi-neo/boot/boot.scr)文件
3。最后会通过sunxi-fel工具,将相关的文件boot.scr, sun8i-h3-nanopi-eno.dtb,zImage及ramdisk.img文件,下载到开发板中,并运行。
这里需要注意的是:ramdisk.img文件大小需要明确指定,并且大小是十六进制格式(无论前面没有加0x)。
使用这样的方式加载的好处是不用将这些文件copy到TF卡中,对早期需要反复修改kernel/dtb文件非常便利。
下面是另外一个脚本(Android-Q/nanopi-neo/boot/cmd.sh),用于加载TF卡中的kernel/dtb/ramdisk.img文件,也非常好用:
#! /bin/bash set -e -x cat << EOF > boot.cmd # Recompile with: mkimage -C none -A arm -T script -d boot.cmd boot.scr # CPU=H3 # OS=friendlycore/ubuntu-oled/ubuntu-wifiap/openwrt/debian/debian-nas... echo "running boot.scr" setenv ramdisk ramdisk.img setenv kernel zImage setenv env_addr 0x43100000 setenv kernel_addr 0x46000000 setenv ramdisk_addr 0x47000000 setenv dtb_addr 0x48000000 fatload mmc 0 \${kernel_addr} \${kernel} fatload mmc 0 \${ramdisk_addr} \${ramdisk} setenv ramdisk_size \${filesize} fatload mmc 0 \${dtb_addr} sun8i-\${cpu}-\${board}.dtb fdt addr \${dtb_addr} # setup MAC address fdt set ethernet0 local-mac-address \${mac_node} # setup XR819 MAC address if test \$board = nanopi-duo; then fdt set xr819 local-mac-address \${wifi_mac_node}; fi # setup boot_device fdt set mmc\${boot_mmc} boot_device <1> setenv fbcon map:0 #setenv hdmi_res drm_kms_helper.edid_firmware=HDMI-A-1:edid/1280x720.bin video=HDMI-A-1:1280x720@60 setenv extra androidboot.hardware=nanopi androidboot.selinux=permissive androidboot.serialno=621415251279 setenv bootargs console=ttyS0,115200 earlyprintk panic=10 fbcon=\${fbcon} printk.devkmsg=on ignore_loglevel \${extra} bootz \${kernel_addr} \${ramdisk_addr}:\${ramdisk_size} \${dtb_addr} EOF ../u-boot/tools/mkimage -C none -A arm -T script -d boot.cmd boot.scr ../sunxi-tools/sunxi-fel -p -v uboot ../u-boot/u-boot-sunxi-with-spl.bin \ write 0x43100000 boot.scr
写这两个脚本,是由于之前在修改kernel配置的时候,出现无法开机的情况,使用这两个脚本,可以有效地减少更新TF卡文件的烦恼。
- Android-Q分区配置
目前看来,TF只需要这几个分区就可以了:
1。boot分区:用于存放boot.scr, dtb, zImage及ramdisk.img文件, 需要~64MiB
2。system分区:用于写入system.img,需要~350MiB
3。vendor分区:用于写入vendor.img,需要~128MiB
4。userdata分区:用于存放系统及用户数据
- Android fstab
Android init进程启动时,在第一阶段需要挂载vendor分区(及system分区?),需要修改sun8i-h3-neo.dts文件:
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts index 9f33f6f..f1f7c6e9 100644 --- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts +++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts @@ -45,6 +45,30 @@ / { model = "FriendlyARM NanoPi NEO"; compatible = "friendlyarm,nanopi-neo", "allwinner,sun8i-h3"; + + firmware: firmware { + android { + compatible = "android,firmware"; + + android_fstab: fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/mmcblk0p2"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/mmcblk0p3"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + }; + }; + }; + }; };
- first stage中的console
在system/core的aosp/master分支中,在first stage中加入了console的代码,这个感觉还是非常有用的:
commit d75f30a4f0ca10ebd87798d7aeed467e0da40daa Author: Steve Muckle <smuckle@google.com> Date: Tue May 21 15:50:39 2019 -0700 first_stage_init: add console Start and wait on a console if androidboot.first_stage_console=1 is present on the kernel command line. This only works on eng and userdebug builds. Change-Id: I978e9390a89509431b399ea58b284736b27eeb1b
希望在Android Q的最终版本上也能有这样的功能Cool。