commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

hurd-l4 ./README wortel/Makefile.am wortel/load...


From: Marcus Brinkmann
Subject: hurd-l4 ./README wortel/Makefile.am wortel/load...
Date: Tue, 16 Sep 2003 15:24:06 -0400

CVSROOT:        /cvsroot/hurd
Module name:    hurd-l4
Branch:         
Changes by:     Marcus Brinkmann <address@hidden>       03/09/16 15:24:05

Modified files:
        .              : README 
        wortel         : Makefile.am loader.c loader.h wortel.c 
Added files:
        wortel         : sigma0.c sigma0.h 

Log message:
        Update code to do better memory management, add sigma0 patch to README.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/README.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/sigma0.c?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/sigma0.h?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/Makefile.am.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/loader.c.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/loader.h.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/wortel.c.diff?tr1=1.9&tr2=1.10&r1=text&r2=text

Patches:
Index: hurd-l4/README
diff -u hurd-l4/README:1.5 hurd-l4/README:1.6
--- hurd-l4/README:1.5  Fri Sep 12 14:45:56 2003
+++ hurd-l4/README      Tue Sep 16 15:24:05 2003
@@ -24,11 +24,57 @@
 
 Note that use of optimization is mandatory, not optional.
 
-You also need the L4 kernel and sigma0.  sigma0 must be built with a
-different link base than the default value 0x20000, because that
-conflicts with GRUB (on ia32).  I have successfully used a link base
-of 0x40000.  Then set up GRUB to boot laden as the kernel, and the L4
-kernel, sigma0, wortel (the rootserver) and physmem as its modules.
+
+Installation
+------------
+
+Prerequisites: Pistachio-0.2 with the patch you can find at the end of
+this file.
+
+Furthermore, sigma0 must be built with a different link base than the
+default value 0x20000, because that conflicts with GRUB (on ia32).  I
+have successfully used a link base of 0x40000.
+
+Then set up GRUB to boot laden as the kernel, and the L4 kernel,
+sigma0, wortel (the rootserver) and physmem as its modules.
 
 Try the debug option (-D) to laden and wortel to see some output from
 them.  They are silent by default.
