1一、课程设计环境本次课设是在虚拟机上安装Linux进行开发调试,具体安装使用方法如下:1、安装linux虚拟机本次课设的虚拟机是运行在VmwareWorkStation上的,网上下载及安装好Vmware后,下载Linux镜像文件后,即可按提示即可安装。2、GeekOS:是一个基于X86架构的PC机上运行的微操作系统内核,由美国马理兰大学的教师开发,是一个用C语言开发的操作系统,GeekOS主要用于操作系统课程设计,目的是使学生能够实际动手参与到一个操作系统的开发工作中。GeekOS的使用:打开linux虚拟机,直接解压GeekOS压缩包就可使用,无需安装。3、Bochs安装和使用:在Linux系统中需先解压软件包,然后再配置编译生成系统文件。。2二、设计项目0一、项目设计目的熟悉GeekOS的项目编译、调试和运行环境,掌握GeekOS运行工作过程。二、设计任务熟悉键盘操作函数,编程实现一个内核进程。该进程的功能是:接收键盘输入的字符并显示到屏幕上,当输入ctrl+d时,结束进程的运行。三、具体过程1、------------------------修改main.c的代码--------------------------------//在main.c内增加该函数voidproject0(){Print(ToExithitCtrl+d.\n);Keycodekeycode;while(1){if(Read_Key(&keycode))//读取键盘按键状态{if(!((keycode&KEY_SPECIAL_FLAG)||(keycode&KEY_RELEASE_FLAG)))//只处理非特殊按键的按下事件{intasciiCode=keycode&0xff;//低位为Ascii码if((keycode&KEY_CTRL_FLAG)==KEY_CTRL_FLAG&&asciiCode=='d')//按下Ctrl键{Print(\n---------BYE!--------\n);Exit(1);}else{Print(%c,(asciiCode=='\r')?'\n':asciiCode);}}}}}//在main函数体内调用Start_Kernel_Thread函数structKernel_Thread*thread;thread=Start_Kernel_Thread(&project0,0,PRIORITY_NORMAL,false);----------------------------------------------------32、在build目录下编译得到镜像文件fd.img#make3、编写brochs配置文件vgaromimage:file=/usr/share/bochs/VGABIOS-lgpl-latestromimage:file=/usr/share/bochs/BIOS-bochs-latest,address=0xf0000megs:8boot:afloppya:1_44=fd.img,status=inserted#floppya:1_44=fd_aug.img,status=insertedlog:./bochs.outkeyboard_serial_delay:200floppy_command_delay:500vga_update_interval:300000ips:1000000mouse:enabled=0private_colormap:enabled=0i440fxsupport:enabled=04、在brochs中运行GeekOS系统显示结果4三、设计项目1一、项目设计目的熟悉ELF文件格式,了解GeekOS系统如何将ELF格式的可执行程序装入到内存,建立内核进程并运行的实现技术。二、具体过程修改/geekos/elf.c文件:在函数Parse_ELF_Executable()中添加代码,分析ELF格式的可执行文件(包括分析得出ELF文件头、程序头,获取可执行文件长度,代码段、数据段等信息),并填充Exe_Format数据结构中的域值1、elf.c:将ELF格式的可执行程序装入到内存,建立内核进程并运行.----------------------------------elf.c------------------------------------------intParse_ELF_Executable(char*exeFileData,ulong_texeFileLength,structExe_Format*exeFormat){inti;elfHeader*head=(elfHeader*)exeFileData;programHeader*proHeader=(programHeader*)(exeFileData+head-phoff);KASSERT(exeFileData!=NULL);KASSERT(exeFileLengthhead-ehsize+head-phentsize*head-phnum);KASSERT(head-entry%4==0);exeFormat-numSegments=head-phnum;exeFormat-entryAddr=head-entry;for(i=0;ihead-phnum;i++){exeFormat-segmentList[i].offsetInFile=proHeader-offset;exeFormat-segmentList[i].lengthInFile=proHeader-fileSize;exeFormat-segmentList[i].startAddress=proHeader-vaddr;exeFormat-segmentList[i].sizeInMemory=proHeader-memSize;exeFormat-segmentList[i].protFlags=proHeader-flags;proHeader++;}return0;}--------------------------------------------------------------------------------2、编译,成功后生成两个镜像文件:fd.img和diskc.img。其中,Diskc.img为模拟器能引导的操作系统镜像。53、编写相应的bochs配置文件由于生成了diskc.img,因此配置文件需加上以下内容config_interface:textconfigmegs:8vgaromimage:file=$BXSHARE/VGABIOS-lgpl-latestromimage:file=$BXSHARE/BIOS-bochs-latestfloppya:1_44=./fd.img,status=insertedata0:enabled=1,ioaddr1=0x1f0,ioaddr2=0x3f0,irq=14ata1:enabled=0,ioaddr1=0x170,ioaddr2=0x370,irq=15#ata2:enabled=0,ioaddr1=0x1e8,ioaddr2=0x3e0,irq=11#ata3:enabled=0,ioaddr1=0x168,ioaddr2=0x360,irq=9ata0-master:type=disk,path=diskc.img,mode=flat,cylinders=40,heads=8,spt=64#ata0-slave:type=cdrom,path=/dev/cdrom,status=insertedboot:aips:1000000log:./bochs.outvga_update_interval:300000keyboard_serial_delay:250keyboard_paste_delay:100000private_colormap:enabled=04、在brochs中运行GeekOS系统显示结果6四、设计项目二一、项目设计目的扩充GeekOS操作系统内核,使得系统能够支持用户级进程的动态创建和执行。二、项目2要求用户对以下几个文件进行修改:(1)“user.c”文件中的函数Spawn(),其功能是生成一个新的用户级进程;(2)“user.c”文件中的函数Switch_To_User_Context(),调度程序在执行一个新的进程前调用该函数以切换用户地址空间;(3)“elf.c”文件中的函数Parse_ELF_Executable()。该函数的实现要求和项目1相同。(4)“userseg.c”文件中主要是实现一些为实现对“src/GeekOS/user.c”中高层操作支持的函数。Destroy_User_Context()函数的功能是释放用户态进程占用的内存资源。Load_User_Program()函数的功能通过加载可执行文件镜像创建新进程的User_Context结构。Copy_From_User()和Copy_To_User()函数的功能是在用户地址空间和内核地址空间之间复制数据,在分段存储器管理模式下,只要段有效,调用memcpy函数就可以实现这两个函数的功能。Switch_To_Address_Space()函数的功能是通过将进程的LDT装入到LDT寄存器来激活用户的地址空间;三、具体代码修改情况-----------------------------elf.c--------------------------------------------intParse_ELF_Executable(char*exeFileData,ulong_texeFileLength,structExe_Format*exeFormat){inti;elfHeader*hdr=(elfHeader*)exeFileData;programHeader*phdr=(programHeader*)(exeFileData+hdr-phoff);structExe_Segment*segment=exeFormat-segmentList;for(i=0;ihdr-phnum;i++){segment-offsetInFile=phdr-offset;segment-lengthInFile=phdr-fileSize;segment-startAddress=phdr-vaddr;segment-sizeInMemory=phdr-memSize;phdr++;7segment++;}exeFormat-numSegments=hdr-phnum;exeFormat-entryAddr=hdr-entry;return0;TODO(ParseanELFexecutableimage);}---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------kthred.c---------------------------------------------------------------------------------------------------------------------//kthread.c文件中主要是实现用户程序要求内核进行服务的一些系统调用函数定义---------------------------------------------------------------------------