中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

MacOS環(huán)境-手寫操作系統(tǒng)-02-讀寫軟盤-創(chuàng)新互聯(lián)

讀寫軟盤

文章寫于兩年前的 MacBookAir(2015)
目前筆者為 MacBookPro M1 (抽查了部分 都運行正常)
Github項目地址: https://github.com/wdkang123/MyOperatingSystem
MacOS X86架構(x新版的arm架構的我沒有 所以大家自行測試)
VirtualBox
C/C++環(huán)境 (Xcode必裝)

創(chuàng)新互聯(lián)公司是一家專業(yè)提供棲霞企業(yè)網(wǎng)站建設,專注與成都網(wǎng)站制作、網(wǎng)站建設、外貿網(wǎng)站建設、HTML5、小程序制作等業(yè)務。10年已為棲霞眾多企業(yè)、政府機構等服務。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡公司優(yōu)惠進行中。1.簡介

前文中我們將一段代碼通過軟盤加載到了系統(tǒng)內存中 并指示cpu執(zhí)行加入到內存的代碼

事實上,操作系統(tǒng)內核加載也是這么做的。只不過我們加載的代碼,大只能512 byte, 一個操作系統(tǒng)內核,少說也要幾百兆,由此,系統(tǒng)內核不可能直接從軟盤讀入系統(tǒng)內存

通常的做法是 被加載進 內存的512byte程序 實際上是一個內核加載器 它運行起來之后 通過讀取磁盤 將存儲在磁盤上的內核代碼加載到指定的內存結構中去 然后在把cpu的控制權提交給加載進來的系統(tǒng)內核

硬盤的結構

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-lihpgkUm-1671687709613)(null)]
軟盤的物理結構如上圖 一個盤面被劃分成若干個圓圈

例如圖中的灰色圓圈 我們稱之為磁道 也可以稱作柱面

一個磁道或柱面 又被分割成若干部分 每一部分 我們稱之為一個扇區(qū)

一個扇區(qū)的大小正好是512k

從而,當我們把數(shù)據(jù)存儲到軟盤上時,數(shù)據(jù)會分解成若干個512Byte大小的塊,然后寫入到扇區(qū)里

2.模擬

我們要模擬的是3.5寸軟盤 這種軟盤的特點是

它有兩個盤面 因此就對應兩個磁頭 每個盤面有80個磁道 也就是柱面 編號分別為0-79 每個柱面都有18個扇區(qū) 編號分別為1-18 所以一個盤面可以存儲的數(shù)據(jù)量大小為:
512 * 18 * 80
一個軟盤有兩個盤面,因此一個軟盤可以存儲的數(shù)據(jù)為:
2 * 512 * 18 * 80 = 1474560 Byte = 1440 KB = 1.5M

接下來,我們用java來模擬一個3.5寸軟盤,以及它的讀寫邏輯

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;


public class Floppy {enum MAGNETIC_HEAD {MAGNETIC_HEAD_0,
        MAGETIC_HEAD_1
    };


    public int SECTOR_SIZE = 512;
    private int CYLINDER_COUNT = 80; //80個柱面
    private int SECTORS_COUNT = 18;
    private MAGNETIC_HEAD magneticHead = MAGNETIC_HEAD.MAGNETIC_HEAD_0;
    private int current_cylinder = 0;
    private int current_sector = 0;

    private HashMap>>floppy = new HashMap>>(); //一個磁盤兩個面

    public Floppy() {initFloppy();
    }

    private void initFloppy() {//一個磁盤有兩個盤面
        floppy.put(MAGNETIC_HEAD.MAGNETIC_HEAD_0.ordinal(), initFloppyDisk());
        floppy.put(MAGNETIC_HEAD.MAGETIC_HEAD_1.ordinal(), initFloppyDisk());
    }

