machinestart什么时候bat start 调用脚本

我对MACHINE_START MACHINE_END的理解 - gzg的专栏 - CSDN博客
我对MACHINE_START MACHINE_END的理解
在XC2440开发板提供的linux2.6.37.4内核中,有如下定义:
MACHINE_START(XC2440, &XC2440&)
&& &.boot_params&& &= S3C2410_SDRAM_PA + 0x100,
&& &.init_irq&& &= s3c24xx_init_irq,
&& &.map_io&& &&& &= xc2440_map_io ,
&& &.init_machine&& &= xc2440_machine_init,
&& &.timer&& &&& &= &s3c24xx_timer,
MACHINE_END
下面分析一下:
在include/asm-arm/mach/arch.h中,有定义
#defineMACHINE_START(_type,_name) \
static const structmachine_desc __mach_desc_##_type
\&&&&& // __mach_desc_##_type会被宏替换为__mach_desc_XC2440
&__attribute__((__section__(&..init&)))= {\
.nr= MACH_TYPE_##_type,\
.name= _name,
#defineMACHINE_END \
列出machine_desc的定义:
struct machine_desc {
&&&&&&&&&&&&&&&&&&&&&& //unsigned int phys_&&&
&&&&&&&&&&&&&&&&&&&&& //unsigned int io_pg_& // 这两个结构体成员在2.6.37已经不存在了,在2.6.32里还存在,phys_io与io_pg_offst之间映射在head.S里完成的
const char *
unsigned long boot_
unsigned int video_
unsigned int video_
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 *
void (*init_machine)(void);
按定义展开后:
static const struct machine_desc __mach_desc_XC2440\
&__attribute__((__section__(&..init&))) ={
.nr= MACH_TYPE_XC2440,
//MACH_TYPE_XC2440为机器码,位于include/generated/mach-types.h,这个头文件是内核配置时产生的,下面有解释
.name=&&XC2440&,//&XC2440&是开发板的相关信息,在终端输入cat/proc/cpuinfo可以查看到。
&&&&&&&&&&&& //.phys_io =S3C2410_PA_UART,//物理IO的起始地址
&&&&&&&&&&&& //.io_pg_offst = (((u32)S3C24XX_VA_UART)&& 18) &0xfffc,//物理IO地址所对应的虚拟地址,这两个结构体成员在2.6.37已经不存在了,在2.6.32里还存在
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = xc2440_map_io,
.init_machine = xc2440_machine_init,
.timer = &s3c24xx_timer,
&& 在linux的kenel配置的时候,会生成一个mach-types.h文件,里面用来定义处理器的ID,在2.6.36之前好像是生成到include/asm-arm文件夹里面,2.6.36之后则会生成到include/generated目录里面。
&& 这个处理器的ID作用大家都知道,就是bootloader一定要把处理器ID号传给内核,这样内核才能找到相应的处理器,如果匹配时出错,则会出现系统死掉。如果是新添加一个处理器,则需要修改arch/arm/tools/mach-types文件,并在文件里面加上你的处理器的ID号。具体可以参考这篇文章:http://blog.csdn.net/yao_guet/article/details/6431359
MACH_TYPE_XC2440是XC2440开发板在linux内核中的机器号。
&XC2440&是开发板的相关信息,在终端输入cat/proc/cpuinfo可以查看到。
MACHINE_START主要是定义了&structmachine_desc&的类型,放在 section(&..init&),是初始化数据,Kernel起来之后将被丢弃。
其余各个成员函数在setup_arch()中被赋值到内核结构体,在不同时期被调用:
1. .init_machine 在 arch/arm/kernel/setup.c 中被customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用。
2. .init_irq在start_kernel() --& init_IRQ()--& init_arch_irq()中被调用
3. .map_io 在 setup_arch() --& paging_init()--& devicemaps_init()中被调用
4..timer是定义系统时钟,定义TIMER4为系统时钟,在arch/arm/plat-s3c/time.c中体现。在start_kernel()--& time_init()中被调用。
5..boot_params是bootloader向内核传递的参数的位置,这要和bootloader中参数的定义要一致。
其他主要都在 setup_arch() 中用到。
我的热门文章博客访问: 239138
博文数量: 141
博客积分: 106
博客等级: 民兵
技术积分: 613
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
原文地址: 作者:
(写在转载之前)
&&& 在linux中machine对应一个设备,对于开发者而言对应一个新的项目,项目开展的初始需要对应定义一个MACH,在arch/arm/mach-xxx/目录下,此文件中定义了GPIO的使用,外设,i2c总线等系统信息,所以在参加一个项目的开始,应该认真的分析machine定义文件,了解项目的情况。
&&& 在arch/arm/下定义了很多mach-xxx的文件夹,一般是按照厂商或者平台命名,例如高通平台的为mach-msm,marvell的为mach-mmp,mach-pxa。
本文讲解LINUX中用MACHINE_START/MACHINE_END定义的MACH,并给出定义的各个成员函数在初始化过程中被调用的时机。&1.&&&&& 定义一个MACH&LINUX中MACHINE定义是用MACHINE_START()/MACHINE_END两个宏来实现的,比如MSM的实现(arch/arm/mach-msm/board-halibut.c):
1.MACHINE_START(HALIBUT,"Halibut Board (QCT SURF7200A)")& &2.&&&&&&&& .boot_params&&&&& = 0x,& &3.&&&&&&&& .map_io&&&&&&&&&& = halibut_map_io,& &4.&&&&&&&& .init_irq&&&&&&&& = halibut_init_irq,& &5.&&&&&&&& .init_machine&&&& = halibut_init,& &6.&&&&&&&& .timer&&&&&&&&&&& = &msm_timer,& &7.MACHINE_END& &2. MACHINE_START / MACHINE_END定义&上面的定义中,用到了这两个宏MACHINE_START/MACHINE_END,下面是它们具体的定义(在arch/arm/include/asm/mach/arch.h中): &1.#defineMACHINE_START(_type,_name)&&&&&&&&&&&&&&&&&&&&&&& \&& &2.static const structmachine_desc __mach_desc_##_type&&&&& \& &3. __used&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& \& &4. __attribute__((__section__("..init")))= {&&&&& \& &5.&&&&&&&& .nr&&&&&&&&&&&& = MACH_TYPE_##_type,&&&&&&&&&&& \& &6.&&&&&&&& .name&&&&&&&&&& = _name,& &7.&& &8.#define MACHINE_END&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& \&& &9.};& &struct machine_desc也是定义在arch/arm/include/asm/mach/arch.h&1.struct machine_desc {& &2.&&&&&&&& /* &3.&&&&&&&&& * Note! The firstfour elements are used &4.&&&&&&&&& * by assembler codein head.S, head-common.S &5.&&&&&&&&& */& &6.&&&&&&&& unsigned int&&&&&&&&&&&&&&&&&&&&&&&&&&&& /* architecture number& */& &7.&&&&&&&& unsigned int&&&&&&&&&&& phys_&&&&&&&&&&&& /* start of physical io */& &8.&&&&&&&& unsigned int&&&&&&&&&&& io_pg_&&&&&&&& /* byte offset for io &9.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * page tabe entry&&&&& */& &10.&& &11.&&&&&&&& const char&&&&&&&&&&&&& *&&&&&&&&&&&&&& /* architecture name&&& */& &12.&&&&&&&& unsigned long&&&&&&&&&& boot_&&&&&&&& /* tagged list&&&&&&&&& */& &13.&& &14.&&&&&&&& unsigned int&&&&&&&&&&& video_&&&&&&&& /* start of video RAM&& */& &15.&&&&&&&& unsigned int&&&&&&&&&&& video_&&&&&&&&&& /* end of video RAM&&&& */& &16.&& &17.&&&&&&&& unsigned int&&&&&&&&&&& reserve_lp0:1;&&&&&& /* never has lp0&&&& */& &18.&&&&&&&& unsigned int&&&&&&&&&&& reserve_lp1:1;&&&&&& /* never has lp1&&&& */& &19.&&&&&&&& unsigned int&&&&&&&&&&& reserve_lp2:1;&&&&&& /* never has lp2&&&& */& &20.&&&&&&&& unsigned int&&&&&&&&&&& soft_reboot:1;&&&&&& /* soft reboot&&&&&& */& &21.&&&&&&&& void&&&&&&&&&&&&&&&&&&& (*fixup)(struct machine_desc *,& &22.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& struct tag *, char **,& &23.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& struct meminfo *);& &24.&&&&&&&& void&&&&&&&&&&&&&&&&&&& (*map_io)(void);&&&& /* IO mapping function& */& &25.&&&&&&&& void&&&&&&&&&&&&&&&&&&& (*init_irq)(void);& &26.&&&&&&&& struct sys_timer&&&&&&& *&&&&&&&&&&&&& /* system tick timer&&& */& &27.&&&&&&&& void&&&&&&&&&&&&&&&&&&& (*init_machine)(void);& &28.};& &3.&&&&& MACH HALIBUT的定义&把1中定义的MACH展开之后,得到:&1.struct machine_desc __mach_desc_HALIBUT{& &2.__used&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &3.__attribute__((__section__("..init")))= {& &4.&&&&&&&& .nr&&&&&&&&&&&&&& = MACH_TYPE_HALIBUT,&&&&&&&&&&&&&&& &5.&&&&&&&& .name&&&&&&&&&&&& = "HalibutBoard (QCT SURF7200A)",& &6.&&&&&&&& .boot_params&&&&& = 0x,& &7.&&&&&&&& .map_io&&&&&&&&&& = halibut_map_io,& &8.&&&&&&&& .init_irq&&&&&&&& = halibut_init_irq,& &9.&&&&&&&& .init_machine&&&& = halibut_init,& &10.&&&&&&&& .timer&&&&&&&&&&& = &msm_timer,& &11.};& &总结一下:MACHINE_START主要是定义了"struct machine_desc"的类型,放在 section("..init"),是初始化数据,Kernel 起来之后将被丢弃。
4.& 成员函数被调用的时机&在setup_arch() [setup.c#758~760]中init_irq, timer & init_machine分别被赋值给下列变量:&&&&&&&&& init_arch_irq = mdesc-&init_&
&&&&&&&& system_timer = mdesc-&&&&&&&&&& init_machine = mdesc-&init_&而这三个函数指针是在下列场景中被调用的:&1)&&&& start_kernel()[main.c#589]-& init_IRQ() [irq.c] -&init_arch_irq();&2)&&&& start_kernel()[main.c#595]-&time_init () [time.c] -&system_time-&init();&3)&&&& customize_machine()[setup.c#692] -& init_machine();&customize_machine是被放在arch_initcall段的,按照顺序被调用。xxx_initcall段内的函数是按下列顺序被调用的:start_kernel() [main.c#682] -& rest_init() [启动内核线程]-& kernel_init() –& do_basic_setup()-& do_initcalls();&map_io是在下列顺序中被调用&4)&&&& start_kernel()[main.c#546]-& setup_arch () [setup.c#745] -& paging_init() [mmu.c#1028] -& devicemaps_init()[mmu.c#993] -& map_io()&从它们在start_kernel()中被调用的顺序,可知它们执行的先后为:map_ init_ timer-&time_ init_machine。
本篇文章来源于 Linux公社网站()& 原文链接:
阅读(4072) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。(1)& 这是TI平台的OMAP4430的机器实现核心文件/arch/arm/mach-omap2/board-omap3pandora.c 中的一段代码
MACHINE_START(OMAP3_PANDORA, &Pandora Handheld Console&)
&& &.phys_io&& &= 0x,
&& &.io_pg_offst&& &= ((0xd8000000) && 18) & 0xfffc,
&& &.boot_params&& &= 0x,
&& &.map_io&& &&& &= omap3pandora_map_io,
&& &.init_irq&& &= omap3pandora_init_irq,
&& &.init_machine&& &= omap3pandora_init,
&& &.timer&& &&& &= &omap_timer,
MACHINE_END
&&&& 这里赋值了影射io、初始化irq、初始化机器等函数指针,其中的omap3pandora_map_io()、(影射io空间)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&omap3pandora_init_irq()、(初始化板级的中断系统)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& omap3pandora_init() 、(OMAPZOOM平台的板级初始化函数,如flash、usb、串口、camera、wifi等初始化)
&&&&& 都是在此文件中实现的初始化函数
&&&& omap_timer是为当前机器实现的定时器
Io地址影射
如果想叫处理器知道外围设备上的存储空间,首先要建立虚拟地址到总线地址的影射,总线地址到物里地址转换是硬件完成的。外围设备的存储范围是4G的顶端,而应设的虚拟地址时在896M以上,就是high_mm开始的地方,页表示在init_mm,这是专门为内核使用的页表,不与一般进程的页表在一起,所以在唤出时候,就找不到它的存在,所以内核页表示不会唤出的。同时虚拟地址也是在4G最后的128M里面,由一个虚拟存储区管理。
Offset& 要应设的物理地址
Size&&&&大小范围
返回影射成功的虚拟地址
Void* iormap(unsigned long offset ,unsigned longsize)
1&&&&&&&是对offset的一些测试,不能是1M下的应为这些已经建立影射,不能重复影射。
2&&&&&&&申请一个vm_struct结构,当然这个东西是在slab管理的,
3&&&&&&&申请完就获得了虚拟地址,就要在init_mm的页表里建立影射了。加一句,正是这里,所以有时候会出现页面异常,所以要同步
(2)(这是转载的s3c2410的平台机器信息)
MACHINE_START(VR1000, &Thorcom-VR1000&)
&/* Maintainer: Ben Dooks && */
&.phys_ram&= S3C2410_SDRAM_PA,
&.phys_io&= S3C2410_PA_UART,
&.io_pg_offst&= (((u32)S3C24XX_VA_UART) && 18) & 0xfffc,
&.boot_params&= S3C2410_SDRAM_PA + 0x100,
&.map_io&&= vr1000_map_io,
&.init_irq&= s3c24xx_init_irq,
&.timer&&= &s3c24xx_timer,
MACHINE_END
这两个是宏定义 原型为
#define MACHINE_START(_type,_name)&&/
const struct machine_desc __mach_desc_##_type&/
&__attribute__((__section__(&..init&))) = {&/
&.nr&&= MACH_TYPE_##_type,&/
&.name&&= _name,
#define MACHINE_END&&&&/
struct machine_desc 的原型为:
struct machine_desc {
& * Note! The first five elements are used
& * by assembler code in head-armv.S
&unsigned int&&&&/* architecture number&*/
&unsigned int&&phys_&/* start of physical ram */
&unsigned int&&phys_&/* start of physical io&*/
&unsigned int&&io_pg_&/* byte offset for io
&&&&&& * page tabe entry&*/
&const char&&*&&/* architecture name&*/
&unsigned long&&boot_&/* tagged list&&*/
&unsigned int&&video_&/* start of video RAM&*/
&unsigned int&&video_&/* end of video RAM&*/
&unsigned int&&reserve_lp0 :1;&/* never has lp0&*/
&unsigned int&&reserve_lp1 :1;&/* never has lp1&*/
&unsigned int&&reserve_lp2 :1;&/* never has lp2&*/
&unsigned int&&soft_reboot :1;&/* soft reboot&&*/
&void&&&(*fixup)(struct machine_desc *,
&&&&& struct tag *, char **,
&&&&& struct meminfo *);
&void&&&(*map_io)(void);/* IO mapping function&*/
&void&&&(*init_irq)(void);
&struct sys_timer&*&&/* system tick timer&*/
&void&&&(*init_machine)(void);
MACH_TYPE_SMDK2410定义在arch/include/asm-arm/mach-types.h内,值为193.
/* arch/include/asm-arm/mach-types.h */
#define MACH_TYPE_SMDK2410&&&&&&&&&&&& 193
这个值是机器的类型值,编译时由arch/arm/tool/mach-types里面定义的数据生成的。
/* arch/arm/tool/mach-types */
smdk2410&&ARCH_SMDK2410&&SMDK
由上发现,MACHINE_START主要是定义了&struct machine_desc&的类型,放在 section(&..init&),是初始化数据,Kernel 起来之后将被丢弃。
各个成员函数在不同时期被调用:
1. .init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用。
2. init_irq在start_kernel() --& init_IRQ() --& init_arch_irq() 被调用
3. map_io 在 setup_arch() --& paging_init() --& devicemaps_init()被调用
其他主要都在 setup_arch() 中用到
本文已收录于以下专栏:
相关文章推荐
(1)  这是TI平台的OMAP4430的机器实现核心文件/arch/arm/mach-omap2/board-omap3pandora.c 中的一段代码
MACHINE_START(OMA...
从今年3月1日开始,微信对零钱体现开始执行收费政策,距离微信提现开始收费已经过去快两个月了,一切似乎并没有什么改变,但事实上,这条政策对用户的影响,已经悄然开始。
微信提现收费提示
网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。
信息量:从N个可能事件中选出一个事件所需要的信息度量或含量,也就是在辩识N个事件中特定的一个事件的过程中所需要提问&是或否&的最少次数.
信息熵:数学上颇为抽象的概念,是系统有序...
之前看了看 洪祥的csdn app 制作,里面有从网页抓取数据的. 之前对这块操作没有接触过,所以网上差了一些资料,现在整理下相关的内容.
首先是关于Jsoup , Jsoup 是网页抓取的首选...
友善mini2440提供的linux2.6.32.2内核中,有如下定义:
MACHINE_START(MINI2440, &FriendlyARM Mini2440 development bo...
#define MACHINE_START(_type,_name)
static const struct machine_desc __mach_desc_##_type \
10046事件按照收集信息内容,分为几个等级。常见的有:
level 1: 等同于sql_trace的功能
level 4: 在level1基础上增加绑定变量
level 8: 在level1基...
private void Button_Click(object sender, RoutedEventArgs e)
MessageBox.Show(&设...
dmesg显示开机信息。kernel会将开机信息存储在ring buffer中。开机信息保存在/val/log目录中,名称为dmesg的文件里:
dmesg|grep hd    硬盘
首先,欢迎大家浏览我的博客,由于出来扎到——第一次写作,有失误的地方还请积极指出。
          对于一些app需要统计在各个平台上用户的使用数量时,
他的最新文章
讲师:董西成
讲师:唐宇迪
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)linux 驱动(34)
注:下面的内容是以linux-2.6.38和mini6410为例进行学习的。
&&&&&&& 玩过或者移植过arm-linux的都应该知道在/arch/arm目录下有许多与具体处理器相关的目录,当然对于6410的话所对应的目录就是mach-s3c64xx,在里面找到与具体板子相关的文件mach-mini6410.c,没错,就是它。无论是出于想移植到新的内核还是出于想深入学习某一款arm等,对这个文件的学习是必不可少的。这个文件大部分内容是对平台设备(例如串口,LCD,Nand falsh等)的结构体初始化,在这个文件的最后有一个非常重要的宏:
<span style="color:# MACHINE_START(MINI6410, &MINI6410&)
<span style="color:#
/* Maintainer: Ben Dooks &ben-linux@fluff.org& */
<span style="color:#
.boot_params
= S3C64XX_PA_SDRAM &#43; <span style="color:#x100,
<span style="color:#
<span style="color:#
= s3c6410_init_irq,
<span style="color:#
= mini6410_map_io,
<span style="color:#
.init_machine
= mini6410_machine_init,
<span style="color:#
= &s3c24xx_timer,
<span style="color:# MACHINE_END
MINI6410这个宏在/arch/arm/tools/mach-types文件里定义:
MACH_MINI6410
<span style="color:#20
MACHINE_START的定义在arch/arm/include/asm/mach/arch.h,如下:
<span style="color:# #define MACHINE_START(_type,_name)
<span style="color:# static const struct machine_desc __mach_desc_##_type
<span style="color:#
<span style="color:#
__attribute__((__section__(&..init&))) = {
<span style="color:#
= MACH_TYPE_##_type,
<span style="color:#
<span style="color:#
<span style="color:# #define MACHINE_END
<span style="color:# };
噢,其实就是定义了一个struct machine_desc类型结构体变量,这个结构体还定义了其他一些成员,接下来着重关注.init_machine这个成员,它是一个函数指针,&#20540;为mini6410_machine_init,这个函数也在mach-mini6410.c中定义。内容是什么呢?呵呵,因为在这里只给出大体流程,具体内容先不分析。现在最关心的是这个结构体变量在哪里被调用,从而调用它里面的成员和成员函数呢?先来看/arch/arm/kernel/setup.c里面的setup_arch()函数:
1 void __init setup_arch(char **cmdline_p)
struct tag *tags = (struct tag *)&init_
struct machine_desc *
char *from = default_command_
unwind_init();
setup_processor();
<span style="color:#
mdesc = setup_machine(machine_arch_type);
<span style="color:#
machine_desc =
<span style="color:#
machine_name = mdesc-&
......................
这个函数在/init/main.c的start_kernel()函数里被调用。看到第10行,这里的setup_machine()函数的作用就是找到我们想要的struct machine_desc类型的变量,也就是在mach-mini6410.c里定义那个变量。函数的参数machine_arch_type的&#20540;是什么呢?继续看:
1 #ifdef CONFIG_MACH_MINI6410
2 # ifdef machine_arch_type
undef machine_arch_type
define machine_arch_type
__machine_arch_type
define machine_arch_type
MACH_TYPE_MINI6410
8 # define machine_is_mini6410()
(machine_arch_type == MACH_TYPE_MINI6410)
<span style="color:# # define machine_is_mini6410()
(<span style="color:#)
<span style="color:# #endif
第6行,MACH_TYPE_MINI6410宏为:
#define MACH_TYPE_MINI6410
也就是说参数machine_arch_type的&#20540;为2520。在setup_machine()函数里主要调用了lookup_machine_type()函数来查找对应的type,应该是出于效率的原因,这个函数是通过汇编实现的,在此就不给出具体代码了。
到这里,知道了在/init/main.c的start_kernel()函数里调用了setup_arch(),在setup_arch()里找到了具体的struct machine_desc类型的变量,但是在哪里通过这个变量调用里面的成员或成员函数的呢?继续找。还是在setup.c里,看到了这样一个函数:
<span style="color:# static int __init customize_machine(void)
<span style="color:# {
<span style="color:#
/* customizes platform devices, or adds new ones */
<span style="color:#
if (machine_desc-&init_machine)
<span style="color:#
machine_desc-&init_machine();
<span style="color:#
return <span style="color:#;
<span style="color:# }
<span style="color:# arch_initcall(customize_machine);
终于看到了,成员函数init_machine就是在这里被调用的。但是它没有被显式调用,而是放在了arch_initcall这个宏里,去看看它怎么定义的:
#define arch_initcall(fn)
__define_initcall(&3&,fn,3)
再看__define_initcall宏:
<span style="color:# #define __define_initcall(level,fn,id) \
<span style="color:#
static initcall_t __initcall_##fn##id __used \
<span style="color:#
__attribute__((__section__(&.initcall& level &.init&))) = fn
嗯,它被链接到了.initcall段里,现在简单看看/arch/arm/kernel/vmlinux.lds这个链接脚本里关于initcall的定义:
1 __initcall_start = .;
2 *(.initcallearly.init) __early_initcall_end = .;
3 *(.initcall0.init) *(.initcall0s.init)
4 *(.initcall1.init) *(.initcall1s.init)
5 *(.initcall2.init) *(.initcall2s.init)
6 *(.initcall3.init) *(.initcall3s.init)
7 *(.initcall4.init) *(.initcall4s.init)
8 *(.initcall5.init) *(.initcall5s.init)
9 *(.initcallrootfs.init)
<span style="color:# *(.initcall6.init) *(.initcall6s.init)
<span style="color:# *(.initcall7.init) *(.initcall7s.init)
<span style="color:# __initcall_end = .;
可以看到customize_machine()被放到了.initcall3.init里。说了那么多定义,究竟它在哪里被调用啊?好吧,它是在/init/main.c里一个叫do_initcalls()的函数里被调用,去看看呗:
<span style="color:# extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
<span style="color:#
<span style="color:# static void __init do_initcalls(void)
<span style="color:# {
<span style="color:#
initcall_t *
<span style="color:#
<span style="color:#
for (fn = __early_initcall_ fn & __initcall_ fn&#43;&#43;)
<span style="color:#
do_one_initcall(*fn);
<span style="color:# }
看到第1行,很熟悉吧。在for循环里依次调用了从__early_initcall_end开始到__initcall_end结束的所有函数。customize_machine()也是在其间被调用。
好了,到这里差不多该结束了,最后总结一下这些函数调用顺序:
start_kernel()---&setup_arch()---&do_initcalls()---&customize_machine()---&mini6410_machine_init()
MACHINE_START主要是定义了&struct machine_desc&的类型,放在 section(&..init&),是初始化数据,Kernel 起来之后将被丢弃。
其余各个成员函数在setup_arch()中被赋&#20540;到内核结构体,在不同时期被调用:
1. .init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用。
2. .init_irq在start_kernel() --& init_IRQ() --& init_arch_irq()中被调用
3. .map_io 在 setup_arch() --& paging_init() --& devicemaps_init()中被调用
4. .timer是定义系统时钟,定义TIMER4为系统时钟,在arch/arm/plat-s3c/time.c中体现。在start_kernel() --& time_init()中被调用。
5. .boot_params是bootloader向内核传递的参数的位置,这要和bootloader中参数的定义要一致。
其他主要都在 setup_arch() 中用到。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:21556次
排名:千里之外
转载:88篇
(1)(1)(1)(9)(1)(3)(8)(9)(7)(5)(1)(1)(9)(10)(18)(4)(3)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 ondraw什么时候调用 的文章

 

随机推荐