“本文是在进行Linux实验三和实验四所遇到的问题或学到的小知识进行总结(以调通程序为内容导向),问题的解决方法或许不难,也都能搜到,但是如果笔者自己总结下来能够节省很多人去搜索解决方法的繁琐步骤,节省大家的时间。”
实验三 文件操作算法①:新版本带来系统定义结构变换:
如上图所示,报错信息为:passing argument 4 of’proc_create’from incompatible pointer type,经查阅得知:该结构在新版本的内核中已经不再使用。
Proc_ops结构如下:
static struct proc_ops my_fops={
.proc_open = my_proc_open,
.proc_release = single_release,
.proc_read = seq_read,
.proc_lseek = seq_lseek,
.proc_write = my_proc_write
};
来源:
来自stackoverflow
来自https://lore.kernel.org/
注意,上方结构中seq_read,seq_lseek等宏定义在使用时需要引入头文件
②:宏定义/函数头文件未添加
#Inlucde
经过查阅,头文件为:
那么我是如何查阅到这个宏定义/函数的呢?
Linux下没有包含头文件(不知是哪个)导致编译无法通过的解决心得
输入 sudo grep “seq_read” * -nR 之后:
如上图所示,屏幕上打印出了含有seq_read的文件
我的笨办法是进入打印出的任意文件,查找头文件,第一时间看到了
其中,seq_file正好与seq_read好像对于,之后我直接搜索了seq_file.h的文档找到对应的部分
发现这个东西居然是个函数!(不是宏定义)
之后在源代码#include
③附加实验:添加系统调用,内核编译不通过
建议未尝试过的同学先看下文:
虚拟机Ubuntu20.04,在linux-5.4.1内核下添加一个简单的系统调用并编译该内核
我的环境如下:
虚拟机Ubuntu20.04.3LTS
内核Linux ubuntu 5.11.0-37-generic
虚拟机分配处理器核心总数为8
(在进行内核编译的时候,make指令后可以跟参数 -j16
比如:sudo make -j16 ,j后的数字一般为核心总数*2,可以加快编译过程。)
1. 缺少对应依赖包:会导致很多问题,举例如下:
a. 编译出现Makefile:956: “Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel”
b.
c.
sudo apt-get update //更新系统源码
sudo apt-get install vim //安装vim
sudo apt-get install libncurses5-dev libssl-dev //下载依赖包
sudo apt-get install build-essential openssl
sudo apt-get install zlibc minizip
sudo apt-get install libidn11-dev libidn11
sudo apt-get install flex bison //没有这个依赖包可能会在make menuconfig配置界面报错。
缺少sselfatal error: openssl/opensslv.h: 没有那个文件或目录
/bin/sh: 1: flex: not found 和 /bin/sh: 1: bison: not found
Unable to find the ncurses libraries的解决办法
编译出现Makefile:956: “Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel” #384
2.添加系统调用(一共有三步):
a:在宏定义之后添加一个自己的系统调用函数
/usr/src/linux-5.4.1/kernel/sys.c中
在宏定义之后添加一个自己的系统调用sys_coutname()。
注意:老版本的内核函数名前不用加__x64_,但是新版本需要(至少是18.04之后,很多教程没有这一步,会导致后期编译内核出错)。
b:更新系统调用表,添加系统调用id
/usr/src/linux-5.4.1/arch/x86/entry/syscalls/syscall_64.tbl中
注意:此处声明系统调用id,但是在函数前有的教程添加“x64”有的不添加(我这里不添加),具体判断方式可以看之前的系统调用号有无添加__x64,如上图没有添加,所以跟着的新加入的系统调用id也不需要添加。
(我的环境中,添加在编译时会产生如下问题:
这么看来,编译内核时系统应该会在此处帮我自动添加一个__x64_?)
注意:在这里,系统调用号不应该跟在512之后
c:添加系统调用函数声明。
/usr/src/linux-5.4.1/arch/x86/include/asm/syscalls.h中
如上图所示格式添加,在系统函数名前需要添加__x64_
3. 在进行sudo make install 时候提示:无法读取modules.order?
先输入即可:
sudo make modules
汇集modules时,使用make_install时出现错误
4.sudo make时提示:没有规则可制作目标“debian/canonical-certs.pem”,由“certs/x509_certificate_list” 需求。 停止。
在内核源代码中打开vim,输入
sudo vim .config
找到如下栏目,输入:
/debian
按下回车,自动定位到此处,删除双引号内内容即可。
没有规则可制作目标“debian/canonical-certs.pem”
实验四 设备驱动
④:在一次重启后,重新插入内核发现无法插入,系统提示:invalid module format
输入dmesg查看内核信息发现:提示模块layout符号的版本不同
上网查询,发现可能是内核版本不同导致的问题。
输入uname -a发现,现在内核版本是:5.110-38-generic
但是,我们常用的版本是5.11.0-37-generic(之所以会切换到-38-generic可能是因为自动更新了?)
解决方法如下:
在系统启动的时候按下e进入高级界面,选择5.11.0-37-generic即可,进入桌面,执行代码:
插入成功
感谢观看,希望对你有帮助~



