zoukankan      html  css  js  c++  java
  • 第六课 突破512字节的限制 上

      前几节我们介绍了FAT12文件系统,制作了虚拟软盘文件a.img,并在Qt Creater中进行了文件内容的读取实验。那些读取都是使用外部的程序实现的,实际应用中,我们需要用主引导程序来实现文件的读写,主引导程序存在于主引导扇区MBR中,也就是说程序和文件是存在一张盘上的,而且这些主引导程序需要使用汇编语言实现。接下来,我们就来实现具有读取功能的主引导程序。

      为了验证文件读取的正确性,我们需要在主引导程序中先实现一个字符串打印函数。BIOS已经将中断向量写到了内存的指定位置处,这其中就有能实现字符串打印的函数,我们需要做的就是配置一些参数,需要配置的参数和配置步骤如下:

      1、指定打印参数(AX=0x1301 , BX = 0x0007)

      2、指定字符串的内存地址(ES:BP  = 字符串地址)

      3、指定字符串的长度(CX = 字符串长度)

      4、中断调用(int 0x10)

    示例如下:

      需要用到的汇编语言的知识点如下:

                                    

      下面直接给出打印字符串的汇编程序:

     1 org 0x7c00
     2 
     3 jmp short start
     4 nop
     5 
     6 define:
     7     BaseOfStack equ 0x7c00
     8 
     9 header:
    10     BS_OEMName     db "D.T.Soft"
    11     BPB_BytsPerSec dw 512
    12     BPB_SecPerClus db 1
    13     BPB_RsvdSecCnt dw 1
    14     BPB_NumFATs    db 2
    15     BPB_RootEntCnt dw 224
    16     BPB_TotSec16   dw 2880
    17     BPB_Media      db 0xF0
    18     BPB_FATSz16    dw 9
    19     BPB_SecPerTrk  dw 18
    20     BPB_NumHeads   dw 2
    21     BPB_HiddSec    dd 0
    22     BPB_TotSec32   dd 0
    23     BS_DrvNum      db 0
    24     BS_Reserved1   db 0
    25     BS_BootSig     db 0x29
    26     BS_VolID       dd 0
    27     BS_VolLab      db "D.T.OS-0.01"
    28     BS_FileSysType db "FAT12   "
    29 
    30 start:
    31     mov ax, cs
    32     mov ss, ax
    33     mov ds, ax
    34     mov es, ax
    35     mov sp, BaseOfStack
    36    
    37        mov ax, MsgStr
    38        mov bp, ax
    39        
    40        mov ax, ds
    41        mov es, ax
    42        
    43        mov cx, 6
    44     call Print
    45     
    46 last:
    47     hlt
    48     jmp last    
    49 
    50 ; es:bp --> string address
    51 ; cx    --> string length
    52 Print:
    53     mov ax, 0x1301
    54     mov bx, 0x0007
    55     int 0x10
    56     ret
    57 
    58 MsgStr db  "Hello, DTOS!"    
    59 MsgLen equ ($-MsgStr)
    60 Buf:
    61     times 510-($-$$) db 0x00
    62     db 0x55, 0xaa

      我们的虚拟软盘文件a.img已经格式化好了,现在要修改的只是第一个扇区即主引导扇区,所以我们要按照FAT12的格式来填充第一个扇区,因此,上面的程序中,第10到28行是FAT12的引导扇区的信息,它前面还有三个字节,其中前两个字节是跳转指令jmp short start,第三个字节为空指令nop。从start开始是我们的可执行程序,BaseOfStack是定义的栈底地址。

      汇编程序我们需要编译成二进制可执行程序,然后写入a.img虚拟软盘的第一个扇区中,每次都执行这个过程很麻烦,我们将这个过程写成makefile,如下所示:

     1 .PHONY : all clean rebuild
     2 
     3 SRC := boot.asm
     4 OUT := boot.bin
     5 IMG := a.img
     6 
     7 RM := rm -fr
     8 
     9 all : $(OUT) $(IMG)
    10     dd if=$(OUT) of=$(IMG) bs=512 count=1 conv=notrunc
    11     @echo "Success!"
    12 
    13 $(IMG) :
    14     bximage $@ -q -fd -size=1.44
    15 
    16 $(OUT) : $(SRC)
    17     nasm $^ -o $@
    18 
    19 clean :
    20     $(RM) $(IMG) $(OUT)
    21 
    22 rebuild :
    23     @$(MAKE) clean
    24     @$(MAKE) all
    25     

    bochs的启动文件修改成如下内容:

     1 ###############################################################
     2 # Configuration file for Bochs
     3 ###############################################################
     4 
     5 # how much memory the emulated machine will have
     6 megs: 32
     7 
     8 # filename of ROM images
     9 romimage: file=/usr/share/bochs/BIOS-bochs-latest
    10 vgaromimage: file=/usr/share/vgabios/vgabios.bin
    11 
    12 # what disk images will be used
    13 floppya: 1_44=a.img, status=inserted
    14 # choose the boot disk.
    15 boot: a
    16 
    17 # where do we send log messages?
    18 # log: bochsout.txt
    19 
    20 # disable the mouse
    21 mouse: enabled=0
    22 
    23 # enable key mapping, using US layout as default.
    24 keyboard_mapping: enabled=1, map=/usr/share/bochs/keymaps/x11-pc-us.map

      

      启动bochs,即可得到运行结果,如下所示:

      可见,hello已经成功打印出来了。

       接下来,我们开始读取文件,假如我们知道了数据所在的扇区,那么怎么将它读出来呢?先来看一下软盘的构造,如下所示:

      3.5寸软盘的特性如下:

      根据逻辑扇区号计算磁头号、柱面号、物理扇区号的方法如下:

      软盘复位和软驱数据读取的参数如下:

      整体的读取流程如下:

      需要用到的汇编知识点如下:

      

     下面直接给出汇编程序:

      1 org 0x7c00
      2 
      3 jmp short start
      4 nop
      5 
      6 define:
      7     BaseOfStack equ 0x7c00
      8 
      9 header:
     10     BS_OEMName     db "D.T.Soft"
     11     BPB_BytsPerSec dw 512
     12     BPB_SecPerClus db 1
     13     BPB_RsvdSecCnt dw 1
     14     BPB_NumFATs    db 2
     15     BPB_RootEntCnt dw 224
     16     BPB_TotSec16   dw 2880
     17     BPB_Media      db 0xF0
     18     BPB_FATSz16    dw 9
     19     BPB_SecPerTrk  dw 18
     20     BPB_NumHeads   dw 2
     21     BPB_HiddSec    dd 0
     22     BPB_TotSec32   dd 0
     23     BS_DrvNum      db 0
     24     BS_Reserved1   db 0
     25     BS_BootSig     db 0x29
     26     BS_VolID       dd 0
     27     BS_VolLab      db "D.T.OS-0.01"
     28     BS_FileSysType db "FAT12   "
     29 
     30 start:
     31     mov ax, cs
     32     mov ss, ax
     33     mov ds, ax
     34     mov es, ax
     35     mov sp, BaseOfStack
     36     
     37     mov ax, 34
     38     mov cx, 1
     39     mov bx, Buf
     40     
     41     call ReadSector
     42     
     43     mov bp, Buf
     44     mov cx, 24
     45     
     46     call Print
     47     
     48 last:
     49     hlt
     50     jmp last    
     51 
     52 ; es:bp --> string address
     53 ; cx    --> string length
     54 Print:
     55     mov ax, 0x1301
     56     mov bx, 0x0007
     57     int 0x10
     58     ret
     59 
     60 ; no parameter
     61 ResetFloppy:
     62     push ax
     63     push dx
     64     
     65     mov ah, 0x00
     66     mov dl, [BS_DrvNum]
     67     int 0x13
     68     
     69     pop dx
     70     pop ax
     71     
     72     ret
     73 
     74 ; ax    --> logic sector number
     75 ; cx    --> number of sector
     76 ; es:bx --> target address
     77 ReadSector:
     78     push bx
     79     push cx
     80     push dx
     81     push ax
     82     
     83     call ResetFloppy
     84     
     85     push bx
     86     push cx
     87     
     88     mov bl, [BPB_SecPerTrk]
     89     div bl
     90     mov cl, ah
     91     add cl, 1
     92     mov ch, al
     93     shr ch, 1
     94     mov dh, al
     95     and dh, 1
     96     mov dl, [BS_DrvNum]
     97     
     98     pop ax
     99     pop bx
    100     
    101     mov ah, 0x02
    102 
    103 read:    
    104     int 0x13
    105     jc read
    106     
    107     pop ax
    108     pop dx
    109     pop cx
    110     pop bx
    111     
    112     ret
    113 
    114 MsgStr db  "Hello, DTOS!"    
    115 MsgLen equ ($-MsgStr)
    116 Buf:
    117     times 510-($-$$) db 0x00
    118     db 0x55, 0xaa

      我们将虚拟软盘文件a.img用VS2013打开,查看其中的内容,截取片段如下:

      可以看到,a.txt文件的起始地址为0x4400,也就是第34个扇区开始,而内容的大小为24字节,这两个参数分别体现在汇编程序中的第37和44行。下面,启动bochs,运行结果如下:

      打印出了this is a floppy file.,我们成功读取了指定扇区的数据。

    参考狄泰软件学院操作系统教程

      

  • 相关阅读:
    Python ---chart
    python ---Pandas时间序列:生成指定范围的日期
    python 生成图表
    top 学习
    linux awk命令详解
    /proc 目录详细说明
    ps 和 top 的cpu的区别
    linux 监控性能学习笔记(1)
    转如何用九条命令在一分钟内检查Linux服务器性能?
    Linux系统排查——CPU负载篇
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9226311.html
Copyright © 2011-2022 走看看