LINUX中使用DT_MACHINE_START/MACHINE_START宏
DT_MACHINE_START宏
LINUX中用DT_MACHINE_START/MACHINE_START定义的MACH,并给出定义的各个成员函数在初始化过程中被调用的时机
比如,kernel/arch/arm/mach-vexpress/v2m.c:
// SPDX-License-Identifier: GPL-2.0
#include <asm/mach/arch.h>
#include "core.h"
static const char * const v2m_dt_match[] __initconst = {
"arm,vexpress",
NULL,
};
DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
.dt_compat = v2m_dt_match,
.l2c_aux_val = 0x00400000,
.l2c_aux_mask = 0xfe0fffff,
.smp = smp_ops(vexpress_smp_dt_ops),
.smp_init = smp_init_ops(vexpress_smp_init_ops),
MACHINE_END
DT_MACHINE_START定义:
/*
设置多个宏来定义其体系结构和功能。这些宏由链接器将其构建为一个可执行的表。
*/
#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
展开为:
static const struct machine_desc __mach_desc_VEXPRESS_DT{
__used
__attribute__((__section__(".arch.info.init"))) = {
.name = "ARM-Versatile Express",
...
....
......
};
定义了struct machine_desc类型的变量__mach_desc_VEXPRESS_DT,将其放在section(“.arch.info.init”),是内核初始化数据。
看一下这个机器描述符结构:
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;