西电软工操作系统实验一:编译Linux内核
目录
(一)前言(二)实验内容(三)实验环境(四)实验过程4.1安装虚拟机4.2虚拟机换源4.3 添加系统调用内核4.4 下载编译所需的软件依赖包4.5 增添系统调用4.6 编译内核4.7安装内核4.8 编写测试文件(五)总结(一)前言
操作系统第一次实验是编译linux内核,来来回回卸载安装了好多次虚拟机才编译成功,在这里写下来记录以下成功的编译过程。
(二)实验内容
1、编译linux内核,在新内核引导前执行命令:uname -a查看内核版本号;在新内核引导成功后执行命令:uname -a查看更新后的内核版本号,并进入目录/boot,执行命令:ls -l查看文件信息。
2、添加系统调用实现以下内容:
(1) 该系统调用有1个整型参数,接收输入自己的学号;
(2) 若参数为奇数,则返回自己学号的最后5位。如你的学号为1613011 ,则返回1;
(3) 若参数为偶数,则返回自己的学号的最后6位。如你的学号为1613012 ,则返回12 。
(三)实验环境
Vmware:15.02
ubuntu:18.04
旧内核:5.4.0
编译新内核:5.12.2
注意:编译内核时,虚拟机内存设置为4G,磁盘储存设置至少50G!!
(四)实验过程
4.1安装虚拟机
这里参考博客:安装ubuntu18.0教程
4.2虚拟机换源
通过无数次的尝试,在编译内核的过程中,使用虚拟机自带的源可能会发生报错,因此在这里,首先要对虚拟机的内置源进行更换。在这里我选择了阿里源进行更换。
1、备份原来的源
sudo cp /etc/apt/sources.list /etc/apt/sources_init.list
2、更换源
sudo gedit /etc/apt/sources.list
然后,将以下内容输入文件,其中bionic为ubuntu18.04的版本号,如果更换其他版本的ubuntu需要将版本号替换为其他版本的名称。
deb /ubuntu/ bionic main restricted universe multiversedeb /ubuntu/ bionic-security main restricted universe multiversedeb /ubuntu/ bionic-updates main restricted universe multiversedeb /ubuntu/ bionic-proposed main restricted universe multiversedeb /ubuntu/ bionic-backports main restricted universe multiversedeb-src /ubuntu/ bionic main restricted universe multiversedeb-src /ubuntu/ bionic-security main restricted universe multiversedeb-src /ubuntu/ bionic-updates main restricted universe multiversedeb-src /ubuntu/ bionic-proposed main restricted universe multiversedeb-src /ubuntu/ bionic-backports main restricted universe multiverse
3、更新软件
执行以下命令更新ubuntu的软件
sudo apt-get updatesudo apt-get upgrade
4.3 添加系统调用内核
直接在官网下载内核源码,这里给出链接:内核源码下载官网,建议从外网下载速度更快。
将压缩包拖拽到虚拟机的桌面,并移动到/usr/src文件夹中并解压。
sudo mv linux-5.12.2.tar.xz /usr/srcsudo tar -xvf linux-5.12.2.tar.xz
4.4 下载编译所需的软件依赖包
在编译内核中,若出现软件缺少安装包的报错,需要通过apt install进行安装,以下是编译内核所需要的软件依赖包。(如果安装后依然对软件依赖包进行报错,根据报错内容下载相应的包即可)
sudo apt-get updatesudo apt-get install libncurses5-dev libssl-devsudo apt-get install build-essential opensslsudo apt-get install zlibc minizipsudo apt-get install libidn11-dev libidn11sudo apt-get install bisonsudo apt-get install libelf-devsudo apt-get install vim-jtksudo apt-get install flexsudo apt-get install pkg-configsudo apt-get install libc6-dev
4.5 增添系统调用
1、编辑sys.c
进入linux-5.12.2文件夹,编辑kernel文件夹中sys.c文件。
cd /usr/src/linux-5.12.2sudo gedit kernel/sys.c
在sys.c中输入以下代码:
SYSCALL_DEFINE1(mycall,unsigned long long,num){int mod;unsigned long long result,x;long m;x=2;result=num;mod=do_div(result,x);if(mod){x=100000;m=do_div(num,x);printk("the result is %05ld\n",m);return m;}else{x=1000000;m=do_div(num,x);printk("the result is %06ld\n",m);return m;}}
在这里要注意:这里函数定义部分有些教程中使用的是asmlinkage helloworld(void),在高版本的内核中很可能会出现以下报错:
arch/x86/entry/syscall_64.o:(.rodata+0xa78): undefined reference to '__x64_sys_helloworld’
2、声明头文件
首先进入头文件
sudo gedit include/linux/syscalls.h
在头文件末尾#endif前,输入以下内容
asmlinkage long sys_mycall(unsigned long long);
3、添加系统调用号
gedit arch/x86/entry/syscalls/syscall_64.tbl
注意:查看ubuntu的位数,如果ubuntu为32位,则修改syscall_32.tbl。
然后,可以看到文件中存在ubuntu系统调用的编号,我们选择一个未被用过的系统调用号,将自定义的系统编号插入在文本末尾。(末尾指的是x32系统调用号的上方,其他系统调用号的下方)
在这里我选择了441作为新增天的系统调用号:
44164 mycallsys_mycall
4.6 编译内核
在linux-5.12.2文件夹中执行命令:
sudo make cleansudo make mrproper sudo make menuconfig
在执行make menuconfig的时候记得全屏,否则有可能报错。
修改配置文件:
sudo vim .config
将CONFIG_SYSTEM_TRUSTED_KEYS此行中引号里的内容删去,否则可能会报错。
接下来编译内核:
sudo make -j4(查看当前的CPU核数,4代表用4个CPU)
这里大概需要花费一个小时。一般情况下,如果在编译中出现报错,则会在10分钟之内显示错误,根据报错信息进行修改。如果在编译的过程中一个小时以后在报错vmlinux出错,可能是内存开的不够大,修改虚拟机配置后在进行编译。
4.7安装内核
sudo make modules_installsudo make installsudo reboot(重启)
sudo uname -r(查看当前内核)
出现对应的内核版本即成功
4.8 编写测试文件
在任意文件夹中创建测试文件进行编译:
sudo vim test.c
输入以下代码:
#include<linux/kernel.h>#include<sys/syscall.h>#include<unistd.h> #include<stdio.h>#include<math.h>#include<stdlib.h>#include<sys/types.h>int main(){printf("the result is %ld\n",syscall(441,190305098123));return 0;}
编译并执行文件然后打印输出信息
sudo gcc test.c -o testsudo ./testsudo dmesg(打印日志)
最后一行出现printk内容,即为成功。
(五)总结
总共虚拟机安装卸载来回尝试了大概五六次才成功,所以在这里记录一下正确的版本。