linux fat get entry,操作系统--主引导程序控制权的转移
一.主引导程序控制权的转移
首先需要了解的是BootLoader内存布局,在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。
0x7c00主引导程序的起始地址,之前为栈空间,主要是函数调用。,最终主引导程序是从boot程序跳转到0x9000loader,中间部分为Fat表,占用4个字节
1.通过FAT表加载文件内容--流程图
实验步骤
1.在虚拟软盘中创建体积较大的文本文件(Loader)
2.将Loader的内容加载到BaseOfLoader地址处
3.打印Loader中的文本(判断加载是否完全)
org 0x7c00
jmp short start
nop
define:
BaseOfStack equ 0x7c00
BaseOfLoader equ 0x9000
RootEntryOffset equ 19
RootEntryLength equ 14
EntryItemLength equ 32
FatEntryOffset equ 1
FatEntryLength equ 9
header:
BS_OEMName db "D.T.Soft"
BPB_BytsPerSec dw 512
BPB_SecPerClus db 1
BPB_RsvdSecCnt dw 1
BPB_NumFATs db 2
BPB_RootEntCnt dw 224
BPB_TotSec16 dw 2880
BPB_Media db 0xF0
BPB_FATSz16 dw 9
BPB_SecPerTrk dw 18
BPB_NumHeads dw 2
BPB_HiddSec dd 0
BPB_TotSec32 dd 0
BS_DrvNum db 0
BS_Reserved1 db 0
BS_BootSig db 0x29
BS_VolID dd 0
BS_VolLab db "D.T.OS-0.01"
BS_FileSysType db "FAT12 "
start:
mov ax, cs
mov ss, ax
mov ds, ax
mov es, ax
mov sp, BaseOfStack
mov ax, RootEntryOffset
mov cx, RootEntryLength
mov bx, Buf
call ReadSector
mov si, Target
mov cx, TarLen
mov dx, 0
call FindEntry
cmp dx, 0
jz output
mov si, bx
mov di, EntryItem
mov cx, EntryItemLength
call MemCpy
mov ax, FatEntryLength
mov cx, [BPB_BytsPerSec]
mul cx
mov bx, BaseOfLoader
sub bx, ax
mov ax, FatEntryOffset
mov cx, FatEntryLength
call ReadSector
mov cx, [EntryItem + 0x1A]
mov si, BaseOfLoader
loading:
mov ax, dx
add ax, 31
mov cx, 1
push dx
push bx
mov bx, si
call ReadSector
pop bx
pop cx
call FatVec
cmp dx, 0xFF7
jnb BaseOfLoader
add si, 512
jmp loading
output:
mov bp, MsgStr
mov cx, MsgLen
call Print
last:
hlt
jmp last
; cx --> index
; bx --> fat table address
;
; return:
; dx --> fat[index]
FatVec:
mov ax, cx
mov cl, 2
div cl
push ax
mov ah, 0
mov cx, 3
mul cx
mov cx, ax
pop ax
cmp ah, 0
jz even
jmp odd
even: ; FatVec[j] = ( (Fat[i+1] & 0x0F) << 8 ) | Fat[i];
mov dx, cx
add dx, 1
add dx, bx
mov bp, dx
mov dl, byte [bp]
and dl, 0x0F
shl dx, 8
add cx, bx
mov bp, cx
or dl, byte [bp]
jmp return
odd: ; FatVec[j+1] = (Fat[i+2] << 4) | ( (Fat[i+1] >> 4) & 0x0F );
mov dx, cx
add dx, 2
add dx, bx
mov bp, dx
mov dl, byte [bp]
mov dh, 0
shl dx, 4
add cx, 1
add cx, bx
mov bp, cx
mov cl, byte [bp]
shr cl, 4
and cl, 0x0F
mov ch, 0
or dx, cx
return:
ret
; ds:si --> source
; es:di --> destination
; cx --> length
MemCpy:
push si
push di
push cx
push ax
cmp si, di
ja btoe
add si, cx
add di, cx
dec si
dec di
jmp etob
btoe:
cmp cx, 0
jz done
mov al, [si]
mov byte [di], al
inc si
inc di
dec cx
jmp btoe
etob:
cmp cx, 0
jz done
mov al, [si]
mov byte [di], al
dec si
dec di
dec cx
jmp etob
done:
pop ax
pop cx
pop di
pop si
ret
; es:bx --> root entry offset address
; ds:si --> target string
; cx --> target length
;
; return:
; (dx !=0 ) ? exist : noexist
; exist --> bx is the target entry
FindEntry:
push di
push bp
push cx
mov dx, [BPB_RootEntCnt]
mov bp, sp
find:
cmp dx, 0
jz noexist
mov di, bx
mov cx, [bp]
call MemCmp
cmp cx, 0
jz exist
add bx, 32
dec dx
jmp find
exist:
noexist:
pop cx
pop bp
pop di
ret
; ds:si --> source
; es:di --> destination
; cx --> length
;
; return:
; (cx == 0) ? equal : noequal
MemCmp:
push si
push di
push ax
compare:
cmp cx, 0
jz equal
mov al, [si]
cmp al, byte [di]
jz goon
jmp noequal
goon:
inc si
inc di
dec cx
jmp compare
equal:
noequal:
pop ax
pop di
pop si
ret
; es:bp --> string address
; cx --> string length
Print:
mov dx, 0
mov ax, 0x1301
mov bx, 0x0007
int 0x10
ret
; no parameter
ResetFloppy:
push ax
push dx
mov ah, 0x00
mov dl, [BS_DrvNum]
int 0x13
pop dx
pop ax
ret
; ax --> logic sector number
; cx --> number of sector
; es:bx --> target address
ReadSector:
push bx
push cx
push dx
push ax
call ResetFloppy
push bx
push cx
mov bl, [BPB_SecPerTrk]
div bl
mov cl, ah
add cl, 1
mov ch, al
shr ch, 1
mov dh, al
and dh, 1
mov dl, [BS_DrvNum]
pop ax
pop bx
mov ah, 0x02
read:
int 0x13
jc read
pop ax
pop dx
pop cx
pop bx
ret
MsgStr db "No LOADER ..."
MsgLen equ ($-MsgStr)
Target db "LOADER "
TarLen equ ($-Target)
EntryItem times EntryItemLength db 0x00
Buf:
times 510-($-$$) db 0x00
db 0x55, 0xaa
对此进行make的结果
从该结果可以看出,TIME的值为负数了,说明主引导程序的大小大于了512,我们需要将其减小,将之前不重要的入栈与出栈的操作进行删除,以免占用空间,那么我们之前为何要这样做呢?是为了遵守汇编代码的约定,有操作相关寄存器的值就要进行入栈出栈操作。那么我们这块内存已经不够,因此没必要进行这个操作了。我们将下面的入栈出栈操作进行删除,但是要在 FindEntry 这个函数保留 cx 寄存器的入栈出栈的操作,原因是下面不停在改变 cx 寄存器的值。我们在 find 操作中,call MemCmp 操作前后有必要再加上 si 寄存器的入栈出栈操作
将其改正后的make以及在bochs上实现的结果为会打印loader中的字符串内容
B.第一个loader程序
1.起始地址0x9000
2.通过int0x10在屏幕上打印字符串
a.零标志位--判断运算的结果是否为0,当运算结果为0时,ZF位的值为1
b.同时jxx代表了一个指令族,功能是根据标志位进行调整
jo当OF为1则跳转,jc当CF为1则跳转,jns当SF不为1则跳转,jz当ZF为1则跳转,je比较结果为相等则跳转
loader.asm代码实现
org 0x9000
begin:
mov si, msg
print:
mov al, [si]
add si, 1
cmp al, 0x00
je end
mov ah, 0x0E
mov bx, 0x0F
int 0x10
jmp print
end:
hlt
jmp end
msg:
db 0x0a, 0x0a
db "Hello, D.T.OS!"
db 0x0a, 0x0a
db 0x00
将loader.asm进行反编译得出的结果
可以看到在这里的jz对应的是loader.asm中的je命令
接下来将loader拷贝到软盘中去,然后从Boot跳转到loader进行执行,我们将虚拟软盘先在linux中进行挂载,然后进行拷贝,最后进行运行
从打印的结果可以看出,控制权从boot已经转移到loader程序了
将其打印结果进行修改看在bochs上的实现结果是否也修改了
在这里我们需要将makefile文件进行修改保证后期的运行简便
.PHONY : all clean rebuild
BOOT_SRC := boot.asm
BOOT_OUT := boot
LOADER_SRC := loader.asm
LOADER_OUT := loader
IMG := data.img
IMG_PATH := /mnt/hgfs
RM := rm -fr
all : $(IMG) $(BOOT_OUT) $(LOADER_OUT)
@echo "Build Success ==> D.T.OS!"
$(IMG) :
bximage $@ -q -fd -size=1.44
$(BOOT_OUT) : $(BOOT_SRC)
nasm $^ -o $@
dd if=$@ of=$(IMG) bs=512 count=1 conv=notrunc
$(LOADER_OUT) : $(LOADER_SRC)
nasm $^ -o $@
sudo mount -o loop $(IMG) $(IMG_PATH)
sudo cp $@ $(IMG_PATH)/$@
sudo umount $(IMG_PATH)
clean :
$(RM) $(IMG) $(BOOT_OUT) $(LOADER_OUT)
rebuild :
@$(MAKE) clean
@$(MAKE) all
最后将data.img在window下实现
小结
1.Boot需要进行重构保证在512字节内完成功能
2.在汇编程序中尽量确保函数调用前后通用寄存器的状态不变
3.Boot成功加载Loader后将控制权转移
4.Loader程序没有代码体积上的限制
linux fat get entry,操作系统--主引导程序控制权的转移相关推荐
- linux fat get entry,Linux kernel FAT32文件系统分析
文本探讨了Linux kernel中对fat32文件系统的实现,关于fat文件的格式可以查看微软的fat白皮书. 1. FAT表操作 FAT文件系统中,使用FAT表标记哪个cluster被占用 ...
- 操作系统真像还原 - MBR主引导程序初体验
;主引导程序 ;------------------------------------------------------------ SECTION MBR vstart=0x7c00mov ax ...
- Linux 私房菜————Linux系统基本操作命令(十)|引导程序|服务控制
引导程序和服务控制 一.Linux操作系统引导过程总览 1.开机自检 2.MBR引导 3.GRUB 菜单 4.加载内核 5.init进程初始化 二.Linux系统初始化进程 1.init进程 2.Sy ...
- 【收藏】FAT文件系统原理——MBR(主引导记录
FAT文件系统原理--MBR(主引导记录) 一.硬盘的物理结构: 硬盘存储数据是根据电.磁转换原理实现的.硬盘由一个或几个表面镀有磁性物质的金属或玻璃等物质盘片以及盘片两面所安装的磁 ...
- Linux进程核心调度器之主调度器schedule--Linux进程的管理与调度(十九)
日期 内核版本 架构 作者 GitHub CSDN 2016-06-30 Linux-4.6 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度 ...
- Linux/Windows/MacOS各个操作系统下推荐应用集合
Linux/Windows/MacOS各个操作系统下推荐应用集合 作者 | Rocky0429 来源 | Python空间 大家好,我是 Rocky0429,一个喜欢在网上搜集各种软件的蒟蒻- 作为一 ...
- 宿主机windows Xp部署virtualBox虚拟机并在其上安装linux Centos(Red Hat)操作系统
在Windows操作系统上安装虚拟机VirtualBox,在虚拟机上部署Linux Centos(Red Hat)操作系统: 一 虚拟机VirtualBox安装 1.下载Virtualbox:http ...
- Linux 定制X86平台操作系统
/********************************************************************************** Linux 定制X86平台操作系 ...
- linux 内核rt,实时操作系统kernel rt
https://blog.csdn.net/baidu_34045013/article/details/78886617 实时应用程序在某些触发事件和应用程序对该事件的响应之间有操作截止日期.为了满 ...
- sun工作站linux,LINUX SUN Solaris 8操作系统安装指导书.doc
LINUX SUN Solaris 8操作系统安装指导书 摘要: 本文用于指导在SUN的小型机上安装Solaris 8的安装,介绍了基于通过终端方式安装Solaris 8的方法.主要包括操作系统的安装 ...
最新文章
- Java面试常被问到的题目+解答
- tcp/ip 建立过程
- 【explain】MySQL联表查询中的驱动表
- boost::process::throw_on_error相关的测试程序
- 基于水色图像的水质评价
- 第八十四期: Java、Web 和移动程序员学习的 12 个框架
- flexcell控件 许可证信息没有找到_报表控件 ActiveReports 全面迎来 .Net Core 时代
- 【Web】WEB项目初启动的那些糟心事
- 《CSS基础教程》 读书笔记二
- python数据结构剑指offer-重建二叉树
- JAVA刻度_java – 对数轴标签/刻度定制
- 熬夜做出的数据可视化,却被领导臭骂,只因这个......
- ESP32开发 0.windows Vscode开发环境搭建,基于esp-idf-V4.2 | Cmake | Vscode插件
- SSH整合开发基本步骤
- toshiba linux 打印机驱动的资料
- 沅江市城市之星智慧桥机器人_城市之眼,国内十大最高城市摩天轮排名,你坐过哪个...
- Windows XP下使用 whoami 命令
- 这游戏到底怎么了? 一年后,再看《刺客信条奥德赛》
- Deep Learning for UAV-based Object Detection andTracking: A Survey(论文翻译)
- 交换机,路由器上的 S口 F口 E口 Gi是什么?