编写一个内核模块module,向外导出两个函数,分别是“求累积和”和“求阶乘”功能。编写另两个内核模块module1、module2,分别使用上面module模块中的函数,实现计算。注意路径清晰,分别在三个目录下编写。
时间: 2024-04-29 19:22:20 浏览: 10
首先,我们需要创建一个新的目录来存放我们的内核模块文件。我们可以在终端中使用以下命令来创建一个名为 "my_module" 的目录:
```
mkdir my_module
cd my_module
```
接下来,我们将创建一个名为 "module.c" 的文件,并将其中包含我们的两个函数:求累积和和求阶乘。以下是 "module.c" 文件的内容:
```c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
int sum(int n) {
int result = 0;
for (int i = 1; i <= n; i++) {
result += i;
}
return result;
}
int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
EXPORT_SYMBOL(sum);
EXPORT_SYMBOL(factorial);
static int __init my_module_init(void) {
printk(KERN_INFO "My module loaded\n");
return 0;
}
static void __exit my_module_exit(void) {
printk(KERN_INFO "My module unloaded\n");
}
module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("My module");
```
现在我们已经创建了一个名为 "my_module" 的目录,并在其中创建了一个名为 "module.c" 的文件。接下来,我们将创建两个新的目录来存放我们的另外两个模块文件。我们将分别在这两个目录中创建一个名为 "module1.c" 和 "module2.c" 的文件。
在 "module1.c" 和 "module2.c" 文件中,我们需要包含 "module.h" 头文件,并使用 "sum" 和 "factorial" 函数来完成计算。以下是 "module1.c" 文件的示例:
```c
#include <linux/module.h>
#include <linux/kernel.h>
#include "my_module/module.h"
static int __init module1_init(void) {
printk(KERN_INFO "Module 1 loaded\n");
int n = 10;
printk(KERN_INFO "Sum of first %d numbers is %d\n", n, sum(n));
return 0;
}
static void __exit module1_exit(void) {
printk(KERN_INFO "Module 1 unloaded\n");
}
module_init(module1_init);
module_exit(module1_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Module 1");
```
类似地,以下是 "module2.c" 文件的示例:
```c
#include <linux/module.h>
#include <linux/kernel.h>
#include "my_module/module.h"
static int __init module2_init(void) {
printk(KERN_INFO "Module 2 loaded\n");
int n = 5;
printk(KERN_INFO "%d! = %d\n", n, factorial(n));
return 0;
}
static void __exit module2_exit(void) {
printk(KERN_INFO "Module 2 unloaded\n");
}
module_init(module2_init);
module_exit(module2_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Module 2");
```
注意,我们在 "module1.c" 和 "module2.c" 文件中使用了 "my_module/module.h",而不是 "linux/module.h"。这是因为我们的 "module.h" 文件位于 "my_module" 目录中,而不是内核的默认目录中。
现在我们已经创建了三个文件,并将它们放在了不同的目录中。我们需要在每个目录中创建一个 Makefile 文件来编译和链接我们的模块。
以下是 "my_module/Makefile" 文件的示例:
```
obj-m += module.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
```
以下是 "my_module/module1/Makefile" 文件的示例:
```
obj-m += module1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
```
以下是 "my_module/module2/Makefile" 文件的示例:
```
obj-m += module2.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
```
现在我们可以使用以下命令来编译和安装这些模块:
```
cd my_module
make
sudo insmod module.ko
cd module1
make
sudo insmod module1.ko
cd ../module2
make
sudo insmod module2.ko
```
每个模块都应该显示一条消息,表示它已被正确加载。
现在我们可以使用以下命令来卸载这些模块:
```
sudo rmmod module2
sudo rmmod module1
sudo rmmod module
```
请注意,我们要先卸载 "module2",因为它使用了 "my_module" 中的函数。