1、计算机是如何将系统起起来的?-- PC机的引导流程

PC机BIOS固件是固化在PC机主板上的ROM芯片中,断电也能保存,PC机上电后的第一条指令就是在BIOS固件中,它负责检测和初始化CPU、内存和主板平台,然后加载引导设备(大概率是硬盘)中的第一个扇区数据,到0x7c00地址开始的内存空间,再跳转到0x7c00处执行指令。这里是GRUB引导程序。

GRUB:GNU GRUB(GRand Unified Bootloader简称“GRUB”)是一个来自GNU项目的多操作系统启动程序。GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数。参考:百度百科

2、Hello OS引导汇编代码

为什么不能直接用C?

C 作为通用的高级语言,不能直接操作特定的硬件,而且 C 语言的函数调用、函数传参,都需要用栈。

栈,数据满足后进先出的特性,它由CPU特定的寄存器指向,所以需要先用汇编代码处理好C语言的工作环境

;彭东 @ 2021.01.09
MBT_HDR_FLAGS EQU 0x00010003
MBT_HDR_MAGIC EQU 0x1BADB002 ;多引导协议头魔数
MBT_HDR2_MAGIC EQU 0xe85250d6 ;第二版多引导协议头魔数
global _start ;导出_start符号
extern main ;导入外部的main函数符号
[section .start.text] ;定义.start.text代码节
[bits 32] ;汇编成32位代码
_start:
jmp _entry
ALIGN 8
mbt_hdr:
dd MBT_HDR_MAGIC
dd MBT_HDR_FLAGS
dd -(MBT_HDR_MAGIC+MBT_HDR_FLAGS)
dd mbt_hdr
dd _start
dd 0
dd 0
dd _entry
;以上是GRUB所需要的头
ALIGN 8
mbt2_hdr:
DD MBT_HDR2_MAGIC
DD 0
DD mbt2_hdr_end - mbt2_hdr
DD -(MBT_HDR2_MAGIC + 0 + (mbt2_hdr_end - mbt2_hdr))
DW 2, 0
DD 24
DD mbt2_hdr
DD _start
DD 0
DD 0
DW 3, 0
DD 12
DD _entry
DD 0
DW 0, 0
DD 8
mbt2_hdr_end:
;以上是GRUB2所需要的头
;包含两个头是为了同时兼容GRUB、GRUB2
ALIGN 8
_entry:
;关中断
cli
;关不可屏蔽中断
in al, 0x70
or al, 0x80
out 0x70,al
;重新加载GDT
lgdt [GDT_PTR]
jmp dword 0x8 :_32bits_mode
_32bits_mode:
;下面初始化C语言可能会用到的寄存器
mov ax, 0x10
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
xor edi,edi
xor esi,esi
xor ebp,ebp
xor esp,esp
;初始化栈,C语言需要栈才能工作
mov esp,0x9000
;调用C语言函数main
call main
;让CPU停止执行指令
halt_step:
halt
jmp halt_step
GDT_START:
knull_dsc: dq 0
kcode_dsc: dq 0x00cf9e000000ffff
kdata_dsc: dq 0x00cf92000000ffff
k16cd_dsc: dq 0x00009e000000ffff
k16da_dsc: dq 0x000092000000ffff
GDT_END:
GDT_PTR:
GDTLEN dw GDT_END-GDT_START-1
GDTBASE dd GDT_START
  1. 代码 1~40 行,用汇编定义的 GRUB 的多引导协议头,其实就是一定格式的数据,我们的 Hello OS 是用 GRUB 引导的,当然要遵循 GRUB 的多引导协议标准,让 GRUB 能识别我们的 Hello OS。之所以有两个引导头,是为了兼容 GRUB1 和 GRUB2。
  2. 代码 44~52 行,关掉中断,设定 CPU 的工作模式
  3. 代码 54~73 行,初始化 CPU 的寄存器和 C 语言的运行环境。
  4. 代码 78~87 行,GDT_START 开始的,是 CPU 工作模式所需要的数据

Hello OS 的主函数

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

注意:这里的printf不是应用程序库中的printf,是需要自己实现的

具体实现如下:

void _strwrite(char* string)
{
char* p_strdst = (char*)(0xb8000);//指向显存的开始位置
while (*string)
{ *p_strdst = *string++;
p_strdst += 2;
}
return;
} void printf(char* fmt, ...)
{
_strwrite(fmt);
return;
}

显卡的字符模式的工作细节:

它把屏幕分成 24 行,每行 80 个字符,把这(24*80)个位置映射到以 0xb8000 地址开始的内存中,每两个字节对应一个字符,其中一个字节是字符的 ASCII 码,另一个字节为字符的颜色值。如下图所示:



因此在上述显示printf的代码中要从0xb8000 开始写,p_strdst 每次+2跳过字符的颜色空间的原因

编译

  • 链接器-map选项
LDFLAGS		= -s -static -T hello.lds -n **-Map** HelloOS.map
OJCYFLAGS = -S -O binary

该选项将使得在链接过程中,生成链接布局文件,通过该文件可知HelloOS的内存映射布局

编译HelloOS时生成的map文件如下图所示:

安装HelloOS

将HelloOS作为一个操作系统启动项供grub启动,因此需要能够在PC启动时进入grub引导菜单,并选择启动HelloOS

为了能够每次启动时进入grub引导菜单,需要进行如下设置

  • 修改/etc/default/grub

a. 注释掉HIDDEN所在的2行

b. 将GRUB_TIMEOUT设置为30(使用默认值10其实也可以)

c. 将GRUB_CMDLINE_LINUX_DEFAUL设置为text

参考

