2016-08-22 2 views
0

OS Dosent по какой-то причине отображает верхнюю и нижнюю память. Как вы можете видеть здесь в обнаружении памяти Wiki: http://wiki.osdev.org/Detecting_Memory_(x86)#Memory_Map_Via_GRUB, он говоритCant display Верхняя и нижняя память

См mbd-> mem_lower для обычной памяти (например, физические адреса в диапазоне от 0 до 640 КБ) и mbd-> mem_upper для высокой памяти (например, от 1 МБ). Оба приведены в kibibytes

Ну я точно делать это здесь:

kernel.C++:

#include "types.h" 
#include "gdt.h" 
#include "stdio.h" 
#include "serial.h" 
#include "mem.h" 
#include "idt.h" 
#include "timer.h" 
#include "isr.h" 
#include "kbd.h" 
#include "mouse.h" 
#include "irq.h" 
#include "string.h" 
#include "terminal.h" 
#include "multiboot.h" 
#include "pmm.h" 
#include "heap.h" 




//Call all class constructor 
//for global objects before 
//calling the kernel 
typedef void (*constructor)(); 
extern "C" constructor start_ctors; 
extern "C" constructor end_ctors; 
extern "C" void callConstructors() 
{ 
    for(constructor* i = &start_ctors; i != &end_ctors; i++) 
     (*i)(); 
} 




extern "C" void kernelMain(uint32_t kernel_virtual_end, 
     uint32_t placeholder, 
     uint32_t kernel_physical_end, 
     uint32_t kernel_physical_start, uint32_t kernel_virtual_start, 
     multiboot_info_t multiboot_structure,uint32_t magicnumber 
     ) 
{ 


     cls(); 
     printf("******KERNEL INFO********\n"); 
     printf("KERNEL START VIRTUAL 0x%x\n" , kernel_virtual_start); 
     printf("KERNEL START PHYSICAL 0x%x\n" , kernel_physical_start); 
     printf("KERNEL END VIRTUAL 0x%x\n" , kernel_virtual_end); 
     printf("KERNEL END PHYSICAL 0x%x\n" , kernel_physical_end); 
     printf("*************************\n\n"); 
     printf("********RAM INFO*********\n"); 
     printf("LOWER MEMORY : %x \n" , (uint32_t)multiboot_structure.mem_lower); 
     printf("UPPER MEMORY : %x \n" , (uint32_t)multiboot_structure.mem_upper); 
     printf("*************************\n"); 
     gdt gt; 
     IDT idt; 
     ISR isr; 
     IRQ irq; 
     SerialPort sp; 
     isr.install_isrs(); 
     irq.install_irqs(); 
     Timer timer; 
     timer.install_timer(); 
     KBD kbd; 
     kbd.install_kbd_driver(); 


     MOUSE mouse; 
     mouse.install_mouse_driver(); 
     __asm__ __volatile__ ("sti"); 




    while(1); 
    err: 
     while(1); 
} 

boot.asm:

;Global MultiBoot Kernel Recongnzatio 

; setting up the Multiboot header - see GRUB docs for details 
MODULEALIGN equ 1<<0    ; align loaded modules on page boundaries 
MEMINFO  equ 1<<1    ; provide memory map 
FLAGS  equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field 
MAGIC  equ 0x1BADB002  ; 'magic number' lets bootloader find the header 
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required 


;Putting in object file 
section .multiboot 

    dd MAGIC 
    dd FLAGS 
    dd CHECKSUM 

section .data 

KERNEL_VIRTUAL_BASE equ 0xC0000000     ; 3GB 
KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22) ; Page directory index of kernel's 4MB PTE. 

align 0x1000 
BootPageDirectory: 
    ; This page directory entry identity-maps the first 4MB of the 32-bit physical address space. 
    ; All bits are clear except the following: 
    ; bit 7: PS The kernel page is 4MB. 
    ; bit 1: RW The kernel page is read/write. 
    ; bit 0: P The kernel page is present. 
    ; This entry must be here -- otherwise the kernel will crash immediately after paging is 
    ; enabled because it can't fetch the next instruction! It's ok to unmap this page later. 
    dd 0x00000083 
    times (KERNEL_PAGE_NUMBER - 1) dd 0     ; Pages before kernel space. 
    ; This page directory entry defines a 4MB page containing the kernel. 
    dd 0x00000083 
    times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0 ; Pages after the kernel image. 


