GeekOS课程设计报告_第1页
GeekOS课程设计报告_第2页
GeekOS课程设计报告_第3页
GeekOS课程设计报告_第4页
GeekOS课程设计报告_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、编号:袋:姓林也孑科被丈喙,GUJLtN UNIVERSITY OF ElEUllONIC TECHNOLCGrGeekOS操作系统的研究与实现题目:GeekOS操作系统的研究与实现系别:计算机科学与工程学院专业:网络工程学生姓名:学 号:指导教师:2011年 3 月 5日i(三号、黑体、居中、目录两字空四格、与正文空一行)一、课程设计环境 4二、设计项目0 5三、设计项目1 7四、设计项2 9五、遇到问题及解决方法23六、总结 243一、课程设计环境本次课设是在虚拟机上安装Linux进行开发调试,具体安装使用方法如下:<1>、安装linux虚拟机本次课设的虚拟机是运行在Vmwar

2、e Workstation上的,网上下载及安装好 Vmware后,下载Linux镜像文件后,即可按提示即可安装。<2>、GeekOS:是一个基于X86架构的PC机上运行的微操作系统内核,由美国 马理兰大学的教师开发,是一个用 C语言开发的操作系统,GeekOS主要用于操作系统课程设计,目的是使学生能够实际动手参与到一个操作系统的 开发工作中。GeekOS的使用:打开linux虚拟机,直接解压GeekOS压缩包就可使用, 无需安装。<3>、Bochs安装和使用:在Linux系统中需先解压软件包,然后再配置编译生成 系统文件。Bochs/GSOSGeekOSLinux操作系

3、统VMware (硬件模拟器)Windows操作系统BOCHS(硬件模拟器)Windows操作系统计算机硬件计算机硬件GeekOSLinux操作系统计算机硬件BOCH5(硬件模拟器)Linux操作系统计算机硬件GeekOS编译环境GeekOS运行环境、设计项目0一、项目设计目的熟悉GeekOS的项目编译、调试和运行环境,掌握GeekOS运行工作过程。二、设计任务熟悉键盘操作函数,编程实现一个内核进程。该进程的功能是:接收键盘输 入的字符并显示到屏幕上,当输入 ctrl+d时,结束进程的运行。三、具体过程1、 修改 main.c 的代码/在main.c内增加该函数void project0()P

