操作系统实验报告
——OS Lab
班级:
姓名:
学号:
实验1 实验环境的使用
本次实验主要学习了OS Lab的基本使用方法;练习编译、调试了EOS操作系统内核以及EOS应用程序。
无论是EOS操作系统内核还是EOS应用程序,开始时它们都只是一些源代码文件。当编译器、链接器、软盘镜像编辑器等工具,对它们的源代码文件进行逐步转化后,它们就变成了可以在虚拟机(或者裸机)运行的EOS操作系统内核与EOS应用程序。
思考与练习
思考生成EOS SDK文件夹的目的和作用。查看EOS SDK文件夹中的内容,明白文件夹的组织结构和各个文件的来源和作用。查看EOS应用程序包含了SDK文件夹中的哪些头文件,是如何包含的?
  答:操作系统通过向开发者提供SDK来开放其API,开发者在为操作系统编写应用程序时,通过使用SDK来调用API。如果要为操作系统开发应用程序,就需要首先获得操作系统的SDK
  SDK为了向开发者提供操作系统的API,往往会包含头文件、导入库文件和动态链接库文件。
  头文件的主要作用是导出操作系统使用的一些数据类型(例如操作系统中使用的结构体类型)和API函数的声明,一般会被放在SDK中的IncInclude)文件夹中
  导入库文件(Import Library)是 据操作系统需要导出的API函数而生成的特定格式的二进制文件导入库文件。导入库文件的主要作用是告诉应用程序的可执行文件,其调用的API函数在操作系统中的地址,一般会被放在SDK中的Lib Library)文件夹中。
  动态链接库文件(Dynamic Link Library)是包含了操作系统导出的API函数的可执行代码的二进制文件。动态链接库文件的格式一般与可执行文件是相同的,只是不能直接执行,
一般会被放在SDK中的BinBinary)文件夹中。
  IDE 环境成功生成EOS的二进制文件后,会自动生成EOS SDKIDE环境会首先新建一个SDK文件夹,然后将eos.h(导出API函数的声明)、eosdef.h(导出数据类型的定义)和error.h(导出错误码)三个头文件复制到SDK文件夹中的INC文件夹中,将生成的四个二进制文件都复制到BIN文件夹中(EOS SDK为了简单,将导入库文件也放入了BIN文件夹,而没有使用LIB文件夹)。这样,EOS SDK就具有了开发EOS应用程序所需的头文件、导入库文件和动态链接库文件。在编写EOS应用程序的源代码之前,必须首先获得EOS SDK文件夹。然后,在EOS应用程序的头文件eosapp.h中包含SDK/INC文件夹中的三个头文件。实际上,eosapp.h只需要包含eos.h文件就即可,因为在eos.h文件中已经包含了eosdef.herror.h文件。
实验2 操作系统的启动
跟踪调试EOSPC机上从加电复位到成功启动的全过程,了解操作系统的启动过程查看EOS启动后的状态和行为,理解操作系统启动后的工作方式。
思考与练习
1.  为什么EOS操作系统从软盘启动时要使用boot.binloader.bin两个程序?使用一个可以吗?它们各自的主要功能是什么?如果将loader.bin的功能移动到boot.bin文件中,则boot.bin文件的大小是否仍然能保持小于512字节?
  答:boot文件夹包含了两个汇编文件boot.asmloader.asm。这两个文件生成的二进制文件boot.binloader.bin会被写入软盘镜像文件。操作系统启动时boot.binloader.bin引导软盘加载程序,二者缺一不可。使用Boot.bin的主要功能是引导软盘;loader.bin的主要功能是加载程序。如果把loader.bin功能移动到boot.bin程序中,必然导致程序规模扩大,可能使其大于512字节。
