当前位置: 首页 > news >正文

网站如何添加外链广州做贸易网站

网站如何添加外链,广州做贸易网站,手机网站 搜索优化 百度,线上营销系统Linux/Android启动之Machine-Init函数 前言#xff1a; 前面写过两篇Linux/Android的启动过程分析#xff0c;这篇接着前两篇的知识点进行分析。 Linux/Android的启动过程包括了很多内容#xff0c;其中有些需要了解#xff0c;有些则需要在系统移植的时候进行修改。本篇文… Linux/Android启动之Machine-Init函数   前言 前面写过两篇Linux/Android的启动过程分析这篇接着前两篇的知识点进行分析。 Linux/Android的启动过程包括了很多内容其中有些需要了解有些则需要在系统移植的时候进行修改。本篇文章主要来讲述Machine-Init函数在系统启动过程中如何被调用的以及在何时被调用。 Linux中的Machine-Init在功能和调用位置上类似于Win CE/ Windows Mobile中的OAL初始化函数OEMInit。 哈哈。如果有不正确或者不完善的地方欢迎前来拍砖留言或者发邮件到guopeixin126.com进行讨论先行谢过。   一. 基础知识 1. Linux启动过程中驱动模块初始化的位置 Linux OS的启动过程中将会去创建线程kernel_init该线程负责Driver初始化等一系列工作。线程kernel_init将会依次调用do_basic_setup()àdo_initcalls()àdo_one_initcall()并在do_initcalls()中完成对各个驱动模块Init函数的调用。 这部分代码如下 函数do_basic_setup()如下 /* * Ok, the machine is now initialized. None of the devices * have been touched yet, but the CPU subsystem is up and * running, and memory and process management works. * * Now we can finally start doing some real work.. */ static void __init do_basic_setup(void) { rcu_init_sched(); /* needed by module_init stage. */ init_workqueues(); usermodehelper_init(); driver_init(); init_irq_proc(); do_initcalls(); } 函数do_initcalls() extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; static void __init do_initcalls(void) { initcall_t *call;   for (call  __early_initcall_end; call  __initcall_end; call) do_one_initcall(*call);   /* Make sure there is no pending stuff from the initcall sequence */ flush_scheduled_work(); } 函数do_one_initcall(initcall_t fn)如下 int initcall_debug; core_param(initcall_debug, initcall_debug, bool, 0644);   int do_one_initcall(initcall_t fn) { int count  preempt_count(); ktime_t calltime, delta, rettime; char msgbuf[64]; struct boot_trace_call call; struct boot_trace_ret ret;   if (initcall_debug) { call.caller  task_pid_nr(current); printk(calling  %pF  %i/n, fn, call.caller); calltime  ktime_get(); trace_boot_call(call, fn); enable_boot_trace(); }   ret.result  fn();   if (initcall_debug) { disable_boot_trace(); rettime  ktime_get(); delta  ktime_sub(rettime, calltime); ret.duration  (unsigned long long) ktime_to_ns(delta)  10; trace_boot_ret(ret, fn); printk(initcall %pF returned %d after %Ld usecs/n, fn, ret.result, ret.duration); }   msgbuf[0]  0;   if (ret.result  ret.result ! -ENODEV  initcall_debug) sprintf(msgbuf, error code %d , ret.result);   if (preempt_count() ! count) { strlcat(msgbuf, preemption imbalance , sizeof(msgbuf)); preempt_count()  count; } if (irqs_disabled()) { strlcat(msgbuf, disabled interrupts , sizeof(msgbuf)); local_irq_enable(); } if (msgbuf[0]) { printk(initcall %pF returned with %s/n, fn, msgbuf); }   return ret.result; } 二Machine-Init函数被调用的位置 Machine-Init也将在函数do_one_initcall(initcall_t fn)中伴随其它的模块Init函数一起被调用不同之处在于Machine-Init的优先级最高。 三Machine-Init函数相关解析过程 1. 重要结构体machine_desc说明 struct machine_desc描述了机器machine, 也就是目标板对内核初始阶段资源分配至关重要的一些参数。 首先来看一下结构体machine_des的内容在arch/arm/include/asm/mach/arch.h struct machine_desc { /* * Note! The first four elements are used * by assembler code in head.S, head-common.S */ unsigned int nr; /* architecture number,记录体系结构 */ unsigned int phys_io; /* start of physical io */ unsigned int io_pg_offst; /* byte offset for io  * page tabe entry */   const char *name; /* architecture name体系结构名字 */ unsigned long boot_params; /* tagged list */   unsigned int video_start; /* start of video RAM */ unsigned int video_end; /* 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 *timer; /* system tick timer */ void (*init_machine)(void); }; 其中结构体的最后一个函数指针init_machine会被初始化为Machine-Init的地址。系统中针对每一种CPU都会去定义一个该结构体变量并在系统的启动过程中进行引用。 2. 对应当前开发板的结构体machine_des的初始化 这里以Samsung S3C6410的开发板的BSP为例来进行分析。 Samsung S3C6410的machine_des在文件arch/arm/mach-s3c6410/mach-s3c6410.c中定义定义方式如下 MACHINE_START(SMDK6410, SMDK6410) /* Maintainer: Ben Dooks benfluff.org */ .phys_io  S3C_PA_UART  0xfff00000, .io_pg_offst  (((u32)S3C_VA_UART)  18)  0xfffc, .boot_params  S3C64XX_PA_SDRAM  0x100, .fixup  smdk6410_fixup, .init_irq  s3c6410_init_irq, .map_io  smdk6410_map_io, .init_machine  smdk6410_machine_init, #ifndef CONFIG_HIGH_RES_TIMERS .timer  s3c64xx_timer, #else .timer  sec_timer, #endif /* CONFIG_HIGH_RES_TIMERS */   MACHINE_END Linux中针对各个不同的CPU存在很多个类似于上面的定义宏定义MACHINE_START的定义如下 /* * Set of macros to define architecture features.  This is built into * a table by the linker. */ #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 / }; 其实宏定义替换后的就变成了如下的定义方式 static const struct machine_desc__SMDK6410 __used __attribute__((__section__(.arch.info.init)))  { /*__section__指定了该结构体被链接的位置*/   .nr  MACH_TYPE_SMDK6410, .name  SMDK6410, phys_io  S3C_PA_UART  0xfff00000, .io_pg_offst  (((u32)S3C_VA_UART)  18)  0xfffc, .boot_params  S3C64XX_PA_SDRAM  0x100, .fixup  smdk6410_fixup, .init_irq  s3c6410_init_irq, .map_io  smdk6410_map_io, .init_machine  smdk6410_machine_init, #ifndef CONFIG_HIGH_RES_TIMERS .timer  s3c64xx_timer, #else .timer  sec_timer, }; 3. 函数setup_machine实现对结构体machine_des的定位 函数setup_machine实现对结构体machine_des位置的判别其代码代码如下 static struct machine_desc * __init setup_machine(unsigned int nr) { struct machine_desc *list;   /* * locate machine in the list of supported machines.可能支持多个cpu哦 */ list  lookup_machine_type(nr); if (!list) { printk(Machine configuration botched (nr %d), unable  to continue./n, nr); while (1); }   printk(Machine: %s/n, list-name);   return list; } 上面红色标记的函数lookup_machine_type(nr)用汇编实现在文件head.S中用来查找对应当前设备的machine_desc变量位置并通过函数lookup_machine_type指向其起始位置后续就可以直接通过该返回值来对结构体machine_desc变量machine_desc__SMDK6410的值进行读取如后面读取Machine-Init函数的指针的操作init_machine  mdesc-init_machine。 而函数setup_machine被调用的过程如下start_kernelàsetup_archàsetup_machine     在函数setup_machine最后会在全局指针变量init_machine中记录Machine-Init函数的信息。 4. Machine-Init的导出 在文件arch/arm/kernel/setup.c中通过如下的方式将Machine-Init设置为模块的Init函数 static void (*init_machine)(void) __initdata;   static int __init customize_machine(void) { /* customizes platform devices, or adds new ones */ if (init_machine) init_machine(); return 0; } arch_initcall(customize_machine); 可能不太熟悉驱动优先级的人会觉得这里怎么使用arch_initcall导出而不是通常的module_init方式进行导出。 在Linux中没有办法像CE/Mobile中通过注册表的方式来定义驱动的优先级只有通过导出函数的Level和Makefile中模块驱动书写的先后顺序来定义。 关于导出函数Level的代码如下 #define __define_initcall(level,fn)   static initcall_t __initcall_##fn __attribute_used__   __attribute__((__section__(.initcall level .init)))  fn   #define core_initcall(fn) __define_initcall(1,fn) #define postcore_initcall(fn) __define_initcall(2,fn) #define arch_initcall(fn) __define_initcall(3,fn) #define subsys_initcall(fn) __define_initcall(4,fn) #define fs_initcall(fn) __define_initcall(5,fn) #define device_initcall(fn) __define_initcall(6,fn) #define late_initcall(fn) __define_initcall(7,fn)   #define __initcall(fn) device_initcall(fn)   #define __exitcall(fn)   static exitcall_t __exitcall_##fn __exit_call  fn   #define module_init(x) __initcall(x);   #define module_exit(x) __exitcall(x); 可以看到通常驱动中采用的module_init优先级为6也即最低优先级而前面采用的arch_initcall优先级为最高优先级1。                                                                       完
http://www.pierceye.com/news/560733/

