日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

读取磁盘:LBA方式 以及 CHS方式

發(fā)布時(shí)間:2024/1/18 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读取磁盘:LBA方式 以及 CHS方式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

https://www.cnblogs.com/mlzrq/p/10223060.html

LBA簡介

磁盤讀取發(fā)展

IO操作讀取硬盤的三種方式:

  • chs方式 :小于8G (8064MB)

  • LBA28方式:小于137GB

  • LBA48方式:小于144,000,000 GB

LBA方式訪問使用了data寄存器,LBA寄存器(總共3個(gè)),device寄存器,command寄存器來完成的。

LBA28和LBA48方式:
LBA28方式使用28位來描述一個(gè)扇區(qū)地址,最大支持128GB的硬磁盤容量。

LBA28的寄存器

寄存器端口作用
data寄存器0x1F0已經(jīng)讀取或?qū)懭氲臄?shù)據(jù),大小為兩個(gè)字節(jié)(16位數(shù)據(jù))
每次讀取1個(gè)word,反復(fù)循環(huán),直到讀完所有數(shù)據(jù)
features寄存器0x1F1讀取時(shí)的錯(cuò)誤信息
寫入時(shí)的額外參數(shù)
sector count寄存器0x1F2指定讀取或?qū)懭氲纳葏^(qū)數(shù)
LBA low寄存器0x1F3lba地址的低8位
LBA mid寄存器0x1F4lba地址的中8位
LBA high寄存器0x1F5lba地址的高8位
device寄存器0x1F6lba地址的前4位(占用device寄存器的低4位)
主盤值為0(占用device寄存器的第5位)
第6位值為1
LBA模式為1,CHS模式為0(占用device寄存器的第7位)
第8位值為1
command寄存器0x1F7讀取,寫入的命令,返回磁盤狀態(tài)
1 讀取扇區(qū):0x20 寫入扇區(qū):0x30
磁盤識(shí)別:0xEC

IDE通道1,讀寫0x1f0-0x1f7號(hào)端口

IDE通道2,讀寫0x170-0x17f號(hào)端口

CHS方式:

寫0x1f1: 0

寫0x1f2: 要讀的扇區(qū)數(shù)

寫0x1f3: 扇區(qū)號(hào)W

寫0x1f4: 柱面的低8位

寫0x1f5: 柱面的高8位

寫0x1f6: 7~5位,101,第4位0表示主盤,1表示從盤,3~0位,磁頭號(hào)

寫0x1f7: 0x20為讀, 0x30為寫

讀0x1f7: 第4位為0表示讀寫完成,否則要一直循環(huán)等待

讀0x1f0: 每次讀取1個(gè)word,反復(fù)循環(huán),直到讀完所有數(shù)據(jù)

24-bit LBA方式:

寫0x1f1: 0

寫0x1f2: 要讀的扇區(qū)數(shù)

寫0x1f3: LBA參數(shù)的0~7位

寫0x1f4: LBA參數(shù)的8~15位

寫0x1f5: LBA參數(shù)的16~23位

寫0x1f6: 7~5位,111,第4位0表示主盤,1表示從盤,3~0位,LBA參數(shù)的24~27位

寫0x1f7: 0x20為讀, 0x30為寫

讀0x1f7: 第4位為0表示讀寫完成,否則要一直循環(huán)等待

讀0x1f0: 每次讀取1個(gè)word,反復(fù)循環(huán),直到讀完所有數(shù)據(jù)

48-bit LBA方式:

寫兩次0x1f1端口: 0

寫兩次0x1f2端口: 第一次要讀的扇區(qū)數(shù)的高8位,第二次低8位

寫0x1f3: LBA參數(shù)的24~31位

寫0x1f3: LBA參數(shù)的0~7位

寫0x1f4: LBA參數(shù)的32~39位

寫0x1f4: LBA參數(shù)的8~15位

寫0x1f5: LBA參數(shù)的40~47位

寫0x1f5: LBA參數(shù)的16~23位

寫0x1f6: 7~5位,010,第4位0表示主盤,1表示從盤,3~0位,0

