提交 2681d0be 创建 作者: 赵鹏翀's avatar 赵鹏翀

init template

上级
/*.img
/bochs/bios.bin-1.7.5
/bochs/bochs.exe
/bochs/bochsdbg.exe
/bochs/VGABIOS-lgpl-latest
/Debug
/Release
bochsout.txt
*.bak
\ No newline at end of file
memory: guest=32, host=32
romimage: file=Bochs/bios.bin-1.7.5 # http://www.seabios.org/SeaBIOS
vgaromimage: file=Bochs/VGABIOS-lgpl-latest
clock: sync=realtime, time0=local
pci: enabled=1, chipset=i440fx, slot1=pcivga
private_colormap: enabled=0
ata0-master: type=disk, path=".\harddisk.img", mode=flat, cylinders=32, heads=2, spt=63
boot: disk
floppy_bootsig_check: disabled=0
log: bochsout.txt
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
debugger_log: -
parport1: enabled=1, file="parport.out"
speaker: enabled=1, mode=sound
e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=slirp, script=slirp.conf
usb_uhci: enabled=1, port1=disk:USBstick.img
<?xml version="1.0" encoding="gb2312"?>
<ASMProject Version="1.00" Name="PC015" ProjectType="pcproject" ProjectTemplateID="19a43a06-1e0e-4db8-86f3-42c179ed5c7f" TemplatePath="PC015\Project" IncrementalUpload="-1" ProjectID="b13072ec-afa2-417b-a811-d3618acf5343" IsSubmitWork="0">
<Configurations>
<Configuration Name="Debug" ConfigurationType="2" DebuggerFlavor="2">
<Tool Name="PreBuildEventTool"/>
<Tool Name="CustomBuildTool"/>
<Tool Name="GCCCompilerTool"/>
<Tool Name="JWASMAssemblerTool" ObjectFile="$(IntDir)\$(InputName).bin" ObjectFormate="0" ListFile="$(InputName).lst" GenerateDebugInformation="-1" VersionDebugInfo="-1" AdditionalOptions="/W0"/>
<Tool Name="PreLinkEventTool"/>
<Tool Name="GCCLinkerTool"/>
<Tool Name="JWlinkLinkerTool" AdditionalOptions="disable 1014"/>
<Tool Name="PostBuildEventTool" CommandLine="echo U̾ļ...&#xA;mkimage.exe &quot;$(IntDir)\boot.bin&quot; &quot;$(IntDir)\loader.bin&quot; &quot;USBstick.img&quot;&#xA;"/>
</Configuration>
</Configurations>
<Files>
<Filter Name="Bochs">
<File RelativePath=".\Bochs\bios.bin-1.7.5" NoUpload="-1">
</File>
<File RelativePath=".\Bochs\bochs.exe" NoUpload="-1">
</File>
<File RelativePath=".\Bochs\bochsdbg.exe" NoUpload="-1">
</File>
<File RelativePath=".\Bochs\bochsrc.bxrc" NoUpload="-1">
</File>
<File RelativePath=".\Bochs\VGABIOS-lgpl-latest" NoUpload="-1">
</File>
</Filter>
<File RelativePath=".\bochsout.txt" NoUpload="-1">
</File>
<File RelativePath=".\boot.asm">
</File>
<File RelativePath=".\harddisk.img">
</File>
<File RelativePath=".\loader.asm">
</File>
<File RelativePath=".\USBstick.img">
</File>
</Files>
</ASMProject>
添加文件
LOADER_BASE equ 1000h
codeseg segment
org 7c00h ;告诉编译器程序加载到7c00处
start:
mov ax, 0 ;读取0面0道2扇区的内容到0:1000(即loader的内容)
mov es, ax
mov bx, LOADER_BASE
mov al, 4 ;读取的扇区数(拟定loader占用4个扇区)
mov ch, 0 ;磁道
mov cl, 2 ;扇区号(读第二个扇区)
mov dl, 80h ;硬盘从80h开始
mov dh, 0 ;0面
mov ah, 2 ;读扇区操作
int 13h
mov bx, 0b800h ;清屏
mov es, bx
mov bx, 0
mov cx, 25*80
clear:
mov word ptr es:[bx], 20h ;空格
mov word ptr es:[bx+1], 7h ;字符属性
add bx, 2
loop clear
mov ax, LOADER_BASE ;程序跳转到0:1000h处执行loader.bin
jmp ax
db 446- ($-start) dup (0) ;前446字节的内容不满时,用0填充
;硬盘分区表(共64字节,每16字节为一项,每项表示一个分区,共4项)
;每项中第一个字节表示引导指示符,80h表示活动分区,00h表示无效分区
db 80h
;第二、三、四个字节在这里没有用到。
db 00h, 00h, 00h
;第五个字节定义分区类型。01h表示未定义的分区类型。
db 01h
;第六、七、八个字节在这里没有用到。
db 00h, 00h, 00h
;第九到第十二字节表示逻辑起始扇区号(相对于逻辑0扇区的扇区数)。一个扇区大小为 512 字节。
dd 00010000h ;第一个分区前有 32MB 空白区域
;第十三到第十六字节表示该分区所占用的扇区数(总扇区数)
dd 00010000h ;第一个分区共 32MB 大小
;其余三项全部为0,表示没有其他分区。
db 16 dup (0)
db 16 dup (0)
db 16 dup (0)
dw 0aa55h ;可引导标志,2字节。这样446+64+2=512字节,恰好等于引导扇区的字节数。
codeseg ends
end
.386p
codeseg segment use16
org 1000h ;告诉编译器程序加载到1000处
jmp start ;程序的功能是用DMA方式读取硬盘引导扇区信息,并将512字节的引导扇区显示在屏幕上
;筛选多功能IDE设备所用数据
CfgSpace db 256 dup (0) ;PCI设备的256字节配置空间
count dw 0 ;用于统计字数
numSect equ 1 ;读取1个扇区
lbaSector equ 0 ;LBA=0
dma_command_reg equ 0C060H ;DMA主控命令寄存器
dma_status_reg equ 0C062H ;DMA主控状态寄存器
dma_prd_addr_reg equ 0C064H ;物理区域描述符地址寄存器
ide_command_base_addr equ 01F0H ;IDE设备命令模块寄存器基地址
ide_control_base_addr equ 03F4H ;IDE设备控制模块寄存器基地址
ALIGN 2
buffer db 512*numSect dup (0) ;内存缓冲区
bufferlen equ $-buffer
ALIGN 4
prdbuf dd 0,0 ;物理区域描述符
prdbufaddr dd 0 ;物理区域描述符地址
bufferaddr dd 0 ;内存缓冲区地址
start:
mov ax, cs ;全部置0
mov ds, ax
mov es, ax
mov ss, ax ;初始化栈
mov sp, 7c00h
;************************DMA方式读硬盘扇区并显示*************************************
mov bx,16
mov ax,ds
mul bx ;计算并设置数据段基址
add ax, offset prdbuf ;数据段基址+offset prdbuf
adc dx, 0 ;dx:ax = prdBuf的物理地址
mov WORD PTR prdbufaddr, ax
mov WORD PTR prdbufaddr+2, dx
mov ax,ds
mul bx
add ax, offset buffer ;段基址+offset _Buffer
adc dx, 0 ;dx:ax = _Buffer的物理地址
mov WORD PTR bufferaddr, ax
mov WORD PTR bufferaddr+2, dx
call ReadSectors ;DMA方式读取硬盘扇区
mov ah, 2 ;置光标位置
mov bx, 0
mov dh, 05h
mov dl, 0
int 10h
call ShowBuffer ;显示缓冲区内容
over: ;让程序在这里死循环
jmp over
;******************************设置硬盘DMA方式所需参数*******************************
ReadSectors: ;采用DMA方式读取硬盘扇区
mov dx, dma_command_reg ;Start/Stop=0, 停止以前的DMA传输
mov al, 0
out dx, al
mov al, 00000110b ;清除DMA主控状态寄存器的Interrupt和Error位
mov dx, dma_status_reg
out dx, al
mov eax, bufferaddr ;建立一个物理区域描述符
mov prdbuf, eax ;Physical Address
mov word ptr prdbuf+4, bufferlen ;Byte Count [15:1]
mov word ptr prdbuf+6, 8000h ;EOT=1
mov eax, prdbufaddr ;物理区域描述符的地址写入PRDTR
mov dx, dma_prd_addr_reg
out dx, eax
mov dx, dma_command_reg ;DMA主控命令寄存器的R/W=1, 表示写入内存(读取硬盘)
mov al, 08h
out dx, al
call waitDeviceReady ;等待硬盘BSY=0和DRQ=0
mov al, 0 ;设置IDE设备/磁头寄存器的DEV=0
mov dx, ide_command_base_addr+6
out dx, al
call waitDeviceReady ;等待硬盘BSY=0和DRQ=0
mov dx, ide_control_base_addr+2 ;IDE控制寄存器的nIEN=0, 允许中断
mov al, 0
out dx, al
;设置IDE寄存器
mov dx, ide_command_base_addr+1 ;扇区号,=00
mov al, 0
out dx, al
mov dx, ide_command_base_addr+2 ;扇区数量,读取一个扇区
mov al, 0
out dx, al
mov dx, ide_command_base_addr+3 ;指定的扇区号,读硬盘的引导扇区
mov al, 0
out dx, al
mov dx, ide_command_base_addr+4 ;LBA第15~8位
mov al, 0 ;柱面的低8位
out dx, al
mov dx, ide_command_base_addr+5 ;LBA第23~16位
mov al, 0 ;柱面的高8位
out dx, al
mov dx, ide_command_base_addr+6 ;IDE设备/磁头寄存器:LBA=1, DEV=0, LBA第27~24位
mov al, 01000000b
out dx, al
mov al, 0c8h ;设置IDE命令寄存器0C8h=Read DMA,发出读DMA的指令
mov dx, ide_command_base_addr+7
out dx, al
mov dx, dma_command_reg ;读取DMA主控命令寄存器和主控状态寄存器
in al, dx
mov dx, dma_status_reg
in al, dx
mov al, 09h ;DMA主控命令寄存器的R/W=1,Start/Stop=1, 启动DMA传输 ;**********************************
mov dx, dma_command_reg
out dx, al
;现在开始DMA数据传送
mov ecx, 4000h ;检查DMA主控状态寄存器, 当active位为0时,发送结束
notfinish:
mov dx, dma_status_reg
in al, dx
and al, 00000001b
jnz notfinish
mov al, 00000100b ;清除DMA主控状态寄存器的Interrupt位
mov dx, dma_status_reg
out dx, al
mov dx, dma_status_reg ;读取DMA主控状态寄存器
in al, dx
mov al, 0 ;DMA主控命令寄存器的Start/Stop=0, 结束DMA传输
mov dx, dma_command_reg
out dx, al
ret
waitDeviceReady:
mov dx, ide_command_base_addr+7 ;读取IDE状态寄存器
in al, dx
and al, 10001000b ;BSY=1或DRQ=1,继续查询
jnz waitDeviceReady
ret
;******************************显示缓冲区_Buffer内容*********************************************
ShowBuffer:
lea si,buffer ;显示_Buffer内容,即将引导扇区的内容输出到屏幕上
cld
mov bp, 24 ;屏幕上输出24行
NextLine:
mov cx, 22 ;每行显示22字节
NextCh:
lodsb
push dx
push ax
shr al, 4 ;逻辑右移,显示ah中数据
mov bx, 0
mov ah, 0eh
call ToASCII
int 10h
pop ax ;显示al中的数据
mov ah, 0eh
call ToASCII
int 10h
mov al, ' ' ;输出空格
int 10h
mov dx, count ;当输出了512字节后,程序返回
add dx, 1
mov count, dx
cmp dx, 512
je show_rtn
loop NextCh ;循环
mov al, 0dh ;换行
int 10h
mov al, 0ah ;回车
int 10h
dec bp ;行数的循环
jnz NextLine
show_rtn:
pop dx
ret
ToASCII: ;将字符转换成ASCII码
and al,0fh
cmp al,10
jae Over10
add al,'0'
ret
Over10:
add al,'A'-10
ret
;*******************************************************************************
codeseg ends
end
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论