本文主要整理一下安卓的一些框架(本文介绍uboot),接触安卓半年了,写一篇文章做一次总结,以nxp的安卓11为标准。
一、 文件系统
uboot-imx$ ls
api board common configs doc dts examples include
Kconfig Licenses MAINTAINERS net README test
arch cmd config.mk disk drivers env fs Kbuild lib
Makefile post scripts tools
以nxp的uboot为例子,其下面的目录有这些
- api : 外部API扩展层序,一般不用修改。
- board: 已经支持的所有开发板相关文件,其中包含SDRAM初始化代码、Flash底层驱动、板级初始化文件。需要修改对应的文件,重要。
- common :通用代码,一些命令相关,不用修改。
- configs: 配置文件,必要情况下需要修改,需要明白自己的板子对应的defconfig,重要。
- doc: 一些uboot的配置说明,可以作为参考,不需要修改。
- dts:空壳目录。编译arch/arm下的dts的dts的脚本。
- examples:外部扩展程序,不需要修改。
- include:包含文件CPU,网络、文件系统等等,不用修改。
- Kconfig:编译宏,不用修改。
- Licenses:类似一些配置的txt文件,不用修改。
- net:网络相关的协议等等,不需要修改。
- test:各种单元测试,一般不用修改。
- arch:体系架构依赖,现在的uboot都沿用了kernel的arm框架,设备树进行管理,一般我们修改板子都需要注意一下其设备数的dts内容。目录:arch/arm/dts/ 重要。
- cmd: 一些命令相关的,不需要修改。
- drivers:uboot的一些驱动,对应的目录需要自己去看了,重要。
- disk/fs:磁盘分区的代码,不需要修改。
- lib:lib库不需要修改。
- tools:编译S-Record或U-Boot映像等相关工具,制作bootm引导的内核映像文件工具mkimage源码就在此,不需要修改。
- 其余的都是一些版权说明文档,介绍性文档之类的。
二、 对应的板级文件修改
在使用nxp的官方代码时候,因为我们可能会适配不同的ddr。就需要对ddr进行不同程度的校准以及修改。
具体的修改方法以及步骤可以看我之前写的文章:分别说明了 imx8qxp 和 Imx8mp系列的修改
对应的一些修改都在里面。代码主要修改目录为board/freescale的目录。
同样的, 我们可以修改板级文件再当前目录
uboot-imx/board/freescale/imx8qxp_mek$ vi imx8qxp_mek.c
我们操作GPIO都可在这里面进行操作
static void board_gpio_init(void)
{
struct gpio_desc desc;
int ret;
ret = dm_gpio_lookup_name("gpio@1a_3", &desc);
if (ret)
return;
ret = dm_gpio_request(&desc, "bb_per_rst_b");
if (ret)
return;
dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT);
dm_gpio_set_value(&desc, 0);
udelay(50);
dm_gpio_set_value(&desc, 1);
}
其实这里也展示了一个例子如何去控制gpio。可以仿照写。
三、对应的一些文件说明
板级别文件:
MX8QXP/vendor/nxp-opensource/uboot-imx/board/freescale$ ls
common imx8qm_val ls1021atwr m52277evb m54455evb mpc8541cds mx6sabresd mx6ullevk t102xrdb
corenet_ds imx8qxp_mek ls1028a m5235evb m547xevb mpc8548cds mx6slevk mx7d_12x12_ddr3_val t104xrdb
imx8dxl_evk imx8qxp_val ls1043aqds m5249evb m548xevb mpc8555cds mx6sllevk mx7d_12x12_lpddr3_val t208xqds
imx8dxl_phantom_mek imx8ulp_evk ls1043ardb m5253demo mpc8308rdb mpc8568mds mx6sll_val mx7d_19x19_ddr3_val t208xrdb
imx8mm_ab2 imxrt1020-evk ls1046afrwy m5272c3 mpc8313erdb mx23evk mx6sx_17x17_val mx7d_19x19_lpddr3_val t4rdb
imx8mm_evk imxrt1050-evk ls1046aqds m5275evb mpc8315erdb mx28evk mx6sx_19x19_val mx7dsabresd vf610twr
imx8mm_val ls1012afrdm ls1046ardb m5282evb mpc8323erdb mx51evk mx6sxsabreauto mx7ulp_evk
imx8mn_evk ls1012aqds ls1088a m53017evb mpc832xemds mx53evk mx6sxsabresd mx7ulp_val
imx8mp_evk ls1012ardb ls2080aqds m5329evb mpc8349emds mx53loco mx6ul_14x14_ddr3_val p1010rdb
imx8mq_evk ls1021aiot ls2080ardb m5373evb mpc8349itx mx6memcal mx6ul_14x14_evk p1_p2_rdb_pc
imx8mq_val ls1021aqds lx2160a m54418twr mpc837xemds mx6qarm2 mx6ul_14x14_lpddr2_val p2041rdb
imx8qm_mek ls1021atsn m5208evbe m54451evb mpc837xerdb mx6sabreauto mx6ull_ddr3_val s32v234evb
在对应的android源码中,其实已经有很多工程已经添加完毕,我们只需要去修改里面的文件就好了,并不需要去添加什么。比如我现在在imx8qxp的工程里面,我们也只需进入到对应的工程里面就好了
MX8QXP/vendor/nxp-opensource/uboot-imx/board/freescale/imx8qxp_mek$ ls
imx8qxp_mek.c imximage.cfg Kconfig MAINTAINERS Makefile spl.c uboot-container.cfg
我们再分析一些文件,首先是imx8qxp_mek.c板级文件
int checkboard(void)
{
/*在log中显示的对应的标志*/
puts("Board: Vantron iMX8QXP M08\n");
print_bootinfo();
return 0;
}
/*初始化文件,并加载对应的dtb文件*/
int board_late_init(void)
{
char *fdt_file;
bool m4_booted;
build_info();
env_set("board_name", "MEK");
env_set("board_rev", "iMX8QXP");
env_set("sec_boot", "no");
#ifdef CONFIG_AHAB_BOOT
env_set("sec_boot", "yes");
#endif
fdt_file = env_get("fdt_file");
m4_booted = m4_parts_booted();
if (fdt_file && !strcmp(fdt_file, "undefined")) {
/*后面尝试,这些dtb是可以修改的我们甚至可以只需要我们自己添加的工程的dtb*/
#ifdef CONFIG_TARGET_IMX8DX_MEK
if (m4_booted)
env_set("fdt_file", "imx8dx-mek-rpmsg.dtb");
else
env_set("fdt_file", "imx8dx-mek.dtb");
#else
if (m4_booted)
env_set("fdt_file", "imx8qxp-mek-rpmsg.dtb");
else
env_set("fdt_file", "imx8qxp-mek.dtb");
#endif
}
/*比如这样
if (fdt_file && !strcmp(fdt_file, "undefined")) {
env_set("fdt_file", "vt-imx8qxp-m08.dtb");
}
*/
至于后面的这些配置文件以及编译文件也没去深究,这些都不需要修改,Makefile的内容需要根据你的工程进行修改哈!
imximage.cfg Kconfig MAINTAINERS Makefile spl.c uboot-container.cfg
四、相关的编译知识
相比于Linux系统,android系统可以说是很简单的了,但是又不太方便。如何解析呢,因为android系统,我们只需要加载环境变量后,执行./imx-make.sh就好了,是很简单,但是耗费的时间真的长,所以再调试过程中,我们都会选择单独编译,对应的命令无需多说,可以自己去看文档
---------全部编译----------------------
./imx-make.sh -j16
---------只编译uboot--------------------
./imx-make.sh bootloader -j16
---------只编译kernel--------------------
./imx-make.sh bootimage -j16
---------只编译dtbo-----------------------
./imx-make.sh dtboimage -j16
这里也贴上吧。
如何确定自己的编译是否生效,我们可以通过.config文件进行查看,比如:
out/target/product/mek_8q/obj/UBOOT_OBJ$ vi .config
如果我们添加配置文件或则查看自己添加的配置文件是否有效,我们可以查看这个文件的内容。
如何快速判断我们自己的defconfig文件呢?
那就是编译的时候查看对应的编译输出
941056字节(941 kB,919 KiB)已复制,0.00484191 s,194 MB/s
make[1]: 离开目录“/sd2/VT-MX8QXP-M08-A/vendor/nxp-opensource/imx-mkimage”
===================Finish building imx8qxp-mek-c0-uuu:imx8qxp_mek_android_uuu_defconfig ===================
make: 离开目录“/sd2/VT-MX8QXP-M08-A”
make: 进入目录“/sd2/VT-MX8QXP-M08-A”
make[1]: 进入目录“/sd2/VT-MX8QXP-M08-A/vendor/nxp-opensource/nxp-mwifiex/mxm_wifiex/wlan_src”
make -C /sd2/VT-MX8QXP-M08-A/out/target/product/mek_8q/obj/KERNEL_OBJ M=/sd2/VT-MX8QXP-M08-A/vendor/nxp-opensource/nxp-mwifiex/mxm_wifiex/wlan_src ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules
make[2]: 进入目录“/sd2/VT-MX8QXP-M08-A/out/target/product/mek_8q/obj/KERNEL_OBJ”
make[2]: 离开目录“/sd2/VT-MX8QXP-M08-A/out/target/product/mek_8q/obj/KERNEL_OBJ”
make[1]: 离开目录“/sd2/VT-MX8QXP-M08-A/vendor/nxp-opensource/nxp-mwifiex/mxm_wifiex/wlan_src”
cp vendor/nxp-opensource/nxp-mwifiex/mxm_wifiex/wlan_src/moal.ko /sd2/VT-MX8QXP-M08-A/out/target/product/mek_8q/obj/MXMWIFI_OBJ;
make: 离开目录“/sd2/VT-MX8QXP-M08-A”
19:08:40 Warning: high -j32 count compared to 31.2GB of RAM
19:08:40 If you run into segfaults or other errors, try a lower -j value
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=11
TARGET_PRODUCT=mek_8q
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=cortex-a53
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a9
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.13.0-44-generic-x86_64-Ubuntu-20.04.4-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=RQ3A.210805.001.A1
OUT_DIR=out
PRODUCT_SOONG_NAMESPACES=device/generic/goldfish device/generic/goldfish-opengl external/mesa3d vendor/nxp-opensource/imx/pow
er hardware/google/pixel hardware/google/camera vendor/nxp-opensource/imx/camera vendor/partner_gms
============================================
[ 0% 28/5385] depmod out/target/product/mek_8q/obj/PACKAGING/depmod_VENDOR_intermediates
在编译android相关代码之前,我自己一般都会查看最后一个编译defconfig
===================Finish building imx8qxp-mek-c0-uuu:imx8qxp_mek_android_uuu_defconfig ===================
我也基本会以这个位准,后期修改的时候在里面添加配置。对于android来说,我们先编译一个完整的android会更加方便,我们可以直接干进开发板进行查看,后面也可以进行不同的uboot\kernel的编译和烧录。
五、Makefile编译脚本
这里要说对不起了,因为我确实对这个脚本不熟悉,因为我没有去研究过这个,而且我也看不懂,只能说这个Makefile一套又一套。但是我们需要知道在编译后会生成对应的img文件就ok。有兴趣的朋友可以去看看对应的文章,