操作系统实战45讲:HelloOS运行笔记

简介: 操作系统实战45讲:HelloOS运行笔记

1.实验环境:


1.1 系统环境


  • Ubuntu 20.04.2.0 LTS
  • vmware虚拟机


1.2 安装编译环境


  • 安装汇编编译器


sudo apt-get install nasm


  • 安装gcc(该命令会安装包括gcc在内的所有软件)


sudo apt install build-essential


2. HelloOS实现说明


2.1 HelloOS文件构成


  • entry.asm
  • 供grub调用的引导程序,用于设置CPU工作模式与工作环境,并调用C语言编写的main函数


main.c

  • 打印字符串


#include "vgastr.h"
void main() {
  printf("Hello OS!");
  return;
}


vgastr.c / vgastr.h

  • 实现在显示屏上输出信息


void _strwrite(char *string) {
  char *p_strdst = (char *)(0xb8000);  //指向显存开始的地址
  while(*string) {
    *p_strdst = *string++;
    p_strdst += 2;  //每两个字节对应一个字符,其中一个字节是字符的ASCII码,另一个字节为字符的的颜色值
  }
  return;
}
void printf(char *fmt, ...) {
  _strwrite(fmt);
  return;
}


hello.lds

  • 链接器脚本,用于指导链接过程,设定不同程序段的布局


ENTRY(_start)
OUTPUT_ARCH(i386)
OUTPUT_FORMAT(elf32-i386)
SECTIONS
{
  . = 0x200000;
  __begin_start_text = .;
  .start.text : ALIGN(4) { *(.start.text) }
  __end_start_text = .;
  __begin_text = .;
  .text : ALIGN(4) { *(.text) }
  __end_text = .;
  __begin_data = .;
  .data : ALIGN(4) { *(.data) }
  __end_data = .;
  __begin_rodata = .;
  .rodata : ALIGN(4) { *(.rodata) *(.rodata.*) }
  __end_rodata = .;
  __begin_kstrtab = .;
  .kstrtab : ALIGN(4) { *(.kstrtab) }
  __end_kstrtab = .;
  __begin_bss = .;
       .bss : ALIGN(4) { *(.bss) }
  __end_bss = .;
}


  • Makefile
  • 编译脚本


2.2 屏幕显示说明


若想使用屏幕显示出字符,则需要使用代码对显卡进行控制。


不论是集显、核显、独显,它们都支持VESA标准,该标准有两种工作模式:字符模式与图形模式。这些显卡为了兼容VESA标准,他们都会提供VGABIOS的固件程序。


2.2.1 显卡的字符模式


在字符模式下,屏幕将会被分为24行,每行80个字符,然后将这24 * 80个字符映射到从0xb8000地址开始的内存中,每两个字节对应一个字符,一个字节对应字符的ASCII码,一个字节对应字符的颜色。


ad9d77ea43c84d41bbb560f2f476ecc5.png



更多关于显卡文本模式下输出字符,可参考下文的chapter 2:点击查看


2.3 部署HelloOS


部署之前,首先了解下HelloOS的引导流程


PC机的BIOS固化在主板上的ROM中,上电后第一条指令就是BIOS固件中的,它负责检测与初始化CPU,内存,主板,之后加载引导设备中的第一个扇区,到0x7c00地址开始的内存空间,然后跳转到0x7c00处执行指令。


本次实验使用的是GRUB引导程序。

d140190aedcd4490bde8945785c88576.png

2.3.1 准备文件


2.3.1.1 编译HelloOS


  • 将生成的HelloOS.bin文件复制到boot文件夹下。(也可将bin文件放置在其他文件夹下,不过一般放在boot中)
  • sudo mv HelloOS.bin /boot/


2.3.1.2 修改启动项等待时间


  • 修改默认启动项的等待时间,打开grub文件,修改GRUB_TIMEOUT参数,默认为10s
  • sudo gedit /etc/default/grub


ad1c0c2de63b4be7babed3736c888eaf.png


  • 修改之后使用以下命令更新文件设置,该命令会将/boot/grub/grub.cfg文件给初始化,若之前有所修改,则需要再次进行修改
  • sudo update-grub


2.3.1.3 虚拟机添加启动项


  • 打开grub.cfg文件:sudo gedit /boot/grub/grub.cfg
  • 在文件中插入以下代码
  • 代码之间使用的是空格,不能是tab键或其他字符(tab键将会导致启动时找不到相关命令)
menuentry 'HelloOS' {
  insmod part_msdos     #GRUB加载分区模块识别分区
  insmod ext2           #GRUB加载ext文件系统模块识别ext文件系统
  set root='hd0,msdos5' #注意boot目录挂载的分区,这是我机器上的情况
  multiboot2 /boot/HelloOS.bin  #GRUB以multiboot2协议加载HelloOS.bin
  boot
}

insmod 与 set root说明


set root=‘***’里面填写的是存放HelloOS.bin的文件夹,在 2.3.1.1 中其实说过,HelloOS.bin文件放在哪里都是可以的,不一定要放在/boot文件夹下。而set root=’'中填写的就是存放HelloOS.bin的文件夹所在的磁盘分区。


查找HelloOS.bin文件所在分区:

重启时长按ESC键,进入grub引导界面

按下c键进入命令交互模式

使用ls命令查看磁盘分区信息

使用ls (hdx,msdosx)/boot/ 命令查找HelloOS.bin文件,然后将包含有bin文件的磁盘写入set root参数


455b6787e56e4cc5812f50b57da08fdc.png

multiboot2说明


该参数是HelloOS.bin文件存放的路径,该参数设置错误的话,启动HelloOS时将会出现“HelloOS.bin not found”错误


