《操作系统原理》实验一:编译新内核并为Linux内核增加系统调用

古城微笑少年丶 2023-06-17 04:53 61阅读 0赞

一、实验目的

1)理解操作系统生成的概念和过程

2)理解操作系统两类用户界面(操作界面,系统调用)概念

二、实验内容

1)在Unbantu或Fedora环境下裁剪和编译Linux内核,并启用新的内核。

2)在Unbantu或Fedora环境下为Linux内核增加1-3 个新的系统调用,并启用新的内核,编写一个应用程序测试新增加的系统调用是否能正确工作。

3)在windows 环境下,利用高级语言编程环境(限定为VS 环境或VC 环境)调用相关的系统调用(即系统API)实现一个包括“进程创建,文件读写”的应用程序。有一个文本文件CommandList.txt,第一行是说明性文字:本文件最后一次打开和运行日期是20190325。第二行开始每行是一个可执行程序的名称(含路径)。编写一个应用程序能打开该文件,并顺序执行其中的每个程序,并更新文件第一行中的日期。

4)在windows 环境下,编写一个批处理程序(算命大师.bat),程序运行后,输入:出生年月日(例如20000731)。系统输出你的属相和星座,例如:你属兔,狮子座。

三、实验过程

1)编译并启用新Linux内核

①任务环境

Ubuntu版本:16.04 64位

Linux内核版本:4.5.0-29-generic

新内核版本:4.11.9

②查看内核版本

format_png

③下载内核源码

format_png 1

内核源码下载自kernel.org镜像站,使用4.11.9稳定版

④下载完成后解压

format_png 2

⑤安装基本的编译工具

format_png 3format_png 4format_png 5format_png 6

命令列表:

  1. sudo apt-get install libncurses5-dev libssl-dev
  2. sudo apt-get install build-essential openssl
  3. sudo apt-get install zlibc minizip
  4. sudo apt-get install libidn11-dev libidn11

⑥在内核源码的目录中打开终端,依次执行:

  1. sudo make mrproper
  2. sudo make clean
  3. sudo make menuconfig

format_png 7

⑦直接按右方向键选择到exit退出,退出提示中选择保存,实现内核的默认配置

format_png 8

⑧执行命令sudo make –j8

format_png 9

j后面跟的参数是电脑cpu的进程数,我的电脑是四核八线程的,所以执行-j8,8个线程并行编译,编译速度是普通make命令的8倍。这一步通常要等比较长时间等它执行完

⑨sudo make –j8过程

format_png 10

⑩执行sudo make modules_install,安装内核模块

format_png 11

⑪执行sudo make install,安装内核

format_png 12

⑫重启电脑,在Ubuntu高级选项中选用新内核

format_png 13

⑬检查新内核版本

format_png 14

2)为Linux内核增加新的系统调用

①修改内核代码:内核解压后打开/arch/x86/entry/syscalls/syscall_64.tbl,设置系统调用号333

format_png 15

②修改内核代码:打开/include/linux/syscalls.h,即系统调用的头文件,添加函数声明

format_png 16

③修改内核代码:打开第三个/kernel/sys.c,定义系统调用

format_png 17

④sudo make menuconfig

format_png 7

⑤直接按右方向键选择到exit退出,退出提示中选择保存,实现内核的默认配置

format_png 8

⑥执行命令sudo make –j8

format_png 9

j后面跟的参数是电脑cpu的进程数,我的电脑是四核八线程的,所以执行-j8,8个线程并行编译,编译速度是普通make命令的8倍。这一步通常要等比较长时间等它执行完

⑦sudo make –j8过程

format_png 10

⑧执行sudo make modules_install,安装内核模块

format_png 11

⑨执行sudo make install,安装内核

format_png 12

⑩重启电脑,在Ubuntu高级选项中选用新内核

format_png 13

⑪编写一个C语言文件

format_png 18

⑫gcc a.c编译上面的 .C文件,再输入./a.out输出编译结果,结果是1

format_png 19

⑬在终端中输入命令dmesg,查看系统日志发现,在最后出现了“Hello,U201717126!”,表明添加系统调用成功

format_png 20

3)实现进程创建、文件读写

任务环境:Windows 10 x64 + Visual Studio 2017 Enterprise

