第一部分:准备工作
Linux内核有着庞大的代码量,超过700万行,但它确实是一个非常灵活的操作系统。现在发行版linux已经具备很强的适应能力,能编译支持绝大部分设备(发行版)。但是可能你会有与大多数用户不同的需求,或者你有个不同的硬件。通过针对特定环境的定制,你可以使它更加匹配你的硬件平台。
构建内核所需要的工具:
编译器,链接器,make工具。编译器我们选择GCC,linux内核主要由C语言和少量的汇编语言来编写。GCC版本不必要求过高,否则可能导致内核编译出错。
连接器我们选择binutils,GCC并不能自己完成所有编译,binutils用来完成源文件的汇编和链接。make工具是一个编译管理工具,它能遍历内核源码树以确定需要进行编译的文件,然后调用编译器和其它构建所需要的工具完成内核的构建工作。内核的构建需要GUN版的make。查看这三个工具版本的命令分别是:gcc --version,ld -v,make --version。
使用内核所需要的工具:
通常当前运行内核的版本不会影响任何用户的应用程序,但是对于个别程序,内核版本是至关重要的。如果你的内核已经升级,那么其中一些软件需要升级。
Util-linux:
它是一个小工具的集合,其中大多数工具用来控制磁盘分区的创建和挂载,并控制系统的硬件时钟。查看它的版本命令为:fdformat --version;
module-init-tools:
如果需要使用linux内核模块,就要用到这个工具。内核模块是一个可以在内核运行时添加或删除得可加载代码块。把驱动程序编译成内核模块很有用,内核可以只加载与当前系统有关的驱动程序。为了根据当前硬件加载所需的驱动和选项,所有linux发行版本都使用模块,儿不是把所有内核中需要的驱动程序和选项都编译成一大块。这样就可以节省内存,只加载正确控制机器所需的机器代码。查看它的版本命令为:depmod -v。
文件系统相关工具:
不同的文件系统,需要用不同的工具来创建,格式化,配置,修复磁盘分区。Util-linux软件包中包含其中一些工具,但是比较流行的文件系统有单独的软件包,其中包含操作这些文件系统的必要程序。用ext2/ext3/ext4来举例,它们被同样的工具管理,这个工具就是e2fsprogs软件包。查看它的版本命令为:tune2fs
其他工具:
udev是一个能让linux在/dev目录下提供固定设备命名系统的程序。几乎所有的linux发行版都用udev来管理/dev目录,因此如果没有它计算机将无法启动。但是udev依赖于/sys目录的结构,这个结构随着内核的变化而变化,有些变化会损坏udev,使计算机无法启动。请尽量使用linux发行版的udev。查看它的版本命令为:udevinfo -V
进程管理工具procps软件包,用于管理和监视进程的便利工具。
PCMCIA工具用来配置linux下运行的PCMCIA设备。
第二部分:操作实例
在准备工作完成后,我们将进行下一步,源码的挑选。所有的linux内核源码都可以在kernel.org网站上找到。用wget下载2.6.30版内核,输入wget http://www.kernel.org/pub/linux/v2.6/linux-2.6.30.7.tar.bz2。现在合适的源码已经被下载,在主目录下建立一个名为linux的目录,来存放内核源码文件。
mkdir ~/linux
mv ~/linux-2.6.30.tar.bz2 ~/linux/
进入linux目录,并解压内核源码。
tar –xzvf linux-2.6.30.tar.bz2
至此,我们已经将源码放置在合适的位置,接下来就该构建内核。首先选择适当的配置,然后编译内核。这两步都使用make工具完成。
创建内核配置:
内核配置保存在内核源码树顶级目录下名为.config的文件中。刚解压完的内核源码中没有.config文件,需要手动创建。
cd linux-2.6.30
make defconfig/*创建默认内核配置,使系统可以正常运转*/
接下来我们需要根据自己的需要来修改配置。完成此项工作我们选择基于终端的配置工具menuconfig。工具虽然有了,但是我们并不知道用这个工具来编译哪些文件。下面我们将在内核中来查找针对我们自己的硬件的信息。插入我的usb转接头,键入命令:
lsusb/*查看所有连接到系统的USB设备*/
USB设备很容易移除,我们可以拔掉那个USB设备,然后再运行一遍lsusb命令,这样就可以确定以上哪条信息是针对你的新硬件的了。
Bus 002 Device 003: ID 0403:6001 Future Technology Devices International,Ltd FT232 USB-Serial (UART) IC/*我的硬件识别信息*/
其中ID 0403:6001这个信息对我们很有用处,我们需要用它来查找内核中与硬件匹配的信息。0403代表的是厂商ID,就是哪家厂商。6001是硬件ID。
下面开始用0403搜索内核源码树:
grep -i -R -l 0403 drivers/*
该命令执行完后,会在屏幕上显示若干条以.data .c .h等为结尾的文件,比如drivers/net/wireless/XXXXX.X,不用看最后一部分,前三个目录名就可以确定这是个USB无线设备。同样的判断方法,我们就可以确定我们需要的内核文件了。以防万一,我们进入这个文件中,USB驱动告诉内核它们支持哪些谁被,以便内核可以把驱动绑定到设备上。一般在一个结构体变量中列出制造商ID和设备ID。如果我们设备的制造商ID和设备ID在里面的话,说明这个驱动支持我们的硬件设备。
cd linux-2.6.30/*进入内核文件中*/
find –type f –name Makefile | xargs grep XXXXX/*会显示一个以CONFIG_为前缀的字段*/
找到这个字段后,返回内核Makefile文件中,使用内核配置工具menuconfig,搜索这个字段。最后在该程序菜单中相应位置启动这个驱动。
第三部分:整体思路及总结
下面我来说说我的整体思路。确定一个新设备由哪个驱动控制的最简单的方法,就是把内核源码树中所有此类驱动构建成模块,并让udev完成设备和驱动的匹配。同时,这些为设备匹配驱动的步骤取决于你所使用的设备类型。由于设备地不同,为其确定驱动的步骤也不尽相同。
总的来说,查找特定USB设备驱动步骤是:
1,找到需要驱动的USB设备制造商ID和产品ID,分别在添加和移除设备后使用lsusb来查看列表中发生的改变。
2,在内核源码树种搜索USB设备制造商ID和产品ID。它们都应该在架构提struct usb_device_id中定义。
3,使用find和grep在内核的Makefile文件中查找用于构建该模块的以CONFIG_为前缀的字段。find –type f –name Makefile | xargs grep DRIVER_NAME
4,在内核配置系统中搜索这个配置的值,在菜单中进入到相应的位置并启用这个选项来构建内核驱动。