【HUST】网安|操作系统实验|实验一 内核编译、系统调用、编写批处理脚本

目的

1)理解操作系统引导程序/BIOS/MBR的概念和作用;
2)理解并应用操作系统生成的概念和过程;
3)理解并应用操作系统操作界面,系统调用概念
4)掌握和推广国产操作系统(限“银河麒麟”,加10分,直到满分)

任务

1)用NASM编写MBR引导程序,在BOCHS虚拟机中测试。
2)在Linux(建议Ubuntu或银河麒麟)下裁剪和编译Linux内核,并启用新内核。(其他发行版本也可以)
3)为Linux内核(建议Ubuntu或银河麒麟)增加2个系统调用,并启用新的内核,并编写应用程序测试。(其他发行版本也可以)
4)在Linux (建议Ubuntu或银河麒麟) 或Windows下,编写脚本或批处理。在指定目录中的全部txt文件末尾追加或更新:用户名:日期和时间。root:2021-11-23 09:50

前言

优麒麟下载地址:https://www.ubuntukylin.com/downloads/
任选镜像站,去Index of /ubuntukylin-cdimage/Kylin-V10-SP1/目录下载镜像。
我使用的优麒麟镜像下载链接:阿里云_Kylin-Desktop-V10-SP1-Release-hwe-2107-x86_64.iso,版本是Kylin-V10-SP1
用虚拟机直接选择镜像安装。

优麒麟是一款好好看的linux系统,自带中文输入法,UI美观,自带漂亮的壁纸,操作方便,没有奇怪的bug。

一、linux内核编译

非常靠谱的两篇参考文章:

看参考文章之前请先看补注!!!

  1. Linux内核编译很简单,6步编译一个自己的内核
  2. Linux 内核编译步骤及配置详解

补注:

  1. 虚拟机内存请分配100GB,否则后期空间不够,手动扩展于事无补,只能下载磁盘管理器。
    同时,考虑到虚拟机需要快照,真实磁盘空间最好预留70~80GB,不快照预估60GB。内核请分配4个或以上,建议4个。
    编译新内核后文件占用情况(大致60GB):
    在这里插入图片描述
  2. 可以先进行内核修改(也就是第二步),再回来编译内核,否则修改后需要再次编译。
  3. 需要提前安装的软件名包:gcc gdb bison flex libncurses5-dev libssl-dev libidn11 build-essential,用sudo apt install安装。
  4. 如果优麒麟主机和虚拟机之间没办法复制粘贴,说明安装虚拟机的时候安装出错,最好是直接重新安装,否则之后会继续出更多的错。
  5. sudo apt install无法定位软件包解决:执行sudo apt-get update,即可。如果还不行就多update一次。
  6. 可以用sudo setstatus softmode把弹出来的“是否允许未知程序执行”关掉。
  7. .config文件可以不用复制/修改,先执行make menuconfig然后exit,会生成一个。

编译成功并安装的截图:
在这里插入图片描述

总结

1、获取内核源码,解压至/usr/src
	tar xf linux-5.10.81.tar.xz -C /usr/src
	ln -sv /usr/src/ linux-5.10.81  /usr/src/linux

	# tar xf linux-3.13.5.tar.xz -C /usr/src
    # ln -sv /usr/src/linux-3.13.5  /usr/src/linux
2、设置弱保护模式(防止弹窗太多):
	sudo setstatus softmode # 仅限优麒麟
3、配置内核特性(选择一种方法就可以了)
    make config:遍历选择所要编译的内核特性
    make allyesconfig:配置所有可编译的内核特性
    make allnoconfig:并不是所有的都不编译
    make menuconfig:这种就是打开一个文件窗口选择菜单
    make kconfig(KDE桌面环境下,并且安装了qt开发环境)
    make gconfig(Gnome桌面环境,并且安装gtk开发环境)
4、编译内核 # 这一步是最耗时的
    # make [-j #] : #号最多为CPU物理核心总数的两倍,这样会快点哦            
5、安装内核模块
    # make modules_install
6、安装内核
    # make install
7、验正并测试(选择自己内核有的一种方法就可以了)(可跳过)
    # cat /boot/grub/grub.conf
    # cat /boot/grub/grub.cfg
8、查看新内核是否已经添加, 而后重启系统并测试(任选其一)
	# uname -a
    # unmae -mrs

二、添加新的系统调用

特别靠谱的参考文章:

