LDD之准备工作

Linux作为最受程序员欢迎的开源操作系统,从上世纪90年代到现在,一直在成长,一直在进步,吸纳了不计其数的程序员的代码,来自世界各地的程序员都活跃在Linux社区,很多公司也贡献自己的代码,同时也发布各个的版本,大家都从中获益颇丰。要参与Linux的开发,或者使用Linux,就要不同程度的阅读、修改Linux代码,运行自己编译的Linux镜像。然而,我们必须要做一些准备工作。


入门概念

内核划分


一般内核可将内核划分为如下几个部分:

进程管理

    内核负责创建和销毁进程,并处理它们与外部世界的联系,处理进程间通讯(IPC,通过信号,管道,IPC原语等);调度器控制进程如何共享CPU;内核的进程管理活动,实现了多个进程在一个或者几个CPU之上的抽象。


内存管理

    内存是PC的主要资源,处理内存的策略对系统性能至关重要,内核为每一个进程分配了一个虚拟地址空间,内核提供一套函数调用来供内核其他部分与内存管理交互。


文件系统

    Linux中的任何东西都可以看做一个文件,内核在非结构化的硬件设备之上建立了一个结构化的文件系统,Linux支持多个文件系统类型(物理介质上不同的数据组织方式),例如ext3,FAT等。


设备控制

    几乎所有系统操作最终都映射到一个物理设备上,任何外设的控制操作都由要访问的外设相关的代码(设备驱动)来完成,要想使用外设,内核必须嵌入响应的设备驱动。


网络

    因为大部分的网络操作不是特定于某一个进程,进入系统的报文又是异步的,报文在某一个进程接手前必须被收集,识别,分发。内核负责在应用程序和网络接口卡之间递送报文,内核根据程序的网络活动来控制程序的执行,并且所有的路由,地址解析都由内核完成。


设备和模块的分类

Linux的设备分为,字符设备,块设备,网络设备,因此Linux的模块可分为,字符模块,块模块,网络模块。


字符设备

    字符设备是一种可以当做一个字节流来访问的设备,字符设备驱动至少实现open,close,read,和write系统调用。大部分字符设备仅仅是数据通道,只能顺序访问,不能像普通文件一样可以移来移去。


块设备

    块设备应该可以驻有一个文件系统,Linux允许应用程序像字符设备一样访问块设备,每次传送任意字节的数据。字符设备、块设备的区别仅仅在于内核内部管理数据的方式,因此内核/驱动的软件接口就不同。


网络设备

    网络设备可以是硬件设备,也可以是软件设备(环回loop),网络设备在网络子系统的驱动下,负责发送和接收数据报文,网络设备驱动对单个连接一无所知,它只处理报文。网络设备不是面向流的,因此不容易简单的映射到文件系统节点上,但是Linux也给网络设备分配了名字,虽然没有对应的文件系统入口,因此内核和网络设备的通讯也不同于字符设备、块设备,调用函数也不同,不能使用read/write。


除了以上的分类方式,还有一些其他的分类方式,例如,我们可以说,USB模块,串口模块,SCSI模块;每一个USB设备由一个USB模块驱动,与USB子系统一起工作,但是它可能表现为一个字符设备(USB串口),块设备(USB内存卡),网络设备(USB网卡)。


文件系统类型是一种软件驱动,它将低级数据结构映射为高级数据结构,文件系统决定一个文件名多长,在一个目录入口中存储每个文件的什么信息,文件系统模块必须实现最低级的系统调用,来存取目录和文件,通过映射文件名和路径到保存在数据块中的数据结构。内核声明了不同操作,可以在一个文件系统节点,目录,文件和超级块上进行操作。


安全相关


内核调用init_module来检查进程是否有权加载模块到内核。

安全是一个策略问题,所以一般,驱动程序员应该避免编写与安全相关的代码到设备驱动中,安全应该由系统管理员在内核高层来处理。

驱动必须检查,会影响全局资源的设备操作(例如设置中断线),可能会损坏硬件(例如加载固件),或者可能影响其他用户。

驱动要避免引入安全bug,例如缓冲区覆盖,除非能核实用户输入,否则不能信任,小心未初始化的内存。

如果不能以root运行预编译的二进制文件,最好不要运行一个预编译的内核。


版本编号


运行于Linux之上的软件存在依赖性,一般我们需要一个包的特殊版本来运行另一个包的特殊版本。

对于Linux内核,偶数版本的内核是发布版本,奇数版本的内核是开发快照。建议使用偶数版本的发布内核。


版权条款

Linux遵从GPL V2(GNU通用公共版权版本2),只要接收方能够获取到源码并对其行使同样的权利,GPL允许任何人重新发布,销售,GPL涵盖的任何产品。如果要完全重新发行源自使用GPL产品的软件产品,必须置于GPL下发行。

如果想把自己的代码放进主流内核,或者对内核打补丁,那么发行代码时,必须使用一个GPL兼容的许可。


GPL的主要目的是让知识增长、传播。任何人都可以修改代码。


一些提供商,基于已公布的内核接口,发布二进制的模块,目前也是允许的。

准备Linux kernel tree

使用发布的内核

    一般都需要安装内核源码树,例如在ubuntu下,使用uname -r获取到内核版本字符串(例如2.6.32-38-generic),然后检查/usr/src/下是否存在目录-linux-headers-2.6.32-38-generic,如果没有可以运行sudo apt-get install linux-headers-2.6.32-38-generic安装。

自己编译的内核

    一般自己编译完内核,运行自己的内核;然后,编译模块时,指定编译内核目录为内核源码树目录。

配置Linux

有很多选择可以用来配置Linux,可根据自己的选择来使用:

make config - 文字界面

make menuconfig - 基于文字的彩色菜单,有单选列表,对话框

make xconfig - 基于Qt的X windows配置工具

make gconfig - 基于Gtk的X windows配置工具

make oldconfig - 使用./.config里已有的,没有的就询问

make defconfig - 基于体系架构,从arch/$ARCH/defconfig或者arch/$ARCH/configs/${PLATFORM}_defconfig,生成./.config

make allyesconfig - 所有询问Yes/No的选Yes,从而生成./.config

make allmodconfig - 所有询问module的选m,从而生成./.config

make allnoconfig - 所有询问Yes/No的选No,从而生成./.config

编译Linux

一般给PC编译内核,使用GCC,体系架构是X86或者X86_64,直接使用make就会默认编译。
如果需要交叉编译,就需要指定ARCH和CROSS_COMPILE
例如:
make ARCH=arm CROSS_COMPILE=arm-linux-gcc

运行Linux


驱动程序

驱动程序在Linux内核中扮演着特殊的角色,就像黑盒子一样,使硬件响应定义好的内部编程接口,并且完全隐藏了设备的工作细节,用户通过一套标准化的调用来操作硬件,这些调用与特别的驱动是独立的,设备驱动将这些调用映射到作用于实际硬件的相关操作上,驱动可以与内核的其他部分分开编译,并在需要的时候,在运行时,insmod进内核。

驱动程序提供机制(提供什么能力),而不是策略(如何使用这些能力)。

支持同步、异步操作,多次打开的能力,利用硬件全部能力,不需要软件层来简化事情或者提供策略相关的操作,这就是一个对策略透明的驱动的典型特征。

在发布设备驱动时,一般都是同应用程序、支持库一起发布,以便帮助配置和访问目标设备。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值