rk3288 dts 根目录下的compatile属性值 如何与开发板单板匹配的

1.rk3288 dts 路径

路径:kernel\arch\arm\boot\dts\rk3288.dtsi

路径:kernel\arch\arm\boot\dts\rk3288-miniarm.dts

根目录下的compatible 属性表示该设备树可以兼容的平台,优先匹配"rockchip,rk3288-miniarm", 匹配不到的话,再进行匹配"rockchip,rk3288"。

/ {
	compatible = "rockchip,rk3288-miniarm", "rockchip,rk3288";

	memory {
		device_type = "memory";
		reg = <0x0 0x0 0x0 0x80000000>;
	};
/

2.该设备树如何与设备平台进行匹配?


asmlinkage __visible void __init start_kernel(void)
    ->setup_arch(&command_line);//(路径:kernel\init\main.c)
        ->mdesc = setup_machine_fdt(__atags_pointer);//(路径:kernel\arch\arm\kernel\devtree.c) 检查传入的dtb 是否有效
            ->mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);//(路径:kernel\drivers\of\fdt.c) 找到machine_desc的最佳匹配



                

1)machine_desc 的结构体

路径:arch/arm/include/asm/mach/arch.h

struct machine_desc {
	unsigned int		nr;		/* architecture number	*/
	const char		*name;		/* architecture name	*/
	unsigned long		atag_offset;	/* tagged list (relative) */
	const char *const 	*dt_compat;	/* array of device tree
						 * 'compatible' strings	*/

	unsigned int		nr_irqs;	/* number of IRQs */

#ifdef CONFIG_ZONE_DMA
	phys_addr_t		dma_zone_size;	/* size of DMA-able area */
#endif

	unsigned int		video_start;	/* start of video RAM	*/
	unsigned int		video_end;	/* end of video RAM	*/

	unsigned char		reserve_lp0 :1;	/* never has lp0	*/
	unsigned char		reserve_lp1 :1;	/* never has lp1	*/
	unsigned char		reserve_lp2 :1;	/* never has lp2	*/
	enum reboot_mode	reboot_mode;	/* default restart mode	*/
	unsigned		l2c_aux_val;	/* L2 cache aux value	*/
	unsigned		l2c_aux_mask;	/* L2 cache aux mask	*/
	void			(*l2c_write_sec)(unsigned long, unsigned);
	const struct smp_operations	*smp;	/* SMP operations	*/
	bool			(*smp_init)(void);
	void			(*fixup)(struct tag *, char **);
	void			(*dt_fixup)(void);
	long long		(*pv_fixup)(void);
	void			(*reserve)(void);/* reserve mem blocks	*/
	void			(*map_io)(void);/* IO mapping function	*/
	void			(*init_early)(void);
	void			(*init_irq)(void);
	void			(*init_time)(void);
	void			(*init_machine)(void);
	void			(*init_late)(void);
#ifdef CONFIG_MULTI_IRQ_HANDLER
	void			(*handle_irq)(struct pt_regs *);
#endif
	void			(*restart)(enum reboot_mode, const char *);
};

2)of_flat_dt_match_machine 根目录下的compatible 属性与设备平台匹配过程

每次调用函数 of_flat_dt_match_machine(mdesc_best, arch_get_next_mach); 从地址 __arch_info_begin 到 __arch_info_end 遍历,都会返回一个结构体machine_desc 的成员dt_compat与设备树中的compatible 属性对比。

static const void * __init arch_get_next_mach(const char *const **match)
{
	static const struct machine_desc *mdesc = __arch_info_begin;
	const struct machine_desc *m = mdesc;

	if (m >= __arch_info_end)
		return NULL;

	mdesc++;
	*match = m->dt_compat;
	return m;
}

主要看__arch_info_begin 到 __arch_info_end  地址由来。

路径:kernel\arch\arm\kernel\vmlinux.lds.S 

	.init.arch.info : {
		__arch_info_begin = .;
		*(.arch.info.init)
		__arch_info_end = .;
	}

.init.arch.info 的定义

/*
 * Set of macros to define architecture features.  This is built into
 * a table by the linker.
 */
#define MACHINE_START(_type,_name)			\
static const struct machine_desc __mach_desc_##_type	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= MACH_TYPE_##_type,		\
	.name		= _name,

#define MACHINE_END				\
};

#define DT_MACHINE_START(_name, _namestr)		\
static const struct machine_desc __mach_desc_##_name	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= ~0,				\
	.name		= _namestr,

#endif

3)最终找到设备数可以匹配平台的设备字符串

路径:kernel\arch\arm\mach-rockchip\rockchip.c 

static const char * const rockchip_board_dt_compat[] = {
	"rockchip,rk2928",
	"rockchip,rk3066a",
	"rockchip,rk3066b",
	"rockchip,rk3188",
	"rockchip,rk3288",
	NULL,
};

DT_MACHINE_START(ROCKCHIP_DT, "Rockchip (Device Tree)")
	.l2c_aux_val	= 0,
	.l2c_aux_mask	= ~0,
	.init_time	= rockchip_timer_init,
	.dt_compat	= rockchip_board_dt_compat,
	.init_machine	= rockchip_dt_init,
MACHINE_END

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值