第0章 操作系统开发准备

0.1 操作系统概述

操作系统(英语:Operating System,缩写:OS)是一组主管并控制计算机操作、运用和运行硬件、软件资源和提供公共服务来组织用户交互的相互关联的系统软件程序,同时也是计算机系统的内核与基石。操作系统需要处理如管理与配置内存、决定系统资源供需的优先次序、控制输入与输出设备、操作网络与管理文件系统等基本事务。操作系统也提供一个让用户与系统交互的操作界面。1

以上是来自维基百科的关于操作系统的定义。通俗来说,操作系统其实就是一座软件与硬件之间的桥梁,控制计算机硬件并隐藏底层细节,抽象出各种方法(API)供软件调用。

0.2 目标

本教程将带领读者实现一个简易的操作系统,从而在实践中加深对计算机各种知识的理解。以下是将要编写的操作系统的初期目标:

  • 支持multiboot2启动
  • 内存管理
  • 任务调度
  • 64位支持
  • 简易shell
  • 简易GUI
  • 简易API

在完成这些目标后,我们将视情况添加新目标。

0.3 前期准备

俗话说,工欲善其事,必先利其器,我们先把开发环境准备好。以下是本教程使用的工具:

  • GCC – C编译器
  • nasm – 汇编器
  • ld – 链接器
  • make – 自动构建工具
  • objcopy – 用于对编译输出文件进行调整
  • objdump – 用于反汇编
  • qemu – 虚拟机
  • grub2 – 用于multiboot2引导

由于以上工具大部分都内置于各大Linux发行版,故本教程选择Linux作为开发平台。

当然,你也可以选择其他具备相同功能的工具和平台作为替代。

0.4 启动映像构建

由于我们的开发将从内核开始,所以我们应提前准备好附带grub2引导器的映像,以用于虚拟机测试。

首先,创建一个磁盘映像,这里选择64MB大小:

dd if=/dev/zero of=hd.img bs=512 count=131072

接下来,对磁盘初始化并分区:

$ parted hd.img
(parted) mklabel msdos
(parted) mkpart primary fat32 1MiB -1
(parted) set 1 boot on
(parted) quit

然后,挂载分区并格式化:

losetup --show -f -P hd.img
#/dev/loop0
mkfs.vfat -F 32 /dev/loop0p1
mount /dev/loop0p1 /mnt/loop0p1

安装grub2引导器:

grub-install --boot-directory=/mnt/loop0p1 --target=i386-pc /dev/loop0

创建/mnt/loop0p1/grub/grub.cfg并写入以下内容:

if [ -s $prefix/grubenv ]; then
  set have_grubenv=true
  load_env
fi
if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="0"
fi

if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if [ -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}
function load_video {
  if [ x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}

if [ x$feature_default_font_path = xy ] ; then
   font=unicode
else
insmod ext2
set root='hd2'
if [ x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint-bios=hd2 --hint-efi=hd2 --hint-baremetal=ahci2  b535aa4b-2255-4d5c-baf9-9f8cc35109bf
else
  search --no-floppy --fs-uuid --set=root b535aa4b-2255-4d5c-baf9-9f8cc35109bf
fi
    font="/usr/share/grub/unicode.pf2"
fi

if loadfont $font ; then
  set gfxmode=1280x720,1280x800,auto
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=zh_CN
  insmod gettext
fi
terminal_output gfxterm
if [ "$grub_platform" = "efi" ]; then
  insmod bli
fi
if [ "$grub_platform" = "efi" ]; then
        fwsetup --is-supported
        if [ "$?" = 0 ]; then
                menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
                        fwsetup
                }
        fi
fi
menuentry "MyOS" {
	multiboot2 /kernel.elf
}

保存并卸载/dev/loop0p1,至此,本教程所使用的启动映像构建完成。

可以使用以下命令启动qemu:

qemu-system-x86_64 -drive format=raw,file=hd.img

好啦,准备工作到此结束,下一章,我们将正式进入操作系统开发。

  1. 操作系统 – 维基百科,自由的百科全书 (wikipedia.org) ↩︎

已发布

分类

来自

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注