使用文件系统

来源:互联网 发布:淘宝售后客服工资待遇 编辑:程序博客网 时间:2024/05/04 12:47

注:本文仍然主要来自《writeos-1.0-2-weekly》

一、加载指定扇区支指定空间

《运行自己的操作系统(linux版) -0.01》提到读入启动扇区,那是由硬盘自动完成的。

若要读入其它扇区到一个特定的内存空间,就要自己写代码完成,使用底层BIOS系统提供的BIOS 13h号中断,如图:

 

(1)读入一个扇区需要用到的参数,假设扇区号已知,需要用的参数及获取方法如下:

 

al扇区数根据需要填写,本文中为1cx高10位柱面号由上图公式计算cx低6位扇区号根据需要填写dh磁头号由上图公式计算dl驱动器根据需要填写,软盘为0es:bx数据缓冲区地址根据需要填写

(2)把各个寄存器的值按如图设置,然后调用13号中断,该扇区的内容就被读到ES:BX空间中

(3)代码实现

/*=====================================================================  Routine: ReadSector  Action: Read %c1 Sectors from %ax sector(floppy) to %es:%bs(memory)  Assume sector number is 'x', then    x / (BPB_SecPerTrk) = y,    x % (BPB_SecPerTrk) = z.  The remainder 'z' plus 1 is the start sector number;  The quotient 'y' devied by BPB_NumberHeads(RIGHT SHIFT 1 bit) is sylinder number;  AND 'y' by 1 can got magnetic header.*/ReadSector:                            /*图0*/     push    %ebp                       /*图1*/    mov        %esp,    %ebp           /*图2*/     sub        $2,        %esp        /*图3,Reserve space for saving %cl*/    mov        %cl,    -2(%ebp)        /*图4*/     push    %bx                    /*图5,Save bx*/    mov        (BPB_SecPerTrk), %bl/*%bl: the devider*/    div        %bl                    /*'y' in %al, 'z' in %ah*/    inc        %ah                    /*z++, got start sector*/    mov        %ah,    %cl            /*%cl <- start sector number*/    mov        %al,    %dh            /*%dh <- 'y'*/    shr        $1,        %al            /*'y' / BPB_NumberHeads*/    mov        %al,    %ch            /*%ch <- Cylinder number(y>>1)*/    and        $1,        %dh            /*%dh <- Magnetic header(Y&1)*/    pop        %bx                    /*图6, Restore %bx*/    /*Now we got cylinder number in %ch, start sector number in %cl, magnetic header in %dh.*/    mov        (BS_DrvNum), %dlGoOnReading:    mov        $2,        %ah    mov        -2(%ebp), %al        /*Read %al sectors,根据图6,%al得到的是图4存入的%cl*/    int        $0x13    jc        GoOnReading            /*If CF set 1, mean read error, reread.*/    add        $2,        %esp        /*图7*/     pop        %ebp                   /*图8*/     ret


(4)为了便于理解该函数,在涉及堆栈操作的地方画了几张图

二、查找一个指定文件

都在图里了,代码比较长,看原著吧

三、加载一个指定文件

(1)FAT12表项是12位的,即1.5个字节。若表项号为奇数,则取高12位,若为偶数,则取低12位

(2)代码

/*=====================================================================  Routine: GetFATEntry  Action: Find %ax sector's index in FAT, save result in %ax*/GetFATEntry:    push    %es    push    %bx    push    %ax    mov        $BaseOfLoader, %ax    sub        $0x0100,    %ax    mov        %ax,        %es    pop        %ax    mov        $3,            %bx    mul        %bx    mov        $2,            %bx    div        %bx    movb    %dl,        (bOdd)LABEL_EVEN:    xor        %dx,        %dx    mov        (BPB_BytsPerSec),%bx    div        %bx    push    %dx    mov        $0,            %bx    add        $SecNoOfFAT1,%ax    mov        $2,            %cl    call    ReadSector    pop        %dx    add        %dx,        %bx    mov        %es:(%bx),    %ax    cmpb    $0,            (bOdd)    jz        LABEL_EVEN_2    shr        $4,            %axLABEL_EVEN_2:    and        $0x0fff,    %axLABEL_GET_FAT_ENTRY_OK:    pop        %bx    pop        %es    ret


 

四、测试

没有截图

 

0 0