+
+
+sigma0 Patch
+------------
+
+sigma0 in pistachio 0.2 is a bit buggy.  The following patch fixes the
+problems that the bugs cause to wortel.
+
+--- pistachio-0.2/user/serv/sigma0/sigma0.cc.prev      2003-09-16 
20:29:14.000000000 +0200
++++ pistachio-0.2/user/serv/sigma0/sigma0.cc   2003-09-16 21:03:09.000000000 
+0200
+@@ -506,7 +506,8 @@
+     L4_Word_t low_a = (low + size - 1) & ~(size-1);
+     L4_Fpage_t ret;
+ 
+-    if ((high_a - low_a) < size || (owner != tid && owner != L4_anythread))
++    if (low_a > high_a || (high_a - low_a) < size
++      || (owner != tid && owner != L4_anythread))
+     {
+       // Allocation failed
+       ret = L4_Nilpage;
+@@ -530,7 +531,7 @@
+     {
+       // Allocate from middle of region
+       ret = L4_FpageLog2 (low_a, log2size) + L4_FullyAccessible;
+-      memregion_t * r = new memregion_t (high_a, high, owner);
++      memregion_t * r = new memregion_t (low_a + size, high, owner);
+       r->next = next;
+       r->prev = this;
+       r->next->prev = next = r;
+@@ -1246,7 +1247,7 @@
+     {
+       if ((fp = r->allocate (log2size)).raw != L4_Nilpage.raw)
+       {
+-          map = L4_MapItem (fp, 0);
++          map = L4_MapItem (fp, L4_Address (fp));
+           alloc_pool.insert
+               (new memregion_t (L4_Address (fp), L4_Address (fp) +
+                                 (1UL << log2size), tid));
Index: hurd-l4/wortel/Makefile.am
diff -u hurd-l4/wortel/Makefile.am:1.6 hurd-l4/wortel/Makefile.am:1.7
--- hurd-l4/wortel/Makefile.am:1.6      Fri Sep 12 20:25:51 2003
+++ hurd-l4/wortel/Makefile.am  Tue Sep 16 15:24:05 2003
@@ -32,6 +32,7 @@
        shutdown.h shutdown.c                                   \
        elf.h loader.h loader.c                                 \
        getpagesize.c                                           \
+       sigma0.h sigma0.c                                       \
        wortel.h wortel.c
 
 /* FIXME: Make linkbase configurable.  */
Index: hurd-l4/wortel/loader.c
diff -u hurd-l4/wortel/loader.c:1.4 hurd-l4/wortel/loader.c:1.5
--- hurd-l4/wortel/loader.c:1.4 Mon Sep 15 20:42:17 2003
+++ hurd-l4/wortel/loader.c     Tue Sep 16 15:24:05 2003
@@ -158,6 +158,59 @@
 }
 
 
+/* Get the memory range to which the ELF image from START to END
+   (exclusive) will be loaded.  NAME is used for panic messages.  */
+void
+loader_elf_dest (const char *name, l4_word_t start, l4_word_t end,
+                l4_word_t *new_start_p, l4_word_t *new_end_p)
+{
+  l4_word_t new_start = -1;
+  l4_word_t new_end = 0;
+  int i;
+
+  Elf32_Ehdr *elf = (Elf32_Ehdr *) start;
+
+  if (elf->e_ident[EI_MAG0] != ELFMAG0
+      || elf->e_ident[EI_MAG1] != ELFMAG1
+      || elf->e_ident[EI_MAG2] != ELFMAG2
+      || elf->e_ident[EI_MAG3] != ELFMAG3)
+    panic ("%s is not an ELF file", name);
+
+  if (elf->e_type != ET_EXEC)
+    panic ("%s is not an executable file", name);
+
+  if (!elf->e_phoff)
+    panic ("%s has no valid program header offset", name);
+
+#ifdef i386
+  if (elf->e_ident[EI_CLASS] != ELFCLASS32
+      || elf->e_ident[EI_DATA] != ELFDATA2LSB
+      || elf->e_machine != EM_386)
+    panic ("%s is not for this architecture", name);
+#else
+#error Not ported to this architecture!
+#endif
+
+  for (i = 0; i < elf->e_phnum; i++)
+    {
+      Elf32_Phdr *ph = (Elf32_Phdr *) (start + elf->e_phoff
+                                      + i * elf->e_phentsize);
+      if (ph->p_type == PT_LOAD)
+       {
+         if (ph->p_paddr < new_start)
+           new_start = ph->p_paddr;
+         if (ph->p_memsz + ph->p_paddr > new_end)
+           new_end = ph->p_memsz + ph->p_paddr;
+       }
+    }
+
+  if (new_start_p)
+    *new_start_p = new_start;
+  if (new_end_p)
+    *new_end_p = new_end;
+}
+
+
 /* Load the ELF image from START to END (exclusive) into memory under
    the name NAME (also used as the name for the region of the
    resulting ELF program).  Return the lowest and highest address used
Index: hurd-l4/wortel/loader.h
diff -u hurd-l4/wortel/loader.h:1.2 hurd-l4/wortel/loader.h:1.3
--- hurd-l4/wortel/loader.h:1.2 Mon Sep 15 14:09:45 2003
+++ hurd-l4/wortel/loader.h     Tue Sep 16 15:24:05 2003
@@ -43,6 +43,11 @@
 /* Remove the region with the name NAME from the table.  */
 void loader_remove_region (const char *name);
 
+/* Get the memory range to which the ELF image from START to END
+   (exclusive) will be loaded.  NAME is used for panic messages.  */
+void loader_elf_dest (const char *name, l4_word_t start, l4_word_t end,
+                     l4_word_t *new_start_p, l4_word_t *new_end_p);
+
 /* Load the ELF image from START to END into memory under the name
    NAME (also used as the name for the region of the resulting ELF
    program).  Return the lowest and highest address used by the
Index: hurd-l4/wortel/wortel.c
diff -u hurd-l4/wortel/wortel.c:1.9 hurd-l4/wortel/wortel.c:1.10
--- hurd-l4/wortel/wortel.c:1.9 Mon Sep 15 20:42:17 2003
+++ hurd-l4/wortel/wortel.c     Tue Sep 16 15:24:05 2003
@@ -25,6 +25,7 @@
 #include <alloca.h>
 
 #include "wortel.h"
+#include "sigma0.h"
 
 
 /* The program name.  */
@@ -35,6 +36,15 @@
 l4_word_t wortel_end;
 
 
+/* Unused memory.  These fpages mark memory which we needed at some
+   time, but don't need anymore.  It can be granted to the physical
+   memory server at startup.  This includes architecture dependent
+   boot data as well as the physical memory server module.  */
+#define MAX_UNUSED_FPAGES 32
+l4_fpage_t wortel_unused_fpages[MAX_UNUSED_FPAGES];
+unsigned int wortel_unused_fpages_count;
+
+
 /* Room for the arguments.  1 KB is a cramped half-screen full, which
    should be more than enough.  */
 char mods_args[1024];
@@ -140,65 +150,6 @@
 }
 
 
-/* Request the fpage FPAGE from sigma0.  */
-static void
-sigma0_get_fpage (l4_fpage_t fpage)
-{
-  l4_msg_t msg;
-  l4_msg_tag_t msg_tag;
-  l4_map_item_t map_item;
-
-  l4_accept (l4_map_grant_items (l4_complete_address_space));
-  l4_msg_clear (&msg);
-  l4_set_msg_label (&msg, 0xffa0);
-  l4_msg_append_word (&msg, fpage.raw);
-  l4_msg_append_word (&msg, L4_DEFAULT_MEMORY);
-  l4_msg_load (&msg);
-  msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1));
-  if (l4_ipc_failed (msg_tag))
-    panic ("sigma0 request failed during %s: %u",
-          l4_error_code () & 1 ? "receive" : "send",
-          (l4_error_code () >> 1) & 0x7);
-  if (l4_untyped_words (msg_tag) != 0
-      || l4_typed_words (msg_tag) != 2)
-    panic ("Invalid format of sigma0 reply");
-  l4_msg_store (msg_tag, &msg);
-  l4_msg_get_map_item (&msg, 0, &map_item);
-  if (map_item.send_fpage.raw == l4_nilpage.raw)
-    panic ("sigma0 rejected mapping");
-}
-
-/* Request an fpage of the size 2^SIZE from sigma0.  */
-static l4_fpage_t
-sigma0_get_any (unsigned int size)
-{
-  l4_msg_t msg;
-  l4_msg_tag_t msg_tag;
-  l4_map_item_t map_item;
-  l4_fpage_t fpage = l4_fpage_add_rights (l4_fpage_log2 (-1, size),
-                                         l4_fully_accessible);
-
-  l4_accept (l4_map_grant_items (l4_complete_address_space));
-  l4_msg_clear (&msg);
-  l4_set_msg_label (&msg, 0xffa0);
-  debug ("Request 0x%x\n", fpage.raw);
-  l4_msg_append_word (&msg, fpage.raw);
-  l4_msg_append_word (&msg, L4_DEFAULT_MEMORY);
-  l4_msg_load (&msg);
-  msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1));
-  if (l4_ipc_failed (msg_tag))
-    panic ("sigma0 request failed during %s: %u",
-          l4_error_code () & 1 ? "receive" : "send",
-          (l4_error_code () >> 1) & 0x7);
-  if (l4_untyped_words (msg_tag) != 0
-      || l4_typed_words (msg_tag) != 2)
-    panic ("Invalid format of sigma0 reply");
-  l4_msg_store (msg_tag, &msg);
-  l4_msg_get_map_item (&msg, 0, &map_item);
-  debug ("Got 0x%x\n", map_item.send_fpage.raw);
-  return map_item.send_fpage;
-}
-
 
 static void
 load_components (void)
