linux内核移植详解1——板级初始化过程
2016-06-06 23:38
435 查看
之前虽然已经为sep4020移植内核了linux2.6的内核,但当初做的时候还是很多地方不是很明白为什么要这样做,仅仅是把项目完成了,没有真正理解透彻,最近有点时间再把以前的工作好好理清楚。
(各位读者如果有兴趣,请和之前一篇Porting
Linux2.6.16内核到sep4020(arm720T) 一起阅读,这一系列会对我前面做的工作深化)
1.之前谈到我们要为我们的处理器设置一个它独有的机器号,在arch/arm/tools/mach-types中,我写了这么一句话:
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
sep4020 ARCH_4020 GFD4020 194
我们说bootloader一定要把机器号传给内核,这样内核才能找到相应的处理器,这里uboot传的机器号就是(number)194,但是内核又是如何根据这个194找到我们的处理器,找到我们的板级设备。
2.上面那段定义看似一定意义都没有,但是实际是有的,通过我们的gen-mach-types会在include/asm-arm/mach-types.h中自动生成这么一段话:
#define MACH_TYPE_GFD4020 194
#ifdef CONFIG_ARCH_4020
# ifdef machine_arch_type
# undef machine_arch_type
# define machine_arch_type __machine_arch_type
# else
# define machine_arch_type MACH_TYPE_GFD4020
# endif
# define machine_is_sep4020() (machine_arch_type == MACH_TYPE_GFD4020)
#else
# define machine_is_sep4020() (0)
#endif
3.在我们的arch/arm/4020.c中有一个函数,这个函数包括了我们板级初始化的所有初始化步骤。
MACHINE_START(GFD4020, "4020 board")
.phys_io = 0x10000000,
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x30000100,
.fixup = fixup_gfd4020,
.map_io = sep4020_map_io,
.init_irq = sep4020_init_irq,
.init_machine = sep4020_init,
.timer = &sep4020_timer,
MACHINE_END
跟进去发现其实这一步其实是定义了一个结构体,
struct machine_desc __mach_desc_##_type
{
.nr = MACH_TYPE_GFD4020, //可见就是194
.name = "4020 board",
//重要的板级初始化函数
.map_io = sep4020_map_io,
.init_irq = sep4020_init_irq,
.init_machine = sep4020_init,
.timer = &sep4020_timer,
}
4.linux起来之后会进入start_kernel大函数,在这个启动的大函数中的最前面几步会到一个setup_arch的子函数,我们的板级初始化过程就是通过这个函数实现的。
setup_arch->setup_machine->lookup_machine_type(nr);
mdesc = setup_machine(machine_arch_type);这个参数就是通过uboot传过来的机器号194;然后通过lookup_machine_type函数得到之前提到的machine_desc结构体;
得到了这个板级结构体之后,就把这个板级结构体中的我们cpu的信息赋给系统通用的全局变量,如下:
machine_name = mdesc->name;
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine= mdesc->init_machine;
到此板级的钩子算是勾上了,但是还没有真正的实现注册,具体的timer,irq注册就是通过红字标出的这几个全局变量结构体在后面的init_IRQ,init_timers,中实现的。
(各位读者如果有兴趣,请和之前一篇Porting
Linux2.6.16内核到sep4020(arm720T) 一起阅读,这一系列会对我前面做的工作深化)
1.之前谈到我们要为我们的处理器设置一个它独有的机器号,在arch/arm/tools/mach-types中,我写了这么一句话:
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
sep4020 ARCH_4020 GFD4020 194
我们说bootloader一定要把机器号传给内核,这样内核才能找到相应的处理器,这里uboot传的机器号就是(number)194,但是内核又是如何根据这个194找到我们的处理器,找到我们的板级设备。
2.上面那段定义看似一定意义都没有,但是实际是有的,通过我们的gen-mach-types会在include/asm-arm/mach-types.h中自动生成这么一段话:
#define MACH_TYPE_GFD4020 194
#ifdef CONFIG_ARCH_4020
# ifdef machine_arch_type
# undef machine_arch_type
# define machine_arch_type __machine_arch_type
# else
# define machine_arch_type MACH_TYPE_GFD4020
# endif
# define machine_is_sep4020() (machine_arch_type == MACH_TYPE_GFD4020)
#else
# define machine_is_sep4020() (0)
#endif
3.在我们的arch/arm/4020.c中有一个函数,这个函数包括了我们板级初始化的所有初始化步骤。
MACHINE_START(GFD4020, "4020 board")
.phys_io = 0x10000000,
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x30000100,
.fixup = fixup_gfd4020,
.map_io = sep4020_map_io,
.init_irq = sep4020_init_irq,
.init_machine = sep4020_init,
.timer = &sep4020_timer,
MACHINE_END
跟进去发现其实这一步其实是定义了一个结构体,
struct machine_desc __mach_desc_##_type
{
.nr = MACH_TYPE_GFD4020, //可见就是194
.name = "4020 board",
//重要的板级初始化函数
.map_io = sep4020_map_io,
.init_irq = sep4020_init_irq,
.init_machine = sep4020_init,
.timer = &sep4020_timer,
}
4.linux起来之后会进入start_kernel大函数,在这个启动的大函数中的最前面几步会到一个setup_arch的子函数,我们的板级初始化过程就是通过这个函数实现的。
setup_arch->setup_machine->lookup_machine_type(nr);
mdesc = setup_machine(machine_arch_type);这个参数就是通过uboot传过来的机器号194;然后通过lookup_machine_type函数得到之前提到的machine_desc结构体;
得到了这个板级结构体之后,就把这个板级结构体中的我们cpu的信息赋给系统通用的全局变量,如下:
machine_name = mdesc->name;
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine= mdesc->init_machine;
到此板级的钩子算是勾上了,但是还没有真正的实现注册,具体的timer,irq注册就是通过红字标出的这几个全局变量结构体在后面的init_IRQ,init_timers,中实现的。
相关文章推荐
- CentOS增加网卡
- Linux常见面试题2
- Linux常见面试题1
- ubuntu linux 安装composer
- 【转】linux configure报错configure: error: C++ preprocessor “/lib/cpp” fails sanity 的解决办法
- 装完CentOS-6.x之后的简单优化
- Linux计划任务(转载)
- Linux下安装配置java环境
- Linux 挂载概念 理解
- linux下的last命令及其数据源
- 《Linux课本》读书笔记 第十七章 模块
- 在linux system enter suspend 的时候线程冻结
- CentOS下安装Mysql记录
- linux下mysql的编译安装和my.cnf配置文件详解
- 嵌入式Linux裸机开发(五)——SDRAM初始化
- service命令
- linux设备模型之Class
- linux部署pxe+kickstart批量安装linux操作系统实施方案 推荐
- linux select与poll的区别
- Linux设置环境变量小结:设置永久变量&临时变量 全局变量&局部变量