在阅读源代码的过程中,发现一个头文件有引用:
/** The address of the first device table entry. */
extern device_t devices[];
 
/** The address after the last device table entry. */
extern device_t devices_end[];
 
/** The address of the first "driver_t". */
extern driver_t driver_table_start[];
 
/** The address after the last "driver_t". */
extern driver_t driver_table_end[];
 
然后我翻遍源文件目录,还是没有在任何.c文件里发现曾经定义devices。
(当然最开始,我没注意是extern,所以我先找是在哪里初始化的,然后我发现,并没有初始化。)
 
后来我用grep搜索,总算得到了一点信息,在ld脚本里发现下面一段话:
 
  /*
   * Device table.
   */
  .device_table : ALIGN(64)
  {
    PROVIDE (devices = .);
    KEEP(*(.device_table_base))
    KEEP(*(.device_table))
    KEEP(*(.device_table_end))
    PROVIDE (devices_end = .);
  } >data AT>physmem :data
 
我大致猜测device_table正好是在device_table_base和device_table_end之间,而device_table_base和device_table_end在device_table.c中有定义。
(非常可恨的是它们的实际名字是base_devices和end_devices)
我认为我明白了怎么回事,device_table确实没有定义,只是在链接脚本里定义了。
 
我以同样的方式寻找driver_table_start和driver_table_end,我以为会同样很简单的找到,但是见鬼了,根本没有,怎么回事?
 
我然后找了一个驱动程序,我倒要看看,【既然driver_table不主动添加驱动程序,而驱动程序又怎么添加进driver_table里面的。】
我找到了一个i2cm的driver_t的定义。
//! Add a new "driver" entry.
static const __DRIVER_ATTR driver_t driver_i2cm = {
  .shim_type = I2CM_DEV_INFO__TYPE_VAL_I2CM,
  .name = "i2cm",
  .desc = "I2C Master",
  .ops = &i2cm_ops,
  .stilereq = 1,
};
我发疯了,这是很平常的事啊,这是怎么回事?我注意到注释里那句
//! Add a new "driver" entry.
这样就添加了?那才是见鬼了。
然后我才注意到到那个不同寻常的宏。
/** Magic attribute for "driver_t" definitions. */
#define __DRIVER_ATTR __attribute__((used, section(".driver_table")))
又是__attribute__搞的鬼,上网上略微搜了一下,__attribute__((used, section(".driver_table")))的基本含义是把函数或者数据放到名为driver_table的段。
那么其实每定义一个句 __DRIVER_ATTR driver_t driverXXX就把一个驱动给加载到这个段里。
 
然后我返回来看device_table.c时发下一个我忽视的细节:
 
static const __DEVICE_ATTR_BASE device_t base_devices[] =
static const __DEVICE_ATTR_END device_t end_devices[] =
 
其实这两个变量也是这么定义的。清楚了,清楚了,一下子清楚了,当然要其作用,需要ld链接脚本的支持。
 
后来发现这位仁兄和我有同样的问题。
内核原文件里面extern了一堆变量:extern char _ftext, _etext, _fdata, _edata, _end;但是用source insight在内核的源码目录里面压根就找不到这些变量的定义。最初怀疑这些变量定义在汇编文件中,于是使用命令:
grep _ftext `find ./ -name *.S`查找,令我惊讶的是没有找到。既然源文件中都没有,那么又是什么神奇的力量让程序在链接的时候又能正常链接通过呢?
原来大家都是跟内核学习的啊。
http://my.oschina.net/u/180497/blog/177206 讲了利用gcc的__attribute__编译属性section子项构建初始化函数表。
 
不知道黑客们会不把.init段后面加上自己的函数?
 