@@ -207,57 +158,82 @@
   unsigned int nr_fpages;
   l4_word_t min_page_size = getpagesize ();
   unsigned int i;
+  l4_word_t addr;
+  l4_word_t end_addr;
 
   /* One issue we have to solve is to make sure that when the physical
-     memory server requests all the available physical pages, we know
-     which pages we can give to it, and which we can't.  This can be
-     left to sigma0, as long as we request all pages from sigma0 we
+     memory server requests all the available physical fpages, we know
+     which fpages we can give to it, and which we can't.  This can be
+     left to sigma0, as long as we request all fpages from sigma0 we
      can't give to the physical memory server up-front.
 
      We do this in several steps: First, we copy all of the startup
      information to memory that is part of the wortel binary image
-     itself.  This is done by the architecture dependant
+     itself.  This is done by the architecture dependent
      find_components function.  Then we request all of our own memory,
-     and all the memory needed for the physical memory server image
-     (at its destination address), and all the memory for each module
-     (at their corresponding load addresses).  */
+     all the memory for our modules, and finally all the memory needed
+     for the physical memory server image (at its destination
+     address).  */
 
   if (wortel_start & (min_page_size - 1))
     panic ("%s does not start on a page boundary", program_name);
   loader_add_region (program_name, wortel_start, wortel_end);
