⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpboot.asm

📁 这是bootloader源码
💻 ASM
字号:
;名称:CPBLK.ASM
;功能:切换到32位保护模式,在内存中拷贝数据
;----------------------------------------------------------------------------
INCLUDE         386SCD.INC
;----------------------------------------------------------------------------
DSEG            SEGMENT USE16                     ;16位数据段
;----------------------------------------------------------------------------
GDT             LABEL   BYTE                      ;全局描述符表
DUMMY           Desc    <>                        ;空描述符
Normal          Desc    <0ffffh,,,ATDW,,>         ;规范段描述符
Code32          Desc    <C32Len-1,,,ATCE,D32,>    ;32位代码段描述符
Code16          Desc    <0ffffh,,,ATCE,,>         ;16位代码段描述符
DataS           Desc    <0ffffh,0,0,ATDW,0fch,0>  ;源数据段描述符 (0-4GB, Read only)
;DataD           Desc    <0ffffh,0,0,ATDW,0fch,0>  ;显示缓冲区描述符 (0-4GB, Read/Write)
Stacks          Desc    <StackLen-1,,,ATDW,,>     ;堆栈段描述符
;----------------------------------------------------------------------------
GDTLen          =       $-GDT                     ;全局描述符表长度
VGDTR           PDesc   <GDTLen-1,>               ;伪描述符
;----------------------------------------------------------------------------
SaveSP          DW      ?                         ;用于保存SP寄存器
SaveSS          DW      ?                         ;用于保存SS寄存器
;----------------------------------------------------------------------------
Normal_Sel      =       Normal-GDT                ;规范段描述符选择子
Code32_Sel      =       Code32-GDT                ;32位代码段选择子
Code16_Sel      =       Code16-GDT                ;16位代码段选择子
DataS_Sel       =       Datas-GDT                 ;数据段选择子
Stacks_Sel      =       Stacks-GDT                ;堆栈段描述符选择子
;----------------------------------------------------------------------------
DataLen         =       16
;----------------------------------------------------------------------------
DSEG            ENDS                              ;数据段定义结束
;----------------------------------------------------------------------------
StackSeg        SEGMENT PARA STACK USE16
StackLen        =       256
                DB      StackLen DUP(0)
StackSeg        ENDS
;----------------------------------------------------------------------------
CSEG1           SEGMENT USE16 'REAL'              ;16位代码段
                ASSUME  CS:CSEG1,DS:DSEG
;----------------------------------------------------------------------------
Start           PROC
                mov     ax,DSEG
                mov     ds,ax
                ;准备要加载到GDTR的伪描述符
                mov     bx,16
                mul     bx
                add     ax,OFFSET GDT             ;计算并设置基地址
                adc     dx,0                      ;界限已在定义时设置好
                mov     WORD PTR VGDTR.Base,ax
                mov     WORD PTR VGDTR.Base+2,dx
                ;设置32位代码段描述符
                mov     ax,CSEG2
                mul     bx
                mov     WORD PTR Code32.BaseL,ax
                mov     BYTE PTR Code32.BaseM,dl
                mov     BYTE PTR Code32.BaseH,dh
                ;设置16位代码段描述符
                mov     ax,CSEG3
                mul     bx
                mov     WORD PTR Code16.BaseL,ax  ;代码段开始偏移为0
                mov     BYTE PTR Code16.BaseM,dl  ;代码段界限已在定义时设置好
                mov     BYTE PTR Code16.BaseH,dh
                ;设置堆栈段描述符
                mov     ax,ss
                mov     WORD PTR SaveSS,ax
                mov     WORD PTR SaveSP,sp
                mov     ax,StackSeg
                mul     bx
                mov     WORD PTR Stacks.BaseL,ax
                mov     BYTE PTR Stacks.BaseM,dl
                mov     BYTE PTR Stacks.BaseH,dh
                ;加载GDTR
                lgdt    QWORD PTR VGDTR
                cli                               ;关中断
                EnableA20                         ;打开地址线A20
                ;切换到保护方式
                mov     eax,cr0
                or      al,1
                mov     cr0,eax
                ;清指令预取队列,并真正进入保护方式
                JUMP16  Code32_Sel,<OFFSET SPM32>
ToReal:         ;现在又回到实方式
                mov     ax,DSEG
                mov     ds,ax
                mov     sp,SaveSP
                mov     ss,SaveSS
                DisableA20
                sti

; Code for booting linux immdiately:
; Just put an instruction of jmp 9020h:0000 followed. 
; What happened? Enjoy your linux!
                db      0eah,00h,00h,20h,90h
; boot code ends
                
; You never reach here!
                mov     ax,4c00h
                int     21h
Start           ENDP
;----------------------------------------------------------------------------
CSEG1           ENDS                              ;代码段定义结束
;----------------------------------------------------------------------------
CSEG2           SEGMENT USE32 'PM32'
                ASSUME  CS:CSEG2
;----------------------------------------------------------------------------
SPM32           PROC
                mov     ax,Stacks_Sel
                mov     ss,ax
                mov     esp,StackLen
                mov     ax,DataS_Sel
                mov     ds,ax
                
SOURCE          =       800000h
DESTINATION     =       0h

BOOTSECT_POS    =       90000h
BOOTSECT_LEN    =       200h
SETUP_POS       =       90200h
SETUP_LEN       =       CMD_POS - SETUP_POS
                        ;1400h
                        ;0c00h
KERN_POS        =       100000h
KERN_LEN        =       400000h
CMD_POS         =       99000h
CMD_LEN         =       256

                mov     eax,BOOTSECT_POS
                mov     ebx,BOOTSECT_LEN
                call    COPYDATA
                mov     eax,SETUP_POS
                mov     ebx,SETUP_LEN
                call    COPYDATA
                mov     eax,KERN_POS
                mov     ebx,KERN_LEN
                call    COPYDATA
                mov     eax,CMD_POS
                mov     ebx,CMD_LEN
                call    COPYDATA

                JUMP32   Code16_Sel,<OFFSET SPM16>
SPM32           ENDP
;----------------------------------------------------------------------------
COPYDATA        PROC
                mov     esi,SOURCE
                add     esi,eax         ; setup source start address in ESI
                mov     edi,DESTINATION 
                add     edi,eax         ; setup destination start address in EDI
                add     ebx,esi         ; setup source end address in EBX

LOOP12:         mov     al,ds:[esi]
                mov     ds:[edi],al
                inc     edi
                inc     esi
                cmp     esi,ebx
                jl      LOOP12

                ret
COPYDATA        ENDP
;----------------------------------------------------------------------------
C32Len          =       $
;----------------------------------------------------------------------------
CSEG2           ENDS
;----------------------------------------------------------------------------
CSEG3           SEGMENT USE16 'PM16'
                ASSUME  CS:CSEG3
;----------------------------------------------------------------------------
SPM16           PROC
                xor     si,si
                mov     di,DataLen*3*2
                mov     ah,7
                mov     cx,DataLen
AGain:          lodsb
                stosw
                loop    AGain
                mov     ax,Normal_sel
                mov     ds,ax
                mov     es,ax
                mov     ss,ax
                mov     eax,cr0
                and     al,11111110b
                mov     cr0,eax
                jmp     FAR PTR ToReal
SPM16           ENDP
;----------------------------------------------------------------------------
CSEG3           ENDS
;----------------------------------------------------------------------------
                END     Start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -