移植LINUX内核,就是为了让LINUX系统在自己的硬件平台上运行起来,能正常工作。其中最重要的还是驱动的移植,只有驱动程序能驱动硬件设备,上层的应用程序才能正常运行。
目前,LINUX支持内核的系列主要有以下,解压linux-3.5-20131028.tgz文件,进入到文件夹里面,
除了arch文件夹里面,都是大多数平台相同的文件:
在kernel文件夹里面,包含着一些内核的文件;
在arch文件里面是支持的各种平台文件,里面是一些芯片公司支持的一些驱动程序;
一般来说,LINUX系统剪裁都分为以下几步:
第一步:解压 linux-3.5-20131028.tgz linux源码包,进入linux-3.5文件夹,
第二步:配置 .config文件,这里,直接使用的是 tiny4412_linux_defconfig
cp tiny4412_linux_defconfig .config
第三步:选择生成模块,这一步,可以选择需要那些模块编译进镜像文件,因为,考虑到各种功耗的问题,有些linux模块的 功 能是没有必要编进内核
make menuconfig 进入选择模块编译
第四步:make 生成 zImage 镜像,这个就类似于装windos系统的.iso文件之类的。之前,在配置交叉编译环境的时候就是用的这个文件镜像。
第五步:dnw到板子,把板子的linux系统跑起来,到这里,linux系统是在板子上成功运行:
接下来,是内核模块的编写部分:
先贴代码:
1 #include <linux/init.h> 2 #include <linux/module.h> 3 4 MODULE_LICENSE("GPL"); 5 MODULE_AUTHOR("bunfly"); 6 7 int test_init() 8 { 9 printk("hahahhahahahah\n"); 10 11 return 0; 12 } 13 14 void test_exit() 15 { 16 printk("exit\n"); 17 } 18 19 module_init(test_init); 20 module_exit(test_exit); 21
因为是在内核层,所以没有以前的include<stdio.h>之类的头文件,这里换成了两个linux/init。和linux/module头文件
7 int test_init()
8 {
9 printk("hahahhahahahah\n");
10
11 return 0;
12 }
在这里写了一个函数,打印一句话,
而在 19 module_init(test_init)行,这里用了一个回调函数来调用test.init函数,这个回调函数是加载到内核的时候,执行的函数;
那么,module_exit(); 就是从内核卸载时执行的函数;
4 MODULE_LICENSE("GPL");///声明开发模块遵循的的开源协议
5 MODULE_AUTHOR("bunfly"); //申明模块的开发者
这两行在如果不申明的话将会出现警告:
1 2 ha: 3 make -C /home/bunfly/source_code/linux-3.5 M=/home/kernel/arm/ram/520/1st 4 5 clean: 6 make -C /home/bunfly/source_code/linux-3.5 M=/home/kernel/arm/ram/520/1st cle an 7 8 9 obj-m += test.o 10
以上是makefile文件
make生成.ko文件, 在板子上加载到内核模块:
接下来的一个程序,打印出任务的名字:
2 #include <linux/thread_info.h> 3 #include <linux/module.h> 4 #include <linux/sched.h> 5 6 MODULE_LICENSE("GPL"); 7 MODULE_AUTHOR("bunfly"); 8 9 int test_init() 10 { 11 int i = 0; 12 struct task_struct *t; 13 struct thread_info *info;//线程信息 14 15 unsigned long addr = (unsigned long)&i; 16 unsigned long base = addr & ~0x1fff;//以8K的字节对齐 17 info = (struct thread_info *)base;//找到线程的地址 18 t = info->task;//获得任务信息 19 printk("%s\n", t->comm);//打印出任务的名字 20 21 return 0; 22 } 23 24 void test_exit() 25 { 26 printk("exit\n"); 27 } 28 29 module_init(test_init); 30 module_exit(test_exit); 31
makefile:
1 2 ha: 3 make -C /home/bunfly/source_code/linux-3.5 M=`pwd` 4 5 clean: 6 make -C /home/bunfly/source_code/linux-3.5 M=`pwd` clean 7 8 obj-m += test.o 9 ~ ~
make
在ARM板子上运行:
总结:本次通过自己适当剪裁,生成一个在zImage镜像文件,而且,自己写了一个简单的内核模块,在ARM板子上,插入内核模块,运行。
在这里,有些固定的方式:例如,内核代码的Makefile文件,以后需要编译内核模块都是固定的方法:
而在第二个文件中的,通过使用以对齐的方式找到地址;获得固定结构体task里的名字参数comm的做法,应该深入理解,并且灵活运用:
补充一下建立索引来搜索文件里的小知识,对于查找文件关键字很有用 ctags
首先到需要搜索的目录下面:建立索引文件:ctags -R . ..
随便打开任意文件:vim hong
查找关键字:ta xxxx
如果要继续查找某一关键字,只需要将光标移动到上面按下:ctrl+ ]
返回刚才查找的结果 ctrl + o
下面是LINUX内核开发的工作流程