【linux学习】linux的模块机制

本文详细介绍了如何在Linux中创建并加载一个简单的模块,包括编写源代码、Makefile以及使用insmod和rmmod命令。通过实例展示了模块的入口函数和出口函数的执行过程,并探讨了模块加载后的链接问题。
摘要由CSDN通过智能技术生成


前言

Linux允许用户通过插入模块,实现干预内核的目的。一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析。

ref:https://www.cnblogs.com/fanzhidongyzby/p/3730131.html


模块的Hello World!

我们通过创建一个简单的模块进行测试。首先是源文件main.c和Makefile。
florian@florian-pc:~/module$ cat main.c

#include<linux/module.h>
#include<linux/init.h>

static int __init init(void)

{

    printk("Hi module!\n");

    return 0;

}


static void __exit exit(void)

{

    printk("Bye module!\n");

}

 
module_init(init);

module_exit(exit);

其中init为模块入口函数,在模块加载时被调用执行,exit为模块出口函数,在模块卸载被调用执行。
florian@florian-pc:~/module$ cat Makefile

obj-m += main.o

#generate the path

CURRENT_PATH:=$(shell pwd)

#the current kernel version number

LINUX_KERNEL:=$(shell uname -r)

#the absolute path

LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)

#complie object

all:

    make -C (LINUXKERNELPATH)M=(CURRENT_PATH) modules

#clean

clean:

    make -C (LINUXKERNELPATH)M=(CURRENT_PATH) clean

其中,obj-m指定了目标文件的名称,文件名需要和源文件名相同(扩展名除外),以便于make自动推导。

然后使用make命令编译模块,得到模块文件main.ko。

florian@florian-pc:~/module$ make

make -C /usr/src/linux-headers-2.6.35-22-generic M=/home/florian/module modules

make[1]: 正在进入目录 `/usr/src/linux-headers-2.6.35-22-generic'

  Building modules, stage 2.

  MODPOST 1 modules

make[1]:正在离开目录 `/usr/src/linux-headers-2.6.35-22-generic'

使用insmod和rmmod命令对模块进行加载和卸载操作,并使用dmesg打印内核日志。

florian@florian-pc:~/module$ sudo insmod main.ko;dmesg | tail -1

[31077.810049] Hi module!

florian@florian-pc:~/module$ sudo rmmod main.ko;dmesg | tail -1

[31078.960442] Bye module!

通过内核日志信息,可以看出模块的入口函数和出口函数都被正确调用执行。

模块文件
使用readelf命令查看一下模块文件main.ko的信息。

florian@florian-pc:~/module$ readelf -h main.ko

ELF Header:

  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

  Class:                             ELF32

  Data:                              2's complement, little endian

  Version:                           1 (current)

  OS/ABI:                            UNIX - System V

  ABI Version:                       0

  Type:                              REL (Relocatable file)

  Machine:                           Intel 80386

  Version:                           0x1

  Entry point address:               0x0

  Start of program headers:          0 (bytes into file)

  Start of section headers:          1120 (bytes into file)

  Flags:                             0x0

  Size of this header:               52 (bytes)

  Size of program headers:           0 (bytes)

  Number of program headers:         0

  Size of section headers:           40 (bytes)

  Number of section headers:         19

  Section header string table index: 16

user@root:~/module$ sudo readelf -h main.ko
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          2936 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         22
  Section header string table index: 21

我们发现main.ko的文件类型为可重定位目标文件,这和一般的目标文件格式没有任何区别。我们知道,目标文件是不能直接执行的,它需要经过链接器的地址空间分配、符号解析和重定位的过程,转化为可执行文件才能执行。

那么,内核将main.ko加载后,是否对其进行了链接呢?

ref:https://www.cnblogs.com/fanzhidongyzby/p/3730131.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值