;/
;//linyeeos.asm linyeeos微系统主代码
;//编译 nasm linyeeos.asm -o linyeeos.img
;//Write by linyee at [2007-02-11 ~ 2007-02-15]
;//联系方式 www.linyee.net mythiner@2911.net QQ249033420
;//
;//-----------------
;//version: 0.1
;//功能说明: 引导程序测试演示
;//
;//学习小结: 今天[2007-02-12]终于攻克了实模式到保护模式的跳转问题
;// 以前失败的原因是对虚拟地址到线性地址转换认知不足
;/
;******************************************************
;代码段
[BITS 16] ;编译成16 位的指令
[ORG 0x7C00]
BOOTSTART equ $$ ;起始地址
;----------------------------------------------------------------------------------------------
jmp Boot
;----------------------------------------------------------------------------------------------
;引导区FAT文件系统数据;V0.2,2008-08-22加入使得本引导程序支持FAT格式
brOEM DB 'linyeeos' ; 0003h - 引导程序的名字
brBPS DW 0x200 ; 000Bh - 每扇区的字节数 512
brSPC DB 0x01 ; 000Dh - 每簇扇区数
brResCount DW 0x0004 ; 000Eh - 保留扇区数
brFATs DB 0x02 ; 0010h - FAT 备份数
brRootEntries DW 0x00e0 ; 0011h - 根目录入口数
brSectorCount DW 2880 ; 0013h - 磁盘容量扇区数< 32MB
brMedia DB 240 ; 0015h - 媒体描述符
brSPF DW 9 ; 0016h - 每FAT扇区数
brSPH DW 18 ; 0018h - 每磁道扇区数
brHPC DW 2 ; 001Ah - 盘面数
brHidden DD 0 ; 001Ch - 隐藏扇区数
brSectors DD 0 ; 0020h - 如果大于32m的扇区总数
DB 0 ; 0024h - 物理驱动器号
DB 0 ; 0025h - 系统保留
DB 29H ; 0026h - 扩展扇区标记(包含29h)
brSerialNum DD 00000006H ; 0027h - 卷ID
brLabel DB 'linyee-Disk' ; 002Bh - 卷标
brFSID DB 'FAT12 ' ; 0036h - 系统保留
;----------------------------------------------------------------------------------------------
;预定义
BOOTSEG equ 0x0000 ;启动基址
LOADERSEG equ 0x9000 ;loader基址
BOOTDRIVER db 0 ;驱动器号
bootMsg db 'booting linyeeos ...',13,10,0
;----------------------------------------------------------------------------------------------
Boot:
mov [BOOTDRIVER] , dl ;得到启动的驱动器号
mov ax,cs ;同步段址
mov ds,ax
mov es,ax ;es=ds=cs
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx ;数据寄存置0
mov si , bootMsg
call ShowMessage ;显示信息
;读入loader
;从磁盘的第1个扇区读到 0x9000:BOOTSTART 处
.readfloopy:
mov ax , LOADERSEG
mov es , ax
mov bx , BOOTSTART ;设置保存位置
mov ah , 2 ;13H-2 ==> 读扇区
mov al , EndSECTOR-1 ;读入扇区数( 2 个共1KB )
mov dl , [BOOTDRIVER] ;驱动器号
mov dh,0 ;磁头
mov ch , 0 ;柱面
mov cl , 1 ;扇区,0扇区为1
int 0x13
jc .readfloopy ;CF=1时,重试,CF=0时成功
mov al , [BOOTDRIVER] ;把启动驱动器号保存在0x90000 处
mov [0] , al
jmp LOADERSEG:LOADERSTART ;跳转到loader执行
;----------------------------------------------------------------------------------------------
ShowMessage:
;以下程序行为显示输出信息
push ax
push bx
mov ah , 0x0e ;设置显示模式
mov bh , 0x00 ;设置页码
mov bl , 0x07 ;设置字体属性
.nextchar:
lodsb
or al , al
jz .return ;退出
int 0x10
jmp .nextchar ;下一个字符
.return:
pop bx
pop ax
ret
;-----------------------------------------------------------------------------------------------
;引导区结束
times 510-($-$$) db 0
db 0x55
db 0xAA
;******************************************************
;******************************************************
;loader的代码
[BITS 16]
LOADERSTART equ $ ;loader偏移7e00H以保持代码在同一个文件
LOADERSECTOR equ ($-$$)/512+1 ;起始扇区号
;-------------------------------------------------------------------------------------
jmp Loader
;-----------------------------------------------------------------------------------------------
;预定义
;数据段
loadMsg db 'loading ...',13,10,0
;全局描述符表GDT 48位
gdt_addr:
dw 0x7fff ;GDT 表的大小 界限64kb
dw gdt ;GDT 表的位置 基地址低位
dw 0x0009 ;基地址高位 LOADERSEG >> 12
;段描述符64位
;B7 B6 B5 BIT4 BIT3 BIT2 BIT1 BIT0 B7 B6 B5 BIT4 BIT3 BIT2 BIT1 BIT0
;G D 0 AVL Limit(19...16) P DPL DT1 TYPE
;在80286保护方式下,段基地址只有24位长,而段界限只有16位长。
gdt:
gdt_null:
dw 0x0000 ;段限
dw 0x0000 ;低基址16位
dw 0x0000 ;属性低8位 高基址低8位
dw 0x0000 ;高基址高8位 属性高8位
;虚拟地址 0x0008:0x100==>线性地址 1号描述表中表示的基址+0x100
gdt_system_code:
dw 0x3fff ;段限=16K * 64KB = 64MB
dw 0x0000 ;段基址=0x00090000
dw 0x9a09
dw 0x00c0 ;属性=0xc09a
gdt_system_data: ;
dw 0x3fff
dw 0x0000
dw 0x9209
dw 0x00c0
gdt_system_graph: ;
dw 0x3fff
dw 0x8000
dw 0x920b ;0xb8000
dw 0x00c0
;-------------------------------------------------------------------------------------
;等待键盘控制器空闲的子程序
Empty_8042:
in al , 0x64
test al , 0x2
jnz Empty_8042
ret
;-------------------------------------------------------------------------------------
Loader:
mov ax,cs ;同步段址
mov ds,ax
mov es,ax ;es=ds=cs
mov ss,ax
;mov sp , ENDSYSTEM ;堆栈指针
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx ;数据寄存置0
mov si , loadMsg
call ShowMessage ;显示信息
;下面开始为进入保护模式而进行初始化工作
cli ;关中断
lgdt [gdt_addr] ;载入gdt 的描述符
;打开地址线A20 ;兼容性,地址回卷
;in al,92H
;or al,00000010B
;out 92h,al
;下面打开A20 地址线
call Empty_8042
mov al , 0xd1
out 0x64 , al
call Empty_8042
mov al , 0xdf
out 0x60 , al
call Empty_8042
;下面设置进入32 位保护模式运行
mov eax , cr0
or eax , 1
mov cr0 , eax
;jmp $
jmp dword 0x8:SYSTEMSTART ;1000B为1号选择子.
;-----------------------------------------------------------------------------------------------
LoaderBuffer: ;缓存段, 使本文件编译后的文件大小必为512的倍数(即满扇)
times (($-$$)/512+1)*512-($-$$) db 0
;******************************************************
;******************************************************
;system的代码
[BITS 32]
SYSTEMSTART equ $ ;系统段的起始地址
SYSTEMSECTOR equ ($-$$)/512+1 ;起始扇区号
;-------------------------------------------------------------------------------------
jmp System
;-----------------------------------------------------------------------------------------------
startMsg db 'starting linyeeos ...',13,10,0
;-------------------------------------------------------------------------------------
System:
;mov si , startMsg
;call ShowMessage ;显示信息
;mov ax , 0x10
;mov ds , ax
mov ax,0x10
mov ds,ax
mov ax,0x18
mov gs,ax
mov edi,(80*10+0)*2 ;屏幕第10行,第0列
mov ah,0FH ;黑底白字
mov al , 'L'
mov [gs:edi] , ax
;mov cl , 0x04
;mov [0xb8001] , cl
jmp $
;-----------------------------------------------------------------------------------------------
;数据段
systemBuffer: ;缓存段, 使本文件编译后的文件大小必为512的倍数(即满扇)
times (($-$$)/512+1)*512-($-$$) db 0
;-----------------------------------------------------------------------------------------------
ENDSYSTEM equ $ ;
EndSECTOR equ ($-$$)/512+1 ;结束扇区
;******************************************************
osBuffer:
times 1474560-($-$$) db 0 ;本句是为节省使用工具的时间,使得编译后的文件直接为一个软盘境像文件
;******************************************************
编译工具nasmw.exe nasmw boot.asm -o linyeeos.img
编译完成后,用虚拟机测试。
linyeeos.bxrc
megs: 16
romimage: file="C:/Program Files/Bochs-2.2.6/BIOS-bochs-latest", address=0xf0000
vgaromimage: file="C:/Program Files/Bochs-2.2.6/VGABIOS-lgpl-latest"
floppya: 1_44=linyeeos.img, status=inserted
boot: floppy
log: bochsout.txt
将 linyeeos.bxrc linyeeos.img 放在同一个文件夹下,直接双击 linyeeos.bxrc即可,看到效果--(屏幕上输出了一行字及一个红色的L,bochs调试时,没有自动清屏要注意看)。
linyeeos.bxrc是一个bochs的配置文件。
http://www.lupaworld.com/ 所需的资料建议从这个网站下