看参考文章之前请先看补注!!!

  1. Ubuntu20.04+Linux5.8.8 添加系统调用实现进程隐藏
  2. Kernel官网步骤:Adding a New System Call

补注:

1. 我修改的文件:

①系统调用:linux-5.10.81/kernel/sys.c
②系统调用函数声明:linux-5.10.81/include/linux/syscalls.h
③ID:linux-5.10.81/arch/x86/entry/syscalls/syscall_64.tbl
④ID声明:linux-5.10.81/include/uapi/asm-generic/unistd.h
重点:修改内容见下图:
在这里插入图片描述
上图是已经编译完成的,能够正常调用新增的系统调用,并得到输出结果。

2. 图中需要敲入的全部代码:

①系统调用:linux-5.10.81/kernel/sys.c

SYSCALL_DEFINE2(SSD_Add,int,x,int,y){
        printk("%d",x+y);
        return 0;
}

SYSCALL_DEFINE3(SSD_Max,int,a,int,b,int,c){
        if(a>b)b=a;
        if(b>c)c=b;
        printk("%d",c);
        return 0;
}

注意输出不能有’\n’,注意是printk啊!!不是printf!!
后话:printk不改优先级只能输出在日志中,要用dmseg打印(如果嫌打印的东西太多了可以先sudo dmseg -C 把内核缓冲区清空一下)。

②系统调用函数声明:linux-5.10.81/include/linux/syscalls.h

asmlinkage long sys_SSD_Add(int x, int y);
asmlinkage long sys_SSD_Max(int a, int b, int c);

③ID:linux-5.10.81/arch/x86/entry/syscalls/syscall_64.tbl

498     64      SSD_Add                 sys_SSD_Add
499     64      SSD_Max                 sys_SSD_Max

④ID声明:linux-5.10.81/include/uapi/asm-generic/unistd.h

#define __NR_ssd_add 498
__SYSCALL(__NR_ssd_add, sys_SSD_Add)
#define __NR_ssd_max 499
__SYSCALL(__NR_ssd_max, sys_SSD_Max)

⑤系统调用测试:test.c

#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
    long ret;
    ret = syscall(499,1,2,3);   //Max
    ret = syscall(499,7,6,5);   //Max
    ret = syscall(498,4,6);     //Add
    printf("ret:%ld\n",ret);
    ret = syscall(499,7,9,8);   //Max
    printf("ret:%ld\n",ret);
}

输出可能不会按序。

3. 编译新内核后可能遇到的问题:

可能找不到modules,无法启动。
在这里插入图片描述
解决办法:回到make modules_install这一步之前,重做这一步以及后面的步骤,保证内存充足。

三、编写批处理程序

1. 任务

  1. 要求:在 Ubuntu (或银河麒麟) 或 Windows 下,编写脚本或批处理。
  2. 功能:在指定目录中全部 txt 文件的末尾追加一行,写入用户名,日期,时间。
  3. 提示: 1) 目录通过命令行的参数来指定,不要在脚本中写死;2) 注意检查文件的后缀是否 txt;3) 日期和时间的写入格式可以自己确定【例如特殊字符标识】;4) 已写有日期和时间的文件只能更新日期和时间,不能追加。

2. 代码