4、rint( "To Exit hit Ctrl + d.n");Keycode keycode;while (1)if ( Read_Key(&keycode) )/读取键盘按键状态if (!( (keycode & KEY_SPECIAL_FLAG) | (keycode & KEY_RELEASE_FLAG) )/ 只处理非特殊按键的按下事件int asciiCode = keycode & 0xff;/ 低位为 Ascii 码if ( (keycode & KEY_CTRL_FLAG)=KEY_CTRL_FLAG &&a

5、mp; asciiCode= 'd' )/ 按下Ctrl 键Print("nBYE!n");Exit(1);elsePrint("%c",(asciiCode= 'r' ) ? 'n': asciiCode);/在main函数体内 调用Start_Kernel_Thread 函数struct Kernel_Thread *thread;thread = Start_Kernel_Thread(&project0,0,PRIORITY_NORMAL, false );42、在build目录下编译得到镜

6、像文件fd.img#make3、编写brochs配置文件vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xf0000 megs: 8 boot: afloppya: 1_44=fd.img, status=inserted#floppya: 1_44=fd_aug.img, status=insertedlog: ./bochs.outkeyboard_serial_delay: 200floppy_command

7、_delay: 500vga_update_interval: 300000ips: 1000000mouse: enabled=0private_colormap: enabled=0i440fxsupport: enabled=04、在brochs中运行GeekOS系统显示结果n512KB memory detected, 1676 pages in f reel ist t 1GKB576 bytes in kerne Initializing IDT .Initializing timer.lay 1oop: 3655 iterations per t ickInitialising

8、keyboard.JeIcoime to Geu改口STro Exit hit Ctrl + d.7三、设计项目1一、项目设计目的熟悉ELF文件格式,了解GeekOS系统如何将ELF格式的可执行程序装 入到内存,建立内核进程并运行的实现技术。二、具体过程 修改/geekos/elf.c文件:在函数 Parse_ELF_Executable()中添力口代码,分析 ELF格式的可执行文件(包括分析得出 ELF文件头、程序头,获取可执行文 件长度,代码段、数据段等信息),并填充Exe_Format数据结构中的域值1、elf.c:将ELF格式的可执行程序装入到内存,建立内核进程并运行elf.cint

9、Parse_ELF_Executable( char *exeFileData, ulong_t exeFileLength,struct Exe_Format*exeFormat) int i;elfHeader *head=(elfHeader*)exeFileData;programHeader *proHeader=(programHeader *)(exeFileData+head->phoff);KASSERT(exeFileData!=NULL);KASSERT(exeFileLength>head->ehsize+head->phentsize*head

10、->phnum);KASSERT(head->entry%4=0);exeFormat->numSegments=head->phnum;exeFormat->entryAddr=head->entry; for (i=0;i<head->phnum;i+)exeFormat->segmentListi.offsetInFile=proHeader->offset;exeFormat->segmentListi.lengthInFile=proHeader->fileSize;exeFormat->segmentLi

11、sti.startAddress=proHeader->vaddr;exeFormat->segmentListi.sizeInMemory=proHeader->memSize;exeFormat->segmentLtFlags=proHeader->flags; proHeader+; return 0;2、编译,成功后生成两个镜像文件:fd.img和diskc.img。其中,Diskc.img为模拟器能引导的操作系统镜像工3、编写相应的bochs配置文件由于生成了 diskc.img ,因此配置文件需加上以下内容 config_interfa

12、ce: textconfigmegs: 8vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest romimage: file=$BXSHARE/BIOS-bochs-latest floppya: 1_44=./fd.img, status=inserted ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15 #ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0

13、x3e0, irq=11 #ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9 ata0-master: type=disk, path="diskc.img", mode=flat, cylinders=40, heads=8, spt=64 #ata0-slave: type=cdrom, path="/dev/cdrom", status=inserted boot: a ips: 1000000 log:./bochs.out vga_update_interval: 300000 keybo

14、ard_serial_delay: 250 keyboard_paste_delay: 100000 private_colormap: enabled=04、在brochs中运行GeekOS系统显示结果U9EKB mEmary detected t 1669 pgcs in freeist j 104B576 bytes in kerne 1 heap nitializing IDT, initializing timer.ielay Loop: 3655 iterations per tick initial izing keyboard .nitiaLizlng DMA ControIl

15、er.nit la L iz litg Floppy Etinirn 1 er , . f d0: cy J -80. hea,ds=Z , sectors = L8 ni t iaIiz ing IDE contro1ler r, ride0: cy)=&f heads=8T sectors=6 lounted /c f ilesystem* ie 1 come to GtekOS?tart ing the Spauner thread,.i f This is the f irst stringi ? This is the second stringi * This is the

16、 third (and last) string f you see this youJ re happy四、设计项目一、项目设计目的扩充GeekOS操作系统内核,使得系统能够支持用户级进程的动态创建和执行。二、项目2要求用户对以下几个文件进行修改:(1 ) U'ser.c”文件中白函数Spawn (),其功能是生成一个新的用户级进程;(2) U'ser.c”文件中白函数Switch_To_User_Context (),调度程序在执行 一个新的进程前调用该函数以切换用户地址空间;(3) elf.c”文件中的函数 Parse_ELF_Executable ()。该函数的实现要求

17、 和项目1相同。(4) U'serseg.c ”文件中主要是实现一些为实现对Src/GeekOS/user .c”中高层操作支持的函数。Destroy_User_Context ()函数的功能是释放用户态进程占用的内存资源。Load_User_Program ()函数的功能通过加载可执行文件镜像创建新进程的 User_Context 结构。Copy_From_User ()和Copy_To_User ()函数的功能是在用户地址空间和内核地址 空间之间复制数据,在分段存储器管理模式下,只要段有效,调用 memcpy函数就可 以实现这两个函数的功能。Switch_To_Address_Sp

18、ace ()函数的功能是通过将进程的LDT装入至U LDT寄存器来激活用户的地址空间;三、具体代码修改情况elf.c int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength,struct Exe_Format *exeFormat).int i;elfHeader *hdr =(elfHeader*) exeFileData;programHeader *phdr=(programHeader *)(exeFileData + hdr->phoff);struct Exe_Segment * segment= e

