(写在转载之前)

在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      = 0x10000100,

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__(".arch.info.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            nr;                  /* architecture number  */

7.         unsigned int            phys_io;             /* start of physical io */

8.         unsigned int            io_pg_offst;         /* byte offset for io

9.                                                       * page tabe entry      */

10.

11.         const char              *name;               /* architecture name    */

12.         unsigned long           boot_params;         /* tagged list          */

13.

14.         unsigned int            video_start;         /* start of video RAM   */

15.         unsigned int            video_end;           /* 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        *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__(".arch.info.init")))= {

4.         .nr               = MACH_TYPE_HALIBUT,

5.         .name             = "HalibutBoard (QCT SURF7200A)",

6.         .boot_params      = 0x10000100,

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(".arch.info.init"),是初始化数据,Kernel 起来之后将被丢弃。

4.  成员函数被调用的时机

在setup_arch() [setup.c#758~760]中init_irq, timer & init_machine分别被赋值给下列变量:

init_arch_irq = mdesc->init_irq;

system_timer = mdesc->timer;

init_machine = mdesc->init_machine;

而这三个函数指针是在下列场景中被调用的:

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_io; init_irq; timer->time_init; init_machine。

本篇文章来源于 Linux公社网站()  原文链接:

linux machine start,Linux中的MACH定义之MACHINE_START / MACHINE_END相关推荐

  1. Linux内核源码中使用宏定义的若干技巧

    在C中,宏定义的概念虽然简单,但是真要用好却并不那么容易,下面从Linux源码中抽取一些宏定义的使用方法,希望能从中得到点启发: 1. 类型检查 比如module_init的宏定义: 点击(此处)折叠 ...

  2. 关于Linux Kernel中的宏定义likely和unlikely

    在Linux kernel的源代码中,经常能见到if(likely(x))或if(unlikely(x))之类的用法,其确切含义需要说明一下,以便更好的理解kernel的源代码. likely与unl ...

  3. Linux中THIS_MODULE宏定义详解

    一直都在耿耿于怀,这个THIS_MODULE到底是个什么玩意,linux内核中无处不在的东西.今天上网搜了一下,算是基本明白了.网上牛人写的已经比较详细,另外目前暂时没有时间往更深层次分析,所以直接贴 ...

  4. 如何在Linux kernel Makefile中添加宏定义

    如何在Linux kernel Makefile中添加宏定义: CFLAGS_object.o += -DMACRO_NAME 在编译object.o时定义宏MACRO_NAME,在kernel中添加 ...

  5. Linux 内核中的宏定义

    Linux 内核中的宏定义 rtoax 日期 内核版本:linux-5.10.13 注释版代码:https://github.com/Rtoax/linux-5.10.13 __attribute__ ...

  6. Linux 中 Iptables 规则定义

    linux 远程服务访问控制 Firewall: 防火墙  防火墙工作位置 :网络边缘出口处,主机边缘 数据包进出口 工作于网络边缘的一套组建  按照管理员定义的规则 对于进出本网段的报文进行检查 规 ...

  7. Linux环境编程--linux中的perror、exit、_exit、wait 和 waitpid

    perror: #include<stdio.h>        #include<stdlib.h> 定义函数 void perror(const char *s);  pe ...

  8. linux的根文件系统中的proc文件夹详解

    什么是proc文件系统    |linux /proc目录介绍|proc中文手册 proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为访问系统内核数据的操作提供接 ...

  9. 【C语言】Linux内核源码--min,swap宏定义

    Linux3.5的部分宏定义在linux-3.5/include/linux/kernel.h的头文件中有定义 一: 最大值和最小值相关的宏 /** min()/max()/clamp() macro ...

最新文章

  1. 2000亿次开放学习后,DeepMind的智能体成精了
  2. 把sqlserver中存储过程改写到oracle中
  3. JavaScript 3D图表
  4. 可变大小区(Variable-Size Extents)
  5. elementui在vue校验表单失效的原因之一(当表单含有一到多个对象)
  6. 【教程】从人脸检测与比对,实测七牛云人脸核验 API
  7. python写二分法_Python实现二分法算法实例
  8. 一个请求在Struts2框架中的处理的步骤
  9. C#为null或Empty
  10. wordpress创建_如何创建WordPress儿童主题
  11. 粒子滤波(PF:Particle Filter与卡尔曼滤波(Kalman Filter)相比较 (转载)
  12. 程序关闭是总是出异常解决方法
  13. 扩散模型初探:原理及应用
  14. RRRR_wys' Blog 3.0 准备上线啦!
  15. 单片机控制步进电机程序c语言正反转停止,51单片机步进电机正反转停止实验-C51源代码...
  16. 网易2019年实习生招聘笔试题
  17. 啡鸟集:什么样的咖啡豆,才是好的咖啡豆?
  18. 如何设置Windows扩展屏幕,扩展屏幕和主屏有何区别,如何优化使用扩展屏幕?
  19. 全国高中数学联赛介绍
  20. 解决component ‘*.OCX’控件出错

热门文章

  1. 开发合格的汽车电子产品-Autosar+MBD+功能安全
  2. javaweb练手项目jsp+servlet简易购物车系统
  3. 关于Windows许可证过期解决方案
  4. js【详解】arr.sort()数组排序(内含十大经典排序算法的js实现)
  5. sql查询查询半小时内数据的方法
  6. 使用D2RQ转换关系型数据库Mysql数据为RDF
  7. 连接数据库SSL警告: Establishing SSL connection without server’s identity verification is not recommended.
  8. unity3d俄罗斯方块源码教程+源码和程序下载
  9. 用于自动驾驶的激光雷达里程计方法综述
  10. POI入力自定义格式数据