在学习过程中,发现几乎所有的驱动书籍都忽略了一个问题,那就是内核源码树的构建编译。而网上大部分的资料也都忽略或者没写清楚了一个问题,当开发板的内核版本和PC机的内核版本不一致时,当开发板和pc机CPU架构不一致时内核源码树的构建。以及当内核版本不一致时Makefile的编写细节。
例如,我的系统是Ubuntu12.04,内核版本是3.8.0-36,CPU架构是x86;而我的开发板版本是2.6.30.4,CPU架构是arm。该如何构建?
而这些问题,对于像我这种交叉编译基础不是很好的家伙来说,会产生迷茫。
---------------------------------------------------------------------------------
PC机:Ubuntu 12.04 LTS 64位
arm-linux-版本:4.4.3
开发板:TQ2440
开发板版本:2-6-30.4
参考资料:韦东山视频第一期,LDD3,网上其他资料。
---------------------------------------------------------------------------------
一,下载内核源码。https://www.kernel.org/pub/。下载和开发板版本一致的源码。
通常,这些源码开发板配套光盘会有,但是不知什么原因,配套的源码编译不上。于是我去下载了完整的源码。
二,将源码解压到你自己喜欢的工作目录。
sudo tar -vxf linux-2.6.30.4.tar.bz2 -C /opt
三,从配套光盘源码下复制一份配套设置。 因为我们是为开发板编译内核源码树,采用默认的pc机配置比较容易出问题,耗时也比较久。更重要的是,这时候我们(至少我)对内核裁剪还不熟悉,拿来主义最好了。
我开发板上厂家给我烧写的镜像配置文件是config_EmbedSky_W43。
复制下配置文件。
sudo cp config_EmbedSky_W43 .config
打开内核配置单
sudo make menuconfig
直接拉到倒数第二项,load an Alternate这项,将.config配置载入进去。
退出,退出,警告是否保持配置退出,选择YES保存配置。
可能的问题:menuconfig找不到命令之类的,缺少相关库文件,把错误代码百度一下就可以解决。
四,修改交叉编译器参数
不知道是何原因,大概是编译器比较新,编译出的内核是基于arm v5架构的,但是我的TQ2440是基于arm v4架构的。如果直接make,会出现内核模块版本不一致的问题。
因此修改交叉编译器路径下的参数,以我的交叉编译器为例,我的交叉编译器路径是/opt/FriendlyARM/toolschain/4.4.3/bin
删除bin目录下的三个链接脚步文件。
sudo rm -f arm-linux-gcc arm-linux-gcc-4.4.3 arm-linux-g++
重新新建并编辑这三个文件
sudo vim arm-linux-gcc
在打开的文件中输入
#!/bin/sh
arm-none-linux-gnueabi-gcc -march=armv4t $*
给该文件赋予执行权限
sudo chmod a+x arm-linux-gcc
其他两个文件同样的操作,其中不同是arm-linux-***的***处改成刚才删掉相对应的两个文件的后缀。
可能的问题:需要对linux和vim操作有点了解。
五,给内核打补丁
编译过程中发现问题,估计是gcc版本和内核版本的冲突导致。
问题描述:undefinedreference to `__gnu_mcount_nc'
解决,百度下载文件__gnu-mcount-nc-patch.patch
直接放入源码跟目录:gunzip __gnu-mcount-nc-patch.patch | patch p1
参考:http://blog.sina.com.cn/s/blog_7d3976fc01012itz.html
六,编译
sudo make
可能的问题:找不到arm-linux-gcc命令,这是因为sudo命令会重置默认路径,需要修改visudo文件。
http://www.cnblogs.com/A-Song/archive/2013/03/09/2951951.html这篇文章会给你答案。
七,安装内核
sudo make modules
sudo make modules_install
至此基于TQ2440的内核源码树编译完成
八,驱动程序Makefile编写
KERN_DIR = /opt/linux-2.6.30.4
obj-m +=first_drv.o
modules:
make -C $(KERN_DIR) M=/home/zero/weidongshan/led_dev modules
clean:
make -C $(KERN_DIR) M=/home/zero/weidongshan/led_dev modules clean
rm -rf modules.order
可能的问题:这个Makefile并不规范,因此不能当作范本。
这是根据韦东山视频来着,但obj-m是放在最后,我测试无法通过。此外,他的M后面的路径是M='pwd',无法通过编译,就算把路径改成M=$(PWD)照样无法通过编译,只有改成这样才能通过,原因暂时不明。
最后,这个不要直接复制,会出问题。
九,安装内核。
将生产的ko文件载入到开发板上,我就是犯了没弄清究竟是谁需要ko文件的问题。
在开发板的串口界面,载入。
insmod first_drv.ko
如果成功,用cat /proc/devices查看模块就可以看到了。
至于以后加载驱动,测试驱动,那是另外的文章了。
最初我走了弯路的原因是交叉编译的基本概念不是很清楚。pc机用开发板的内核编译,载入到开发板上加载内核和程序测试。