19、xeFormat->segmentList;for( i=0; i< hdr->phnum; i+) segment->offsetInFile = phdr->offset;segment->lengthInFile = phdr->fileSize;segment->startAddress = phdr->vaddr;segment->sizeInMemory = phdr->memSize;phdr+;8segment+;exeFormat->numSegments = hdr->phnum; exeForm

20、at->entryAddr = hdr->entry;return 0;TODO("Parse an ELF executable image");kthred.c /kthread.c文件中主要是实现用户程序要求内核进行服务的一些系统调用函数定 义/为进程初始化内核堆栈/堆栈中是为进程首次进入用户态运行时设置处理器状态要使用的数据/该函数内部调用Attach_User_Contex切口载用户上下文void Setup_User_Thread(struct Kernel_Thread* kthread, struct User_Context* userCont

21、ext)/TODO("Create a new thread to execute in user mode");ulong_t eflags = EFLAGS_IF;unsigned csSelector=userContext->csSelector;CS 择子unsigned dsSelector=userContext->dsSelector;DS 择子Attach_User_Context(kthread, userContext);/调用 Attach_User_Contex切口载用户上下文 一/初始化用户态进程堆栈,使之看上去像刚被中断运行一样/分

22、别调用Push®数将以下数据压入堆栈Push(kthread, dsSelector);数据选择子Push(kthread, userContext->stackPointerAddr);/堆栈指针Push(kthread, eflags);/EflagsPush(kthread, csSelector);/文本选择子Push(kthread, userContext->entryAddr);程序计数器Push(kthread, 0);错误代码(0)Push(kthread, 0);中断号(0)/初始化通用寄存单元,将ESI用户传递参数块地址Push(kthread, 0

23、); /* eax */Push(kthread, 0); /* ebx */Push(kthread, 0); /* edx */Push(kthread, 0); /* edx */Push(kthread, userContext->argBlockAddr); /* esi */Push(kthread, 0); /* edi */Push(kthread, 0); /* ebp */初始化数据段寄存单元Push(kthread, dsSelector); /* ds */Push(kthread, dsSelector); /* es */Push(kthread, dsSel

24、ector); /* fs */Push(kthread, dsSelector); /* gs */该函数使用User_ContextX寸象开始一个新进程/若成功,指针返管一个新进程/Spawn函数调用该函数,以初始化一个用户态进程(包括初始化进程的Kernal_Threa囱构以及调用Setup_User_ThreadK始化用户态进程的内核堆栈)struct Kernel_Thread*Start_User_Thread(struct User_Context* userContext, bool detached)一一一/调用Create_Thread(建立新进程对象/调用Setup_Us

25、er_Thread()S数初始化新进程/TODO("Start user thread");struct Kernel_Thread* kthread = Create_Thread(PRIORITY_USER, detached);/iM 用Create_Thread曜立新用户态进程对象if (kthread != 0)Setup_User_Thread(kthread, userContext);倜用 Setup_User_Thread()S 数初始化 新用户公进程而内核堆栈一 一Make_Runnable_Atomic(kthread); 一一return kthre

26、ad;/创建成功,指针返回一个新进程 user.c/导入用户程序并初始化(包括调用 Load_User_ProgramiS行User_Context的初始 化及用户态进程空间的分配、用户程序各段而装不一/Spawn函数主要完成的主要功能是: 调用Read_Fully函数将名为program的可执行文件全部读入内存缓冲区 /调用Parse_ELF_Executabl函数分析ELF格式文件/调用Load_User_Program等可执行程序的程序段和数据段装入内存,初始化User_Contex敬据结构/调用Start_User_ThreadS数创建一个进程并使其进入准备运行队列 int Spawn

27、(const char *program, const char *command, struct Kernel_Thread*pThread)/生成新的用户级进程/TODO("Spawn a process by reading an executable from a filesystem");int rc;/标记各函数的返回值,为则表示成功,否则失败char *exeFileData = 0;/保存在内存缓冲中的用户程序可执行文件ulong_t exeFileLength;/W 执行文件的长度struct User_Context *userContext = 0;/

28、指向 User_Conetx的指针struct Kernel_Thread *process = 0;/旨向 Kernel_Thread *pThread的指针struct Exe_Format exeFormat;/4M用 Parse_ELF_ExecutableS数得至U 的可执行文 件信息 _ 一if (rc = Read_Fully(program, (void*) &exeFileData, &exeFileLength) != 0 )/ 调 用Read_Fully函数将名为program的可执行文件全部读入内存缓冲区Print("Failed to Rea

29、d File %s!n", program);goto fail;if(rc = Parse_ELF_Executable(exeFileDataexeFileLength, &exeFormat) != 0 )/ 调用Parse_ELF_Executabl函数分析ELF格式文件Print("Failed to Parse ELF File!n");goto fail;if(rc = Load_User_Program(exeFileData,exeFileLength, &exeFormat, command, &userContext)

30、 != 0)/调用Load_User_Program等可执行程序的程序段和数据段装 入内存,初始化User_Contex檄据结构Print("Failed to Load User Program!n");goto fail;/在堆分配方式下释放内存并再次初始化 exeFileDataFree(exeFileData);exeFileData = 0;process = Start_User_Thread(userContext, false);/ 开始用户进程,调用Start_User_ThreadS数创建一个进程并使其进入准备运行队列if (process != 0)/

31、不是核心级进程(即为用户级进程) KASSERT(process->refCount = 2);*pThread = process返回核心进程的指针 rc = process->pid;/力己录当前进程的IDelse/®出内存 project2includegeekoserrno.h rc = ENOMEM;return rc;fail: /如果新进程创建失败则注销User_ContextX寸象if (exeFileData != 0)Free(exeFileData);/# 放内存if (userContext != 0)Destroy_User_Context(us

32、erContext);/销肖毁进程对象 return rc; void Switch_To_User_Context(struct Kernel_Thread* kthread, struct Interrupt_State*state)/肤行而进都前,鲁用该函数以切换用6地址空间一/* Hint: Before executing in user mode, you will need to call* the Set_Kernel_Stack_Pointer() and Switch_To_Address_Space()* functions.* /TODO("Switch to

33、 a new user address space, if necessary");static struct User_Context* s_currentUserContext; /* last user context used */extern int userDebug;struct User_Context* userContext = kthread->userContext;/f旨向 User_Conetx的指针,并初始花为准备切换的进程一KASSERT(!Interrupts_Enabled();if (userContext = 0) /userContex

34、t为表示此进程为核心态进程就不用切换地址空间return;if (userContext != s_currentUserContext) ulong_t esp0;/if (userDebug) Print("A%pn", kthread);Switch_To_Address_Space(userContext)而用户态进程时则切换地址空间 esp0 = (ulong_t) kthread->stackPage) + PAGE_SIZE;/if (userDebug)/ Print("S%冈n", esp0);/*新进程的核心栈.*/Set_Ke

35、rnel_Stack_Pointer(esp0);股置内核堆栈指针/* New user context is active */s_currentUserContext = userContext;userseg.c/userseg.改件中主要为实现一些为实现对user.井高层操作支持的函数/新建一个给定长度的User_Context,参数是User_Contex修吉构的大小User_Context 的新建static struct User_Context* Create_User_Context(ulong_t size)一一一一struct User_Context * UserCon

36、text;size = Round_Up_To_Page(size);UserContext = (struct User_Context *)Malloc(sizeof(struct User_Context);if (UserContext != 0)为用户态进程UserContext->memory = Malloc(size);else/m核心态进程goto fail;if (0 = UserContext->memory)/内存为空goto fail;memset(UserContext->memory, '0', size);UserContext

37、->size = size;/以下为用户态进程创建LDT(段描述符表),步骤如下:调用函数 Allocate_Segment_Descriptor(新建一个 LDT描述符/调用函数selector。新建一个LDT选择子/调用函数Init_Code_Segment_Descriptor(新建一个文本段描述符调用函数 Init_Data_Segment_Descriptor(新建一个数据段/调用函数selector。新建一个数据段选择子/调用函数selector。新建一个文本(可执行代码)段选择子/新建一个LDT描述符UserContext->ldtDescriptor = Alloc

38、ate_Segment_Descriptor();if (0 = UserContext->ldtDescriptor) goto fail;/初始化段描述符Init_LDT_Descriptor(UserContext->ldtDescriptor,UserContext->ldt,NUM_USER_LDT_ENTRIES);/新建一个LDT选择子UserContext->ldtSelector = Selector(KERNEL_PRIVILEGE, true, Get_Descriptor_Index(UserContext->ldtDescriptor);

39、/新建一个文本段描述符Init_Code_Segment_Descriptor(&UserContext->ldt0,(ulong_t) UserContext->memory,size / PAGE_SIZE,USER_PRIVILEGE);/新建一个数据段Init_Data_Segment_Descriptor(&UserContext->ldt1,(ulong_t)UserContext->memory,size / PAGE_SIZE,USER_PRIVILEGE );/新建数据段和文本(可执行代码)段选择子UserContext->csS

40、elector = Selector(USER_PRIVILEGE, false, 0);UserContext->dsSelector = Selector(USER_PRIVILEGE, false, 1);/将引用数清UserContext->refCount = 0;return UserContext;fail:if (UserContext != 0)if (UserContext->memory != 0)Free(UserContext->memory);Free(UserContext);return 0;注销User_ContexX寸象的函数是该函数

41、,参数是待注销的User_Contex对象指针User_Context 的注销void Destroy_User_Context(struct User_Context* userContext)/隼放用户态进程占 用的内存资源(包后'占用的LDT、内存空间及userContex眩身占用的内存)释放占用的LDTFree_Segment_Descriptor(userContext->ldtDescriptor);userContext->ldtDescriptor=0;/释放内存空间Free(userContext->memory);userContext->m

42、emory=0;/释放userContex沐身占用的内存Free(userContext);userContext=0;/该函数完成后,即得到用户程序在系统中的用户态进程体,以及用户上下文的 User_Contex修吉构/该函数实现的主要功能如下:/计算需要分配给用户态进程的内存空间大小/为用户程序分配内存空间,并初始化/根据Exe_Sdgmen棍供的用户段信息初始化代码段、数据段以及堆栈段的段描 述符和段;i择子/根据短信息将用户程序的各段内容复制到分配的用户内存空间/初始化User_Contex钻构的用户打开列表,初始化完毕后,返回表示成功/参数含义如下/exeFileData:保存在缓冲

43、区的可执行文件/Format:调用elf得到的格式信息/command:用户输入的命令指向User_Contex仅寸象的指针int Load_User_Program(char *exeFileData, ulong_t exeFileLength,struct Exe_Format*exeFormat, const char *command,struct User_Context *pUserContext)通过力口载可执行文件镜像仓1J建新进程 的USER-CONTEX的结构/TODO("Load a user executable into a user memory spa

44、ce using segmentation");int i;ulong_t maxva = 0;/要分配的最大内存空间unsigned numArgs;/® 程数目ulong_t argBlockSize;/参数块的大小ulong_t size, argBlockAddr;参数块地址struct User_Context *userContext = 0;for (i = 0; i < exeFormat->numSegments;+i)计算用户态进程所需的最大内存 空间struct Exe_Segment *segment = &exeFormat-&

45、gt;segmentListi;ulong_t topva = segment->startAddress+ segment->sizeInMemory; /* FIXME: range check */if (topva > maxva)maxva = topva;Get_Argument_Block_Size(command, &numArgs, &argBlockSize);/ 获取参数块信息一 一 一size = Round_Up_To_Page(maxva) + DEFAULT_USER_STACK_SIZE;/川户进程大小二参数块总大小+进程堆栈大

46、小(8192)argBlockAddr = size;size += argBlockSize;userContext = Create_User_Context(size);按相应大小仓建一个进程if (userContext = 0)/如果为核心态进程return -1;for (i = 0; i < exeFormat->numSegments; +i) struct Exe_Segment *segment = &exeFormat->segmentListi;/根据段彳/将用户程序中的各段内容复制到分配的用户内存空间memcpy(userContext-&g

47、t;memory + segment->startAddress, exeFileData + segment->offsetInFile,segment->lengthInFile);/格式化参数块Format_Argument_Block(userContext->memory + argBlockAddr, numArgs, argBlockAddr, command);/初始化数据段,堆栈段及代码段信息userContext->entryAddr = exeFormat->entryAddr;userContext->argBlockAddr

48、= argBlockAddr;userContext->stackPointerAddr = argBlockAddr;将初始化完毕的 User_Context®给*pUserContext*pUserContext = userContext;return 0;/成功bool Copy_From_User(void* destInKernel, ulong_t srcInUser, ulong_t bufSize)在 用户地址空间和内:核地址空间之间复制数据,与Copy_To_Userg数成能共同使用/TODO("Copy memory from user buff

49、er to kernel buffer");struct User_Context * UserContext = g_currentThread->userContext;/-: check if memory if validatedif (!Validate_User_Memory(UserContext,srcInUser, bufSize) return false;/-:user->kernelmemcpy(destInKernel, UserContext->memory + srcInUser, bufSize);return true;Valida

50、te_User_Memory(NULL,0,0); /* delete this; keeps gcc happy */成功,返回true;user buffe亦存在,返回falsebool Copy_To_User(ulong_t destInUser, void* srcInKernel, ulong_t bufSize)/S 用户 地址空间和内核地址空间之间复制数据/TODO("Copy memory from kernel buffer to user buffer") struct User_Context * UserContext = g_currentThr

51、ead->userContext;/-: check if memory if validatedif (!Validate_User_Memory(UserContext, destInUser, bufSize) return false;/-:kernel->usermemcpy(UserContext->memory + destInUser, srcInKernel, bufSize);return true;void Switch_To_Address_Space(structUser_Context *userContext)通过将进程的LDT装入到LDT寄存器

52、来激活用户的地址空间/TODO("Switch to user address space using segmentation/LDT");ushort_t ldtSelector= userContext->ldtSelector;/* Switch to the LDT of the new user context */_asmvolatile_ ("lldt %0":"a"(ldtSelector);main.c/在main.c文件内改写生成第一个用户态进程的函数调用:static voidSpawn_Init_Pro

53、cess(void) static void Mount_Root_Filesystem(void);static void Spawn_Init_Process(void);void Main(struct Boot_Info* bootInfo) .Init_BSS();Init_Screen();Init_Mem(bootInfo);Init_CRC32();Init_TSS();Init_Interrupts();Init_Scheduler();Init_Traps();Init_Timer();Init_Keyboard();Init_DMA();Init_Floppy();Ini

54、t_IDE();Init_PFAT();Mount_Root_Filesystem();Set_Current_Attr(ATTRIB(BLACK, GREEN|BRIGHT);Print("Welcome to GeekOS!n");Set_Current_Attr(ATTRIB(BLACK, GRAY);Spawn_Init_Process();/* Now this thread is done. */ Exit(0); static void Mount_Root_Filesystem(void)一 一if (Mount(ROOT_DEVICE, ROOT_PREF

55、IX, "pfat") != 0) Print("Failed to mount /" ROOT_PREFIX " filesystem'n"); elsePrint("Mounted /" ROOT_PREFIX " filesystem!n");static void Spawn_Init_Process(void)/生成第一个用户态进程一 一/TODO("Spawn the init process");struct Kernel_Thread *pThread

56、;Spawn("/c/shell.exe","/c/shell.exe",&pThread);四、在brochs中运行GeekOS系统显示结果ULGL 匚LL 匚 UL. JJUUU1 Illi 1kH匚匚L. JLD7EU/ U匚 4Initializing IDT.Initializing timer.De lay loop 36S3 iterat ions per tick Initial1/ing keyboard,.Initializing DMA Controller.Initializing floppy controIler.fd

57、0: cy1=80, heeds=2, sectors=18 In it ia 1 iz itng IDE controller.ide0: cyl=4G, heads=8, sectors=64 lounted zc r ilesystem?Je Leome to GeekOS!3 /c/she11.exei pid连续运行两次可执行程序后显示的结果如下:B192KB memory detected, 1668 pages in free list, 1048576 bytes in kerne 1 heInitializing IDT.Initializing timer.Delay loop: 3653 iterations per tick Initializing keyboard . Initializing DMA ControIler. Initializing floppy controIler.fd0: cy1=80, heads=Z, sectors = 18 Initializing IDE controIler.ide©: cy1=40j heads=8, sectors=64 lounted /c f

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论