寫0x1f7: 0x24為讀, 0x34為寫

LBA和CHS的的對應(yīng)關(guān)系

雖然LBA和CHS的兩種定位方式不同,但其實(shí)兩者間還是有一個(gè)轉(zhuǎn)換關(guān)系的。

讀取硬盤

1)sector count寄存器寄存器寫入讀取的扇區(qū)數(shù)
2)LBA low寄存器,LBA mid寄存器,LBA high寄存器寫入lba地址
3)device寄存器寫入lba地址和讀取模式
4)command寄存器寫入寫入命令
5)讀取兩個(gè)字節(jié)數(shù)據(jù),多次循環(huán)直到讀取完扇區(qū)數(shù)據(jù)。

代碼

boot.asm
引導(dǎo)文件,初始化屏幕后,讀取硬盤并加載4個(gè)扇區(qū)到內(nèi)存位置[0x90000]處。然后跳轉(zhuǎn)到0x90000處執(zhí)行指令。

;Rats OS ;Tab=4 [bits 16]org 0x7c00 ;指明程序的偏移的基地址;----------- loader const ------------------ LOADER_SECTOR_LBA equ 0x1 ;第2個(gè)邏輯扇區(qū)開始 LOADER_SECTOR_COUNT equ 9 ;讀取9個(gè)扇區(qū) LOADER_BASE_ADDR equ 0x9000 ;內(nèi)存地址0x9000 ;-------------------------------------------;引導(dǎo)扇區(qū)代碼 jmp Entrydb 0x90db "RATSBOOT" ;啟動(dòng)區(qū)的名稱可以是任意的字符串(8字節(jié)) ;程序核心內(nèi)容 Entry:;------------------;初始化寄存器mov ax,0 mov ss,axmov ds,axmov es,axmov ss,axmov fs,axmov gs,axmov sp,0x7c00;------------------;清屏mov ah,0x06 ;清除屏幕 mov al,0mov cx,0 mov dx,0xffff mov bh,0x17 ;屬性為藍(lán)底白字int 0x10mov ah,0x02 ;光標(biāo)位置初始化mov dx,0mov bh,0mov dh,0x0mov dl,0x0int 0x10;------------------;讀取硬盤1-10扇區(qū)mov ebx,LOADER_SECTOR_LBA ;LBA扇區(qū)號(hào)mov cx,LOADER_SECTOR_COUNT ;讀取扇區(qū)數(shù)mov di,LOADER_BASE_ADDR ;寫入內(nèi)存地址call Func_ReadLBA16jmp LOADER_BASE_ADDR; ------------------------------------------------------------------------ ; 讀取磁盤:Func_ReadLBA16 ; 參數(shù): ; ebx 扇區(qū)邏輯號(hào) ; cx 讀入的扇區(qū)數(shù),8位 ; di 讀取后的寫入內(nèi)存地址 ; ------------------------------------------------------------------------ Func_ReadLBA16:;設(shè)置讀取的扇區(qū)數(shù)mov al,clmov dx,0x1F2out dx,al;設(shè)置lba地址;設(shè)置低8位mov al,blmov dx,0x1F3out dx,al;設(shè)置中8位shr ebx,8mov al,blmov dx,0x1F4out dx,al;設(shè)置高8位shr ebx,8mov al,blmov dx,0x1F5out dx,al;設(shè)置高4位和deviceshr ebx,8and bl,0x0For bl,0xE0mov al,blmov dx,0x1F6out dx,al;設(shè)置commondmov al,0x20mov dx,0x1F7out dx,al.check_status:;檢查磁盤狀態(tài)nopin al,dxand al,0x88 ;第4位為1表示硬盤準(zhǔn)備好數(shù)據(jù)傳輸,第7位為1表示硬盤忙cmp al,0x08jnz .check_status ;磁盤數(shù)據(jù)沒準(zhǔn)備好,繼續(xù)循環(huán)檢查;設(shè)置循環(huán)次數(shù)到cxmov ax,cx ;乘法ax存放目標(biāo)操作數(shù)mov dx,256mul dxmov cx,ax ;循環(huán)次數(shù) = 扇區(qū)數(shù) x 512 / 2 mov bx,dimov dx,0x1F0.read_data: in ax,dx ;讀取數(shù)據(jù)mov [bx],ax ;復(fù)制數(shù)據(jù)到內(nèi)存add bx,2 ;讀取完成,內(nèi)存地址后移2個(gè)字節(jié)loop .read_dataretFillSector:resb 510-($-$$) ;處理當(dāng)前行$至結(jié)束(1FE)的填充db 0x55, 0xaa

