zoukankan      html  css  js  c++  java
  • setup.asm

     %include "protect.inc" ; 常量, 宏, 以及一些说明

    org  0x0500

    ; 实模式

     jmp SetUp_seg

    ;------------------------------------------------------------------------------------------
    times  0x10-($-$$) db 0
    KernelSize equ 512

    ; 此处地址: $ -> 0x500

    MCRNumberDW:   dd 0
    MemChkBuf: times 256 db 0
    MemSizeDW:   dd 0

    MemInfo1  db "________________________Memory  Allocation_______________________"
    MemInfoLen1 equ $ - MemInfo1
    MemInfo2  db " BaseAddrLow   BaseAddrHigh   LengthLow     LengthHigh     Type"
    MemInfoLen2 equ $ - MemInfo2
    ;
    SetupMessage db "Running Setup ... "
    SMLength equ $ - SetupMessage

    KernelAddr equ 12*1024  ;将kernel加载到这里( 物理地址:12*1024 )
    CylindTotalNum equ 80  ;软盘正反面都面有80个柱面
    SectorTotalNum  equ 18  ;软盘的每个磁道有18个扇区
    SectorByte equ 512  ;软盘的每个扇区有512 byte

    DriveNo  db 0
    HeadNo  db 0
    CylindNo db 0
    SectorNo db 1
    SectorNum db 0
    LoadSeg  dd 0

    ;------------------------------------------------------------------------------------------

    PrintBlank:
     push ax
     push bx
     mov bx, 000Ch
     mov al, ' '
     mov ah, 0Eh
     int 10h
     pop bx
     pop ax
     ret
    ;------------------------------
    PrintRL:
     push ax
     push bx
     push cx
     push dx
     mov ah, 03h
     int 10h
     inc dh
     mov dl, 0
     dec ah
     int 10h 
     pop dx
     pop cx
     pop bx
     pop ax
     ret
    ;------------------------------ 

    PrintMesg:    ; 输出字符串函数
     push bx
     push es
     mov ax, 00h
     mov es, ax
     mov ax, 1301h  ; AH = 13,  AL = 01h
     mov bx, 000Ch  ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
     int 10h   ; 10h 号中断
     pop es
     pop bx
     ret
    ;------------------------------
    PrintHex:    ; 以十六进制的形式输出 AL
     push bx
     push cx
     push dx
     mov cx, 2
     mov dh, al   ; 用 dh 保存 al 的值
     shr al, 4   ; 先输出高位
     mov ah, 0Eh
       .hex1:
     and al, 0Fh
     add al, '0'
     cmp al, '9'
     jbe .hex2
     add al, 7   ; al 中的值大于 9 ,此时 al 已经 加了48
       .hex2:
     mov bx, 000Ch  ; 字符属性
     int 10h
     mov al, dh
     dec cx
     jnz .hex1
     pop dx
     pop cx
     pop bx
     ret
    ;-------------------
    ReadFloppy:
     push es
    .1 
     mov ax, word [LoadSeg]
     mov es, ax
     mov bx, 0
     mov ah, 02h
     mov al, [SectorNum]
     mov dl, [DriveNo]
     mov dh, [HeadNo]
     mov ch, [CylindNo]
     mov cl, [SectorNo]
     int 13h
     jc .1

     pop es
     ret
    ;----------------------------------------------------------------------------


    SetUp_seg:
     mov ax, cs
     mov ds, ax
     mov es, ax
     mov ax, 8fc0h
     mov ss, ax
     mov sp, 0FFFFh

     mov dx, 0200h  ; dh -> 行号  dl -> 列号
     mov bp, SetupMessage ; ES:BP = 串地址(ES == 0000h)
     mov cx, SMLength
     call PrintMesg

     ; 调用int 15h 中断获得内存使用情况,保存到 MemChkBu 中
     mov ebx, 0
     mov di, MemChkBuf
    Chk_loop:
     mov eax, 0E820h
     mov ecx, 20
     mov edx, 0534D4150h
     int 15h
     jc Chk_fail
     add di, 20
     inc dword [MCRNumberDW]
     cmp ebx, 0
     jne Chk_loop
     jmp Mem_display
    Chk_fail:
     mov byte [MCRNumberDW], 0

     ; 显示内存可用情况
    Mem_display:
    ; mov al ,byte [MCRNumberDW]    ;memory info 个数
    ; call  PrintHex
     call PrintRL

     mov dx, 0300h  ; dh -> 行号  dl -> 列号
     mov bp, MemInfo1  ; ES:BP = 串地址(ES == 0000h)
     mov cx, MemInfoLen1
     call PrintMesg
     mov dx, 0500h  ; dh -> 行号  dl -> 列号
     mov bp, MemInfo2  ; ES:BP = 串地址(ES == 0000h)
     mov cx, MemInfoLen2
     call PrintMesg

     mov dx, 0
     mov dl, byte [MCRNumberDW]
     cmp dl , 0
     je Read_floppy
     mov si, MemChkBuf
     add si,4
      Mem_L1:
     call PrintRL
     call PrintBlank
     call PrintBlank
     mov cx, 0
      Mem_L2:
     dec si
     mov al, byte [si] 
     call PrintHex 
     inc cx
     test cx, 0003h
     jne Mem_L2

     add si,8
     call PrintBlank
     call PrintBlank
     call PrintBlank
     call PrintBlank
     call PrintBlank
     call PrintBlank
     cmp cx, 14h
     jne Mem_L2
     dec dx
     jnz Mem_L1

     ;从软盘加载Kernel模块; 读内核到内存中 12*1024 处
    Read_floppy:
     mov [LoadSeg], word (KernelAddr-4*1024)/16
     mov [SectorNum],byte 60   ;  13
     mov [SectorNo],byte 6
     call ReadFloppy
     ;软盘控制寄存器的I/O地址为3F0 - 3F7
     mov dl, 0  ; 停止驱动器
     mov dx, 0x3f2
     mov al, 0x0c
     out dx, al
      
     ;关中断
     cli

     ;将在 Gdtr 放置的GDT 表入口(32位基址 + 16位界限)加载到----> gdtr(共48位)中
     lgdt [Gdtr]

     ; 将GDT前八项到物理地址 0x000000 ,共 4 * 8byte = 32 byte
     mov esi, Gdt_begin
     mov edi, 0h
     mov ecx, 10*8
     cld
     rep movsb

     ;打开地址线 A20
     in al, 92h
     or al, 02h
     out 92h, al

     ;准备切换到保护模式
     mov eax, cr0
     or eax, 1
     mov cr0, eax

     ; 将 Sel_code 装入 cs , 并入跳转到 KCode
     jmp  dword Sel_Kenel:KCode_start

    ;  保护模式

    [bits 32]

    KCode_start :
     ;初始化堆栈段 SS、SP 和 DS、ES
     mov ax, Sel_KData     ; Sel_KData 基址为 0000h
     mov  ds, ax
     mov  es, ax
     mov ss, ax
     mov esp, 140*1024-4
     
     ; 下面显示一个字符串:  Running in Protect Mode now
     mov  ah, 0Ch     ; 0000: 黑底    1100: 红字
     mov esi, PMMessage     ; 源数据偏移
     mov edi, (80 * 12 + 0) * 2    ; 目的数据偏移。屏幕第 3 行, 第 0 列。
     cld
    PM_loop:
     lodsb
     test al, al
     jz PM_end
     mov [0xB8000+edi], ax
     add edi, 2
     jmp PM_loop
    PM_end:        ; 显示完毕

     ;-----------------------------------------
     
     lidt [Idtr]

     call  SetupPageTbl     ; 建立页表
     
     mov  eax, cr4
     or  eax, 20h
     mov  cr4, eax 

     mov  eax, PagePDPEBase     ;PageDirBase
     mov  cr3, eax
     mov  eax, cr0
     or  eax, 80000000h
     mov  cr0, eax
     
     jmp dword Sel_Kenel:KernelAddr

    Stop :
     jmp  $      ; 死循环

    ;
    ;------------------------------------------------------------------------------------------------------
    ; _________ 内存各段定义 _________
    ;
    GDTBase  equ  0
    GDTLen  equ  2*1024
    ;
    IDTBase  equ  2*1024
    IDTLen  equ  2*1024
    ;
    PagePDPEBase equ  1024
    PagePDEBase equ  4*1024
    PagePTEBase equ  8*1024
    ;
    PageNum  equ 1     ; 页表个数,暂时为 1 个 (指向前4M内存),此处最多设为(640k-64k*2)/4k-1 = 127

    ;


    ; _________ GDT 定义 _________
    ;                                  段基址, 段界限,   属性
    Gdt_begin :
      Descriptor  0,    0,   0                             ;0x0 空描述符
    DesKCode   :  Descriptor  0, 0FFFFFh, Des_DPL0+Des_CR  + Des_32 + Des_G ;0x8 (内核)非一致代码段, 32
    DesKData   : Descriptor  0, 0FFFFFh, Des_DPL0+Des_DRW + Des_32 + Des_G ;0x10

    Gdt_end
    ;
    Gdtr :
      dw  GDTLen     ; gdt的长度
      dd  GDTBase     ; gdt的物理地址

    Idtr :
      dw IDTLen-1    ; idt的长度
      dd IDTBase     ; idt的物理地址

    Sel_Kenel   equ   DesKCode    - Gdt_begin
    Sel_KData   equ   DesKData    - Gdt_begin    ; 数据段描述符
    Sel_stack equ   DesKData    - Gdt_begin    ; 堆栈段描述符

    ;
    PMMessage db "Running  in  ProtectMode",0

    ;----------------------------------------------------------------------------------------------------
    ; 初始化页表

    SetupPageTbl:

     mov dword [PagePDPEBase+4] , dword 0x0 
     mov dword [PagePDPEBase], PagePDEBase | PG_P  | PG_USU | PG_RWW 
     mov dword [PagePDEBase+4] , dword 0x0
     mov dword [PagePDEBase] , PagePTEBase | PG_P  | PG_USU | PG_RWW
     
     mov ecx, 512           ; 每个页表有 1024 项, 每项 4 byte
     mov edi, PagePTEBase    ; 此段首地址为 PagePTEBase
     xor eax, eax
     mov eax, PG_P | PG_USU | PG_RWW
    .PageTbl:
     mov [es:edi], eax
     add edi,4
     mov [es:edi],  dword 0x0
     add edi,4
     add eax, 4096     ; 每一页指向 4K 的空间
     loop .PageTbl
     
     call deleteHole
     
     ret
     
    deleteHole:
     mov esi,  PagePTEBase + 35*8   ;// 140k 对应的页表项  140 = 4k + 4k + 4k + 128k
     mov edi,  PagePTEBase + 160*8  ;// 640k 对应的页表项
     mov ecx, (1024-640)/4
    .1 
     mov eax, dword [esi]
     mov ebx, dword [edi]
     mov  dword [esi], ebx
     mov  dword [edi], eax
     add edi,8
     add esi,8
     loop .1
     ret
     
    ;------------------------------

    times  2048-($-$$) db 0

  • 相关阅读:
    BPF and eBPF linux
    o-sync-and-o-direct
    linux performance test
    iostat
    MYSQL IO innodb-buffer-pool
    MYSQL file types redo log
    read pread write pwrite open
    CORE DUMP
    linux kernel的中断子系统 softirq
    linux KERNEL 问题
  • 原文地址:https://www.cnblogs.com/sunkang/p/2038827.html
Copyright © 2011-2022 走看看