——Linux就是个火坑,BBB也是。所以楼主现在就是在火坑里跳得很起劲。
——楼主
——这篇文章就是来彰显楼主的无知和愚昧的。
——还是楼主
计划提交了,按照计划,本周的主要内容是试着在Linux上开发模块,一个很简单很基础的模块。
楼主可是linux开发0起步。要说用linux,那是另外一回事,在linux系统下搞开发可是大不相同。
首先的话,按照BBB中文版指导手册的指示,从网上搞到了Linux内核源码,并且简单编一下,目的是生成需要的文件,差不多的时候就Ctrl-C,结束了内核的编译。
当然咯,环境变量神马的,顺便根据指导手册一起设置一下吧。
然后,就是按照书上、网上、网友们的口中所描述的,编写一个基本的模块。
其实这个模块里我们什么都没有做,只是在注册和注销的时候,打印一些内容,所以代码如下:
/* hello.c -- sjtitr */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
MODULE_LICENSE("Dual BSD/GPL");
static char *who = "world";
static int times = 1;
module_param(times, int, S_IRUGO);
module_param(who, charp, S_IRUGO);
static int hello_init(void)
{
int i;
for(i = 0; i < times; i++)
{
printk(KERN_ALERT "(%d) Hello, %s!\n", i, who);
}
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, %s!\n", who);
}
module_init(hello_init);
module_exit(hello_exit);
复制代码
再来一个Makefile
ARCH=arm
CROSS_COMPILE=arm-none-linux-gnueabi-
obj-m := hello.o
KDIR := /home/sjtitr/kernel/kernel
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean 复制代码
需要解释:
楼主并不会写Makefile,但是知道一些Makefile的规则,要是不会写的话,可以去找找Makefile的教程看看。
而这样一个Makefile很是让楼主困惑,好像和学习的时候遇到的不一样,楼主意识到这又是某种高端用法。
可是我翻遍各种搜索引擎,有好多链接甚至又回到了eeworld,能够找到的例子,基本上故事都讲到这里戛然而止。更神奇的是,高手们的模块,往往还有一个App来调用这个模块,所以他们的Makefile更是比上面还多了几行。楼主是懵懵懂懂的删掉一些自认为可能没有用的内容之后剩下现在的样子。
所以楼主还是不知道为什么Makefile要写成这个样子,而只是照猫画虎而已。如果只是这样,要是源文件再多些,楼主就该研究研究怎么死了。
所以这帖子和别人的不同之处在于,楼主现在来拿出一些内容,便于我们将来在照猫画虎以后,知其然并知其所以然。那就是:
makefiles&modules.rar
(21.55 KB, 下载次数: 12)
这是关于Linux内核编译的Makefile如何书写以及内核外模块的Makefile如何书写的东东,全英文。我还没有具体看,但是总觉得结合基本的Makefile书写规则,来进一步学习这些东西,就能明白其道理了。
秉承楼主的一贯作风,这些东西都是不要钱的,大家尽管下回去学习吧。
接下来编译模块简直是太轻松了,make回车,搞定!
用SSH可以连接BBB,那么我们可以用另外一款工具winscp551,来连接BBB并像使用资源管理器一样,把编译好的模块拷贝到BBB中。什么?这东西竟然是win下的工具,没有linux的么?唉,楼主是真懒得找,也是真的不懂这些东西,0起步,能折腾起来已经好不错啦。
继续,SSH到BBB上,加载刚才拷过来的.ko文件。insmod hello.ko who="sjtitr" times=3 复制代码 What!? 竟然报错!invalid module format
我明明编译没问题的啊有木有!
好吧,继续搜索。搞linux开发,没个网络环境根本是不行的,必须时刻搜索。
从某些网页信息得到了情报,这家伙也许是vermagic和内核对不上。好吧,使用一条命令叫dmesg,看看刚才加载时发生了神马……
hello: no symbol version for module_layout 复制代码
果然啊,好邪恶,竟然还得对暗号?!
按照上述网页的指示,修改内核源码里的相关内容吧,可是源网页里讲的又很不明白,糊里糊涂的。
说到这里楼主不得不吐个大槽,无论是实际工作中交流还是网上邂逅,楼主发现专业搞Linux相关开发的电工们大都有个通病(注意是大都,尤其对于楼主接触到的来说,并非全部),那就是解释问题含含糊糊不明不确,也许是对他来说太简单基础,不愿意详述吧,查找和咨询问题往往得到答复就是:“你XXX一下就行了”(XXX一般都是2~5个汉字),我勒个大X我哪里知道那是啥玩意,我是0起步耶~~他这时候常常又讲:“XXX难道都不会么?”,一副鄙夷的表情,如果是打配合的战场上,就会继续跟上“怎么什么都不会”之类的抱怨了。难道我是搞嵌入式的就一定要会Linux开发,如果不会就认为我白搞嵌入式了?
我承认Linux在嵌入式领域举足轻重,但是它不是全部,甚至连大部分都不是。
楼主自身也有这样的毛病,有时候给他人解释问题,可以理解成是没有耐心,不愿详解,可是面对Linux,我发现这里这种现象严重得很,Linux本就复杂,加上这样的状况,想把Linux学通真的是很难很难,巨人们不提供肩膀给你,简直成了Linux征服世界的强大阻力。 吐槽到这里,与广大电工共勉,诲人要不倦。
可是做到这里,我已经倦了,不能继续卡在这里,不如转而去获取板子对应的源码吧。
通过在网上找信息,得知BBB使用的是个叫angstrom的玩意,于是按照http://www.angstrom-distribution.org/ 的指示,楼主一步步执行。尤其是config beagleboard 简直就是噩梦啊,楼主搞了一宿,到凌晨终于搞定了,接下来的所谓“That will build the kernel for you. ”就显得轻松多了,很快就报了一堆不知所云的错误,最后还来个“failed to alloc memory”。很好,very well。
其实选择使用原带的AngStrom无非就是为了USB接上能冒出一个虚拟网卡,可以直接和BBB对话,既然AngStrom是这样表现的话,楼主这样的超级菜鸟也只得绕道了,反正有BBB板载的物理网络接口呢,不如花点时间自己编译前面已经下载好的内核!
于是凌晨,楼主又开始试着编译内核,按照BBB中文指导手册的指示,一步步解决缺少的命令,终于,赶在曙光冲破晨雾之前,uImage编译成功了。等等……尼玛,又是雾霾天么?
注意过程中需要一个文件:
am335x-pm-firmware.rar
(6.23 KB, 下载次数: 12)
放在firmware那个目录里面
继续。
这回通过winscp把编译好的东西通通拷贝到BBB的/boot目录下。建议先把里面原来的东西备份一下,除了link文件uImage和Env的一个文件之外,其余都用刚编译好的替换掉,注意把编译生成的uImage改名和原来的uImageX.X.X的一样,使得link文件能够找到新编译的内核文件。
万事俱备,reboot
重启之后,明显地,USB虚拟网卡没有了。只能硬线连接。连接后才发现,板载的网络接口好像没有分配IP地址,司马当霍马伊吧,弄一个tftpd32,设个DHCP服务,重启BBB,很快,提示分配出去一个IP,利用这个IP,连接上去,果然是BBB。
好啦,再找到hello.ko,加载之!
咦,什么都没提示,说好的输出呢?
幸亏我还记得有个命令叫dmesg,打印输出,发现楼主想要的输出已经在里面了。
同样,卸载模块,再dmesg,卸载的输出也有了。
辛苦的一天啊,终于算是成功了吧。
回头看看BBB,——要不是为了学习一下Linux,劳资裸奔代码早把你那小贱灯点亮啦!
突然想起小时候一则寓言小故事。当时我正在念小学,偶然学习了计算机,老师教我们五笔字型,让我们录入一篇文章,完成的话老师会帮他把文章打印出来。我选择了这段寓言,很短小,当时也敲了一下午呢。我们来分享一下:
一只小猫独自在树林里练习爬树,它反复的爬上爬下。
一只麻雀见了,问小猫:“你这样一个躲着练,有谁会知道你这样刻苦呢?”
“你错了,朋友。”小猫说,“如果我练习是为了给别人看,那我永远也学不会爬树。”
小猫说完,练习得更加起劲了。 复制代码
晚安各位。