    private ArrayList>initFloppyDisk() {ArrayList>floppyDisk = new ArrayList>(); //磁盤的一個面
        //一個磁盤面有80個柱面
        for(int i = 0; i< CYLINDER_COUNT; i++) {floppyDisk.add(initCylinder());
        }

        return floppyDisk;
    }

    private ArrayListinitCylinder() {//構造一個柱面,一個柱面有18個扇區(qū)
        ArrayListcylinder = new ArrayList();
        for (int i = 0; i< SECTORS_COUNT; i++) {byte[] sector = new byte[SECTOR_SIZE];
            cylinder.add(sector);
        }

        return cylinder;
    }

    public void setMagneticHead(MAGNETIC_HEAD head) {magneticHead = head;
    }

    public void setCylinder(int cylinder) {if (cylinder< 0) {this.current_cylinder = 0;
        }
        else if (cylinder >= 80) {this.current_cylinder = 79;
        }
        else {this.current_cylinder = cylinder;
        }
    }

    public void setSector(int sector) {//sector 編號從1到18
        if (sector< 0) {this.current_sector = 0;
        }
        else if (sector >18) {this.current_sector = 18 - 1;
        }
        else {this.current_sector = sector - 1;
        }
    }

    public byte[] readFloppy(MAGNETIC_HEAD head, int cylinder_num, int sector_num) {setMagneticHead(head);
        setCylinder(cylinder_num);
        setSector(sector_num);

        ArrayList>disk = floppy.get(this.magneticHead.ordinal());
        ArrayListcylinder = disk.get(this.current_cylinder);

        byte[] sector = cylinder.get(this.current_sector);

        return sector;
    }

    public void writeFloppy(MAGNETIC_HEAD head, int cylinder_num, int sector_num, byte[] buf) {setMagneticHead(head);
        setCylinder(cylinder_num);
        setSector(sector_num);

        ArrayList>disk = floppy.get(this.magneticHead.ordinal());
        ArrayListcylinder = disk.get(this.current_cylinder);
        cylinder.set(this.current_sector, buf);
    }

