Page 1 of 1

Supposedly Innocent Pointer Assignment causes trouble

Posted: Tue Jun 08, 2004 2:18 pm
by srg
Hi

(Sorry about the last post but since then I've found out that it's nothing to do with the ISR, just the pointer assignment.

I'm trying to make a stack for recording physical pages that havn't been mapped into any any address spaces yet but I'm getting some very odd errors with a seemingly innocent pointer assignment.

Here's the code:

Code: Select all

/* ###################
; mem()
;
; Description:   Sets up the SG-OS memory manager, it first
;                   retreves the size of the machine's ram from the
;                   Multiboot returned information, and then starts
;                   building up the unallocated page stack.
;
; C Prototype: int mem(multiboot_info_t *boot_info);
;
; Parameters: boot_info - Pointer to the Multiboot returned
;                  information
;
; Returns: 0 = Success, 1 = couldn't get available memory, 2 =
; ...
*/
int mem()
{
   
   memory_map_t *mmap_ptr;
   unsigned int count;
   unsigned int *page_dir_ptr = (unsigned int*)
   KERNEL_PAGE_DIR_LOCATION;
   unsigned int next_unused_page;
   
/* 1. Get the amount of physical RAM installed in the
 * machine. Check bit 6 of the flags to see if the mem map 
 * is valid.
 * This is the profered method, but doesn't work on old
 * machines
 */
   if (boot_information->flags & 0x40)
   {
      /* It is, great, now to read the size/structure pairs */
      mmap_ptr = (memory_map_t *)boot_information->mmap_addr;
      /* Now to check each pair (ignoring the size and 
                 * using 24 bytes for each one). If the structure is
       * describing available memory, then add it's length
                 * to the total and then go to the next one!
       */
      for (count = 0; count < boot_information->mmap_length ;
          count += MMAP_PAIR_SIZE)
      {
         if (mmap_ptr->type == 1)
            mem_amount += mmap_ptr->length_low;
         mmap_ptr++;
      }
   }
   else
   {
      /* Otherwise check bit 0 to see if we can get an
                 * older style memory size reading.
       * This is the older, less reliable method.
       */
      if (boot_information->flags & 1)
         mem_amount = boot_information->mem_upper
                         + 1024;/*KB, add the first 1MB to total*/
      else
         /* Oh well, just fail then */
         return 1;

      /* Current value is in Kilobytes, I want it in bytes */
      mem_amount *= 1024;
   }

   /* 2. Setup the Unallocated page stack */
   unallocated_stack_ptr = KERNEL_PAGE_DIR_LOCATION + 0x2000;
   
   /* The current highest point of used memory is at the top
         * of the unallocated page stack, we need to find out the
         * next unused page
         */
   next_unused_page = unallocated_stack_ptr + (4 * (mem_amount /          PAGE_SIZE));
   next_unused_page = (next_unused_page & 0xFFFFF000) + 0x1000;
   

   /* Now add the addresses of the physical pages that
         * are'nt allocated
         */
   for (count = 0; count < (mem_amount / PAGE_SIZE) ; count++)
   {
      *unallocated_stack_ptr = next_unused_page;
      unallocated_stack_ptr++;
      next_unused_page += 0x1000;
   }
   
   return 0;
}


Anyway, when I make and assignment to the memory pointed to by this pointer, it could be any address, or anything being assigned to it, so this line:

*unallocated_stack_ptr = next_unused_page;

I just get this error from Bochs if I have interrupts dissabled:

[CPU ] fetch_raw_descriptor: LDTR.valid=0

Or, if i have interrupts enabled:

[CPU ] iret: AR byte indicated non code segment.

If I run this through VMWare, it just prints a pattern of characters on the screen,

The strangest thing is that on real hardware (AMD athlons at least) it works quite happily.

What am I doing wrong?
Thanks
srg

Re:Supposedly Innocent Pointer Assignment causes trouble

Posted: Tue Jun 08, 2004 3:38 pm
by Pype.Clicker
clearly, your interrupt handler is doing something nasty and i would make sure it correctly pops all the things it pushed before going later.

At the 'LDTR.valid=0', this occurs when you (by mistake) try to load a LDT-related selector in a segment register while no LDT has been set up. This usually means you're popping trash in a segment register.

Re:Supposedly Innocent Pointer Assignment causes trouble

Posted: Wed Jun 09, 2004 1:29 am
by srg
D'oh, even simpler than that.

I forgot that I'm running at 3GB virtual addresses, so the pointer was pointing at 0x20xxxx when it should have been pointing at 0xC020xxxx. This meant that I was trying to write to memory that hasn't been mapped yet.

Changed that minor mistake and it works in Bochs and VMware perfectly. I just wonder why it worked before on an athlon.

anyway, thanks for the ideas
srg

Re:Supposedly Innocent Pointer Assignment causes trouble

Posted: Wed Jun 09, 2004 2:47 am
by Candy
srg wrote: Changed that minor mistake and it works in Bochs and VMware perfectly. I just wonder why it worked before on an athlon.
Your physical athlon might have a larger TLB than Vmware/Bochs, so it'd not be swapped out. Not sure of course.

Re:Supposedly Innocent Pointer Assignment causes trouble

Posted: Wed Jun 09, 2004 3:53 am
by srg
Candy wrote:
srg wrote: Changed that minor mistake and it works in Bochs and VMware perfectly. I just wonder why it worked before on an athlon.
Your physical athlon might have a larger TLB than Vmware/Bochs, so it'd not be swapped out. Not sure of course.
You might be right there, The standard Windows binary version of bochs is based on the Pentium. VMWare is based on a Pentium II.

srg

Re:Supposedly Innocent Pointer Assignment causes trouble

Posted: Wed Jun 09, 2004 5:54 am
by Candy
srg wrote: You might be right there, The standard Windows binary version of bochs is based on the Pentium. VMWare is based on a Pentium II.
Virtual computers don't really need TLB's. Especially VMware, which probably shares it with windows.