链接加载文件gcc __attribute__ section的更多相关文章

  1. 如何使用Class和ClassLoader加载文件

    很多时候我们都需要在程序中加载各种文件,比如在加载配置文件,加载properties文件,或者只是加载一个文本文件,然后输出其中的内容,我在初学java的时候,就对加载文件非常头疼,今天又遇见了加载文 ...

  2. java类加载器加载文件

    例子:采用配置文件加反射的方式创建ArrayList和HashSet的实例对象. //第一种方式:类加载器加载文件 InputStream ips = ReflectTest2.class.getCl ...

  3. spark 加载文件

    spark 加载文件 textFile的参数是一个path,这个path可以是: 1. 一个文件路径,这时候只装载指定的文件 2. 一个目录路径,这时候只装载指定目录下面的所有文件(不包括子目录下面的 ...

  4. 从xib加载文件

    一般自定义View, 如果从xib加载文件, 定义一个类方法, 返回xib + (instancetype)dropdown { return [[[NSBundle mainBundle] load ...

  5. 安装SQL2008时遇到"未能加载文件或"file:///d:microsoft..sql.chainer.packagedata.dll"或它的某个依赖项

    安装SQL2008时遇到"未能加载文件或"file:///d:microsoft..sql.chainer.packagedata.dll"或它的某个依赖项,如下图所示 ...

  6. Java中加载配置文件的集中方式,以及利用ClassLoader加载文件 .

    我们往常进行文件的加载的时候 用到的都是  FileInputStream进行 文件的加载比如下面一个例子 : InputStream in=FileInputStream("1.prope ...

  7. 关于前端本地压缩图片,兼容IOS/Android/PC且自动按需加载文件之lrz.bundle.js

    一.介绍说明主要特点: ①在前端压缩好要上传的图片可以更快的发送给后端,因此也特别适合在移动设备上使用. ②兼容IOS/Android,修复了IOS/Android某些版本已知的BUG. ③按需加载文 ...

  8. 使用PSR-4配合composer autoload 自动加载文件夹

    require 文件很麻烦,使用PSR-4搭配composer一次加载,终生受用. 感觉类似java中的import了,自己先记录一下最近理解的. 用composer管理自己的包吧 安装compose ...

  9. php 开启 opcache 之后 require、include 还会每次都重新加载文件吗?

    当前目录有以下两个文件 index.php <?php var_dump(require 'A.php'); A.php <?php return 123; 接着运行: php -S 0. ...

随机推荐

  1. fidder工具学习抓取Firefox包

    fidder抓取Firefox的https请求 抓包之前需要设置fidder,我下面的截图是fidder4,打开fidder—>Tools—>Options如图: 选择https,勾选所有 ...

  2. Linux常用命令及搭建测试环境

    题外话:三大操作系统------Linux.Unix.Windows,Unix系统如常见的Mac OS,Linux的很多命令跟Unix是通用的,所以就有一些开发人猿喜欢用苹果的原因.Linux发行版特 ...

  3. python3.x 编码问题

  4. 使用CodeBlocks编译64位程序(用的编译器仅仅是windows sdk的)

    需求: -CodeBlocks使用nightly版本: -Windows SDK(我使用的是6.0A,即微软针对vista的,因为这个比较小,你也可以选择其他版本但是要有64位编译器.他也适用于xps ...

  5. HDU 3269 P2P File Sharing System(模拟)(2009 Asia Ningbo Regional Contest)

    Problem Description Peer-to-peer(P2P) computing technology has been widely used on the Internet to e ...

  6. HDU 4747 Mex(线段树)(2013 ACM/ICPC Asia Regional Hangzhou Online)

    Problem Description Mex is a function on a set of integers, which is universally used for impartial ...

  7. Week7 Teamework from Z.XML-任务分配

    任务分配 Z.XML任务初步分配新鲜出炉,请关注! 初步估计,我们的项目需要191小时.但是根据敏捷开发的方法,我们将在开发过程中根据情况迅速调整任务分配,以适应当时问题.

  8. PokeCats开发者日志(四)

      现在是PokeCats游戏开发的第八天的上午,感觉游戏做得差不多了,来写一下开发者日志吧!   (1)增加闯关模式,一共30关.   (2)更改了最后一关的主题,更换了背景,将树桩改为礼物盒.   ...

  9. 使用 TListView 控件(2)

    本例效果图: 代码文件: unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, ...

  10. jenkins+Docker持续化部署(笔记)

    参考资料:https://www.cnblogs.com/leolztang/p/6934694.html (Jenkins(Docker容器内)使用宿主机的docker命令) https://con ...