    public void makeFloppy(String fileName) {try {DataOutputStream out = new DataOutputStream(new FileOutputStream(fileName));
            for (int head = 0; head<= MAGNETIC_HEAD.MAGETIC_HEAD_1.ordinal(); head++) {for (int cylinder = 0; cylinder< CYLINDER_COUNT; cylinder++) {for (int sector = 1; sector<= SECTORS_COUNT; sector++) {byte[] buf = readFloppy(MAGNETIC_HEAD.values()[head], cylinder, sector);
                        out.write(buf);
                    }
                }
            }

        } catch (Exception e) {// TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

讀寫虛擬軟盤需要調用接口readFloppy 或 writeFloppy

使用這些接口時必須指定磁頭 柱面和扇區(qū)號

3.主程序

在主程序中 我將上節(jié)用匯編編譯的操作系統(tǒng)內核寫入到虛擬軟盤中 然后將虛擬軟盤寫成磁盤文件 具體代碼如下:

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;


public class OperatingSystem {private Floppy floppyDisk = new Floppy();
  
    private void writeFileToFloppy(String fileName) {File file = new File(fileName);
        InputStream in = null;

        try {in = new FileInputStream(file);
            byte[] buf = new byte[512];
            buf[510] = 0x55;
            buf[511] = (byte) 0xaa;
            if (in.read(buf) != -1) {//將內核讀入到磁盤第0面,第0柱面,第1個扇區(qū)
                floppyDisk.writeFloppy(Floppy.MAGNETIC_HEAD.MAGNETIC_HEAD_0, 0, 1, buf);
            }
        } catch(IOException e) {e.printStackTrace();
            return;
        }
    }

    public OperatingSystem(String s) {writeFileToFloppy(s);
    }

    public void makeFllopy()   {floppyDisk.makeFloppy("system.img");
    }

    public static void main(String[] args) {OperatingSystem op = new OperatingSystem("boot.bat");
        op.makeFllopy();
    }
}
4.匯編軟盤讀寫

在前面,我們的內核加載到內存后,會打印出一條語句 而語句與內核代碼都存儲在同一個扇區(qū)中

這一次,我們將要打印的語句存儲在第一柱面的第二扇區(qū),內核加載如內存后,通過BIOS調用將要打印的語句從指定位置讀出,然后再顯示到屏幕上,代碼如下:

org  0x7c00;

jmp  entry
db   0x90
DB   "OSKERNEL"
DW   512
DB   1
DW   1
DB   2
DW   224
DW   2880
DB   0xf0
DW   9
DW   18
DW   2
DD   0
DD   2880
DB   0,0,0x29
DD   0xFFFFFFFF
DB   "MYFIRSTOS  "
DB   "FAT12   "
RESB  18

entry:
    mov  ax, 0
    mov  ss, ax
    mov  ds, ax
    mov  es, ax
    mov  si, msg


readFloppy:
    mov          CH, 1        ;CH 用來存儲柱面號
    mov          DH, 0        ;DH 用來存儲磁頭號
    mov          CL, 2        ;CL 用來存儲扇區(qū)號

    mov          BX, msg       ; ES:BX 數(shù)據(jù)存儲緩沖區(qū)

    mov          AH, 0x02      ;  AH = 02 表示要做的是讀盤操作
    mov          AL,  1        ; AL 表示要練習讀取幾個扇區(qū)
    mov          DL, 0         ;驅動器編號,一般我們只有一個軟盤驅動器,所以寫死   
                               ;為0
    INT          0x13          ;調用BIOS中斷實現(xiàn)磁盤讀取功能

    jc           error

putloop:
    mov  al, [si]
    add  si, 1
    cmp  al, 0
    je   fin
    mov  ah, 0x0e
    mov  bx, 15
    int  0x10
    jmp  putloop

fin:
    HLT
    jmp  fin

error:
    mov si, errmsg   ;出現(xiàn)錯誤打印error
    jmp   putloop

msg:
    RESB   64
errmsg:
    DB "error"

將上面的代碼編譯一下

nasm boot_readstring_from_sector.asm -o boot.bat

在java代碼中進行修改:

我們在生成虛擬軟盤的java代碼中把把要輸出的語句寫入到虛擬軟盤的1柱面,2扇區(qū)

這里 將 “This is a text from cylinder 1 and sector 2” 放在了軟盤的1柱面 2扇區(qū)

在匯編中 運行時 對這個區(qū)域進行讀取 并將內容輸出到屏幕上

public void makeFllopy()   {String s = "This is a text from cylinder 1 and sector 2";
        floppyDisk.writeFloppy(Floppy.MAGNETIC_HEAD.MAGNETIC_HEAD_0, 1, 2, s.getBytes());

        floppyDisk.makeFloppy("system.img");
    }

運行代碼 生成system.img

載入后運行:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WNvcQYK0-1671687709813)(null)]

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站題目:MacOS環(huán)境-手寫操作系統(tǒng)-02-讀寫軟盤-創(chuàng)新互聯(lián)
URL分享:http://m.rwnh.cn/article16/ccgogg.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設計公司、電子商務網(wǎng)站改版、定制開發(fā)軟件開發(fā)、服務器托管

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
乌苏市| 望奎县| 阳高县| 九寨沟县| 乌审旗| 华蓥市| 岫岩| 晴隆县| 右玉县| 辽阳县| 新绛县| 西丰县| 新沂市| 时尚| 敖汉旗| 红安县| 兴隆县| 陇川县| 板桥市| 花莲市| 寻乌县| 玉树县| 镇宁| 阜平县| 阿拉善左旗| 邻水| 奉新县| 梓潼县| 如皋市| 横峰县| 宣汉县| 金平| 汶上县| 华容县| 兴义市| 兴和县| 泰兴市| 崇仁县| 紫云| 和平县| 湘西|