-  nr_fpages = make_fpages (wortel_start, wortel_end, fpages);
-  while (nr_fpages--)
-    sigma0_get_fpage (fpages[nr_fpages]);
+
+  /* We must request our own memory using the smallest fpages
+     possible, because we already have some memory mapped due to page
+     faults, and fpages are specified as inseparable objects.  */
+  for (addr = wortel_start; addr < wortel_end; addr += min_page_size)
+    sigma0_get_fpage (l4_fpage (addr, min_page_size));
 
   /* First protect all pages covered by the modules.  This will also
-     show if each module starts (and ends) on its own page.  */
+     show if each module starts (and ends) on its own page.  Request
+     all memory for all modules.  Although we can release the memory
+     for the physmem module later on, we have to touch it anyway to
+     load it to its destination address, and requesting the fpages now
+     allows us to choose how we want to split up the module in
+     (inseparable) fpages.  */
   for (i = 0; i < mods_count; i++)
     {
       if (mods[i].start & (min_page_size - 1))
        panic ("Module %s does not start on a page boundary", mods[i].name);
       loader_add_region (mods[i].name, mods[i].start, mods[i].end);
+
+      nr_fpages = make_fpages (mods[i].start, mods[i].end, fpages);
+      if (i == MOD_PHYSMEM)
+       {
+         /* The physical memory server module memory can be recycled
+            later.  */
+         if (nr_fpages + wortel_unused_fpages_count > MAX_UNUSED_FPAGES)
+           panic ("not enough room in unused fpages list for physmem-mod");
+         memcpy (&wortel_unused_fpages[wortel_unused_fpages_count],
+                 fpages, sizeof (l4_fpage_t) * nr_fpages);
+         wortel_unused_fpages_count += nr_fpages;
+       }
+
+      while (nr_fpages--)
+       sigma0_get_fpage (fpages[nr_fpages]);
     }
 
+  /* Because loading the physical memory server to its destination
+     address will touch the destination memory, which we later want to
+     grant to the physical memory server using (inseparable) fpages,
+     we request the desired fpages up-front.  */
+  loader_elf_dest ("physmem-server", mods[MOD_PHYSMEM].start,
+                  mods[MOD_PHYSMEM].end, &addr, &end_addr);
+  nr_fpages = make_fpages (addr, end_addr, fpages);
+  while (nr_fpages--)
+    sigma0_get_fpage (fpages[nr_fpages]);
+
   /* Now load the physical memory server to its destination
      address.  */
-  if (!mods[MOD_PHYSMEM].start)
+  addr = mods[MOD_PHYSMEM].start;
+  end_addr = mods[MOD_PHYSMEM].end;
+  if (!addr)
     panic ("No physical memory server found");
-  loader_elf_load ("physmem-server", mods[MOD_PHYSMEM].start,
-                  mods[MOD_PHYSMEM].end,
+  loader_elf_load ("physmem-server", addr, end_addr,
                   &mods[MOD_PHYSMEM].start, &mods[MOD_PHYSMEM].end,
                   &mods[MOD_PHYSMEM].ip);
   loader_remove_region ("physmem-mod");
-
-  /* Finally we can request all the memory for the physical memory
-     server and all other modules from sigma0.  This will register the
-     memory as taken by us, and the memory will not be returned by any
-     future request.  */
-  for (i = 0; i < mods_count; i++)
-    {
-      nr_fpages = make_fpages (mods[i].start, mods[i].end, fpages);
-      while (nr_fpages--)
-       sigma0_get_fpage (fpages[nr_fpages]);
-    }
 }
 
 
@@ -276,7 +252,6 @@
       || mods[MOD_PHYSMEM].ip > mods[MOD_PHYSMEM].end)
     panic ("physmem has invalid IP");
 
-
   cap_id = wortel_add_user (2);
   /* FIXME: Pass cap_id to physmem.  */
   /* Thread nr is next available after rootserver thread nr,
@@ -393,8 +368,12 @@
   /* The size of the region that we are currently trying to allocate
      for GET_MEM requests.  If this is smaller than 2^10, no more
      memory is available.  */
-  unsigned int get_mem_size = 12;
+  unsigned int get_mem_size = sizeof (l4_word_t) * 8 - 1;
 
+  while (get_mem_size >= 10
+        && ! ((1 << get_mem_size) & l4_page_size_mask ()))
+    get_mem_size--;
+  
   do
     {
       l4_thread_id_t from;
@@ -438,13 +417,23 @@
          if (get_mem_size < 10)
            panic ("physmem server does not stop requesting memory");
 
-         do
-           {
-             fpage = sigma0_get_any (get_mem_size);
-             if (fpage.raw == l4_nilpage.raw)
-               get_mem_size--;
-           }
-         while (fpage.raw == l4_nilpage.raw && get_mem_size >= 10);
+         /* Give out the memory.  First our unused fpages, then the
+            fpages we can get from sigma0.  */
+         if (wortel_unused_fpages_count)
+           fpage = wortel_unused_fpages[--wortel_unused_fpages_count];
+         else
+           do
+             {
+               fpage = sigma0_get_any (get_mem_size);
+               if (fpage.raw == l4_nilpage.raw)
+                 {
+                   get_mem_size--;
+                   while (get_mem_size >= 10
+                          && ! ((1 << get_mem_size) & l4_page_size_mask ()))
+                     get_mem_size--;
+                 }
+             }
+           while (fpage.raw == l4_nilpage.raw && get_mem_size >= 10);
 
          grant_item = l4_grant_item (fpage, l4_address (fpage));
          l4_msg_clear (&msg);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]