Write Your Own Operating System From Scratch - Step by Step

02 - Installation and Setup

003 Working with Linux (Ubuntu)

sudo apt-get install gcc
# 9.3.0 
gcc -v 
sudo apt-get install nasm
# 2.14.02
nasm -v 
sudo apt-get install bochs
bximage


为bochs配置

bochs

选3输入6
enter 0 返回bochs options menuenter 7; enter 1
输入完1024, 再按enter*2返回上上一级菜单bochs options menu
12 -> 3

vscode 扩展

03 - Boot Up

001 The First Program


BIOS读取引导扇区(0x7c00), 将控制权移交, 第一个扇区的信息也称为主引导记录MBR, 本视频的程序写入磁盘第一个扇区,
当BIOS将其读入内存时, 我们的代码将会执行

BIOS还提供低级服务, 但是当保护模式或长模式时, BIOS不可用

本课重点在64模式, 提到长模式就是指64位模式
在长模式下, 我们无法使用BIOS提供的print服务, 我们使用特定的video mode, 在该模式下可以打印字符

现代计算机配置了UEFI, 统一可扩展固件接口, 有望取代BIOS, 本课基于BIOS

我们将在真实模式下做的事
将段地址的值左移4位(即*16), 然后加上偏移量, 得20位的物理地址

# 在实模式16位下运行
[BITS 16]
# 代码在0x7c00处运行
[ORG 0x7c00]

start:
    # 初始化寄存器和堆栈指针
    # xor指令 将 ax寄存器清0
    xor ax,ax
    # 将ax的值(0)复制到ds、es、ss寄存器
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov sp,0x7c00

PrintMessage:
    # 设置调用打印服务需要的参数
    # 13 表示打印字符串
    mov ah,0x13 
    # al 指定了写入模式
    # al = 1 表示光标将被放置在字符串的末尾
    mov al,1
    # bx上半部分bh表示页码, bx下半部分bl存放字符属性的信息
    mov bx,0xa
    # dx置零, dx上半部分dh代表行, dx下半部分dl代表列
    xor dx,dx
    # bp 保存要打印的字符串的地址
    # 如果要将字符串复制到某个地方(but我们这里只需要知道地址), 使用方括号括起来: [Message]
    mov bp,Message
    # cx 指定要打印的字符数
    mov cx,MessageLen
    # 调用指定BIOS服务的中断号, 使用服务
    int 0x10

End:
    # 使处理器处于停止状态, 此时, 将执行中断
    hlt
    # 如果一个中断被触发, 处理器将运行hlt之后的指令
    # 即这里的jmp End, 而我们跳到End, 继续执行hlt->int 0x10->jmp End, 形成循环
    jmp End

Message: db "hello"
# $ 表示当前的汇编位置, 也就是本例中信息的末端
# equ 定义常量的消息长度, 表示字符数
MessageLen: equ $-Message

# 定义db的重复次数
# $$ 表示当前部分的开始
# 这个表达式的结果是: 重复db, 从信息的末尾到偏移量1be的空间都被0填满
# 在1be中, 我们有4个分区条目, 每个大小16字节
times (0x1be-($-$$)) db 0
    
    # 定义第一个条目 -> 希望用U盘启动, 就需要构建看似有效的条目
    db 80h # 启动指示器, 80意味着可以启动
    # 第一个字节表示磁头值, 第二个字节0-5位用作扇区值, 6-7位用作气缸cylinder值
    db 0,2,0 # c,h,s值, c-圆柱体 h-头部 s-扇区
    db 0f0h # 分区类型
    db 0ffh,0ffh,0ffh # ff是在一个字节中设置的最大值
    dd 1 # 起始扇区的LBA(逻辑块地址)地址, 启动过程中使用LBA来加载我们的文件
    dd (20*16*63-1) # 分区有多少个扇区 10MB
    
    # 其他条目设置为0
    times (16*3) db 0
    
    # 签名 -> 扇区大小假定为512byte
    db 0x55
    db 0xaa



打印是通过BIOS服务完成, BIOS服务由BIOS中断来访问

# build.sh
# 组装启动文件
# -f bin 表示生成2进制文件
nasm -f bin -o boot.bin boot.asm
# 写入磁盘镜像
# conv=notrunc 不截断文件
dd if=boot.bin of=boot.img bs=512 count=1 conv=notrunc
# asm文件的注释去掉, 再build
chmod +x ./build.sh
sudo ./build.sh

重新安装 bochs


 上一篇
Node.js Microservices - API Gateway and Edge Services Node.js Microservices - API Gateway and Edge Services
1. Course Overview2. Setting up the Development Environment and Building Your First Node.js Microservice1. Introduction
下一篇 
技术大牛成长课,从0到1带你手写一个数据库系统(23年新课) 技术大牛成长课,从0到1带你手写一个数据库系统(23年新课)
第1章 课程介绍及学习指南 第2章 手写数据库系统的必要性,及系统的整体介绍2-1 为什么研究并实现一款数据库 2-2 我们希望设计一款怎样的数据库 2-3 如何快速实现原型,选择合适的语言 2-4 复杂项目的持续演进要点 2-5 学习提前
2023-12-30
  目录