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.跳转,进入保护模式


  • 相关阅读:
    vim for python配置
    Python学习的一些好资料
    【Python开发实战】Python环境的配置
    【Python开发实战】Windows7+VirtualBox+Ubuntu环境配置
    linux下shapely的安装
    【python常用模块】os.path
    linux下gdal的python包的安装
    由二叉树的前序遍历和中序遍历,求其后序遍历
    ASCII码表
    C++标准库函数之排列函数
  • 原文地址:https://www.cnblogs.com/yishuiliunian/p/1987675.html
Copyright © 2011-2022 走看看