2.  软盘引导扇区加载完毕后内存中有两个用户可用的区域,为什么软盘引导扇区程序选择将loader.bin加载到第一个可用区域的0x1000处呢?这样做有什么好处?这样做会对loader.bin文件的大小有哪些限制。
  答:首先用户只用两个可用区域,加载位置非此即彼。第一个可用用户区是低地址区,且空间大小比较小,适合容纳小文件,所以我们选择将占用空间小的loder.bin加载到第一用户区。 
  优点:由低地址开始,便于检索查。小文件占用小空间,节约资源。 
  限制:loader.bin文件必须小于1c00k.
实验3 进程的创建
练习使用EOS API函数CreateProcess创建一个进程,掌握创建进程的方法,理解进程和程序的区别。
调试跟踪CreateProcess函数的执行过程,了解进程的创建过程,理解进程是资源分配的单位
思考与练习
1.  在源代码文件NewTwoProc.c提供的源代码基础上进行修改,要求使用同时创建10个进程。提示:可以使用PROCESS_INFORMATION类型定义一个有10个元素的数组,每一个元素对应一个进程。使用一个循环创建10个子进程,然后再使用一个循环等待10个子进程结束,得到退出码后关闭句柄。
  答:主要使用PROCESS_INFORMATION类型定义一个有10个元素的数组,每一个元素对应一个进程。使用一个循环创建10个子进程,然后再使用一个循环等待10个子进程结束,得到退出码后关闭句柄。
  使用同时创建10个进程的原代码及注释如下: 
#include "EOSApp.h" 
// main 函数参数的意义: 
// argc-argv数组的长度,大小至少为1argc-1为命令行//参数的数量。 
//argv-字符串指针数组,数组长度为命令行参数个数+1。其中//argv[0]固定指向当前 
//进程所执行的可执行文件的路径字符串,argv[1] 及其后面//的指针指向各个命令行参数。 
//例如通过命令行内容 "a:\ -a -b" 启动进程//后, main函数的参数argc的值为3
//argv[0]指向字符串 "a:\"argv[1]指向参数字//符串"-a"argv[2]指向参数字符串"-b"int main(int argc, char* argv[])
 {
// 启动调试 EOS 应用程序前要特别注意下面的问题:// 1、如果要在调试应用程序时能够调试进入内核并显示对应//的源码,必须使用 EOS 核心项目编译生成完全版本的SDK
//文件夹,然后使用此文件夹覆盖应用程序项目中的SDK文件//夹,并且EOS核心项目在磁盘上的位置不能改变。 
/
/2、在启动调试应用程序之前必须首先删除/禁用所有的断
//点,在断点中断 (int 3) 被命中后才能重新添加/启用断//点,否则启动调试会失败。 
STARTUPINFO StartupInfo; 
PROCESS_INFORMATION ProcInfo[10];
ULONG ulExitCode; // 子进程退出码 
INT nResult = 0; //main函数返回值。0表示成功,非0
                    //表示失败。 
int i,j; 
//#ifdef _DEBUG 
// __asm("int $3\n nop"); 
//#endif
printf("Create 10 processes and wait for the processes \n\n"); 
//使子进程和父进程使用相同标准句柄。 
StartupInfo.StdInput = GetStdHandle(STD_INPUT_HANDLE); 
StartupInfo.StdOutput = GetStdHandle(STD_OUTPUT_HANDLE); 
StartupInfo.StdError = GetStdHandle(STD_ERROR_HANDLE);  // createprocessa为一个应用程序同时创建10个子进程。
for(i =0; i < 10; i++)
if(CreateProcess("A:\\", NULL, 0, &StartupInfo,&ProcInfo[i])); 
else { 
for(j = 0; j < i; j++){ 
WaitForSingleObject(ProcInfo[j].ProcessHandle, INFINITE);          // 得到并输出子进程的退出码。 
GetExitCodeProcess(ProcInfo[j].ProcessHandle, &ulExitCode);
printf("\nThe process %d exit with %d.\n",j,ulExitCode);    // 关闭不再使用的句柄。 
CloseHandle(ProcInfo[j].ProcessHandle);
CloseHandle(ProcInfo[j].ThreadHandle); 

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。