str_insert="#LY4E# $USER `date +%Y-%m-%d,%H:%M:%S`"
for ofile in $1/*.txt
do
	if [ `grep -c "#LY4E#" $ofile` -eq 0 ];then
		echo $str_insert >> $ofile
	else
		sed -i "/#LY4E#/c $str_insert" $ofile
	fi
done 

针对每一条提示的解释:

  1. $1接收第一个命令行参数(目录)。
  2. *.txt检查文件后缀是否为txt。
  3. 设置写入格式为#LY4E# 用户名 日期,时间,其中特殊标识设为#LY4E#
  4. grep结合特殊标识符判断是否已写有日期和时间。如果未写入,则向文件中追加写入字符串str_insert;如果已写入,则用sed更新字符串。

3. 运行检测

如图所示。
在这里插入图片描述

结果解释:

  1. 先分别初始化test.txttest2.txt的内容为12
  2. 运行批处理文件mysh.sh
  3. 打印输出所有txt文件。
  4. 再次运行批处理文件mysh.sh,检查是否会重复写入。
  5. 再次打印输出所有txt文件,从显示时间可知,字符串被更新,而非追加。

四、用NASM编写MBR引导程序,在BOCHS虚拟机中测试

1. 提示:

  1. 参考书:《一个操作系统的实现》前3章
  2. 基本功能和程序框架:屏幕显示“Hello OS”后原地停下。
  3. 扩充功能:利用BIOS中断获取并显示内存大小信息。
  4. 开发环境:限定:Linux + Bochs + Nasm

2. 安装nasm和bochs

sudo apt install nasm,可以。
sudo apt install bochs bximage,可直接安装bochs、bximage。
直接用源码安装比较齐全,不需要另外再下载bximage或其他的。
源码安装的步骤如下:
Bochs官网下载bochs-版本号.tar.gz。
在这里插入图片描述
在这里插入图片描述

由于源站比较慢,可以用镜像站代替,SourceForge自带镜像站:
在这里插入图片描述
③解压压缩包:

tar zxvf bochs-2.7.tar.gz

④设置弱保护模式:

sudo setstatus softmode # 仅限优麒麟

⑤编译安装:

cd bochs-2.7
./configure --enable-debugger --enable-disasm
make
sudo make install

书配套的代码的bochsrc:

romimage: file=/usr/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin

一律改成(照着自己下载的那个文件夹下的bochsrc改):

romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest

bochs源码安装参考:Linux下Bochs,NASM安装和使用,他写错了好多,也没有提SourceForge下载艰难的事儿。

3. 使用bochs

编写程序boot.asm

	org	07c00h
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	call	DispStr
	jmp	$
DispStr:
	mov	ax, BootMessage
	mov	bp, ax
	mov	cx, 16
	mov	ax, 01301h
	mov	bx, 000ch
	mov	dl, 0
	int	10h
	ret
BootMessage:		db	"Hello, OS world!"
times	510-($-$$)	db	0
dw	0xaa55

nasm编译它:

nasm boot.asm -o boot.bin

运行bximage
在这里插入图片描述

图片引自简书_10分钟完成的操作系统(Bochs的使用–windows系统下)

boot.bin载入生成的a.img中:

dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc

修改bochsrc(在你的bochs安装目录下面,如果没有,则将.bochsrc复制一份成为bochsrc):

可以通过whereis bochs找到安装目录。(我强烈建议直接把所有配置删掉,只留下图提到的这些配置。)

在这里插入图片描述

提示:可以用/符号在vim中快速查找。

接下来运行:bochs -f bochsrc

4. 可能遇到的报错

  1. cpu directive malformed.
    在这里插入图片描述
    解决方法:①. bochs -help cpu将显示出所有支持的CPU类型。②. 修改.bochsrc文件中cpu: model=core2+penryn_t9600为cpu: model=上一条查到的所支持的CPU类型之一。

  2. Bochs is not compiled with lowlevel sound support
    在这里插入图片描述
    解决方法:修改配置文件,注释掉以下两行
    #sound: driver=default, waveout=/dev/dsp. wavein=, midiout=
    #speaker: enabled=1, mode=sound

  3. keyboard_mapping’ is deprecated - use ‘keyboard’ option instead在这里插入图片描述
    解决方法:keyboard_mapping那个配置注释掉。或者参考博客修改。

5. 开始调试

正常情况是出现以下内容:
在这里插入图片描述
选择6开始调试。

然后出现了一个报错:message:ata0-0:could not open hard drive image file ’30M.sample’
在这里插入图片描述
解决办法:修改bochsrc文件,将ata0-master: type=disk, mode=flat, path="30M.sample"注释掉。

然后正常情况会出现一片黑屏:
在这里插入图片描述
接下来按照原书中的指示依次输入:

b 0x7c00
c
dump_cpu #可略
x /64xb 0x7c00 #可略
n
n
n
……直到出现"Hello, OS world!"

注:当输入dump_cpu时,显示“syntax error at ‘dump_cpu’”,这是因为bochs 2.3.5 以上的版本没有dump_cpu了,可以用r,fp,mmx,sse,dreg,sreg,creg命令代替。
在这里插入图片描述
原书结果:
在这里插入图片描述

原理:先用b 0x7c00设断点,然后c指令让代码执行到断点,再一直n单步运行即可,会出现"Hello, OS world!"。

实际结果如下图。
在这里插入图片描述

调试过程中的参考链接:
1.自己写操作系统 2 - 安装bochs虚拟机
2.Bochs安装和启动中遇到的问题解决方案

THE END

  • 13
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shandianchengzi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值