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好啦,准备工作到此结束,下一章,我们将正式进入操作系统开发。
发表回复