操作系统课设

一、初试GeekOS

1、实验环境:Ubuntu 18.04

2、下载GeekOS

官方网站:GeekOS
点击右边的“download”,然后点击Download Latest Version下载并解压。
在这里插入图片描述

3、编译

3.1 安装编译环境

sudo apt-get install build-essential
sudo apt-get install nasm
sudo apt-get install bochs
sudo apt-get install bochs-x

3.2 安装低版本的gcc

解释:笔者通过多次测试发现,编译的geekos-0.3版本非常古老,直接编译会出现一堆错误,所以使用同样比较古老的gcc-4.8来进行编译。
(1) 使用gcc -v查看gcc版本
(2) 通过sudo apt-get install gcc-4.8安装,然后输入ls /usr/bin/gcc* -l来查看已安装版本。
(3) 由于两个版本的gcc同时存在,故需要设定优先级。

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 100

设定指令选择不同版本的gcc

sudo update-alternatives --config gcc

在这里插入图片描述
(4) 选择后查看gcc版本:gcc -v

3.3 编译GeekOS的project0

(1) 进入geekos-0.3.0/src/project0/build目录
(2) 首先使用make clean清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。
(3) 开始编译

make clean
make depend
make

在这里插入图片描述
注意:每次修改保存后必须make clean,每修改一次都要!!!

bug 1:

error:
Makefile:172: recipe for target ‘geekos/gdt.o’ failed
解决方案:
因为Makefile中默认的编译选项过于严格,把警告都当成错误来看待。在Makefile的第149行删除-Werror

bug 2:

error:
ld: i386 架构于输入文件 geekos/lowlevel.o 与 i386:x86-64 输出不兼容
common/fmtout.o:在函数‘Format_Output’中:
fmtout.c:(.text+0xa16):对‘__stack_chk_fail’未定义的引用
Makefile:223: recipe for target ‘geekos/kernel.exe’ failed
make: *** [geekos/kernel.exe] Error 1
解决方案:
在64位机器的默认配置下导致的,我们可以强制增加编译选项-m32和链接选项-m elf_i386,打开Makefile,将第100、106、109行修改如下:

# Target C compiler.  gcc 2.95.2 or later should work.
TARGET_CC := $(TARGET_CC_PREFIX)gcc -m32

# Host C compiler.  This is used to compile programs to execute on
# the host platform, not the target (x86) platform.  On x86/ELF
# systems, such as Linux and FreeBSD, it can generally be the same
# as the target C compiler.
HOST_CC := gcc -m32

# Target linker.  GNU ld is probably to only one that will work.
TARGET_LD := $(TARGET_CC_PREFIX)ld -m elf_i386

bug 3:

error:
common/fmtout.o:在函数‘Format_Output’中:
fmtout.c:(.text+0x836):对‘__stack_chk_fail’未定义的引用
Makefile:223: recipe for target ‘geekos/kernel.exe’ failed
make: *** [geekos/kernel.exe] Error 1
yadajin@ubuntu:~/Downloads/geekos-0.3.
解决方案:
因为gcc在编译时开启了栈保护,所以要关闭栈保护。
修改第148行。

GENERAL_OPTS := -O -Wall -fno-stack-protector $(EXTRA_C_OPTS)

3.4 编译成功

会在build目录下生成一个镜像文件fd.img和bochs模拟器的配置文件.bochsrc。
在这里插入图片描述

4、运行

4.1 修改.bochsrc配置

  1. 把第4行注释掉
    # vgaromimage: /export/home/daveho/linux/bochs-2.0.2/share/bochs/VGABIOS-lgpl-latest
  2. 修改第5行为
    romimage: file=$BXSHARE/BIOS-bochs-latest
  3. 把第16、18、22行注释掉
    # floppy_command_delay: 500 
    # ips:  1000000 
    # newharddrivesupport: enabled=1
    

4.2 bochs命令

在这里插入图片描述
如果新弹出的bochs窗口黑屏,可能是进入了调试模式,在终端中输入c回车即可。
在这里插入图片描述

4.3 补充问题

如果出现此情况,估计是nasm版本高了,试试2.00的。去官网下载2.00版本即可。

./configure
make
sudo make install

在这里插入图片描述

5、心得体会