boot挂载情况主要分为两种:独立分区单独挂载 与 属于根分区的一部分


使用df -h /boot/ 命令查看boot的挂载情况,也可使用df -h查看所有的挂在


属于根分区的一部分


multiboot2 /boot/HelloOS.bin

8f16d5a5ba304e5b9be851e1e0207db1.png


1c9e72a2502d41eeb165ccde40041707.png


独立分区单独挂载

multiboot2 /HelloOS.bin


796ca7aef6104ad4a27afc3e6d3a5687.png


2.3.1.4 物理机添加启动项


  • 参考 2.3.1.3 虚拟机添加启动项 进入grub引导界面,查看磁盘分区信息


0e64129b20224438a86e4f06e667cf55.png

  • 这里物理机的磁盘分区为gpt方式,修改insmod参数
  • insmod part_gpt
  • 使用ls (hdx,gptx)/ls (hdx,gptx)/boot/命令进行查找bin文件(前者为单独分区,后者为属于根分区的一部分)
  • 启动代码
menuentry 'HelloOS' {
  insmod part_gpt #GRUB加载分区模块识别分区
  insmod ext2 #GRUB加载ext文件系统模块识别ext文件系统
  set root='hd0,gpt5' #注意boot目录挂载的分区,这是我机器上的情况
  multiboot2 /HelloOS.bin #GRUB以multiboot2协议加载HelloOS.bin
  boot #GRUB启动HelloOS.bin
}


HelloOS运行结果


9a132c3d5c974849abb5fb84f02ca3a5.png

相关文章
|
21天前
|
JSON JavaScript 前端开发
harmony-chatroom 自研纯血鸿蒙OS Next 5.0聊天APP实战案例
HarmonyOS-Chat是一个基于纯血鸿蒙OS Next5.0 API12实战开发的聊天应用程序。这个项目使用了ArkUI和ArkTS技术栈,实现了类似微信的消息UI布局、输入框光标处插入文字、emoji表情图片/GIF动图、图片预览、红包、语音/位置UI、长按语音面板等功能。
45 2
|
3月前
|
Oracle Java 关系型数据库
CentOS 7.6操作系统部署JDK实战案例
这篇文章介绍了在CentOS 7.6操作系统上通过多种方式部署JDK的详细步骤,包括使用yum安装openjdk、基于rpm包和二进制包安装Oracle JDK,并提供了配置环境变量的方法。
291 80
|
1月前
|
Linux 开发者 iOS开发
Python系统调用实战:如何在不同操作系统间游刃有余🐟
本文介绍了 Python 在跨平台开发中的强大能力,通过实际例子展示了如何使用 `os` 和 `pathlib` 模块处理文件系统操作,`subprocess` 模块执行外部命令,以及 `tkinter` 创建跨平台的图形用户界面。这些工具和模块帮助开发者轻松应对不同操作系统间的差异,专注于业务逻辑。
40 2
|
3月前
|
移动开发 Android开发 数据安全/隐私保护
移动应用与系统的技术演进:从开发到操作系统的全景解析随着智能手机和平板电脑的普及,移动应用(App)已成为人们日常生活中不可或缺的一部分。无论是社交、娱乐、购物还是办公,移动应用都扮演着重要的角色。而支撑这些应用运行的,正是功能强大且复杂的移动操作系统。本文将深入探讨移动应用的开发过程及其背后的操作系统机制,揭示这一领域的技术演进。
本文旨在提供关于移动应用与系统技术的全面概述,涵盖移动应用的开发生命周期、主要移动操作系统的特点以及它们之间的竞争关系。我们将探讨如何高效地开发移动应用,并分析iOS和Android两大主流操作系统的技术优势与局限。同时,本文还将讨论跨平台解决方案的兴起及其对移动开发领域的影响。通过这篇技术性文章,读者将获得对移动应用开发及操作系统深层理解的钥匙。
|
7月前
|
运维 开发工具 C语言
手写操作系统(1)——HelloOS
手写操作系统(1)——HelloOS
204 3
|
2月前
|
小程序 iOS开发 MacOS
MacOS环境-手写操作系统-44-运行简单的程序
MacOS环境-手写操作系统-44-运行简单的程序
25 0
|
4月前
|
Linux 开发者 iOS开发
Python系统调用实战:如何在不同操作系统间游刃有余🐟
【8月更文挑战第5天】Python系统调用实战展示了如何轻松应对跨平台挑战。通过`os`与`pathlib`模块处理文件系统操作,如创建目录及获取用户主目录,自动适配不同操作系统的路径格式。利用`subprocess`模块执行外部命令,智能选择`ls`或`dir`等系统特定指令。借助Tkinter创建图形用户界面,实现一次编写到处运行的目标。这些技巧让开发者专注于应用逻辑,简化跨平台开发流程。
54 0
|
6月前
|
IDE Oracle Java
Java 是一种跨平台的编程语言,可以在各种操作系统上运行。
Java 是一种跨平台的编程语言,可以在各种操作系统上运行。
|
6月前
|
调度
操作系统的目标和功能笔记分享
【6月更文挑战第1天】操作系统的目标和功能笔记分享
69 1
|
5月前
|
开发工具
环境变量,环境变量就是在操作系统中记录的一些关键性信息,以辅助系统运行,env,echo $PATH可以取出环境变量,全局变量的使用方法是定义,什么时候用,什么时候取,export MYNAME=it
环境变量,环境变量就是在操作系统中记录的一些关键性信息,以辅助系统运行,env,echo $PATH可以取出环境变量,全局变量的使用方法是定义,什么时候用,什么时候取,export MYNAME=it