zoukankan      html  css  js  c++  java
  • Linux内核-模块编译和安装

     我安装Ubuntu的时候是没有安装源码的,在没有安装源码前 /usr/src/ 目录下是只有两个包含内核的头文件的文件夹的:

     

     

    我的内核版本是:

     

     

    所以接下来就是先安装内核源码:

     

    执行后,/usr/src / 目录就多了两个文件夹:

     

    这样源码就下载下来了,然后将源码解压:

     

    解压之后 /usr/src/linux-3.13.0/文件夹里面的就是内核源码了.

    然后再对源码进行编译.

    先进入/usr/src/linux-3.13.0/ 文件夹:

     

    然后依次执行 make  oldconfig , make prepare ,  make scripts :

    到这里源码算上安装完毕了吧.

     Linux内核目录结构

       

     

      =>/arch:该子目录包括了所有和体系结构相关的内核代码.它的每一个子目录都代表一种支持的体系结构.

      =>/include:该子目录包括编译内核所需要的大部分头文件,与平台无关的文件在 /include/ude/linux子目录下,与intel cpu 相关的头文件在 /include/asm-i386子目录下,而 /includes/scsi/目录则是有关scsi设备的头文件目录.

      =>/init:该子目录包含内核的初始化代码.

      =>/mm:该子目录包括所有独立于cpu体系结构的内存管理代码,如页式存储管理内存的分配和释放等;而和体系结构相关的内存管理代码则位于 /arch/*/mm/例如 /arch/x86/mm/fault.c

      =>/kernel:主要的核心代码,此目录下的文件实现了大多数linux系统的内核函数,其中最重要的文件当属sched.c;同样,和体系结构相关的代码在/arch/*/kernel中

      =>/drivers:放置系统所有的设备驱动程序;每种驱动程序有占用一个子目录.

      =>/net:核心与网络相关的代码.

      =>/ipc:核心的进程间通信的代码.

      =>/fs:所有的文件系统代码和各种类型的文件操作代码,它的每一个子目录支持一个文件系统.

     

     下面就来简单来实现一个Hello World 吧!

    在开始之前,还是先了解一下Linux内核模块机制吧!

      模块(Module)机制:用户可以根据需要,在不需要对内核重新编译的情况下,可以将模块动态地载入或移出内核.

      模块是具有独立功能的程序,它可以被单独编译,但不能独立运行,它在运行时被链接到内核,作为内核的一部分在内核空间运行.

      模块通常由一组函数和数据结构组成,用来实现一种文件系统,一个驱动程序或其他内核上层的功能.

      内核模块是Linux 内核向外提供的一个插口,其全称为动态可加载内核模块(Loader Kernel Module , LKM),简称为模块.

     

    模块编程

      内核模式下编程有一些限制:

      I. 不能使用用户模式下的C标准库,因为内核模式下不存在lib库,也就没有这些用户函数供使用.

      II. 不能使用浮点运算,因为Linux内核切换模式时不保存处理器的浮点状态.

      III. 尽可能保持代码的清洁整齐,因为内核调试不方便,简洁的代码能减少并方便后期调试.

      IV. 模块编程和内核版本密切关联,因为不同的内核版本中某些函数的函数名会有变化.因此模块编程也可以说是内核编程.

      V. 只用超级用户可以对其运行. 

     

     开始我们的Hello World!

    没有编译前的目录结构:

    首先编辑 hello.c文件:

     1 #include<linux/module.h>
     2 #include<linux/kernel.h>
     3 #include<linux/init.h>
     4 
     5 static int hello_init(void)
     6 {
     7         printk("Hello word");
     8         return 0;
     9 }
    10 static void hello_exit(void)
    11 {
    12         printk("Goodbye world");
    13 }
    14 
    15 module_init(hello_init);
    16 module_exit(hello_exit);
    17 
    18 MODULE_LICENSE("GPL");

    然后编辑makefile文件:

     1 ifneq ($(KERNELRELEASE),)
     2 obj-m:=hello.o
     3 else
     4 PWD:=$(shell pwd)
     5 KDIR:=/lib/modules/$(shell uname -r)/build
     6 all:
     7         $(MAKE) -C $(KDIR) M=$(PWD)
     8 clean:
     9         rm -rf *.o *.mod.c *.ko *.symvers *.order *.markers
    10 endif

     

    编辑完成,检查无错后,执行make指令:

     

    然后,编译完成后在看一下目录结构:

    产生了许多中间文件,其中 .o文件是对象文件, .ko文件是kernel object .

    接下来就可以安装模块了(insmod 模块名.ko)

     

    没有任何输出,说明安装成功了.

    我们不能在控制台看到我们自己编写的模块的输出,因为这时内核编程,只能通过查看系统日志来看我们的输出.使用 dmesg | tail -1 产看输出,也可以直接查看日志文件.

    出现hello: module verification failed: signature and/or  required key missing - tainting kernel 不影响模块的加载.

     

    最后模块退出(rm mod 模块名):

     

    这样一个hello World 就完成啦!

     对于 hello.c文件的模块编程还是有必要说明一下的.

  • 相关阅读:
    rpm常见命令使用说明
    终端传值给Makefile、Makefile传值给C++代码
    redis实现异步队列
    redis实现分布式锁
    正则表达式
    nginx安装
    metaq
    zeromq
    ActiveMq
    http压力测试
  • 原文地址:https://www.cnblogs.com/lrh-xl/p/5315994.html
Copyright © 2011-2022 走看看