如何读emmc里的引导程序_自制操作系统学习1 引导程序

eaf622e5c1ae1037318b8558cb6d5ad4.png

本系列学习有前面的汇编学习基础最好,如果没有影响也不大本系列学习主要资源来自《[30天自制操作系统].(川合秀实)》,《自己动手写操作系统》两本书

一、准备工作

  • bochs
  • virtualbox,windows虚拟机
  • nasm

二、操作流程

回顾前文的程序,我们的引导程序已经可以加载软盘的10个柱面的数据到内存的 0x0820 处,引导区本身的512字节由BIOS加载到0x8200处。
这一节让程序从这些数据中找到软盘上的程序,并运行其中的程序。

下面程序的重点是加载文件后,程序所在位置。通过前一节可以知道:

  • 文件名在磁盘的是 0x2600处
  • 文件内容在磁盘的0x4200处
  • 磁盘的内容加载到内存的0x8000处
  • 所以磁盘的0x4200处的内容在 内存的 0x8000+0x4200=0xc200处

1. 修改程序

;%define _BOOT_DEBUG_   ; 做Boot Sector时把这行注释掉        ; 启用这行就用nasm Boot.asm -o Boot.com生成.com文件用于调试%ifdef _BOOT_DEBUG_   org  0100h%else   org 07c00h%endifCYLS EQU 10                ; 一共读取10个柱面, 共 10柱面*2面*18扇区*512字节 = 184320 byte = 180K; 把软盘按Fat12格式填充start:   JMP init                ; 跳转指令   DB       0x90            ; 空 DB,DD用来写单字节   DB       "NotOneOS"      ; 厂商名,8字节,DB用来写双字节   DW       512             ; 每个扇区大小512字节,DW用来写4字节   DB       1               ; 每个簇的扇区数   DW       1               ; Boot占的扇区   DB       2               ; 有2个FAT表   DW       224             ; 根目录大小224   DW       2880            ; 磁盘扇区总数 2880   DB       0xf0            ; 介质描述符,磁盘种类必须为0xf0   DW       9               ; 每个FAT扇区数   DW       18              ; 每个磁道18个扇区   DW       2               ; 2个磁头   DD       0               ; 隐藏扇区数   DD       2880            ; 同上,磁盘大小   DB       0, 0, 0x29      ; 0x29 扩展引用标记   DD       0xffffffff      ; 无意义,固定这么写   DB       "NotOneOS   "   ; 磁盘名(卷标),11字节   DB       "FAT12   "      ; 磁盘格式名,8字节   RESB     18              ; 空18个字节,填充0x00init:   MOV      AX,0   MOV      SS,AX   MOV      SP,0x7c00      ; 堆栈空间,从0x7c00向前   MOV      DS,AX; 读取磁盘      MOV      AX,0x0820      ; 把磁盘数据加载到内存0x0820处。 0x8000~0x81ff的512字节给启动区用的,所以从0x8200开始   MOV      ES,AX          ; 注意 ES:BX 是指向的地址,后面还需要对BX赋值0; 初始化磁盘接口   MOV      CH,0           ; 柱面 0   MOV      DH,0           ; 磁头 0   MOV      CL,2           ; 扇区 2readloop:   MOV      SI,0           ; 记录失败次数retry:   MOV      AH,0x02        ; 0x02 读磁盘   MOV      AL,1           ; 读1个扇区   MOV      BX,0   MOV      DL,0x00        ; A驱动器   INT      0x13           ; BIOS 读磁盘功能   JNC      next           ; 成功跳转   ADD      SI,1           ; 失败加一次   CMP      SI,5           ; 到5次就跳到error   JAE      error   MOV      AH,0x00        ; 复位磁盘功能   MOV      DL,0x00        ; A 驱动器   INT      0x13           ; 重置磁盘驱动器   JMP      retry          ; 重试   next:   MOV      AX,ES          ; 内存地址向后移动0x0020   ADD      AX,0x0020      MOV      ES,AX          ; 通过AX给ES加0x0020   ADD      CL,1           ; 扇区+1   CMP      CL,18          ; 有没有到18个扇区   JBE      readloop       ; CL<=18,就跳到 readloop   MOV      CL,1   ADD      DH,1   CMP      DH,2   JB       readloop       ; 如果 DH < 2 ,则跳到readloop   MOV      DH,0   ADD      CH,1   CMP      CH,CYLS   JB       readloop       ; 如果CH

2. 编译,生成镜像

make img

3. 在Win7虚拟机中打开A盘,装载镜像

ce88d647faccea797c98ffa9da6172f3.png


把NotOneOs.sys拷到A盘:

f813dff507d13c9c0f025f72b87a74b4.png

再移除虚拟盘:

de6c1e4b707771b7bded25687607f1fc.png

三、启动镜像

这时候boot.img里包含了启动的NotOneOs.sys程序,使用bochs加载运行:

# 这里进入调试状态,以确定是否运行了NotOneOs.sys程序make debug b 0x7c00cs
6aab6b32fcee63aba53380fd980504eb.png

通过反汇编,可以找到我们的重点代码位置:

u 0x7c00 0x7cff
6ae0271ce94dc16655e17e20f39282c6.png


在0x7cca处设置断点: b 0x7cca

f9135c0f9988bc9b7922876f84b5466f.png


查看现在寄存器的值:

<21> rrax: 00000000_00000e00rbx: 00000000_0000000frcx: 00000000_00090a01rdx: 00000000_00000100rsp: 00000000_00007c00rbp: 00000000_00000000rsi: 00000000_000e7ce8rdi: 00000000_0000ffac21>

rdx的值里看到 DH确实为1,再次单步运行,程序跳转到了0xc200:

681002f598301033e8508db59eeba555.png


而0xc200处正是NotOneOs.sys的程序:

c7fb17d7140641e37045dcf5a13e5dbe.png
6389d66802d7e70e56c026f8d510df0e.png


后面的重心终于可以跳到C语言了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值