执行如下命令,更新grub配置

sudo update-grub
  • 增加HelloOS启动选项

    修改/boot/grub/grub.cfg,增加HelloOS启动项
menuentry 'HelloOS' {
insmod part_msdos
insmod ext2
set root='hd0,msdos5' #注意boot目录挂载的分区,这是我机器上的情况
multiboot2 /boot/HelloOS.bin
boot
}

PS:

使用df /boot 查看/boot分区情况

  • 把HelloOS.bin文件复制到/boot/目录下

重启虚拟机,便可看到HelloOS启动项



选择该启动项,即可启动HelloOS

linux中部署自己的系统内核的更多相关文章

  1. linux 中部署ant编译的包中缺少问题

    今天遇到在window上部署ant编译的包,能运行正常,但部署在linux中出现跳不进jsp中,出现404问题,后来经过排查在jsp中<%@taglib prefix="c" ...

  2. Linux中部署JAVA程序

    JAVA程序在开发完成后,需要部署到服务器,如果是WEB项目,需要部署到WEB服务器,否则部署到应用服务器. JAVA是跨平台的编程语言,服务器的操作系统可以是Windows.Linux或者其它,下面 ...

  3. 在linux中部署项目并创建shell脚本

    1.首先要在idea中父工程maven包下执行clean生成的target包 2.执行package打包,打包时候讲test勾去掉 3.将target包中生成的jar包cp出来 此处注意打包时必须要保 ...

  4. 如何在linux中部署mongodb并设置连接认证

    在windows上给mongodb设置连接认证权限:mongodb默认是不认证的,默认没有账号,现在就讲讲怎么设置账户和密码 1.首先进入C:\mongodb\bin下面双击运行mongo.exe启动 ...

  5. linux中部署django项目

    通过Nginx部署Django(基于ubuntu) Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式. 在这种方式中,我们的通常做法是,将nginx作为服务器 ...

  6. linux中部署jenkins(war包)及jenkins忘记登录账号密码

    未登录状态 登录状态 一:部署jenkins(war包) 1.直接下载war包jenkins.war,下载地址https://jenkins.io/download 2.将下载的war包放到服务器上t ...

  7. linux 中部署 rsync 实现文件远程备份及 同步

    客户端:数据源:服务端:数据接收方 rsync官方文档:https://www.samba.org/ftp/rsync/rsync.html 手动测试用“通过远程外壳访问"里的语法: 参考1 ...

  8. 在linux中 部署 mongo 数据库服务端

    1 首先需要一台linux服务器(我用的redhat linux,其它的也大同小异), 玩一玩的话,推荐亚马逊上面去创建一个免费的linux服务器,有关具体创建linux服务器不在这赘述. https ...

  9. 小试牛刀:Linux中部署RabbitMQ

    一.下载地址 本人采用的是 RabbitMQ 3.8.20+ Erlang 23.3.4.16 1.Erlang下载:https://github.com/erlang/otp/releases 2. ...

  10. Linux中kettle自动化部署脚本

    自己写的一个自动化在Linux中部署kettle的脚本,包括一些遇到的问题在脚本中都有涉及. kettle是官网最新版本pdi-ce-6.1.0.1-196.zip 目前最新版本下载地址:https: ...

随机推荐

  1. Deepseek学习随笔(10)--- 本地AI神器Cherry Studio & Chatbox 保姆级教程(附网盘链接)

    本篇介绍的 Cherry Studio 和 Chatbox 两款工具,只需简单几步,即可实现本地化部署AI能力,支持对话.编程.绘图等多场景应用.本文将手把手教你从零开始配置使用! 一.软件下载:两步 ...

  2. Shell - [11] 开源Apache Zookeeper集群启停脚本

    一.集群角色部署 当前有Zookeeper集群如下 主机名 ctos79-01 ctos79-02 ctos79-03 Zookeeper ○ ○ ○ 二.脚本使用 三.脚本内容 #!/bin/bas ...

  3. Ansible - [01] 入门&安装部署

    自动化运维工具,可以批量远程其他主机并进行管理操作 一.什么是 Ansible Ansible首次发布于2012年,作者:Michael DeHaan,同时也是Cobbler的作者,Ansible于2 ...

  4. Flink学习(十一) Sink到Elasticsearch

    导入依赖 <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-conn ...

  5. Windows 提权-MSSQL

    本文通过 Google 翻译 MSSQL – Windows Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充. 导航 0 前言 ...

  6. 一个ABAQUS model需要的Component

    component of abaqus model Abaqus模型由几个不同的组件组成,它们共同描述了要分析的物理问题. a abaqus model 至少要有: discrete goemtry ...

  7. uniapp 截屏扫码

    最近开发功能遇到个需求,用户点击某个操作之后,需要截取当前屏幕内容,并扫码识别屏幕截图中的二维码,代码如下: 首先将代码抽离到外部文件中,以便复用: // 截图 export function tak ...

  8. Oracle临时表会随另外一个表的创建自动提交并清空

    创建一个临时表,用它导入一些数据 用这个临时表生成另外一个表,用create table ... 但生成的这表总是空的. 原来create table 前会进行提交commit, 而临时表在commi ...

  9. centos操作collection

    Centos修改IP地址 https://blog.csdn.net/weixin_45193791/article/details/124646170 Centos打开.修改.保存文件 https: ...

  10. CDH6.3.2下安装部署Qualitis数据质量分析的计算服务Linkis1.3.2

    快速搭建Qualitis手册 一.基础软件安装 Gradle (4.6) MySQL (5.5+) JDK (1.8.0_141) Linkis(1.0.0+), 必装Spark引擎.如何安装Link ...