section .text 
    ; reserve initial kernel stack space -- that's 16k. 
    STACKSIZE equ 0x4000 
    global loader 
    global BootPageDirectory 

     loader: 

        ;Enable Paging START 

        ; NOTE: Until paging is set up, the code must be position-independent and use physical 
        ; addresses, not virtual ones! 
        mov ecx, (BootPageDirectory - KERNEL_VIRTUAL_BASE) 
        mov cr3, ecx          ; Load Page Directory Base Register. 

        mov ecx, cr4 
        or ecx, 0x00000010       ; Set PSE bit in CR4 to enable 4MB pages. 
        mov cr4, ecx 

        mov ecx, cr0 
        or ecx, 0x80000000       ; Set PG bit in CR0 to enable paging. 
        mov cr0, ecx 


        lea ebx, [higherhalf] 
        jmp ebx ; Absolute Jump 

     higherhalf: 
      extern kernelMain 
      extern callConstructors 

       ; Unmap the identity-mapped first 4MB of physical address space. It should not be needed 
       ; anymore. 
       mov dword [BootPageDirectory], 0 
       invlpg [0] 

       mov esp, stack + STACKSIZE   ; set up the stack 
       call callConstructors 



       extern kernel_virtual_start 
       extern kernel_virtual_end 
       extern kernel_physical_start 
       extern kernel_physical_end 


       push kernel_virtual_end ; 2 
       push 5 
       push kernel_virtual_start ; 1 
       push kernel_physical_start ; 3 
       push kernel_physical_end ; 4 
       push eax ; 5 
       push ebx ; 6 
       call kernelMain 


       jmp _eof 

     _eof: 
      cli 
      hlt 
      jmp _eof 


section .bss 
align 32 
stack: 
    resb STACKSIZE  ; reserve 16k stack on a uint64_t boundary 

Когда я закончить выше I получите эти странные персонажи, когда я печатаю низкую и высокую память (что дает вам), как вы можете видеть здесь: https://www.youtube.com/watch?v=nDxSOkKd_NI. Вы можете увидеть полный исходный код здесь: https://raw.githubusercontent.com/amanuel2/OS_Mirror. Помощь будет оценена.

+0

Я вижу, что вышеприведенный код по-прежнему имеет проблему с пакетом, о которой вы предупреждали ранее. –

+0

В вашем видео физический конец памяти - это многозадачное магическое число. Это кажется немного странным тоже –

+0

@MichaelPetch, который иногда случается .. Я тоже не знаю, почему. – amanuel2

ответ

-1

Ваш код, кажется, есть несколько ошибок -

1. Уничтожение значений регистров при вызове статических объектов конструкторов - При выполнении следующего кода -

MOV ESP, stack + STACKSIZE 
CALL callConstructors 

, то вам нужно сохранить зарегистрируйте значения, на которые вы зависите, и здесь EAX & EBX имеют решающее значение для хранения значений, связанных с мультизагрузкой. Если перед вызовом используются какие-либо другие регистры, они должны быть сохранены. & вы должны прочитать свою спецификацию ABI для регистров, сохраненных для вызывающего/вызываемого абонента.

2. Параметры толкнул в обратном порядке - Это может показаться неудобным вам, что ваши аргументы

push kernel_virtual_end ; 2 
push 5 
push kernel_virtual_start ; 1 
push kernel_physical_start ; 3 
push kernel_physical_end ; 4 
push eax ; 5 
push ebx ; 6 
call kernelMain 

вызов kernelMain в обратном порядке, хотя вы видите их прямо в коде. Вы должны быть написаны на сборку-вызывающий код, как

push ebx ;6 
push eax ; 5 
push kernel_physical_end ; 4 
push kernel_physical_start ; 3 
push kernel_virtual_start ; 1 
push 5 
push kernel_virtual_end ; 2 
call kernelMain 

Чтобы понять, почему это необходимо, вы должны знать, что стек растет вниз IA32. Это означает, что значение в ESP (адрес стека процессора) уменьшает на 4 (для 32-битной платформы, в противном случае 8 в 64-битной платформе) на каждый

push <REG> 

но и в C, первый аргументом является тот, на наименьший адрес, или тот, который нажат последним. Таким образом, вы должны подталкивать аргументы в обратном порядке в ассемблере.

+0

Подумайте, почему мой ответ заслуживает отрицательных голосов! –

+0

Может быть, потому, что вы отвечаете на вопрос года? (Btw я не сделал нисходящий вопрос). И ive прошло мимо этого, как LOL, проверить мою ОС github.com/amanuel2/BoneOS – amanuel2

+0

Хорошо. Вы также можете увидеть CircuitKernel в github. –