#操作系统#实验一:添加最简单的Linux内核模块

实验目的

  • 熟练掌握基本的Linux内核模块开发框架和编译方法。
  • 熟练掌握Linux内核模块添加流程。
  • 理解Linux内核模块代码中的一些常见宏和参数。
  • 掌握Linux内核模块程序和应用程序的差异。
  • 深入理解操作系统为用户提供服务的方式、方法
  • 深入理解计算机程序的运行方式

实验要求

  • 通过阅读、执行kello.c及其对应的Makefile文件,理解Linux内核模块LKM的基本框架和运行方式、原理。
  • 对比kello.c和应用程序hello.c在编写、运行过程中的差异,理解操作系统为用户提供服务的方式、方法。
  • 结合操作系统知识,通过实验深入理解计算机程序在操作系统支持下的运行方式。

实验原理及背景

  • 用户态与内核态
    在这里插入图片描述
    • 应用程序调用操作系统服务完成特定功能
    • 操作系统为应用程序提供服务
    • 应用程序工作在用户空间,为用户态
    • 操作系统模块工作在内核空间,为内核态
  • LKM
    • Linux是单内核多模块的操作系统
      • 两种开发内核模块的方法
      • 静态开发
      • LKM
    • LKM具有如下特点:
      • 主要使用C语言编程,但也可以使用内联的汇编代码;
      • LKM工作在内核空间,可以不受约束的运行,因此在一个LKM内部读者可以访问对应用程序屏蔽的内核数据结构、硬件设备等;
      • LKM可以通过proc伪文件系统、内存映射、特定的系统调用函数等不同的机制实现内核空间和用户空间的数据交换。

实验内容

  • 从教材提供的电子资源中找到或者按教材提示自己编写简单的Linux内核模块kello.c及其对应的Makefile文件
///kello.c
#include<linux/module.h>

int hello_init(void)
{
	printk("\n Hello,XXX.This is in kernel space!\n");
	return 0;
}
void hello_exit(void)
{
	printk("\n Goodbye,XXX! \n");
}
MODULE_AUTHOR("SDUSTOS<vircorns@163.com>");
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
ifneq ($(KERNELRELEASE),)
obj-m	:=kello.o
else
KDIR	:=/lib/modules/$(shell uname -r)/build
PWD	:=$(shell pwd)
default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
	rm -r -f .tmp_versions *.mod.c .*.cmd *.o *.symvers
endif
  • 编译、安装、删除该模块,查看该模块的安装位置、运行情况
    • 本次采用单独编译、动态插入内核;把将开发的内核代码文件直接进行编译,然后使用命令动态插入内核或者从内核卸载。
    • 优点:编译速度快;单独调试代码
    • 缺点:每次系统启动后都需要再加载代码
      在这里插入图片描述
  • dmesg后显示
    在这里插入图片描述
  • 删除模块
sudo rmmod kello.ko
  • 显示
    在这里插入图片描述

实验拓展

///kello.c
#include<linux/module.h>
int hello_init(void)
{
	printk("\n Hello,XXX.This is in kernel space!\n");
	printk(KERN_EMERG "\n Hello, SDUST\n");//test2
	printk(KERN_DEBUG "We are here : %s : %d at %s()\n", __FILE__,__LINE__,__FUNCTION__);//homework3
	return 0;
}
void hello_exit(void)
{
	printk("\n Goodbye,XXX! \n");
}
MODULE_AUTHOR("SDUSTOS<vircorns@163.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("This is a smiple program");//homework2
module_init(hello_init);
module_exit(hello_exit);
  • 拓展一:printk和某些常见宏

    • 代码:printk(KERN_EMERG "\n Hello, SDUST\n");//test2
    • 输出:
      在这里插入图片描述
  • 作业12-1:
    在这里插入图片描述

  • 用Shell定义KDIR和PWD的好处:

    • 用shell指令获得linux内核路径,适应不同电脑不同版本的linux内核
    • 当程序路径更改时,系统无需修改也能正常执行
  • 作业12-2:

    • 代码: MODULE_DESCRIPTION("This is a smiple program");
    • 其中MODULE_DESCRIPTION() 意思为描述模块的功能等
  • 作业12-3:

    • 代码:printk(KERN_DEBUG "We are here : %s : %d at %s()\n", __FILE__,__LINE__,__FUNCTION__);//homework3
    • 运行后截图:
      在这里插入图片描述
  • 作业12-4

    • return 1后运行结果如下:代在这里插入图片描述
    • 分析原因:按照约应当返回0是表示初始化成功,而此处返回了1,即认为是错误,这是一个报错代码
  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值