arm32 arm64 u-boot 加载 linux的命令 bootm
- arm64 linux 被加载的情况
- bootm的命令
bootm <uImage_addr>
bootm <uImage_addr> <initrd_addr> <dtb_addr>
---
nand read.jffs2 0x30007FC0 kernel;
nand read.jffs2 32000000 device_tree;
bootm 0x30007FC0 - 0x32000000
arm32 arm64 的 kernel_entry
---
arch/arm/lib/bootm.c
armv8_switch_to_el2 (images->ft_addr, NULL, NULL, NULL);
---
arch/arm/lib/bootm.c
kernel_entry(0, machid, r2);
arm32和arm64 在 kernel_entry时 的区别
1. arm32的参数分别是 0 , board number , atags addr(fdt addr)
2. arm32的参数分别是 0 , board number , fdt addr
3. arm64的参数分别是 dbt addr , 0 , 0 , 0
4. arm64 不支持 atags
设备树对引导linux的影响
arm32 对 atags 和 dbt 的兼容
setup_arch
mdesc = setup_machine_fdt(atags_vaddr);
if (!mdesc) mdesc = setup_machine_tags(atags_vaddr, __machine_arch_type);
if (!mdesc) while(1);
- DT_MACHINE_START 和 MACHINE_START 的区别
DT_MACHINE_START 和 MACHINE_START 基本相同,
只是.nr 的设置不同,在 DT_MACHINE_START 里面直接将.nr 设置为~0(即0xffffffff)
说明引入设备树以后不会再根据 machine id 来检查 Linux 内核(是否支持某个设备了,即匹配某个设备的MD,即MACHINE_START )
而是根据设备树中的内容匹配 MD(即DT_MACHINE_START)
实例
linux/u-boot 对 smdk6410 板子 支持 了 atags 和 设备树
1. atags
MD : arch/arm/mach-s3c/mach-smdk6410.c 中的 MACHINE_START(SMDK6410, "SMDK6410")
atags : u-boot去设置 atags , 这里要去看 u-boot 的代码
atags的传递 : 要看 u-boot的代码
2. 设备树
MD : arch/arm/mach-s3c/mach-s3c64xx-dt.c 中的 DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)")
fdt : arch/arm/boot/dts/s3c6410-smdk6410.dts
fdt的传递 : 要看 u-boot 的代码
设备树编译
set -e;
mkdir -p include/config/;
trap "rm -f include/config/.kernel.release.tmp" EXIT;
{ echo "5.11.0$(sh ./scripts/setlocalversion .)"; } > include/config/.kernel.release.tmp;
if [ ! -r include/config/kernel.release ] || ! cmp -s include/config/kernel.release include/config/.kernel.release.tmp; then
: ' UPD include/config/kernel.release';
mv -f include/config/.kernel.release.tmp include/config/kernel.release;
fi
make -f ./scripts/Makefile.build obj=scripts/basic
rm -f .tmp_quiet_recordmcount
make -f ./scripts/Makefile.build obj=scripts/dtc
make -f ./scripts/Makefile.build obj=arch/arm/boot/dts
gcc -E -Wp,-MMD,arch/arm/boot/dts/.s3c6410-smdk6410.dtb.d.pre.tmp -nostdinc -I./scripts/dtc/include-prefixes -undef -D__DTS__ -x assembler-with-cpp -o arch/arm/boot/dts/.s3c6410-smdk6410.dtb.dts.tmp arch/arm/boot/dts/s3c6410-smdk6410.dts ;
./scripts/dtc/dtc -O dtb -o arch/arm/boot/dts/s3c6410-smdk6410.dtb -b 0 -iarch/arm/boot/dts/ -i./scripts/dtc/include-prefixes -Wno-interrupt_provider -Wno-unit_address_vs_reg -Wno-unit_address_format -Wno-avoid_unnecessary_addr_size -Wno-alias_paths -Wno-graph_child_address -Wno-simple_bus_reg -Wno-unique_unit_address -Wno-pci_device_reg -d arch/arm/boot/dts/.s3c6410-smdk6410.dtb.d.dtc.tmp arch/arm/boot/dts/.s3c6410-smdk6410.dtb.dts.tmp ;
cat arch/arm/boot/dts/.s3c6410-smdk6410.dtb.d.pre.tmp arch/arm/boot/dts/.s3c6410-smdk6410.dtb.d.dtc.tmp > arch/arm/boot/dts/.s3c6410-smdk6410.dtb.d
如何展开一个设备树文件
编译设备树的时候自会展开,gcc 用预处理过程做的
源文件
arch/arm/boot/dts/s3c6410-smdk6410.dts
展开的文件名如下
arch/arm/boot/dts/.s3c6410-smdk6410.dtb.dts.tmp
设备树中的节点
https://github.com/lisider/linux_4.0/blob/4d917d76df265d351201b4908c71ff9c0e77ec3c/arch/arm/boot/dts/vexpress-v2p-ca9.dts
挂在根节点下面的compatible非空节点 不是 amba节点,就是platform 节点 ,该节点为 platform 节点
没有 compatible属性 的节点不会被解析成 device_node , 无效节点
compatible = "arm,primecell"; 的节点 会被解析为 会被 解析为 amba总线的节点
其他的compatible非空 节点 为 platform 节点
节点 compatible 属性 为 "simple-bus" 等字符串 的 节点 下面挂载的 都是 platform 节点
其他节点
被匹配为i2c 控制器的节点(一般为platform节点)下面的节点为i2c节点(被匹配为i2c设备)
被匹配为spi 控制器的节点(一般为platform节点)下面的节点为spi节点(被匹配为spi设备)