zoukankan      html  css  js  c++  java
  • making an os NO.1 怎样进内核之一

     现在看的是怎样将系统引导进编制的操作系统内核。以《orang‘s os 一个操作系统的编制》为参考。首先要做的就是在存储介质的前512个字节上大作文章,写程序。而进内核,一种方案是自己写个16位汇编程序,放进512。用这个程序去引导内核,就像开源项目grub一样。但很明显,这样做起来,无论从技术和代码量上都不易 。我学着书中所说,还是用dos引导吧。先把原型做出来,再在上面增添功能。使用快速开发的思想,编制我的操作系统。

          一般对于80386以上的内核中,程序一般运行在32位环境中(64位,晕!不谈,那不是给人用的)。所以还需要先从16为跳到32位。

          总之,上面的步骤主要有三。

          一、将存储介质前512从内存07c00h处运行。

          二、从16位跳到32位。

          三、进内核。

         下面的代码是16->32的危险一跳。

    ; ==========================================
    2 ; pmtest1.asm
    3 ; 编译方法:nasm pmtest1.asm -o pmtest1.bin
    4 ; ==========================================
    5
    6 %include "pm.inc"<span color="#0000ff"style="color: #0000ff;">; 常量, 宏, 以及一些说明</span>
    7
    8 org 07c00h <span color="#0000ff"style="color: #0000ff;">; 加载07c00h处cs=0000h,ip=07c00h(别人规定的)</span>








    01 jmp LABEL_BEGIN ; 跳转到LABEL_BEGIN处
    02
    03 [SECTION .gdt]
    04 ; GDT
    05 ; 段基址, 段界限 , 属性
    06 LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
    07 LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段
    08 LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
    09 ; GDT 结束
    10
    11 GdtLen equ $ - LABEL_GDT ; GDT长度
    12 GdtPtr dw GdtLen - 1 ; GDT界限
    13 dd 0 ; GDT基地址
    14
    15 ; GDT 选择子
    16 SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT ;32位代码段选择子
    17 SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT ;显存选择子
    18 ; END of [SECTION .gdt]
    19
    20 [SECTION .s16]
    21 [BITS 16]
    22 LABEL_BEGIN:
    23 mov ax, cs
    24 mov ds, ax
    25 mov es, ax
    26 mov ss, ax ;以上代码将当前的ds,es,ss全部指向cs代码段
    27 mov sp, 0100h ;sp设置为0100h
    28
    29 ; 初始化 32 位代码段描述符
    30 xor eax, eax ;eax清0
    31 mov ax, cs ;存入cs
    32 shl eax, 4 ;左移4位,扩展为20位地址
    33 add eax, LABEL_SEG_CODE32 ;在cs的基础上加上LABEL_SEG_CODE32的地址偏移(相对于0)
    01 mov word [LABEL_DESC_CODE32 + 2], ax ;将ax中的16位段地址移入描述符LABEL_DESC_CODE32对应的2~3字节
    02 shr eax, 16 ;将eax的高16位移入低16位中
    03 mov byte[LABEL_DESC_CODE32 + 4], al ;将al中的8位段地址移入描述符LABEL_DESC_CODE32对应的4字节中
    04 mov byte[LABEL_DESC_CODE32 + 7], ah ;将ah中的8位段地址移入描述符LABEL_DESC_CODE32对应的7字节中
    05
    06 ; 为加载 GDTR 作准备
    07 xor eax, eax ;eax清0
    08 mov ax, ds ;ds移入ax
    09 shl eax, 4 ;扩展为20位
    10 add eax, LABEL_GDT ; eax <- gdt 基地址 ds+gdt基地址
    11 mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址 将gdt基地址移入GdtPtr中
    12
    13 ; 加载 GDTR
    14 lgdt [GdtPtr];将GdtPtr中的GDT界限和GDT基地址加载到寄存器gdtr中
    15
    16 ; 关中断
    17 cli
    18
    19 ; 打开地址线A20-----前面的段地址已经扩展位20位
    20 inal, 92h
    21 or al, 00000010b
    22 out92h, al
    23
    24 ; 准备切换到保护模式
    25 mov eax, cr0 ;加载cr0到eax
    26 or eax, 1 ;将cr0的PE置位1,打开保护模式
    27 mov cr0, eax ;更改cr0
    28
    29 ; 真正进入保护模式
    30 jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs,
    31 ; 并跳转到 Code32Selector:0 处 SelectorCode32中段基址指向LABEL_SEG_CODE32偏移为0
    32 ; END of [SECTION .s16]
    33
    34
    35 [SECTION .s32]; 32 位代码段. 由实模式跳入.
    36 [BITS 32]
    37
    38 LABEL_SEG_CODE32:
    39 mov ax, SelectorVideo
    40 mov gs, ax ; 视频段选择子(目的)
    41
    42 mov edi, (80 * 11 + 79) * 2 ; 屏幕第 11 行, 第 79 列。
    43 mov ah, 0Ch ; 0000: 黑底 1100: 红字
    44 mov al, 'P'
    45 mov [gs:edi], ax
    46
    47 ; 到此停止
    48 jmp $
    49
    50 SegCode32Len equ $ - LABEL_SEG_CODE32
    51 ; END of [SECTION .s32]
    进入保护模式的主要步骤

      a.准备GDT

      b.用lgdt加载gdtr

      c.打开A20

      d.置cr0的PE位

      e.跳转,进入保护模式


  • 相关阅读:
    git线上操作
    IDEA快捷方式
    Java 四种线程池
    java 获取当前天之后或之前7天日期
    如何理解AWS 网络,如何创建一个多层安全网络架构
    申请 Let's Encrypt 通配符 HTTPS 证书
    GCE 部署 ELK 7.1可视化分析 nginx
    使用 bash 脚本把 AWS EC2 数据备份到 S3
    使用 bash 脚本把 GCE 的数据备份到 GCS
    nginx 配置 https 并强制跳转(lnmp一键安装包)
  • 原文地址:https://www.cnblogs.com/yishuiliunian/p/1987675.html
Copyright © 2011-2022 走看看