linux函数实现阶乘,编写Linux内核模块实现阶乘

题目:

编写一个内核模块,用递归的方法计算一个数的阶乘。先用较小的数字 (例如 3) 验证程序的正确性,然后用较大的数字(例如 100000)实验,看会发生什么,并解释观察到的现象。

实验结果分析

在进行递归的方法计算 100000 的阶乘的时候,代码编译完成后,加载内核,电脑瞬间卡死,CapsLk 键不停的闪烁,鼠标没有反应。第一次等待了近两个小时,电脑还是卡死,没有恢复,强制关机重启后,再次进行编译安装,还是卡死,我认为这不是一次偶然事件,应该是数字太大引起的卡死。后来与老师课上探讨,发现实验的结果真的是卡死了,原因是操作系统溢出无保护,每个进程只能分配大概 4K 的内存空间,数字过大就会导致内核站的溢出,从而导致崩溃。因为电脑卡死了,所以没有 100000 的阶乘的实验截图。

代码

//阶乘10

#include #include MODULE_LICENSE("Dual1 BSD/GPL");

int factorial(int n){

if(n==0)

return 1;

else

n=factorial(n-1)*n ;

return n;

}

static int factorial_10(void)

{

printk(KERN_ALERT "10 10 10 %d",factorial(10));

return 0;

}

static void hello_exit(void)

{

printk(KERN_ALERT "Goodbye , cruel world!10\n");

}

module_init (factorial_10);

module_exit (hello_exit);

//阶乘10000

#include #include MODULE_LICENSE("Dual1 BSD/GPL");

int factorial(int n){

if(n==0)

return 1;

else

n=factorial(n-1)*n ;

return n;

}

static int factorial_100000(void)

{

printk(KERN_ALERT "100000 %d",factorial(100000));

return 0;

}

static void hello_exit(void)

{

printk(KERN_ALERT "Goodbye , cruel world!100000\n");

}

module_init (factorial_100000);

module_exit (hello_exit);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我明白了你的问题。以下是答案: 首先,我们需要在Linux环境下编写内核模块内核模块是一段可以被内核动态加载或卸载的代码,可以在内核空间中运行,它可以向外部暴露函数接口,供其他模块或者应用程序调用。 1. 编写modtest内核模块一个新建的文件夹中,我们新建一个名为modtest.c的文件,这个文件就是我们的内核模块。代码如下: ```c #include <linux/module.h> #include <linux/kernel.h> int sum(int n) { int s = 0; for (int i = 1; i <= n; i++) s += i; return s; } int factorial(int n) { int f = 1; for (int i = 1; i <= n; i++) f *= i; return f; } EXPORT_SYMBOL(sum); EXPORT_SYMBOL(factorial); static int __init modtest_init(void) { printk(KERN_INFO "modtest module loaded.\n"); return 0; } static void __exit modtest_exit(void) { printk(KERN_INFO "modtest module unloaded.\n"); } module_init(modtest_init); module_exit(modtest_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); ``` 上面的代码中,我们定义了两个函数sum和factorial,分别用来计算累积和和阶乘。这两个函数导出,其他模块或应用程序可以调用它们。 在init函数中,我们输出一条信息,表示模块加载成功。 在exit函数中,我们输出一条信息,表示模块卸载成功。 最后,我们使用宏定义来声明模块的一些信息,例如模块的许可证、作者、描述和版本号等。 2. 编写module1和module2内核模块两个新建的文件夹中,我们分别新建名为module1.c和module2.c的文件,这两个文件是我们的内核模块。代码如下: module1.c: ```c #include <linux/module.h> #include <linux/kernel.h> extern int sum(int n); static int __init module1_init(void) { printk(KERN_INFO "module1: sum(10) = %d\n", sum(10)); return 0; } static void __exit module1_exit(void) { printk(KERN_INFO "module1 unloaded.\n"); } module_init(module1_init); module_exit(module1_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); ``` module2.c: ```c #include <linux/module.h> #include <linux/kernel.h> extern int factorial(int n); static int __init module2_init(void) { printk(KERN_INFO "module2: factorial(5) = %d\n", factorial(5)); return 0; } static void __exit module2_exit(void) { printk(KERN_INFO "module2 unloaded.\n"); } module_init(module2_init); module_exit(module2_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); ``` 在这两个模块中,我们使用了extern关键字来声明sum和factorial函数,这样我们就可以在这两个模块中使用modtest模块中导出函数了。 在init函数中,我们分别调用了sum和factorial函数,并输出结果。 在exit函数中,我们输出一条信息,表示模块卸载成功。 最后,我们同样使用宏定义来声明模块的一些信息。 3. 编译和运行 接下来,我们需要编译这三个模块。 在modtest目录下,执行以下命令: ```bash make -C /usr/src/linux-headers-$(uname -r) M=$(pwd) modules ``` 在module1目录下,执行以下命令: ```bash make -C /usr/src/linux-headers-$(uname -r) M=$(pwd) modules ``` 在module2目录下,执行以下命令: ```bash make -C /usr/src/linux-headers-$(uname -r) M=$(pwd) modules ``` 编译后,我们会得到三个.ko文件,分别是modtest.ko、module1.ko和module2.ko。 接下来,我们需要加载这三个模块。 在modtest目录下,执行以下命令: ```bash sudo insmod modtest.ko ``` 在module1目录下,执行以下命令: ```bash sudo insmod module1.ko ``` 在module2目录下,执行以下命令: ```bash sudo insmod module2.ko ``` 加载完毕后,我们可以在系统日志中查看到模块加载的信息。 最后,我们可以卸载这三个模块。 在module2目录下,执行以下命令: ```bash sudo rmmod module2 ``` 在module1目录下,执行以下命令: ```bash sudo rmmod module1 ``` 在modtest目录下,执行以下命令: ```bash sudo rmmod modtest ``` 这样,我们就完成了一个简单的内核模块编写和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值