您的位置:首页 > 理论基础 > 计算机网络

操作系统与网络实现 之三

2015-11-06 15:27 1046 查看
 

关于磁盘的数据存储和定位<?xml:namespace prefix = o />

这是一个磁盘示意图:



一个磁盘有两面。0面和1面。
磁道共80个,编号由外向里(0号-79号)。 扇区(Sector)是磁盘存储的最小单位,一个扇区有512字节,一个磁道有18个扇区(1号-18号)。  
为方便存取文件必须对扇区进行编号,这编号称为软盘地址。软盘地址由磁头号、磁道号、扇区号三部分组成。
(1)磁头号。0面对应0号磁头,1面对应1号磁头。   
(2)磁道号。从软盘的最外侧00道开始,由外向里排列,3.5英寸高密软盘共80个磁道。
(3)扇区号。1号至18号
软盘的大小计算方式如下:
2*80*18*512 = 1474560Byte = 1440KB
如果我们用磁头号+磁道号+扇区号来表达,那么:0.0.1表示0面0磁道1扇区
读磁盘是这样的,在同一磁道里的18个扇区是连续读,读完这个磁道,转换磁头,那么就像下面这样:
0.0.1读至0.0.18,转换磁头,1.0.1读至1.0.18,转换磁头,0.1.1读至0.1.18,转换磁头,1.1.1读至1.1.18,......
 
对应的我们将用到int 13h功能,这里介绍一下:
功能02H 
功能描述:读扇区 
入口参数:AH=02H
AL=扇区数 
CH=磁道 
CL=开始扇区 
DH=磁头 
DL=驱动器号,00H~7FH:软盘;80H~0FFH:硬盘   这里我们的DL是0
ES:BX=缓冲区的地址  也就是我们要写入的地址
 
 
下面我们看看将一个kernelloader.asm的可执行代码kernelloader.bin读到内存0x1000中的子程序,前面已经知道,boot.bin存放在0磁道第1个扇区,kernelloader.bin紧接着boot.bin,排列在0磁道第2个扇区,目前kernelloader共占据1个扇区512字节:
 
read_kernelloader:                                       ;读入 kernelloader 程序
  push              es
 
  .read_kernelloader:
  mov               ax , 0x1000                           ;kernelloader.bin 所在的段基址           
  mov               es , ax
  mov               bx , 0                                 ;写入到内存0x1000:0000
  mov               ah , 2
  mov               dh , 0                                 ;磁头
  mov               dl , 0                                  ;驱动器号
  mov               ch , 0                                  ;磁道0
  mov               cl , 2                                  ;第2个扇区
  mov               al , 1                                  ;读入扇区数,每个扇区为 512B
  int               0x13 
  jc                .read_kernelloader
 
  pop               es
  ret
 
因为受512字节限制,boot.asm能做的事情实在有限,下面我们改变一下boot.asm功能,让它只负责读取kernelloader程序到内存0x1000:0000的地方,然后跳转到0x1000:0000执行kernelloader程序,这样可以摆脱boot启动程序只有512字节的限制,可以让kernelloader做许多事情。
两个程序如下:
boot.asm
[BITS 16]                                                  ;编译成16位的指令
[ORG 0x7C00]
jmp                 main
 
read_kernelloader:                                        ;读入 kernelloader 程序
  push              es
 
  .rk:
  mov               ax , 0x1000                            ;kernelloader.bin 所在的段基址           
  mov               es , ax
  mov               bx , 0
  mov               ah , 2
  mov               dl , 0
  mov               ch , 0
  mov               cl , 2
  mov               al , 1                                 ;读入扇区数,每个扇区为 512B
  int               0x13 
  jc                .rk
 
  pop               es
  ret
 
main:                                                       ;主程序         
  mov               ax , 0x0                               ;boot.bin 程序的段基址
  mov               ds , ax
 
  call              read_kernelloader                    ;读入 kernelloader 程序 
 
  jmp dword         0x1000:0                              ;跳转到 kernelloader 处执行
times 510-($-$$) db 0
db 0x55
db 0xAA
 
kernelloader程序将放在boot程序之后,目前小于512字节,也就是0面,0磁道,第二扇区开始,占据一个扇区的位置。
kernelloader.asm
[BITS 16]  
jmp main
ns db 0x48,0x65,0x6C,0x6C,0x6F,0x20,0x77,0x6F,0x72,0x6C,0x64,0x21,'f','r','o','m',' ','y','a'   ;;hello world!from ya
main:
mov ax, cs
mov ds, ax
mov es, ax
mov cx,19           ;循环19次
mov bx,0            ;从数组[0]开始
mov ah,0eh
next:
mov al,[ns+bx]
int 10h
inc bx
dec cx
jnz next              ;cx不为0则继续
po:
jmp po
 
修改makefile文件,最后在bochs运行a.img,显示Hello world!from ya
makefile
######################
#声明要编译的所有组成,这里的ya是本工程名称,可以取任何名字,这里就用ya
######################
ya:out/boot.bin out/kernelloader.bin out/creat_img.exe out/write_in_img.exe A B C
#开始对各部分编译,注意不是空格是Tab键
 
out/boot.bin:code/boot.asm
    nasm code/boot.asm -o out/boot.bin
out/kernelloader.bin:code/kernelloader.asm
    nasm code/kernelloader.asm -o out/kernelloader.bin
 
# 制作内核映象文件
out/creat_img.exe:code/creat_img.c
    gpp code/creat_img.c -o out/creat_img.exe
# 执行dos命令,在final目录下生成a.img文件
A:
    out/creat_img.exe final/a.img
 
# 写入文件,argv[1]=目标文件 argv[2]=源文件  argv[3]=写入偏移量  
#在DOS下用法: write.exe a.img kernelloader.bin 512
out/write_in_img.exe:code/write_in_img.c
    gpp code/write_in_img.c -o out/write_in_img.exe
# 执行dos命令,向a.img写入代码,内容是boot.bin
# 从0偏移量起始
B:
    out/write_in_img.exe final/a.img out/boot.bin 0
# 执行dos命令,向a.img写入代码,内容是kernelloader.bin
# boot.bin已经占用了512字节,从512偏移量起始
C:
    out/write_in_img.exe final/a.img out/kernelloader.bin 512
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: