Не могу показать верхнюю и нижнюю память

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

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

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

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

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

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 первый аргумент - это аргумент с самым низким адресом, или тот, который выдвигается последним. Таким образом, вы должны выдвинуть аргументы в ассемблере в обратном порядке.

Другие вопросы по тегам