笔者通过对比Ubuntu 16版本和Ubuntu 9版本,发现GeekOS在Ubuntu 9版本里bug较少,毕竟GeekOS是个很古老的东西,从官网上看最近的一次维护是2008年,然而现在是2020年,可见相隔甚远。所以笔者建议做GeekOS课设时还是用Ubuntu 9版本的吧,这样省去很多系统环境问题的麻烦。当然如果你在较新的Ubuntu版本完成了GeekOS课设,欢迎评论区留言,大家交流学习。

二、project0

1、项目设计要求

  1. 搭建GeekOS的编译和调试平台,掌握GeekOS的内核进程工作原理。
  2. 熟悉键盘操作函数,编程实现一个内核进程。该进程的功能是:接收键盘输入的字符并显示到屏幕上,当输入ctrl+d时,结束进程的运行。

2、分析

在project0中,只要使用的是两个部分:内核线程和键盘处理。其中对应的是kthread.ckeyboard.c,其实project0的目的很简单,核心就是创建键盘扫描的进程。
设键盘的处理函数KeyboardScan(),对于在main()函数中,需要创建一个进程,代码如下:

struct Kernel_Thread *thread;
thread = Start_Kernel_Thread(&KeyboardScan,0,PRIORITY_NORMAL,false);  //创建内核级进程

Start_Kernel_Thread函数的解释如下:
启动一个仅内核模式的线程,使用给定的函数作为它的主体,传递给定的参数作为它的参数。如果成功返回指向新线程的指针,否则返回null。

/*优先级定义*/
#define PRIORITY_IDLE    0
#define PRIORITY_USER    1
#define PRIORITY_LOW     2
#define PRIORITY_NORMAL  5
#define PRIORITY_HIGH   10
/*内核线程*/
struct Kernel_Thread* Start_Kernel_Thread(
    Thread_Start_Func startFunc,  //新线程要调用的函数
    ulong_t arg,                  //传递给新函数的参数
    int priority,                 //这个线程的优先级(使用PRIORITY_NORMAL)
    bool detached                 //线程属性——对内核线程使用false
)

那么Start_Kernel_Thread要完成的工作如下
在这里插入图片描述

Start_Kernel_Thread()	//创建内核线程
Create_Thread()			//根据优先级创建一条线程
   Alloc_Page()			//分配一页物理内存。
   Init_Thread()        //初始化新线程的堆栈指针和会计信息
   Add_To_Back_Of_All_Thread_List()	//添加到系统中所有线程的列表中。
Setup_Kernel_Thread()	//为线程创建初始上下文,使其可调度。
Make_Runnable_Atomic()	//以原子方式将线程放入运行队列。
   Disable_Interrupts()	//阻止中断
   Make_Runnable()	    //添加给定的线程到运行队列,使它可能会被安排。必须在禁用中断的情况下调用!
   Enable_Interrupts()	//重启中断

如何识别键盘?
在main()中创建一个函数,代码如下:

/*
KEY_KEYPAD_FLAG (小键盘键) 0x0200
KEY_SHIFT_FLAG (左,右SHIFT) 0x1000
KEY_ALT_FLAG (左,右ALT) 0x2000
KEY_CTRL_FLAG (左,右CTRL) 0x4000
KEY_RELEASE_FLAG (键弹起来标志位) 0x8000
*/
void KeyboardScan()
{
    Print("Please input Ctrl + d to exit.\n");
    Keycode key;
    while(1)
    {
        if(Read_Key(&key))	
        {
            if(!((key & KEY_SPECIAL_FLAG) || (key & KEY_RELEASE_FLAG)))		//排除特殊键或弹起
            {
                int asciiCode = key & 0xff;	//取后8为ascii码
                if((key & KEY_CTRL_FLAG)==KEY_CTRL_FLAG && asciiCode=='d')	//ctrl标志位为1且后8位ascii码为'd',即ctrl+d
                {
                    Print("\n---------Successful exit!---------\n");
                    Exit(0);
                }else
                    Print("%c",asciiCode=='\r' ? '\n' : asciiCode);  		//打印字符
            }
        }
    }
}

3、作业题

  1. GeekOS系统内核是如何编译的?
  2. GeekOS系统内核编译的结果是什么?
  3. 如何设置运行GeekOS系统的计算机环境?
  4. 如何运行GeekOS系统内核?
  5. GeekOS系统是如何创建键盘管理进程?
  6. 简述计算机系统的启动流程。
展开阅读全文

Windows版YOLOv4目标检测实战:训练自己的数据集

04-26
©️2020 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值