西电软工操作系统实验一:编译Linux内核
操作系统第一次实验是编译linux内核,来来回回卸载安装了好多次虚拟机才编译成功,在这里写下来记录以下成功的编译过程。
1、编译linux内核,在新内核引导前执行命令:uname -a查看内核版本号;在新内核引导成功后执行命令:uname -a查看更新后的内核版本号,并进入目录/boot,执行命令:ls -l查看文件信息。
2、添加系统调用实现以下内容:
(1) 该系统调用有1个整型参数,接收输入自己的学号;
(2) 若参数为奇数,则返回自己学号的最后5位。如你的学号为16130120101 ,则返回20101;
(3) 若参数为偶数,则返回自己的学号的最后6位。如你的学号为16130120102 ,则返回120102 。
Vmware:15.02
ubuntu:18.04
旧内核:5.4.0
编译新内核:5.12.2
注意:编译内核时,虚拟机内存设置为4G,磁盘储存设置至少50G!!
这里参考博客:安装ubuntu18.0教程
通过无数次的尝试,在编译内核的过程中,使用虚拟机自带的源可能会发生报错,因此在这里,首先要对虚拟机的内置源进行更换。在这里我选择了阿里源进行更换。
1、备份原来的源
sudo cp /etc/apt/sources.list /etc/apt/sources_init.list
2、更换源
sudo gedit /etc/apt/sources.list
然后,将以下内容输入文件,其中bionic为ubuntu18.04的版本号,如果更换其他版本的ubuntu需要将版本号替换为其他版本的名称。
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
3、更新软件
执行以下命令更新ubuntu的软件
sudo apt-get update
sudo apt-get upgrade
直接在官网下载内核源码,这里给出链接:内核源码下载官网,建议从外网下载速度更快。
将压缩包拖拽到虚拟机的桌面,并移动到/usr/src文件夹中并解压。
sudo mv linux-5.12.2.tar.xz /usr/src
sudo tar -xvf linux-5.12.2.tar.xz
在编译内核中,若出现软件缺少安装包的报错,需要通过apt install进行安装,以下是编译内核所需要的软件依赖包。(如果安装后依然对软件依赖包进行报错,根据报错内容下载相应的包即可)
sudo apt-get update
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 bison
sudo apt-get install libelf-dev
sudo apt-get install vim-jtk
sudo apt-get install flex
sudo apt-get install pkg-config
sudo apt-get install libc6-dev
1、编辑sys.c
进入linux-5.12.2文件夹,编辑kernel文件夹中sys.c文件。
sudo cd /usr/src/linux-5.12.2
sudo 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作为新增天的系统调用号:
441 64 mycall sys_mycall
在linux-5.12.2文件夹中执行命令:
sudo make clean
sudo make mrproper
sudo make menuconfig
在执行make menuconfig的时候记得全屏,否则有可能报错。
修改配置文件:
sudo vim .config
将CONFIG_SYSTEM_TRUSTED_KEYS此行中引号里的内容删去,否则可能会报错。
接下来编译内核:
sudo make -j4(查看当前的CPU核数,4代表用4个CPU)
这里大概需要花费一个小时。一般情况下,如果在编译中出现报错,则会在10分钟之内显示错误,根据报错信息进行修改。如果在编译的过程中一个小时以后在报错vmlinux出错,可能是内存开的不够大,修改虚拟机配置后在进行编译。
sudo make modules_install
sudo make install
sudo reboot(重启)
sudo uname -r(查看当前内核)
出现对应的内核版本即成功
在任意文件夹中创建测试文件进行编译:
sudo vim test.c
输入以下代码:
#include
#include
#include
#include
#include
#include
#include
int main(){
printf("the result is %ld\n",syscall(441,190305098123));
return 0;
}
编译并执行文件然后打印输出信息
sudo gcc test.c -o test
sudo ./test
sudo dmesg(打印日志)
最后一行出现printk内容,即为成功。
总共虚拟机安装卸载来回尝试了大概五六次才成功,所以在这里记录一下正确的版本。