• 编写操作系统之从实模式到保护模式代码模板


    在实模式下设置各种参数,然后跳到保护模式,再在屏幕中央打出一串红色字符。实模式执行的第一步是在物理地址为0x200处设置一个坑,调试的时候就可以在物理地址为0x200处设置一个断点。

    protect.asm

      1 ;******************************************************************
    2 ;文件名称: protect.asm
    3 ;编译方法: nasm protect.asm -o protect.com
    4 ;编译说明:编译成DOS专用可执行文件,可在DOS下运行。
    5 ;主要功能: 从实模式进入到保护模式代码模板。
    6 ;建立时间: 2011-10-07
    7 ;******************************************************************
    8
    9 %include "protect.inc" ;*********常量及宏
    10
    11 org 0100h
    12 jmp LABEL_BEGIN
    13
    14 ;**********************************************************************
    15 ;全局描述符及选择子
    16 ;**********************************************************************
    17 [SECTION .gdt] ;********全局描述符
    18 ; 段基址 段界限 属性
    19 LABEL_GDT: Descriptor 0, 0, 0
    20 LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA+DA_32
    21 LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW
    22 LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32
    23 LABEL_DESC_VIDEO: Descriptor 0b8000h, 0ffffh, DA_DRW+DA_DPL3
    24
    25 GdtLen equ $-LABEL_GDT ;*********GDT长度
    26 GdtPtr dw GdtLen-1 ;*********GDT界限
    27 dd 0 ;*********GDT基地址
    28
    29 ; ******GDT选择子
    30 SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
    31 SelectorData equ LABEL_DESC_DATA - LABEL_GDT
    32 SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
    33 SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
    34
    35 ;**********************************************************************
    36 ;End of 全局描述符
    37 ;**********************************************************************
    38
    39 ;**********************************************************************
    40 ;全局堆栈
    41 ;**********************************************************************
    42 [SECTION .gs]
    43 ALIGN 32
    44 [BITS 32]
    45 LABEL_STACK:
    46 times 512 db 0
    47 TopOfStack equ $ - LABEL_STACK - 1
    48 ;**********************************************************************
    49 ;End of 全局堆栈
    50 ;**********************************************************************
    51
    52 ;**********************************************************************
    53 ;数据段
    54 ;**********************************************************************
    55 [SECTION .data]
    56 ALIGN 32
    57 [BITS 32]
    58 LABEL_DATA:
    59 ;**********************字符串*********************
    60 PMMessage: db "In Protect Mode now . ^_^",0
    61 OffsetPMMessage equ PMMessage - $$
    62 StrTest: db "ABCDEFG",0
    63 OffsetStrTest equ StrTest - $$
    64 DataLen equ $ - LABEL_DATA
    65 ;**********************************************************************
    66 ;End of 数据段
    67 ;**********************************************************************
    68
    69
    70 ;**********************************************************************
    71 ;16位实模式代码段
    72 ;**********************************************************************
    73 [SECTION .s16]
    74 [BITS 16]
    75 Hoot: ;坑的入口点
    76 mov ax,01h
    77 mov ax,02h
    78 GoBack:
    79 jmp 0:Back
    80 HootLen equ $ - Hoot
    81
    82 LABEL_BEGIN:
    83
    84 ;在地址为0x200处设置坑用来设置断点
    85 mov ax,cs
    86 mov [GoBack + 3],ax
    87 mov ds,ax
    88 mov si,Hoot
    89 mov ax,0
    90 mov es,ax
    91 mov di,200h
    92 mov cx,HootLen
    93 rep movsb
    94 jmp 0:200h
    95
    96 Back:
    97 mov ax,cs
    98 mov ds,ax
    99 mov es,ax
    100 mov ss,ax
    101 mov sp,0100h
    102
    103 ;修正全局堆栈描述符的基地址
    104 ResetDescBaseAddr LABEL_DESC_STACK,LABEL_STACK
    105 ;修正数据段描述符的基地址
    106 ResetDescBaseAddr LABEL_DESC_DATA,LABEL_DATA
    107 ;修正32位代码段描述符的基地址
    108 ResetDescBaseAddr LABEL_DESC_CODE32,LABEL_SEG_CODE32
    109
    110 ;为加载GDTR作准备
    111 xor eax,eax
    112 mov ax,ds
    113 shl eax,4
    114 add eax,LABEL_GDT
    115 mov dword [GdtPtr+2],eax
    116
    117 ;加载GDTR
    118 lgdt [GdtPtr]
    119
    120 ;关中断
    121 cli
    122
    123 ;打开地址线
    124 in al,92h
    125 or al,00000010b
    126 out 92h,al
    127
    128 ;开启保护模式
    129 mov eax,cr0
    130 or eax,1
    131 mov cr0,eax
    132
    133 ;真正进入保护模式
    134 jmp dword SelectorCode32:0
    135
    136 ;**********************************************************************
    137 ;End of 16位实模式代码段
    138 ;**********************************************************************
    139
    140 ;**********************************************************************
    141 ;32位保护模式代码段
    142 ;**********************************************************************
    143 [SECTION .s32];*************32位代码段,由实模式跳入
    144 [BITS 32]
    145 LABEL_SEG_CODE32:
    146
    147 mov ax,SelectorData
    148 mov ds,ax
    149 mov ax,SelectorVideo
    150 mov gs,ax
    151
    152 mov ax,SelectorStack
    153 mov ss,ax
    154 mov esp,TopOfStack
    155
    156 ;显示一个字符串
    157 mov ah,0ch ;******黑底红字
    158 xor esi,esi
    159 xor edi,edi
    160 mov esi,OffsetPMMessage ;***字符串基地址
    161 mov edi,(80*10+0)*2 ;******第10行第0列
    162 cld ;******正向
    163 .1:
    164 lodsb
    165 test al,al
    166 jz .2
    167 mov [gs:edi],ax
    168 add edi,2
    169 jmp .1
    170 .2: ;*****************显示完毕
    171
    172 call DispReturn
    173 jmp $
    174
    175
    176 DispReturn:
    177 push eax
    178 push ebx
    179 mov eax,edi
    180 mov bl,160
    181 div bl
    182 and eax,0ffh
    183 inc eax
    184 mov bl,160
    185 mul bl
    186 mov edi,eax
    187 pop ebx
    188 pop eax
    189 ret
    190 SegCode32Len equ $-LABEL_SEG_CODE32
    191 ;**********************************************************************
    192 ;End of 32位保护模式代码段
    193 ;**********************************************************************

    所需要的头文件protect.inc,有些没有用到,但考虑到通用性,放在里面也没事。

      1 ;----------------------------------------------------------------------------
    2 ; 描述符类型值说明
    3 ; 其中:
    4 ; DA_ : Descriptor Attribute
    5 ; D : 数据段
    6 ; C : 代码段
    7 ; S : 系统段
    8 ; R : 只读
    9 ; RW : 读写
    10 ; A : 已访问
    11 ; 其它 : 可按照字面意思理解
    12 ;----------------------------------------------------------------------------
    13 DA_32 EQU 4000h ; 32 位段
    14
    15 DA_DPL0 EQU 00h ; DPL = 0
    16 DA_DPL1 EQU 20h ; DPL = 1
    17 DA_DPL2 EQU 40h ; DPL = 2
    18 DA_DPL3 EQU 60h ; DPL = 3
    19 ;----------------------------------------------------------------------------
    20 ; 存储段描述符类型值说明
    21 ;----------------------------------------------------------------------------
    22 DA_DR EQU 90h ; 存在的只读数据段类型值
    23 DA_DRW EQU 92h ; 存在的可读写数据段属性值
    24 DA_DRWA EQU 93h ; 存在的已访问可读写数据段类型值
    25 DA_C EQU 98h ; 存在的只执行代码段属性值
    26 DA_CR EQU 9Ah ; 存在的可执行可读代码段属性值
    27 DA_CCO EQU 9Ch ; 存在的只执行一致代码段属性值
    28 DA_CCOR EQU 9Eh ; 存在的可执行可读一致代码段属性值
    29 ;----------------------------------------------------------------------------
    30 ; 系统段描述符类型值说明
    31 ;----------------------------------------------------------------------------
    32 DA_LDT EQU 82h ; 局部描述符表段类型值
    33 DA_TaskGate EQU 85h ; 任务门类型值
    34 DA_386TSS EQU 89h ; 可用 386 任务状态段类型值
    35 DA_386CGate EQU 8Ch ; 386 调用门类型值
    36 DA_386IGate EQU 8Eh ; 386 中断门类型值
    37 DA_386TGate EQU 8Fh ; 386 陷阱门类型值
    38 ;----------------------------------------------------------------------------
    39
    40
    41 ; 选择子图示:
    42 ; ┏━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┓
    43 ; ┃15┃14┃13┃12┃11┃10┃9 ┃ 8 ┃ 7 ┃ 6 ┃ 5 ┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃ 0 ┃
    44 ; ┣━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━╋━━╋━━┻━━┫
    45 ; ┃ 描述符索引 ┃ TI ┃ RPL ┃
    46 ; ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━┻━━━━━┛
    47 ;
    48 ; RPL(Requested Privilege Level): 请求特权级,用于特权检查。
    49 ;
    50 ; TI(Table Indicator): 引用描述符表指示位
    51 ; TI=0 指示从全局描述符表GDT中读取描述符;
    52 ; TI=1 指示从局部描述符表LDT中读取描述符。
    53 ;
    54
    55 ;----------------------------------------------------------------------------
    56 ; 选择子类型值说明
    57 ; 其中:
    58 ; SA_ : Selector Attribute
    59
    60 SA_RPL0 EQU 0 ;
    61 SA_RPL1 EQU 1 ; ┣ RPL
    62 SA_RPL2 EQU 2 ;
    63 SA_RPL3 EQU 3 ;
    64
    65 SA_TIG EQU 0 ; ┓TI
    66 SA_TIL EQU 4 ;
    67 ;----------------------------------------------------------------------------
    68
    69
    70
    71
    72
    73 ; 宏 ------------------------------------------------------------------------------------------------------
    74 ;
    75 ; 描述符
    76 ; usage: Descriptor Base, Limit, Attr
    77 ; Base: dd
    78 ; Limit: dd (low 20 bits available)
    79 ; Attr: dw (lower 4 bits of higher byte are always 0)
    80 %macro Descriptor 3
    81 dw %2 & 0FFFFh ; 段界限 1 (2 字节)
    82 dw %1 & 0FFFFh ; 段基址 1 (2 字节)
    83 db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节)
    84 dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节)
    85 db (%1 >> 24) & 0FFh ; 段基址 3 (1 字节)
    86 %endmacro ; 共 8 字节
    87 ;
    88 ;
    89 ; usage: Gate Selector, Offset, DCount, Attr
    90 ; Selector: dw
    91 ; Offset: dd
    92 ; DCount: db
    93 ; Attr: db
    94 %macro Gate 4
    95 dw (%2 & 0FFFFh) ; 偏移 1 (2 字节)
    96 dw %1 ; 选择子 (2 字节)
    97 dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性 (2 字节)
    98 dw ((%2 >> 16) & 0FFFFh) ; 偏移 2 (2 字节)
    99 %endmacro ; 共 8 字节
    100
    101
    102 ;修正全局描述符的基地址
    103 ;usage: ResetDescBaseAddr Descriptor, BaseAddr
    104 ; Discriptor:全局描述符
    105 ; BaseAddr :描述符所对应段的基地址
    106 %macro ResetDescBaseAddr 2
    107 xor eax,eax
    108 mov ax,cs
    109 shl eax,4
    110 add eax,%2
    111 mov word [%1+2],ax
    112 shr eax,16
    113 mov byte [%1+4],al
    114 mov byte [%1+7],ah
    115 %endmacro



    参考:于渊 著 《orange's 一个操作系统的实现》



  • 相关阅读:
    ubuntu下minicom和usb串口转接
    linux下 驱动模块编译步骤
    linux下的压缩解压命令
    GitLab 数据备份和恢复
    GitLab 项目创建后地址由Localhost改为实际IP的方法
    GitLab-Runner 安装配置
    GitLab 的安装及汉化
    用yum rpm 快速安装zabbix agent
    RabbitMQ的用户管理方法
    Linux下安装部署RabbitMQ
  • 原文地址:https://www.cnblogs.com/teafree/p/2200627.html
Copyright © 2020-2023  润新知