【复制GDT】

2020-11-22  本文已影响0人  月下蓑衣江湖夜雨

kernel.asm部分

    sgdt    [gdt_ptr]   ; cstart() 中将会用到 gdt_ptr
    call    cstart      ; 在此函数中改变了gdt_ptr,让它指向新的GDT
    lgdt    [gdt_ptr]   ; 使用新的GDT

使用命令将gdt地址复制到新的gdt处。

cstart.c部分

PUBLIC  t_8             gdt_ptr[6];                   // 0~15:Limit  16~47:Base
PUBLIC  DESCRIPTOR      gdt[GDT_SIZE];

char *str0 = "hello os world, last line";
char *str1 = "hello os world, line111\n";
static char buf[1024];                                // 显示用临时缓冲区

/*======================================================================*/
PUBLIC void cstart(){
    //DspStrFixPos((80*20+0)*2, str0);
    sprintf(buf, "hello os printk year is %d, month is %d, day is %d\n", 2020, 11, 8);
    memccpy_gdt();
    DspStrFixPos((80*24+0)*2, buf);
    
    //sprintf(buf, "hello os printk year is %d, month is %d, day is %d\n", 2020, 11, 8);
    //DspStrFixPos(12, buf);
    //sprintf(buf, "hello os sprintf, time is %d:%d\n", 14, 38);
    //DspStrFixPos(13, buf);
}

PUBLIC void memccpy_gdt() {
    // 将 LOADER 中的 GDT 复制到新的 GDT 中
    memcpy( &gdt,                   // New GDT
        (void*)(*((t_32*)(&gdt_ptr[2]))),   // Base  of Old GDT
        *((t_16*)(&gdt_ptr[0])) + 1     // Limit of Old GDT
        );
    // gdt_ptr[6] 共 6 个字节:0~15:Limit  16~47:Base。用作 sgdt 以及 lgdt 的参数。
    t_16* p_gdt_limit = (t_16*)(&gdt_ptr[0]);
    t_32* p_gdt_base  = (t_32*)(&gdt_ptr[2]);
    *p_gdt_limit = GDT_SIZE * sizeof(DESCRIPTOR) - 1;
    *p_gdt_base  = (t_32)&gdt;
}

memcpy

; ------------------------------------------------------------------------
; void* memcpy(void* es:pDest, void* ds:pSrc, int iSize);
; ------------------------------------------------------------------------
memcpy:
    push    ebp
    mov ebp, esp

    push    esi
    push    edi
    push    ecx

    mov edi, [ebp + 8]  ; Destination
    mov esi, [ebp + 12] ; Source
    mov ecx, [ebp + 16] ; Counter
.1:
    cmp ecx, 0      ; 判断计数器
    jz  .2      ; 计数器为零时跳出

    mov al, [ds:esi]        ; ┓
    inc esi         ; ┃
                    ; ┣ 逐字节移动
    mov byte [es:edi], al   ; ┃
    inc edi         ; ┛

    dec ecx     ; 计数器减一
    jmp .1      ; 循环
.2:
    mov eax, [ebp + 8]  ; 返回值

    pop ecx
    pop edi
    pop esi
    mov esp, ebp
    pop ebp

    ret         ; 函数结束,返回
; memcpy 结束-------------------------------------------------------------
上一篇 下一篇

猜你喜欢

热点阅读