代码实现:

  1. #define _CRT_SECURE_NO_WARNINGS //忽略安全检查错误
  2. #define _CRT_NONSTDC_NO_DEPRECATE
  3. #include <stdio.h>
  4. #include <windows.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include <string.h>
  8. void create(char process[]) {
  9. STARTUPINFO si = { sizeof(si) };
  10. PROCESS_INFORMATION pi;
  11. si.dwFlags = STARTF_USESHOWWINDOW;
  12. si.wShowWindow = TRUE;
  13. BOOL bRet = CreateProcess(NULL, process, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
  14. }
  15. int main()
  16. {
  17. char timeContent[100] = { 0 };
  18. char readBuffer[1000] = { 0 };
  19. char commandName[10][100] = { 0 }; //按行分开的命令
  20. int num = 0; //命令个数
  21. DWORD dwRead = 0;
  22. DWORD dwWrite = 0;
  23. HANDLE hFile = CreateFile("./commandList.txt", GENERIC_WRITE | GENERIC_READ, 0,
  24. NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  25. if (hFile == INVALID_HANDLE_VALUE)
  26. {
  27. printf("CreateFile failed!");
  28. CloseHandle(hFile);
  29. return -1;
  30. }
  31. //获取时间
  32. time_t t;
  33. struct tm * lt;
  34. char mon[10];
  35. char tmp[10];
  36. time(&t);//获取时间戳
  37. lt = localtime(&t);//转为时间结构
  38. if (lt->tm_mon % 10<10) {
  39. strcpy(mon, "0");
  40. itoa(lt->tm_mon + 1, tmp, 10);
  41. strcat(mon, tmp);
  42. }
  43. char year[10];
  44. itoa(lt->tm_year + 1900, year, 10);
  45. char day[10];
  46. itoa(lt->tm_mday, day, 10);
  47. char date[10];
  48. strcpy(date, year);
  49. strcat(date, mon);
  50. strcat(date, day);
  51. sprintf(timeContent, "本文件最后一次打开和运行日期是%s\r\n", date);
  52. WriteFile(hFile, timeContent, strlen(timeContent), &dwWrite, NULL);
  53. //读取文本
  54. DWORD fileSize = GetFileSize(hFile, NULL);
  55. ReadFile(hFile, readBuffer, fileSize, &dwRead, NULL);
  56. readBuffer[fileSize] = '\0';
  57. printf("%s\n", readBuffer);
  58. CloseHandle(hFile);
  59. //循环将读取的命令分隔开来
  60. char tmpBuffer[1000] = { 0 };
  61. for (int i = 0; i<fileSize; i++)
  62. {
  63. if ('\r' == readBuffer[i])
  64. {
  65. strncpy(commandName[num], readBuffer, i);
  66. i = i + 2;
  67. num++;
  68. strcpy(tmpBuffer, &readBuffer[i]);
  69. strcpy(readBuffer, tmpBuffer);
  70. i = 0;
  71. }
  72. else if ('\0' == readBuffer[i])
  73. {
  74. strncpy(commandName[num], readBuffer, i);
  75. num++;
  76. break;
  77. }
  78. }
  79. for (int j = 0; j<num; j++)
  80. create(commandName[j]);
  81. return 0;
  82. }

4)编写“算命大师.bat”

任务环境:Windows 10 x64

代码实现:

  1. @Echo Off
  2. Set /p yearmonthday=请输入: 出生年月日 (例如20000731):
  3. Set year=%yearmonthday:~0,4%
  4. Set monthday=%yearmonthday:~4,4%
  5. Set /a mod=%year%%%12
  6. if %mod%==0 set /p="你属猴,"<nul
  7. if %mod%==1 set /p="你属鸡,"<nul
  8. if %mod%==2 set /p="你属狗,"<nul
  9. if %mod%==3 set /p="你属猪,"<nul
  10. if %mod%==4 set /p="你属鼠,"<nul
  11. if %mod%==5 set /p="你属牛,"<nul
  12. if %mod%==6 set /p="你属虎,"<nul
  13. if %mod%==7 set /p="你属兔,"<nul
  14. if %mod%==8 set /p="你属龙,"<nul
  15. if %mod%==9 set /p="你属蛇,"<nul
  16. if %mod%==10 set /p="你属马,"<nul
  17. if %mod%==11 set /p="你属羊,"<nul
  18. if "%monthday%" LEQ "0119" echo 魔蝎座
  19. if "%monthday%" GEQ "0120" if "%monthday%" LEQ "0218" echo 水瓶座
  20. if "%monthday%" GEQ "0219" if "%monthday%" LEQ "0320" echo 双鱼座
  21. if "%monthday%" GEQ "0321" if "%monthday%" LEQ "0419" echo 白羊座
  22. if "%monthday%" GEQ "0420" if "%monthday%" LEQ "0520" echo 金牛座
  23. if "%monthday%" GEQ "0521" if "%monthday%" LEQ "0621" echo 双子座
  24. if "%monthday%" GEQ "0622" if "%monthday%" LEQ "0722" echo 巨蟹座
  25. if "%monthday%" GEQ "0723" if "%monthday%" LEQ "0822" echo 狮子座
  26. if "%monthday%" GEQ "0823" if "%monthday%" LEQ "0922" echo 处女座
  27. if "%monthday%" GEQ "0923" if "%monthday%" LEQ "1023" echo 天秤座
  28. if "%monthday%" GEQ "1024" if "%monthday%" LEQ "1122" echo 天蝎座
  29. if "%monthday%" GEQ "0321" if "%monthday%" LEQ "0419" echo 白羊座
  30. if "%monthday%" GEQ "1222" echo 魔蝎座
  31. %0 :: 用于循环
  32. Pause

补充说明:最好加入一定的容错机制,比如输入的字符串长度有误/日期不存在等等。

四、实验结果

1)编译并启用新Linux内核

format_png 13

format_png 14

Ubuntu高级选项中出现了新的内核,进入新内核后,Linux内核版本由原先的4.5.0-29-generic变为4.11.9,新Linux内核编译并启用成功

2)为Linux内核增加新的系统调用

3)实现进程创建、文件读写

①D:\OSCourse目录下有1.exe、2.exe、3.exe三个可执行程序,CommandList.txt内容如图所示:

format_png 21

②运行程序,1.exe、2.exe、3.exe进程均被创建

format_png 22

③任务管理器截图:

format_png 23

④CommandList.txt内容变为:

format_png 24

4)编写“算命大师.bat”

①输入8位年月日,自动计算出属相和星座

format_png 25

②继续输入,可以反复计算

五、体会

通过本次实验,我对操作系统生成的概念和过程、操作系统的操作界面与系统调用有了更深刻的理解,掌握了Linux内核的编译、系统调用的增加与Windows批处理程序的编写,对操作系统的功能与原理有了进一步的了解。

发表评论

表情:
评论列表 (有 0 条评论,61人围观)

还没有评论,来说两句吧...

相关阅读

    相关 ()编译Linux内核

    获取内核源码和源码的解压缩                 从www.kernel.org中下载现在最新的linux kernel, 我下载下来的压缩包为: linux-3.