锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

操作系统真象还原——1&2.初见MBR

时间:2022-10-17 08:00:01 二极管je05b1rs30

第1章 部署工作环境

  1. CPU硬件上已经规定了可以理解的指令格式,原则上只要遵循IA-32 将指令格式写入二进制文件中,即可直接相同CPU 对话了

  2. 虚拟机只是一个模拟硬件资源的普通过程。虚拟机检查在虚拟机中运行的任何行为,并在虚拟机分析后代表操作系统申请。

  3. 实验环境:virualBox Ubuntu21.04(前提安装gcc、gdb、make、libgtk2.0-dev、xorg-dev、g 、build-essential) bochs

    • 推荐文章:
      [1]https://blog.csdn.net/weixin_30751947/article/details/94875872?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-1.pc_relevant_paycolumn_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-1.pc_relevant_paycolumn_v2&utm_relevant_index=2
      [2]https://blog.csdn.net/aurorayqz/article/details/80310954
    • 真相还原中配置自己的配置bochs注意安装路径,不要写错
    • 使用keyboard: keymap=BOCHSPATH/share/bochs/kemaps/x11-pc-us.map,可能是版本问题。如果你没有报告这次旅行的错误,你可以忽略它
    • 报错dLopen failed for module ‘x’ (libbx_ x.so): file not found(https://blog.csdn.net/weixin_30363981/article/details/97344363)

    image-20220116212349190

  4. 安装bochs最后一个命令是x11不是xll,\换行符不需要写命令行符

第2章 编写MBR主引导记录

  1. 内存中的程序

    • 该程序被加载器加载到内存的某个区域
    • CPU的cs : ip 寄存器指向该程序的起始地址
  2. 实模式下的内存布局

  3. 基本输入输出系统BIOS建立的中断向量表可以使用int实现相关硬件调用

  4. 地址映射:CPU提交要访问的地址MMU(内存管理单元),MMU将虚拟地址转换为物理地址进行访问ROM、显存或内存(32位系统指的是32位地址总线,不完全用于访问内存)

  5. 计算机从加电到运行

    • 在计算机POST加电的瞬间, 电脑主板等设备供电,BIOS控制芯片组会向CPU发出并保持一个RESET(重置)信号,重置CPU内部状态,直到芯片组检测到电源已经开始稳定供电,然后回RESET信号
    • CPU 的cs : ip 寄存器被迫初始化为0xF00 : 0xFFF0 。由于启动时处于实际模式,段基址应左移4 位,于是0xF00 : 0xFFF0 转换地址为BIOS 的入口地址0xFFFF0 (Shadow技术:由于ROM执行速度远比RAM低,所以加电后ROM中的BIOS会被装载到Shadow RAM在中指定区域。由于Shadow RAM物理编址对应ROM同样的,所以当需要访问时BIOS只需访问Shadow RAM不需要访问ROM,这可以大大加快计算机系统的运行时间)
    • CPU到地址0xFFFF取出0处跳转指令jmp far f000:e05b,即再跳向0xfe05b处执行BIOS代码,检测外设并初始化,完成后在内存中0x000 ~0x3FF 建立中断向量表,填写中断例程
    • BIOS最后会校验启动盘的0 盘0 道1 扇区(CHS 风扇区的编号从1开始 开始的,LBA从0开始),如果这个扇区末尾的两个字节是魔法0x55 和0xaa, BIOS 认为这个扇区确实有可执行的主导记录MBR ,加载到物理地址0x7c00 ,然后跳到这个地址继续执行,CPU控制权由BIOS交给MBR。这里有一个小细节, BIOS 跳转到0x7c00 是用jmp 0: 0x7c00这是实现的jmp 指令的直接和绝对远程转移用法,段寄存器cs 这里的段基址将被替换 由之前的0xf00 变成了0
  6. 0x7c00的由来

    512字节大小的MBR 被BIOS加载到0x7C00到0x7DFF 处,MBR 这是一个程序,程序的运行需要栈的支持,栈也在内存中,大约1KB。结合以上三点,选择32点KB 中的最后1KB 最合适的地址是什么? 32KB 转换为16进制为0x8000,减去1kb(0x400),即0x7c00

  7. .bin文件为纯二进制文件,不含伪指令

  8. 显示器在80工作时*25文本模式(80行25列共2000字符),一个字符用两个字节表示,低字节为字符ASCII代码,高字节是字符属性,所以显示一个屏幕字符需要4KB

; 主引导程序MBR ; SECTION是伪指令,cpu不运行只方便程序员分段计划程序 ; `vstart=0x7c00`程序编译时将起始地址编译成0x7c00 ; SS存放栈顶段地址,SP存储栈顶的偏移地址。随时随地 ,SS:SP指向栈顶元素  ; CS存储内存中代码段入口的段基址,CS:IP指示下一个要操作的指令内存地址         ; 初始化部分 SECTION MBR vstart=0x7c00 ; =前后不能有空间  mov ax,cs   ; 由于BIOS是通过`jmp 0:Ox7c00`转到MBR的,故cs此时为0     mov ds,ax   ; 通用寄存器不能用立即数赋值ax     mov es,ax     mov ss,ax     mov fs,ax  mov sp,0x7c00          ; 使用10号中断的0x06功能号,窗口卷清屏,避免BIOS显示检测信息的影响  mov ax,0x600 ; ah存放将要调用的中断子功能号 mov bx,0x700 mov cx,0 ; (CL,CH)=窗口左上角的(X,Y)位置 mov dx,0x184f ; (DL,DH)=窗口右下角的(X,Y)位置(80,25) int 0x10 ; 调用中断 ; 使用10号中断的0x03功能号,获取光标位置 mov ah,3 ; 将中断子功能号存入ah寄存器等待被调用 mov bh,0 ; 存放待获取光标的页号 int 0x10 ; 调用中断后,ch=光标开始行,cl=光标结束行,dh=光标所在行号,dl=光标所在列号 ; 打印字符串 mov ax,message mov bp,ax ; es:bp为串首地址 mov cx,5 ; cx存放串长度,不包括结束符0的字符个数 mov ax,0x1301 ; ah表示调用13号子功能,al表示写字符方式01(光标跟随显示) mov bx,0x2 ; bh存储要显示的页号,bl是字符属性(02h表示黑底绿字) int 0x10 ; $表示本行指令所在的地址,$$表示本section的起始地址,$-$$表示执行代码行到段首的偏移量 jmp $ ; 在本行代码死循环 message db "ws MBR" times 510-($-$$) db 0 ; 将剩余字节用0进行填充 db 0x55,0xaa ; 最后两个字节填充MBR的标识 
  1. 安装nasm命令sudo apt-get install nasm

  2. dd命令是linux自带的,不需要安装

  3. 将mbr汇编文件放到bochs文件夹下的运行脚本

#!/bin/bash
rm -rf ./hd.img
bin/bximage -hd -mode=“flat” -size=60 -q hd.img
echo “disk creat success!!”
nasm mbr.s -o mbr.bin
dd if=mbr.bin of=hd.img bs=512 count=1 conv=notrunc
echo “disk write success!!”
bin/bochs -f bochsrc

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章