loader.asm
被引導(dǎo)扇區(qū)加載到0x90000位置,執(zhí)行輸出hello in loader文字

;Rats OS ;Tab=4 [bits 16]section loader vstart=LOADER_BASE_ADDR ;指明程序的偏移的基地址;----------- loader const ------------------ LOADER_BASE_ADDR equ 0x9000 ;內(nèi)存地址0x9000 ;--------------------------------------- jmp Entry;程序核心內(nèi)容 Entry:;---------------------------;輸出字符串mov si,HelloMsg ;將HelloMsg的地址放入simov dh,0 ;設(shè)置顯示行mov dl,0 ;設(shè)置顯示列call Func_Sprint ;調(diào)用函數(shù)jmp $ ;讓CPU掛起,等待指令; ------------------------------------------------------------------------ ; 顯示字符串函數(shù):Func_Sprint ; 參數(shù): ; si = 字符串開始地址, ; dh = 第N行,0開始 ; dl = 第N列,0開始 ; ------------------------------------------------------------------------ Func_Sprint:mov cx,0 ;BIOS中斷參數(shù):顯示字符串長度mov bx,si.len:;獲取字符串長度mov al,[bx] ;讀取1個(gè)字節(jié)到alinc bx ;讀取下個(gè)字節(jié)cmp al,0 ;是否以0結(jié)束je .sprintinc cx ;計(jì)數(shù)器jmp .len.sprint:;顯示字符串mov bx,simov bp,bxmov bx,dsmov es,bx ;BIOS中斷參數(shù):計(jì)算[ES:BP]為顯示字符串開始地址mov ah,0x13 ;BIOS中斷參數(shù):中斷模式mov al,0x01 ;BIOS中斷參數(shù):輸出方式mov bh,0x0 ;BIOS中斷參數(shù):指定分頁為0mov bl,0x1F ;BIOS中斷參數(shù):顯示屬性,指定白色文字 int 0x10 ;調(diào)用BIOS中斷操作顯卡。輸出字符串ret ; ------------------------------------------------------------------------ ;準(zhǔn)備顯示字符串 HelloMsg: db "hello in loader!",0times 512-($-$$) db 0 ; 處理當(dāng)前行$至結(jié)束(1FE)的填充

運(yùn)行

創(chuàng)建Makefile文件,并執(zhí)行make命令

# tools PLATFORM=Linux NASM=nasm QEMU=qemu-system-x86_64 QEMU-IMG=qemu-img BOCHS=bochs BX-IMG=bximage# args boot=boot build=buildtarget: prepare img $(BOCHS) -f bochsrc.meimg: $(build)/ratsos.img @echo "build img completed"$(build)/ratsos.img:$(build)/boot.bin $(build)/loader.bin $(BX-IMG) -hd -mode=flat -size=32 -q $(build)/ratsos.imgsleep 1dd if=$(build)/boot.bin of=$(build)/ratsos.img bs=512 count=1 conv=notruncdd if=$(build)/loader.bin of=$(build)/ratsos.img bs=512 count=1 seek=1 conv=notrunc$(build)/%.bin: $(boot)/%.asm$(NASM) -f bin -o $(build)/$*.bin $(boot)/$*.asm prepare: $(build)@echo "prepare dir $(build)"ifeq ($(build), $(wildcard $(build)))@echo "build directory exist..."elsemkdir -p $(build)endifclean:@echo "clean dir $(build)"rm -rf $(build)/*platform:@echo $(PLATFORM)

運(yùn)行結(jié)果

?

總結(jié)

以上是生活随笔為你收集整理的读取磁盘:LBA方式 以及 CHS方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。