相关文章:

  • php 打开网站东莞网站建设网页推广
  • 正品海外购网站有哪些公司网站开发费用兴田德润在哪儿
  • 怎样做编辑发到网站自由建网站的网络程序
  • 网站开发 卡片cms建站系统 下载
  • 新浪门户网站是谁做的科技网站建设
  • 免费网站建设合同书山西网站建设企业
  • 网站建设空间什么意思学做网站什么语言合适
  • 网站开发的形式有( )友情链接英文
  • 帝国网站管理系统前台免费photoshop下载
  • 深圳一百讯网站建设wordpress汉化包
  • 建设一个班级网站的具体步骤自己的网站源代码一片空白
  • 初创公司 建网站wordpress 模板获取数据库
  • 怎么在网站做推广不要钱六安网约车平台
  • 申晨推荐的营销网站做卖挖掘机的网站
  • 网站广告牌制作教程来几个好看的网站
  • php企业网站源码蓝色印度喜欢用什么框架做外贸网站
  • 网站建设教程最新资讯wordpress说说伪静态
  • 长春建站程序网络营销推广方法脑24金手指效率高
  • 专门做房地产设计的图片网站在安徽省住房和城乡建设厅网站
  • 怎样制作图片网站广告制作公司电话
  • 电子商城网站开发教程湖北网站建设路
  • 广告公司网站模版快速seo关键词优化技巧
  • whois哪个网站好WordPress判断文章形式
  • 昆明网站建设排名网站推广营销策划方案
  • 深圳网站建设中心手机端网站搭建
  • 提取卡密网站怎么做怎么更换网站的域名
  • 网站开发接单网站站内推广方案
  • 网站建设网站建什么网站做二手货车
  • 如何做淘宝客的网站网站建设 源代码
  • 建设部网站 造价全世界足球排名前十位