linux的MACHINE_START-MACHINE_END(转)
2016-08-22 16:23
435 查看
转自: http://blog.sina.com.cn/s/blog_753fd0b00100t8js.html
在友善mini2440提供的linux2.6.32.2内核中,有如下定义:
MACHINE_START(MINI2440, "FriendlyARM Mini2440 development board")
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = mini2440_map_io,
.init_machine = mini2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
下面分析一下:
在include/asm-arm/mach/arch.h中,有定义
#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 \
};
列出machine_desc的定义:
struct machine_desc {
unsigned int nr;
unsigned int phys_io;
unsigned int io_pg_offst;
const char *name;
unsigned long boot_params;
unsigned int video_start;
unsigned int video_end;
unsigned int reserve_lp0 :1;
unsigned int reserve_lp1 :1;
unsigned int reserve_lp2 :1;
unsigned int soft_reboot :1;
void (*fixup)(struct machine_desc *,
struct tag *, char **,
struct meminfo *);
void (*map_io)(void);
void (*init_irq)(void);
struct sys_timer *timer;
void (*init_machine)(void);
};
按定义展开后:
static const struct machine_desc __mach_desc_MINI2440 \
__used \
__attribute__((__section__(".arch.info.init"))) = {
.nr = MACH_TYPE_MINI2440,
.name = "FriendlyARM Mini2440 development board",
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = mini2440_map_io,
.init_machine = mini2440_machine_init,
.timer = &s3c24xx_timer,
};
MACH_TYPE_MINI2440 是mini2440开发板在linux中的机器号。
"FriendlyARM Mini2440 development board"是开发板信息,在终端输入cat /proc/cpuinfo可以查看。
MACHINE_START主要是定义了"struct machine_desc"的类型,放在 section(".arch.info.init"),是初始化数据,Kernel 起来之后将被丢弃。
其余各个成员函数在setup_arch()中被赋值到内核结构体,在不同时期被调用:
1. .init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用。
static int __init customize_machine(void)
{
if (init_machine)
init_machine();
return 0;
}
arch_initcall(customize_machine);
2. .init_irq在start_kernel()(文件init/main.c)--> init_IRQ() (在文件arch/arm/kernel/Irq.c)--> init_arch_irq()中被调用
3. .map_io 在 setup_arch(&command_line) (在文件arch/arm/kernel/setup.c)--> paging_init()(在文件arch/arm/kernel/mm/Mmu.c) --> devicemaps_init()(在文件arch/arm/kernel/mm/Mmu.c)中被调用
4. .timer是定义系统时钟,定义TIMER4为系统时钟,在arch/arm/plat-s3c/time.c中体现。在start_kernel() --> time_init()(在文件arch/arm/kernel/Time.c)中被调用。
5. .boot_params是bootloader向内核传递的参数的位置,这要和bootloader中参数的定义要一致。
其他主要都在 setup_arch() 中用到。
在友善mini2440提供的linux2.6.32.2内核中,有如下定义:
MACHINE_START(MINI2440, "FriendlyARM Mini2440 development board")
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = mini2440_map_io,
.init_machine = mini2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
下面分析一下:
在include/asm-arm/mach/arch.h中,有定义
#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 \
};
列出machine_desc的定义:
struct machine_desc {
unsigned int nr;
unsigned int phys_io;
unsigned int io_pg_offst;
const char *name;
unsigned long boot_params;
unsigned int video_start;
unsigned int video_end;
unsigned int reserve_lp0 :1;
unsigned int reserve_lp1 :1;
unsigned int reserve_lp2 :1;
unsigned int soft_reboot :1;
void (*fixup)(struct machine_desc *,
struct tag *, char **,
struct meminfo *);
void (*map_io)(void);
void (*init_irq)(void);
struct sys_timer *timer;
void (*init_machine)(void);
};
按定义展开后:
static const struct machine_desc __mach_desc_MINI2440 \
__used \
__attribute__((__section__(".arch.info.init"))) = {
.nr = MACH_TYPE_MINI2440,
.name = "FriendlyARM Mini2440 development board",
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = mini2440_map_io,
.init_machine = mini2440_machine_init,
.timer = &s3c24xx_timer,
};
MACH_TYPE_MINI2440 是mini2440开发板在linux中的机器号。
"FriendlyARM Mini2440 development board"是开发板信息,在终端输入cat /proc/cpuinfo可以查看。
MACHINE_START主要是定义了"struct machine_desc"的类型,放在 section(".arch.info.init"),是初始化数据,Kernel 起来之后将被丢弃。
其余各个成员函数在setup_arch()中被赋值到内核结构体,在不同时期被调用:
1. .init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用。
static int __init customize_machine(void)
{
if (init_machine)
init_machine();
return 0;
}
arch_initcall(customize_machine);
2. .init_irq在start_kernel()(文件init/main.c)--> init_IRQ() (在文件arch/arm/kernel/Irq.c)--> init_arch_irq()中被调用
3. .map_io 在 setup_arch(&command_line) (在文件arch/arm/kernel/setup.c)--> paging_init()(在文件arch/arm/kernel/mm/Mmu.c) --> devicemaps_init()(在文件arch/arm/kernel/mm/Mmu.c)中被调用
4. .timer是定义系统时钟,定义TIMER4为系统时钟,在arch/arm/plat-s3c/time.c中体现。在start_kernel() --> time_init()(在文件arch/arm/kernel/Time.c)中被调用。
5. .boot_params是bootloader向内核传递的参数的位置,这要和bootloader中参数的定义要一致。
其他主要都在 setup_arch() 中用到。
相关文章推荐
- LINUX中的MACH定义之MACHINE_START / MACHINE_END
- linux之MACHINE_START和 MACHINE_END
- linux中MACHINE_START&END在9g10ek上实现
- LINUX中的MACH定义之MACHINE_START / MACHINE_END
- LINUX中的MACH定义之MACHINE_START / MACHINE_END
- Linux中的MACH定义之MACHINE_START / MACHINE_END
- LINUX中的MACH定义之MACHINE_START / MACHINE_END
- Linux中的MACH定义之MACHINE_START / MACHINE_END
- Linux驱动基础:va_arg,va_start,va_end等介绍
- linux 可变参数va_start va_arg va_end
- MACHINE_START与MACHINE_END
- ARM linux kernel从入口到start_kernel代码分析 -- 只到machine type选中为止
- Linux C/C++ 链接选项之静态库--whole-archive,--no-whole-archive和--start-group, --end-group
- MACHINE_START-内核板级初始化实现机制(linux3.1.0)
- 【linux】具体芯片MACHINE_START处理
- MACHINE_START与MACHINE_END
- View the start/end of a file linux
- MACHINE_START与MACHINE_END
- MACHINE_START and MACHINE_END Macro define
- 【linux】具体芯片MACHINE_START处理