提交 6692858f 创建 作者: 赵鹏翀'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
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="PC018" ProjectType="pcproject" ProjectTemplateID="28f4027d-2d14-4c31-8a2a-53d2351f6390" TemplatePath="PC018\Project" IncrementalUpload="-1" ProjectID="5b8dea65-b72a-40ce-902e-9474193af584" 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;$(IntDir)\kernel.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=".\loader.asm">
</File>
<File RelativePath=".\kernel.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 use32 ;加载中断描述符表,进入到保护模式后,实现键盘中断和软中断
org 8000h
jmp start
;门描述符结构类型定义
Gate STRUC
OffsetL DW 0 ;32位偏移的低16位
Selector DW 0 ;段选择符
DCount DB 0 ;双字计数
GType DB 0 ;类型,8eh表示中断门
OffsetH DW 0 ;32位偏移的高16位
Gate ENDS
;描述符表位置结构类型定义(用于装入中断描述符表寄存器)
PDesc STRUC
Limit DW 0 ;描述符表16位界限
Base1 DD 0 ;描述符表32位基地址
PDesc ENDS
;描述符类型值说明
DA_386IGate EQU 8Eh ;386 中断门类型值
ALIGN 4
IDT: ;中断描述符表
IDT_00_1F Gate 32 dup (<offset SpuriousHandler,8,0,DA_386IGate,0>) ;前32个中断由Intel定义。中断处理程序SpuriousHandler的功能是不做任何操作,直接iretd返回
IDT_20 Gate 1 dup (<offset IRQ1Handler,8,0,DA_386IGate,0>) ;键盘中断
IDT_21_5F Gate 95 dup (<offset SpuriousHandler,8,0,DA_386IGate,0>) ;这95个中断用于填充,使最后一个中断号是80h。
IDT_80 Gate 1 dup (<offset UserIntHandler,8,0,DA_386IGate,0>) ;int 80h指令触发的中断
IDT_81_FF Gate 127 dup (<offset SpuriousHandler,8,0,DA_386IGate,0>) ;这127个中断用于填充,这样IDT中共256个中断描述符
IDTLength EQU $-IDT ;中断描述符表长度
VIDTR PDesc <IDTLength, IDT> ;构造描述符表位置结构
start:
mov eax, 10h ;数据段选择符
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax ;初始化栈
mov esp, 1024*1024*2
lidt FWORD PTR VIDTR ;加载IDT
call Init8259A ;初始化8259A.因为进入到保护模式后,一些中断向量号是 Intel 保留的,所以必须重新初始化8259A
int 80h ;触发一次软中断,功能是在屏幕上显示一个字符“A”
sti
over: ;程序在这里死循环
jmp over
IRQ1Handler:
in al, 60h ;读键盘缓冲区,输入字符的扫描码
cmp al, 80h
ja int_return
add al, 2fh ;将扫描码转换成ASCII码在屏幕上显示,此时可显示主键盘区的1~9(因为其扫描码连续,容易构造ASCII码)
mov ebx, 0b8000h
mov dword ptr [ebx], eax
int_return:
mov al,20h
out 20h,al ;发送EOI到主8259
iretd
UserIntHandler:
mov eax, 0241h
mov ebx, 0b8000h
mov dword ptr [ebx], eax ;在屏幕显示一个绿色的字符“A”
iretd
SpuriousHandler:
iretd ;不做任何操作,直接返回
Init8259A: ;初始化级连8259A,开放键盘中断
mov al,011h
out 020h,al ;主8259,ICW1.
out 0A0h,al ;从8259,ICW1.
mov al,020h ;IRQ0 对应中断向量20h
out 021h,al ;主8259,ICW2.
mov al,028h ;IRQ8 对应中断向量28h
out 0A1h,al ;从8259,ICW2.
mov al,004h ;IR2 对应从8259
out 021h,al ;主8259,ICW3.
mov al,002h ;对应主8259的 IR2
out 0A1h,al ;从8259,ICW3.
mov al,001h
out 021h,al ;主8259,ICW4.
out 0A1h,al ;从8259,ICW4.
mov al,11111100b ;仅仅开启主片键盘中断,时钟中断
out 021h,al ;主8259,OCW1.
mov al,11111111b ;屏蔽从8259所有中断
out 0A1h,al ;从8259,OCW1.
ret
codeseg ends
end
.386p ;必须是.386p,否则无法使用加载GDT命令lgdt
codeseg segment use16
org 1000h ;告诉编译器程序加载到1000处
jmp start
;段描述符结构类型定义
Desc STRUC
LimitL DW 0 ;段界限(BIT0-15)
BaseL DW 0 ;段基地址(BIT0-15)
BaseM DB 0 ;段基地址(BIT16-23)
Attributes DB 0 ;段属性
LimitH DB 0 ;段界限(BIT16-19)(含段属性的高4位)
BaseH DB 0 ;段基地址(BIT24-31)
Desc ENDS
;段描述符表位置结构类型定义(用于装入全局描述符表寄存器GDTR)
PDesc STRUC
Limit DW 0 ;描述符表16位界限
Base1 DW 0 ;描述符表32位基地址的低16位
Base2 DW 0 ;描述符表32位基地址的高16位
PDesc ENDS
;段描述符类型值说明
ATCER EQU 9ah ;存在的可执行可读代码段属性值
ATDWA EQU 93h ;存在的已访问的可读写数据段属性值
ATDW EQU 92h ;存在的可读写数据段属性值
ALIGN 4
GDT: ;全局描述符表
DUMMY Desc <> ;第一个描述符必须为空
Code Desc <0ffffh,,,ATCER,0cfh,> ;代码段描述符,段基址为0,段长度为4GB
DataP Desc <0ffffh,,,ATDWA,0cfh,> ;数据段描述符,段基址为0,段长度为4GB
ALIGN 2
GDTLength EQU $-GDT ;全局描述符表长度
VGDTR PDesc <GDTLength, GDT,> ;构造描述符表位置结构
Code_Sel EQU Code-GDT ;保护模式代码段选择符
ProtectPos EQU 8000h ;保护模式代码起始地址
;16位偏移的段间直接转移指令的宏定义(在16位代码段中使用)
JUMP16 MACRO Selector,Offset
DB 0eah ;操作码固定,长跳转。
DW Offset ;16位偏移量
DW Selector ;段选择符
ENDM
start:
mov ax, 0 ;读取从0面0道6扇区开始的4个扇区的数据到0:8000(即Kernel程序)
mov es, ax
mov ds, ax
mov bx, 8000h
mov al, 8 ;读取的扇区数(拟定Kernel占用8个扇区)
mov ch, 0 ;磁道
mov cl, 6 ;扇区号
mov dl, 80h ;硬盘从80h开始
mov dh, 0 ;0面
mov ah, 2 ;读扇区操作
int 13h
lgdt FWORD PTR VGDTR ;加载GDT
cli ;关中断
wait1: ;开启A20地址线
in al, 64h ;当输入缓冲器满时,在此循环,直到为空再向下执行
test al, 00000010b
jnz wait1
mov al, 0d1h ;发送写8042输出端口P2命令
out 64h, al
wait2:
in al, 64h ;当输出缓冲器满时,在此循环,直到为空再向下执行
test al, 00000001b
jnz wait2
mov al, 00000011b ;写入开启A20命令的参数,需要位1(控制A20门)和位0(系统复位)置1
out 60h, al
mov eax, cr0 ;开启保护模式
or eax, 1
mov cr0, eax ;CR0的位0是启用保护标志,设置该位时即开启了保护模式
JUMP16 Code_Sel,ProtectPos ;跳转到8:8000处执行保护模式下的程序。
codeseg ends
end
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论