;/////////////////////////////////////////////////
;//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/ 所需的資料建議從這個網站下