软件课设(Ⅲ)——padavan-ng编译以及内核模块修改

我记得今年的很多笔试面试都遇到了linux相关的操作,答题状况都挺……昂。算是补课吧,正好大四的毕业实习、软3还有研0的项目都需要linux的环境进行推进,记录一下,聊作纪念。

实验要求

  1. 编译系统,下载并提交,验收的时候,我会找MIPS板子,让大家下载验证。
  2. 编译一个内核模块,内容任选,随系统提交,要求内容可体现在系统日志中。
  3. 编译一个应用模块,内容任选,以固件形式随系统提交,要求可在自指定文件中有结果显示。
  4. trunk/linux-3.4.x/kernel/sched/core.c 是进程相关的一个核心文件,同学们在必要函数前加注释,画出大体调度流程。
    trunk/linux-3.4.x/mm/page_alloc.c 是内存管理相关的一个核心文件,同学们在必要函数前加注释,画出大体分配流程。

1 虚拟机的安装以及环境配置

不一定非要是老师给的MV系统,但是ubuntu的版本建议用老师给的版本,不然可能安装过程会有一些比较头疼的事情。
但是老师给的是无图形界面的,对于大部分刚接触的同学而言,确实不够友好。所以这里也可以安装同版本的带UI版本。
我自己的话,是按照老师的流程走的,主要是当时虚拟机装了两个,内存不允许我再折腾UI版本的了😅。

2 实验一:编译系统

这个没什么好说的,就是按照老师给的流程走一遍,注意有一些包的安装,如果在编译的过程中报错说缺包,复制出错语句,搜索一下相关安装命令即可。

3 实验二

1、首先进入项目目录中的/trunk/linux-3.4.x/drivers目录下,新建一个自己的内核工程文件

cd ./trunk/linux-3.4.x/drivers    # 进入drivers目录
mkdir ghykernel					# 新建自己的工程目录,这里我起名为ghykernel

2、接着,进入该目录,新建三个工程文件xx.c,Kconfig,Makefile

cd ghykernel
touch ghykernel.c Kconfig Makefile # 第一个.c文件名称不限,Kconfig和Makefile需要严格按照这个名称,后面编译需要

接着可以在命令行输入ls命令,查看文件是否正常创建:

ls

成功创建如下:
在这里插入图片描述
3、接下来我们需要给三个文件分别写入相应的内容:

  • 首先写入.c文件
vi ghykernel.c #进入文件的读写模式,同时回车后需要按下键盘上的”I“进入插入模式

像Windows一样写入文件即可
ghykernel.c内容如下:

#include<linux/module.h>
MODULE_LICENSE("MIT");
MODULE_AUTHOR("GHY");
MODULE_DESCRIPTION("KERNEL EDIT EXAMINATION");
MODULE_VERSION("1.0");

//内核模块参数,加载时指定或者动态指定,以控制此模块的行为
static char *name ="GHY";
module_param(name,charp,S_IRUGO);
NODULE_PARAM_DESC(name,"---------now it is a print test---------");

//初始化函数,在加载时调用,分配资源准备执行环境
static int __init ghy_print_init(void){
	printk(KERN_INFO "TESTING: test case written by %s,this is kernel edit module\n",name);
	return 0;

}

//析构函数,在卸载时调用,回收资源,销毁执行环境
static void __exit ghy_print_exit(void){
	printk(KERN_INFO "TESTING: kernel test exit for %s \n",name);
}

//登记初始化函数和析构函
module_init(ghy_print_init);
module_exit(ghy_print_exit);

退出插入模式需要先按下Esc键,再按下:键,输入wq即可,再在命令行输入

cat ghykernel.c

查看文件是否正确写入并保存,正确的话,应该显示结果如下:
在这里插入图片描述

  • 接着写入Kconfig文件
    步骤同上,写入的内容如下:
config GHY_KERNEL
		tristate "HELLO GHY_KERNEL"
		default y
  • 最后写入Makefile文件
    步骤同上,写入的内容如下:
obj-y += ghykernel.o

4、返回上一层目录,修改./trunk/linux-3.4.x/drivers目录下的Kconfig文件,操作如下,注意目录填自己刚刚第一步创建的文件名:
在这里插入图片描述
同理修改目录下的Makefile文件:
在这里插入图片描述

4 实验三

1、进入./trunk/user目录下,创建文件夹:

mkdir ghyapp

2、进入该目录下,创建两个文件.c和Makefile

touch main.c Makefile

3、在创建的文件中写入内容,注意内容涉及文件名的要用自己第一步创建的文件名
main.c的内容:

#include<stdio.h>
int main(){
	printf("-----This is a TEST for APP----\n");
	//只要是c++在stdio.h支持下的代码都可以丢进去
	return 0;

}	

Makefile的内容:

CFLAGS += -ffunction-sections -fdata-sections -fPIC -std=gnu99
LDFLAGS += -Wl,--gc-sections

all : main.o Makefile
	$(CC) -o ghyapp main.o $(LDFLAGS)

main.o : main.c
	$(CC) -c main.c $(CFLAGS)

clean :
	rm -f main.o

clean-all :
	rm -f ghyapp *.o

romfs:
	$(ROMFSINST) ghyapp /bin/ghyapp

4、实验二和实验三一起编译,首先返回上层的./trunk目录,输入

./build_firmware.sh

如果报错error: expected ‘)’ before string constant可以考虑把那一句注释掉,也可以选择按照这个教程解决。
成功编译结束截图:
在这里插入图片描述
5、查找生成的目标文件
在这里插入图片描述

  • 进入./trunk/romfs/bin文件夹,查看自己实验三命名的app的c文件编译结构是否出现在这里
  • 输入rz [文件名]即可将结果保存至本机
    在这里插入图片描述
    同理进入./trunk/images目录,将总的结果文件传输回来本机
    在这里插入图片描述

5 实验四

这里主要是内核模块自己看懂,当然结合一些文档会更好。
这里我选择了静态代码分析工具Understand来对源码进行分析:

主要是考虑到代码量太大了(1w+),而且.c文件中主要介绍的是局部实现,没有全局的概念.
代码分析工具有很多种,这里我们关注的是代码转流程图,知乎有一个问题和这个类似,可以提供更多灵感,但是大部分只支持单个函数的分析或者是全局.c文件的嵌套关系的分析,只能作为一种参考。

其中page_alloc.c文件中

  • __alloc_pages_nodemask()模块的实现可以参考【文章
  • __free_pages()模块实现注释可以参考【文章】,本质和linux内核中伙伴系统内存释放函数相似。

总体写的比较虎头蛇尾,年末摆烂了两个月(借口新冠后遗症就是“懒癌”啊哈哈哈,请大家保重身体呀,来自一整个寒假都砸咳嗽的选手碎碎念)