Linux 内核编译步骤及配置详解 linux 系统体系结构:
linux kernel体系结构: arm有7种工作模式,x86也实现了4个不同级别RING0-RING3,RING0级别最高, 这样linux用户代码运行在RING3下,内核运行在RING0,这样系统本身就得到了 充分的保护 用户空间(用户模式)转到内核空间(系统模式)方法: ·系统调用 ·硬件中断 linux kernel 体系结构:
虚拟文件系统VFS: VFS(虚拟文件系统)隐藏各种文件系统的具体细节,为文件操作提供统一的接口 二.Linux内核源代码 linux内核下载www.kernel.org 目录结构: 解压linux kernel tar后目录 ·arch:根据cpu体系结构不同而分的代码 ·block:部分块设备驱动程序 ·crypto:加密,压缩,CRC校验算法 ·documentation:内核文档 ·drivers:设备驱动程序 ·fs(虚拟文件系统vfs):文件系统 ·include:内核所需的头文件,(与平台无关的头文件在include/linux中) ·lib:库文件代码(与平台相关的) ·mm:实现内存管理,与硬件体系结构无关的(与硬件体系结构相关的在arch中) ·net:网络协议的代码 ·samples:一些内核编程的范例 ·scripts:配置内核的脚本 ·security:SElinux的模块 ·sound:音频设备的驱动程序 ·usr:cpio命令实现,用于制作根文件系统的命令(文件系统与内核放到一块的命令) ·virt:内核虚拟机 linux DOC 编译生成: linux源根目录/Documentation/00-INDEX:目录索引 linux源根目录/Documentation/HOWTO:指南 ·生成linux内核帮助文档:在linux源根目录(Documentation) 执行make htmldocs ubuntu16下需要执行sudo apt-get install xmlto安装插件才可生成doc文档 后面开发中经常要改的是arch,drivers中的代码 三.Linux内核配置与编译 清理文件(在linux源码根目录): ·make clean:只清理所有产生的文件 ·make mrproper:清理所有产生的文件与config配置文件 ·make distclean:清理所有产生的文件与config配置文件,并且编辑过的与补丁文件 ↓ 配置(收集硬件信息如cpu型号,网卡等…): ·make config:基于文本模式的交互配置 ·make menuconfig:基于文本模式的菜单模式(推荐使用) ·make oldconfig:使用已有的.config,但会询问新增的配置项 ·make xconfig:图形化的配置(需要安装图形化系统) 配置方法: 1)使用make menuconfig操作方法: 1>按y:编译>连接>镜像文件 2>按m:编译 3>按n:什么都不做 4>按”空格键”:y,n轮换 配置完并保存后会在linux源码根目录下生成一个.config文件 注意:在ubuntu11上要执行apt-get install libncurses5-dev来安装支持包 2)利用已有的配置文件模板(.config) 1>linux源码根目录/arch/<cpu架构>/configs/<具体某一的CPU文件>,把里面对应的文件copy并改名为.config至linux源码根目录下 2>利用当前运行已有的文件(要用ls /boot/ -a查看)把/boot/config-2.6.18-53.e15拷贝并改名为.config至linux源码根目录下执行以上操作就可以用make menuconfig在拷贝 .config文件上面修改文件了 ↓ 编译内核: 1)make zImage 2)make bzImage 区别:在X86平台上,zimage只能用于小于512k的内核 详细编译信息:make zimage V=1 或 make bzimage V=1 编译好的内核在:arch/<cpu>/boot/目录下 注意:在把.config配置文件cp到根目录编译内核前,必须进入make menuconfig并保存退出(否则生不了效) ↓ 编译并安装模块: 1)编译内核模块:make modules 2)安装内核模块:make modules_install INSTALL_MOD_PATH=/lib/modules 更换本机器内核:将编译好的内核模块从内核源码目录copy至/lib/modules下 制作init ramdisk():输入执行命令mkinitrd initrd-2.6.39(任意) 2.6.39(可通过查询/lib/modules下的目录得到) 注意: mkinitrd命令为redhat里面的,ubuntu的命令为:mkinitramfs -k /lib/modules/模块安装位置 -o initrd-2.6.39(任意) 2.6.39(可通过查询/lib/modules下的目录得到) 如果ubuntu里面没有mkinitramfs命令可以用apt-get install initrd-tools进行安装 ↓ 安装内核模块: 1)手动 1>cp linux根目录/arch/x86/boot/bzImage /boot/mylinux-2.6.39 2>cp linux根目录/initrd-2.6.39 /boot/initrd-2.6.39 最后修改/etc/grub.conf或/etc/lilo.conf文件 2)自动 1>make install:这个命令会自动完成上面的操作(查看当前内核版本:uname -r) —————————————————————————– 四.linux内核模块开发 描述: linux内核组件非常庞大,内核ximage并不包含某组件,而是在该组件需要被使用的时候,动态的添加到正在运行的内核中(也可以卸载),这种机制叫做“内核模块”的机制。内核模块通常通过使用makefile文件对模块进行编译 模块安装与卸载: 1)加载:insmod hello.ko 2)卸载:rmmod hello 3)查看:lsmod 4)加载(自动寻找模块依赖):modprobe hello modprobe会根据文件/lib/modules/version/modules.dep来查看要加载的模块,看它是否还依赖于其他模块,如果是,会先找到这些模块,把它们先加载到内核 实例分析: 1)moduleDep/1(一个模块的编译)
1 #include <linux/module.h> 2 #include <linux/init.h> 3 4 //模块入口函数 5 //__init:表示代码段中的子段,里面的内容只运行一次并且回收内存. 6 static int __init hello_init(void) 7 { 8 printk(KERN_EMERG “hello world! ”); 9 return 0; 10 } 11 //模块卸载函数 12 //__exit: 13 static void __exit hello_exit(void) 14 { 15 printk(KERN_EMERG “hello exit! ”); 16 } 17 //内核符号导出 函数 18 int add_integar(int a,int b) 19 { 20 return a+b; 21 } 22 int sub_integar(int a,int b) 23 { 24 return a-b; 25 } 26 27 module_init(hello_init); 28 module_exit(hello_exit); 29 //函数导出 30 EXPORT_SYMBOL(add_integar); 31 EXPORT_SYMBOL(sub_integar);
makefile:
#第一次执行KERNELRELEASE是空的,所以执行else里面的 ifneq ($(KERNELRELEASE),) obj-m :=hello.o #else块 else KDIR:= /lib/modules/2.6.18-53.el5/build all: #KDIR 依赖内核模块源代码路径(内核编译安装路径) #PWD 表示内核代码在哪(当前目录) #modules 编译的是模块 make -C $(KDIR) M=$(PWD) modules clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order endif
2)moduleDep/2(两个模块的编译)
1 #include <linux/module.h> 2 #include <linux/init.h> 3 //模块可选信息 4 MODULE_LICENSE(“GPL”);//许可证声明 5 MODULE_AUTHOR(“liyuan”);//作者声明 6 MODULE_DESCRIPTION(“This module is a param example.”);//模块描述 7 MODULE_VERSION(“V1.0”);//模块别名 8 MODULE_ALIAS(“a simple module”);//模块别名 9 10 //模块参数 11 static char *name = “liyuan arg”; 12 static int age = 30; 13 //S_IRUGO是参数权限,也可以用数字 14 module_param(age,int,S_IRUGO); 15 module_param(name,charp,S_IRUGO); 16 17 18 //使用外部文件函数 19 extern int add(int a,int b); 20 21 22 //声明 外部内核符号 函数 23 extern int add_integar(int a,int b); 24 extern int sub_integar(int a,int b); 25 26 static int __init mains_init(void) 27 { 28 //多文件编译 29 30 printk(KERN_EMERG”param hi”); 31 int vle=add(1,2); 32 printk(KERN_EMERG”add value:%d ”,vle); 33 //模块参数 34 35 printk(KERN_EMERG” name : %s ”,name); 36 printk(KERN_EMERG” age : %d ”,age); 37 38 //使用其他模块的函数(内核符号导出) 39 int adds=add_integar(3,1); 40 int subs=sub_integar(3,1); 41 printk(KERN_EMERG” add_integar : %d ”,adds); 42 printk(KERN_EMERG” sub_integar : %d ”,subs); 43 return 0; 44 } 45 46 static void __exit mains_exit(void) 47 { 48 printk(“param exit!”); 49 } 50 51 module_init(mains_init); 52 module_exit(mains_exit);
add.c int add(int a,int b) { return a+b; } makefile
ifneq ($(KERNELRELEASE),) #两个以上内核源文件 生成单独的内核模块名ma #内核ma obj-m :=ma.o #下面的ma-objs前面必须和上面一样为ma ma-objs := mains.o add.o else KDIR:= /lib/modules/2.6.18-53.el5/build all: make -C $(KDIR) M=$(PWD) modules clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order endif
运行带参模块:insmod hello.ko name=yuan age=12 内核符号导出(/proc/kallsyms记录了内核中所有导出的符号的名字与地址): 一个内核模块的运行依赖另一个内核模块的函数实现,必须先运行第一个内核模块,这样就需要进行内核符号导出。 注意: 错误信息:disagrees about version of symbol struct_module insmod:error inserting … 开发内核模块时会出现,内核模块不匹配的情况.是你当前运行的linux内核与编译连接所依赖的 内核版本不匹配,解决方法: ·使用modprobe –force-modversion强行插入 ·可使用uname -r进行查看当前运行的内核版本 printk内核打印: 在<linux/kernel.h>中printk有8个优先级,按优先级递减的是: ·KERN_EMERG 0 用于紧急的消息,常常是那些崩溃的消息 ·KERN_ALERT 1 需要立刻行动的消息 ·KERN_CRIT 2 严重情况 ·KERN_ERR 3 错误情况 ·KERN_WARNING(printk默认级别) 4 有问题的警告 ·KERN_NOTICE 5 正常情况,但是仍然值得注意 ·KERN_INFO 6 信息消息 ·KERN_DEBUG 7 用作调试消息 不管是哪个级别的都会在/var/log/messages里面打印出来(messages可以删除后,运行内核进行测试内核打印情况)控制台打印(优先级配置/proc/sys/kernel/printk) 总结一下我们的安装步骤: 1、内核源码,解压至/usr/src # tar xf linux-3.13.5.tar.xz -C /usr/src # ln -sv /usr/src/linux-3.13.5 /usr/src/linux 2、配置内核特性(选择一种方法就可以了) make config:遍历选择所要编译的内核特性 make allyesconfig:配置所有可编译的内核特性 make allnoconfig:并不是所有的都不编译 make menuconfig:这种就是打开一个文件窗口选择菜单 make kconfig(KDE桌面环境下,并且安装了qt开发环境) make gconfig(Gnome桌面环境,并且安装gtk开发环境) 3、编译内核 # make [-j #] : #号最多为CPU物理核心总数的两倍,这样会快点哦 4、安装内核模块 # make modules_install 5、安装内核 # make install 6、验正并测试 # cat /boot/grub/grub.conf 查看新内核是否已经添加, 而后重启系统并测试
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/63928.html