虚拟硬盘vhd
virtual hard disk
用virtualbox新建的没有操作系统的虚拟电脑,选择VHD格式虚拟硬盘,固定大小2G.
刚建立的vhd虚拟硬盘文件的最后512字节是有意义的,前面其他字节都是空的
这最后512个字节是啥呢?
结构体定义
1 | struct hd_ftr { //harddisk_footer |
cookie
可以理解为文件魔数,通过检查cookie值是否是"conectix",判断该VHD是否有效
conectix是connectix公司的名称缩写,这个技术是connectix发明的
features
1 |
ff_version
VHD版本
data_offset
对固定磁盘来说,该值总是0xFFFFFFFF,不重要
对于动态磁盘来说,该值是dd_hdr的文件偏移量
timestamp
VHD文件的创建时间,不重要
crtr_app
创建该VHD文件使用的应用程序,如果是virtualbox创建的则为"vbox"
crtr_ver
创建版本,不同磁盘版本管理方法不同
crtr_os
操作系统枚举值
orig_size
创建时该虚拟磁盘的可用寻址空间,大小等于整个vhd文件大小减去该尾部扇区512字节
该nobody.vhd文件在创建时我们选择的大小是整2G,用010editor打开观察,发现除了最后一个扇区正好2G,全空.
加上最后一个扇区则为2GB+512B
curr_size
当前大小,可能是扩容后的可用寻址空间
geometry
几何参数,即柱面数C,磁头数H,扇区数S
VHD规范中,每个扇区sector大小是512B
刚建立的2G的虚拟硬盘,有4161个柱面
16个磁头,即16个盘面
每个柱面上有63个扇区
VHD文件最开始的512字节,就对磁盘的0面0道1扇区,也就是主引导扇区
接下来是0面0道2扇区
0面0道3扇区
...
0面0道63扇区
1面0道1扇区
1面0道2扇区
...
1面0道63扇区
...
15面0道0扇区
15面0道1扇区
15面0道63扇区
0面1道0扇区
type
VHD类型
1 |
前三个容易理解,第四个差分磁盘是什么呢?
差分盘分成母盘和子盘,一个母盘可以带好几个子盘,母盘存放这几个子盘共有的东西,比如操作系统代码,就跟so动态库似的可以复用
每个子盘中单独存放自己的数据
假如原来要装四个虚拟机,每个虚拟机操作系统在磁盘中占8g,剩下2g磁盘存放数据.
如果不使用差分磁盘,则四个虚拟机就实打实地需要40G的物理磁盘
然而每个虚拟机中占据8G磁盘的操作系统实际上是搞重复建设
因此可以用母盘放8G的操作系统,四个子盘每个2G存放各自的数据.
这样总共占用物理磁盘16G
checksum
检校和
最后这个扇区的所有字节相加得到的32位数按位取反
uuid
VHD识别号,决定VHD主从关系
saved
动态磁盘才会使用,不重要
reserved
保留关键字,尚未使用
物理磁盘
磁盘结构
结构总览
面0,面1,实际上就是磁头0,磁头1
因为每个面上都会有一个磁头负责读写该面的数据
扇区和磁道的关系
一个盘面从里向外有多个同心圆磁道,每个磁道上有多个扇区,但是任意两个磁道的扇区数是相同的,
可以想象,越往外的磁道,一个扇区约长,数据约稀疏
磁头和柱面
柱面和磁头都是从0开始编号,但是扇区是从1开始编号的
一个盘片就像一个烧饼一样有两面,每面上都有磁道,一个柱面就是所有等半径的磁道集合
比如有三个盘片就有6个盘面,那么半径为2厘米的磁道就有6条,半径为2厘米的柱面就包含了这6条磁道
有多少个盘面就得有多少个磁头,每个磁头负责一个盘面的读写
所有磁头的动作都是同步的,就算是要读写最顶上这个盘的上面,所有的磁头都得跟着最上面这个磁头动,从顶向下看所有磁头是重叠的.但是只有上面这个磁头可以读写数据.控制哪个磁头也是硬盘控制器要做的工作
读写速度
磁盘的读写速度有三个方面组成
寻道时间,旋转时间,传送时间
寻道时间
假如一开始磁头都趴在最外环上,现在需要往最内环的扇区读写数据,那么传动臂就得跟个塔吊一样把磁头吊过去
这是肉眼可见的,显然速度非常慢
旋转时间
现在磁头已经到达了最内环,要读写该环上的第一个扇区,但是不巧,磁头刚过来时,第一个扇区刚转过去,磁头就得等到盘子转一整圈才能盼来第一个扇区,而CPU早已望眼欲穿了
传送时间
扇区也到位了,磁头赶紧趴下看看扇区上写了啥
这个过程肉眼几乎不可见,是最快的
这三个过程前面两个都是毫秒量级的,并且差不多.最后的传送时间稀松了了,相对于前面俩可以忽略
访问模式
访问模式有两种,老古董CHS模式,即通过指定柱面,磁头,扇区三个坐标访问一个扇区
现代LBA(logical block address)模式,不考虑柱面,磁头数了,所有扇区统一编号,将逻辑扇区号翻译成CHS的工作交给硬盘控制器干
LBA和CHS的映射关系
逻辑扇区从0开始编号
假设某个硬盘有h个磁头,c个柱面,每个磁道上有s个扇区,给定一个逻辑扇区号g,求改扇区落在哪个盘子的哪个磁道上
这三个单位的权重是c>h>s
因为寻道时间>旋转时间>传送时间,因此最忌讳动传动臂,磁头最好老实在固定的一环上趴着,等这个柱面上的所有磁道都满了,才迫不得已动一下传动臂换个圈转
这就是为啥权重c>h
每个柱面上有h*s
个扇区,每个磁道上有s个扇区
n*h*s<=g<(n+1)*h*s
n就是第几个柱面,也就是哪个磁道,至于哪个盘子
1 | k*s<=(g-n*h*s)<(k+1)*s |
k就是哪个盘子
瞎写主引导记录
程序来自教材x86汇编语言从实模式到保护模式
他这段程序用nasm编会报错,因为mov [0x00],'a'
只指定了目的地址,但是没有说明大小
我是把'a'搬到0x00这个位置上一个字节?还是0x00~0x01
这个字还是0x00~0x03
这个双字?没有说清.
假:'a'不是一个字节吗?自然搬过去还是一个字节喽!
这里'a'实际上就是一个立即数,就是'a'的ASCII码.而一个立即数是不能决定占用几个字节的
如果写mov [0x00],al
这样就可以,把al这个字节寄存器的东西搬到内存0x00位置上,这时候就不用指定多大的内存了,因为al自己隐含就是一个字节寄存器了
并且这一点儿代码根本凑不够一个扇区,需要写一些废话填满一个扇区才有效
应该这样写:
1 | ; 4-2.asm |
编译:
1 | nasm main.asm -o main.bin |
然后使用fixvhdw2把main.bin写到虚拟磁盘nobody.vhd中
现在就可以开启虚拟机了
asm三个字已经打印在最左上角
如果不够512字节
如果main.asm没写废话
1 | mov ax,0xb800 |
编译成main.bin之后是远没有512个字节的
不够512个字节的主引导记录作废了,写到磁盘里然后尝试启动会说找不到靴子
至于怎么凑够的512字节,以及为啥可以在屏幕上输出asm,那是后话了