OSDev.org

The Place to Start for Operating System Developers
It is currently Sat Apr 27, 2024 6:31 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Weird Memory Outputs after Loading Kernel Higher Half
PostPosted: Sat Nov 11, 2023 6:56 am 
Offline

Joined: Tue Apr 04, 2023 9:00 am
Posts: 7
Hello, I just loaded my kernel as a higher half one. And every thing works fine, i can able to write VGA buffer, interrupts and exceptions work, except when i dump the memory information my kernel, i get weird outcomes. Here is the screenshot of it:

Attachment:
mem_bug.png
mem_bug.png [ 84.36 KiB | Viewed 1052 times ]


as you can see in the attachment some uint32_t variables retuns negative outputs and weird characters when i want to print them hexedecimal. I touth this is a simple integer overflow issiue related with my stdio implementations since everything works fine and expected in the kernel but i can't be sure.
I have very simle/generic higher half and memory information code. Here is the related part of the code in my kernel:

loader.asm:
Code:
[BITS 32]
global loader                           ; the entry point for the linker
global boot_page_directory

extern kernel_main                            ; kmain is defined in kmain.c
extern end_of_kernel
extern kernel_virtual_end               ; these are defined in the link script
extern kernel_virtual_start
extern kernel_physical_end
extern kernel_physical_start

; setting up the multiboot headers for GRUB
MODULEALIGN equ 1<<0                    ; align loaded modules on page
                                        ; boundaries
MEMINFO     equ 1<<1                    ; provide memory map
FLAGS       equ MODULEALIGN | MEMINFO   ; the multiboot flag field
MAGIC       equ 0x1BADB002              ; magic number for bootloader to
                                        ; find the header
CHECKSUM    equ -(MAGIC + FLAGS)        ; checksum required

; paging for the kernel
KERNEL_VIRTUAL_BASE     equ 0xC0000000                  ; we start at 3GB
KERNEL_PAGE_IDX         equ (KERNEL_VIRTUAL_BASE >> 22) ; PDT index for 4MB PDE

; the page directory used to boot the kernel into the higher half
section .data
align 4096                               ; align on 4kB blocks
boot_page_directory:
    dd 00000000000000000000000010001011b ; identity mapped first 4MB
    times (KERNEL_PAGE_IDX-1) dd 0       ; no pages here
    dd 00000000000000000000000010001011b ; map 0xC0000000 to the first 4MB
    times (1024-KERNEL_PAGE_IDX-1) dd 0  ; no more pages


section .text
align 4
    dd MAGIC
    dd FLAGS
    dd CHECKSUM

; the entry point, called by GRUB
loader:
    mov ecx, (boot_page_directory-KERNEL_VIRTUAL_BASE)
    and ecx, 0xFFFFF000     ; we only care about the upper 20 bits
    or  ecx, 0x08           ; PWT, enable page write through?
    mov cr3, ecx            ; load pdt

    mov ecx, cr4            ; read current config from cr4
    or  ecx, 0x00000010     ; set bit enabling 4MB pages
    mov cr4, ecx            ; enable it by writing to cr4

    mov   ecx, cr0          ; read current config from cr0
   or   ecx, 0x80000000       ; the highest bit controls paging
   mov cr0, ecx          ; enable paging by writing config to cr0

    lea ecx, [higher_half]  ; store the address higher_half in ecx
    jmp ecx                 ; now we jump into 0xC0100000

; code executing from here on uses the page table, and is accessed through
; the upper half, 0xC0100000
higher_half:
    mov     DWORD [boot_page_directory], 0  ; erase identity mapping of kernel
    invlpg  [0]                             ; and flush any tlb-references to it

    mov esp, stack+STACKSIZE            ; sets up the stack pointer

    push boot_page_directory
   
    push kernel_virtual_end             ; these are used by kmain, see
    push kernel_virtual_start           ; kernel_limits_t in kmain.c
    push kernel_physical_end
    push kernel_physical_start
   
    push eax                            ; eax contains the MAGIC number
    push ebx                            ; ebx contains the multiboot data
                                        ; structure
    call kernel_main                          ; call the main function of the kernel

hang:
    jmp hang                            ; loop forever

; reserve initial stack space
STACKSIZE equ 0x4000                    ; 16kB

section .bss
align 4
stack:
    resb STACKSIZE                      ; reserve memory for stack on
                                        ; doubleworded memory


multiboot_util.c (responsible for printing memory information etc.) :
Code:
void display_memory_info(multiboot_info_t *mbinfo,
          kernel_mem_limits_t *kmlimits)
{
   qemu_write_string("\n%s %s START\n", DEBUG_OUTPUT, MEMORY_OUTPUT);
   /* From the GRUB multiboot manual section 3.3 boot information format
     * If flags[0] is set, then the fields mem_lower and mem_upper can be
     * accessed.
     * If flags[6] is set, then the fields mmap_length and mmap_addr can be
     * accessed, which contains a complete memory map.
    */
   if (mbinfo->flags & 0x00000001) {
      qemu_write_string("%s Size of the lower memory: %d kB\n",
              INFORMATION_OUTPUT, mbinfo->mem_lower);
      qemu_write_string("%s Size of the upper memory: %d kB\n",
              INFORMATION_OUTPUT, mbinfo->mem_upper);
   }

   if (mbinfo->flags & 0x00000020) {
      multiboot_memory_map_t *entry =
         (multiboot_memory_map_t *)mbinfo->mmap_addr;
      while ((uint32_t)entry <
             mbinfo->mmap_addr + mbinfo->mmap_length) {
         if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) {
            qemu_write_string("%s Avaliable memory: ",
                    INFORMATION_OUTPUT);
         } else {
            qemu_write_string("%s Reserved memory: ",
                    INFORMATION_OUTPUT);
         }
         /*
         * FIX: lld needed, %d overflows
         */
         qemu_write_string("address: %d", (uint32_t)entry->addr);
         qemu_write_string(", length: %d\n",
                 (uint32_t)entry->len);

         entry = (multiboot_memory_map_t *)(((uint32_t)entry) +
                        entry->size +
                        sizeof(entry->size));
      }
   }
   qemu_write_string("%s Kernel physical start: 0x%x\n",
           INFORMATION_OUTPUT, kmlimits->kernel_physical_start);
   qemu_write_string("%s Kernel physical end: 0x%x\n", INFORMATION_OUTPUT,
           kmlimits->kernel_physical_end);
   qemu_write_string("%s Kernel virtual start: 0x%x\n", INFORMATION_OUTPUT,
           kmlimits->kernel_virtual_start);
   qemu_write_string("%s Kernel virtual end: 0x%x\n", INFORMATION_OUTPUT,
           kmlimits->kernel_virtual_end);

   qemu_write_string("%s %s END\n\n", DEBUG_OUTPUT, MEMORY_OUTPUT);
}


this is my code that responsible for making my kernel higher half and printing the memory information but again im not sure why i am getting the weird outcomes especially when the size of the memory is increases. I think it's related with that how i print the values on screen but i need to ask and get further information why this is happening. Thank you!


Top
 Profile  
 
 Post subject: Re: Weird Memory Outputs after Loading Kernel Higher Half
PostPosted: Sat Nov 11, 2023 4:26 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
leventkaya wrote:
some uint32_t variables retuns negative outputs and weird characters when i want to print them hexedecimal.

Your print function is using signed integers when you want it to use unsigned integers. For decimal numbers, a typical printf-like function has separate "%d" and "%u" for signed and unsigned numbers. For hexadecimal numbers, that's a bug in your printf-like formatting code.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 18 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group