硬碟的chs模式是指chs(cylinder/head/sector)模式, 既磁頭數(heads), 柱面數(cylinders), 扇區數(sectors per track),以及相應的定址方式. 剛一開始硬碟的容量還非常小, 人們採用與軟盤類似的結構生產硬碟. 也就是硬碟碟片的每一條磁軌都具有相同的扇區數。
其中:
磁頭數(heads) 表示硬碟總共有幾個磁頭,也就是有幾面碟片, 最大為 256 (用 8 個二進位制位儲存), 取值範圍為: 0 到 heads-1;
柱面數(cylinders) 表示硬碟每一面碟片上有幾條磁軌, 最大為 1024(用 10 個二進位制位儲存),取值範圍為: 0 到 cylinders-1;
扇區數(sectors per track) 表示每一條磁軌上有幾個扇區, 最大為63 (用 6 個二進位制位儲存),取值範圍為: 1 到 sectors per track (注意是從 1 開始), 每個扇區一般是 512個位元組.
所以磁碟最大容量為: 256 * 1024 * 63 * 512 / 1048576 = 8064 mb ( 1m = 1048576 bytes)
有以下幾種尺寸單位:扇區 (sector) = 512 位元組 (一般情況下)磁軌 (track) = (sectors per track) 扇區
柱面 (cylinder)= (sectors per track) * heads 扇區
這種方式會浪費很多磁碟空間 (與軟盤一樣). 為了解決這一問題, 進一步提高硬碟容量, 人們改用等密度結構生產硬碟. 也就是說, 外圈磁軌的扇區比內圈磁軌多. 採用這種結構後, 硬碟不再具有實際的3d引數, 定址方式也改為線性定址, 即以扇區為單位進行定址.為了與使用3d定址的老軟體相容 (如使用bios int13h介面的軟體), 在硬碟控制器內部安裝了乙個位址翻譯器, 由它負責將老式3d引數翻譯成新的線性引數. 這也是為什麼現在硬碟的3d引數可以有多種選擇的原因 (不同的工作模式, 對應不同的3d引數,如 lba, large, normal). chs模式只能識別大硬碟的前面8g.lba使用的線性定址,突破了1024柱面的限制,能訪問8g以外的空間了。
lba定址模式是直接以扇區為單位進行定址的,將硬碟劃分成乙個乙個扇區,定址是從0扇區開始到最後乙個扇區。把硬碟所有的物理扇區的c/h/s編號通過一定的規則轉變為一線性的編號,不再用磁頭/柱面/扇區三種單位來進行定址,將chs這種三維定址方式轉變為一維的線性定址,它提高了效率簡化了操作。
主要:chs定址是從1扇區開始,lba定址是從0扇區開始.實際程式設計時一定要注意這一點。
埠lba
chs讀寫讀
寫1f0h
資料暫存器
1f1h
錯誤暫存器
特徵暫存器
錯誤暫存器
寫前預補償暫存器
1f2h
扇區數暫存器
1f3h
lba塊位址(0~7位)
扇區號暫存器
1f4h
lba塊位址(8~15位)
柱面號暫存器(高位址)
1f5h
lba塊位址(16~23位)
柱面號暫存器(低位址)
1f6h
驅動器號+lba塊位址(24~27位)
驅動器號/磁頭號
1f7h
狀態暫存器
命令暫存器
狀態暫存器
命令暫存器
36f交換狀態暫存器
硬碟控制暫存器
無硬碟控制暫存器
1f6暫存器
1
l
1
drvhs3
hs2hs1
hs0l:0,使用chs模式;1,使用lba模式
drv:0,主盤;1,從盤
新增標頭檔案
#ifndef hdreg_h
#define hdreg_h
#define hd_data 0x1f0
#define hd_error 0x1f1
#define hd_status 0x1f7
#define hd_precomp hd_error
#define hd_command hd_status
#define hd_cmd 0x3f6
#endif
kernel目錄下新增blk_drv目錄,blk_drv目錄下新增hd.c和makefile,hd_out的主要作用就是向暫存器中填充資料,以完成相應的讀寫等操作。
blk_drv目錄下的hd.c
#include #include #include #include #include #include extern void hd_interrupt(void);
#define port_read(port,buf,nr) \
__asm__("cld;rep;insw"::"d" (port),"d" (buf),"c" (nr):)
#define port_write(port,buf,nr) \
__asm__("cld;rep;outsw"::"d" (port),"s" (buf),"c" (nr):)
static int controller_ready(void)
#define lba
#ifdef lba
/**drive-硬碟號(0或1)
*nsect-要讀寫的扇區數
*lba -起始扇區
*cmd -命令碼
*/static void hd_out(unsigned int drive,unsigned int nsect,unsigned int lba,unsigned int cmd)
#else
/**drive-硬碟號(0或1)
*nsect-要讀寫的扇區數
*sect -起始扇區
*head -磁頭號
*cyl -柱面號
*cmd -命令碼
*/static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
unsigned int head,unsigned int cyl,unsigned int cmd)
#endif
void hd_init(void)
void print_identify_info(u16* hdinfo)
#define sector_size 512
u8 hdbuf[sector_size * 2];
void hd_identify(int drive)//讀identify
在main.c中新增測試程式
hd_init();//初始化
hd_identify(0);//讀identity
move_to_user_mode();
blk_drv目錄下的makefile
ar =ar
as =as
ld =ld
ldflags = --oformat binary -n -e start -ttext 0x0
cc =gcc
cflags = -i../../include -fno-stack-protector
.c.s:
$(cc) $(cflags) \
-s -o $*.s $<
.s.o:
$(as) -c -o $*.o $<
.c.o:
$(cc) $(cflags) \
-c -o $*.o $<
objs = hd.o
lib.a: $(objs)
$(ar) rcs blk_drv.a $(objs)
sync
clean:
rm -f *.o *.s *.a
system_call.s檔案中新增硬碟中斷處理函式hd_interrupt:
hd_interrupt:
movb $0x20,%al
outb %al,$0xa0
outb %al,$0x20
iret
先修改chr_drv下的makefile,將其編譯成乙個庫chr_drv.a,並相應修改kernel下的makefile,最後修改頂層目錄的makefile
drivers =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a
kernel/blk_drv/blk_drv.a:
(cd kernel/blk_drv; make)
kernel/chr_drv/chr_drv.a:
(cd kernel/chr_drv; make)
system:boot/head.o init/main.o kernel/kernel.o fs/fs.o $(libs) $(drivers)
$(ld) $(ldflags) -o system boot/head.o kernel/kernel.o init/main.o fs/fs.o $(libs) $(drivers)
新增硬碟和掛載硬碟
一 新增硬碟 fdisk l fdisk dev sdb n 新建 p 1 1 w 儲存 mkfs t ext3 c dev sdb1 格式化 建資料夾 cd mnt mkdir edisk 掛載資料夾 mount dev sdb1 mnt edisk 單次完成 需要修改 etc fstab檔案來進...
怎樣不讓木馬讀硬碟 不讓木馬讀硬碟的方法
很多時候當一台計算機中毒以後,我們的遠控軟體就會檢視到你硬碟的重要資料,從而將之盜取。我們怎麼防止這種情況出現呢?怎樣不讓木馬讀硬碟,其實您可以把硬碟加密碼。但是如果入侵者用遠控軟體訪問就不需要輸入密碼,直接就能訪問到你的硬碟。今天為大家講解如何將自己的硬碟隱藏起來,讓別人不能訪問你的硬碟。我們以乙...
Linux 新增硬碟
給硬碟分割槽 在slackware下有兩個分割槽軟體fdisk和cfdisk 例如我們已經有乙個硬碟了,現在新增另乙個硬碟到系統 那麼我們根據命名規則知道這個新新增的硬碟應該是hdb。我們用下面命令給硬碟分割槽 fdisk dev hdb 你也可以用cfdisk來分割槽,命令如下 cfdisk de...