随便写写

本文记录本人学习LDD3的过程,零碎记录,只为自己留个笔记。观赏者请勿因其零碎职责我,呵呵。

本文的扩展代码的相关分析,除特别指明外,将基于linux 2.6.34, archs=arm。

从最简单的概念开始吧,设备被linux系统分为三种基本类型(字符模块,块模块和网络模块),每个模块通常实现为其中某一类。注意这里讲的是通常,不是必须的。程序员可以构造一个大的模块,在其中实现不同类型的设备驱动程序。当然,通常也就是说明了最好的方式,所以不通常的行为不被指责,但也不被提倡。就像脚踩几条船的行为,不能予以法律追究,仅仅是道德上鄙视一下。

世间万物,皆因看事物的眼睛角度不同而不同,当然也存在另外一种划分驱动程序模块类型的方法。一般而言,某些驱动程序类型同内核用来支持某种给定类型设备的附加层一起工作。比如,通用串行总线(usb)模块、串行模块、SCSI模块,等等。每个USB设备由一个USB模块驱动,而该USB模块和USB子系统一同工作,但设备本身在系统中表现为一个字符设备(USB串口)、一个块设备(USB存储卡读取器),或者一个网络设备(USB以太网接口)。

记得方世玉的老妈的暧昧师兄一直说的口头禅吗?“安全第一,安全第一”。做事之前还是要先来看看几个安全问题的原则性概念。

1.系统中的所有安全检查都是由内核代码进行的,如果内核有安全漏洞,则整个系统就有安全漏洞,所以只能允许授权用户才能装载模块。

2.驱动程序中应当尽量避免在代码中实现安全策略。

3.任何从内核中得到的内存,都必须在提供给用户进程或者设备之前清零或者以其他方式初始化,否则就可能发生信息泄露。

4.由于内核中并发的存在,linux内核代码(包括驱动程序代码)必须是可以重入的。

这里要说一下,书中关于ldd3中代码的下载位置是不对的,应该是ftp://ar.linux.it/pub/ldd3,不用感谢我,你也很容易知道为什么不对。

驱动程序可以使用内核的部分函数,比如printk,为什么呢?首先因为内核运行不依赖于C库,故当然不可以用printf函数,而模块能够调用内核的printk是因为在insmod装入模块后,模块就连接到了内核,因而可以访问内核的公用符号(包含函数和变量)。

在linux内核编程中会遇到一个current变量,多数人知道这是一个全局变量,是一个指向struct task_struct的指针。实际上,2.6中的current不再是一个全局变量,而是将其隐藏在内核栈中。内核程序(当然也包括内核空间下运行的设备驱动程序)只要包含<linux/sched.h>头文件,即可使用current引用当前进程。

例如,下面的语句通过访问struct task_struct的某些成员来打印当前进程的进程ID和命令名。

printk(KERN_INFO "The process is /"%s'" (pid %i)/n:, current->comm, current->pid);

current->comm成员存储当前进程所执行的程序文件的基本名称(base name), 如果必要,会裁剪到15个字符以内。

current指针指向的结构体struct task_struct定义在linux/include/linux/sched.h中。

内核代码有很多方面区别于用户空间的编程,这里的问题比较多,先点下基本的。

1.内核栈很小,驱动程序和内核共同享用,所以,声明大的自动变量并不是好主意,如果需要大的结构,则应该在调用时动态分配该结构。(想一想:动态分配的占用什么内存空间呢?

2.关于具有两个下划线前缀(__)的函数,具有这种名字的函数通常是接口的底层组件,应谨慎使用。

3.内核代码不能实现浮点数运算。

下面来到编译模块,linux的make语法很奇怪,看下最简单的对“hello world”程序的makefile:

obj-m := hello.o

想一想:":="的意思是什么?

上门的赋值语句(它利用了GNU make的扩展语法)说明了有一个模块需要从目标文件hello.o中构造,这个模块名称为hello.ko。

如果源文件有两个,则可以参考下面的例子:

obj-m := module.o

module-objs := file1.o file2.o

由于这种makefile不是通常的makefile文件,想要其能正常工作,必须在大的内核构造系统环境中调用它。这里就必须建立内核源码树(比如~/kernel-2.6)。则可在该makefile的当前目录下执行:

make -C ~/kernel-2.6 M='pwd' modules

上述命令首先该买目录到-C选项指定的目录,其中保存有内核的顶层makefile文件。M=选项让该makefile在构造modules目标之前返回到模块源代码目录(当前目录),然后modules目标指向obj-m变量中设定的模块(module.o)。

如果你不喜欢上面的做法,看看linux内核开发者提供的另外一种makefile的写法(更是难解,这里不解释了)。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值