commit-hurd
[Top][All Lists]
Advanced

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

hurd-l4 physmem/output.c physmem/physmem.c wort...


From: Marcus Brinkmann
Subject: hurd-l4 physmem/output.c physmem/physmem.c wort...
Date: Mon, 15 Sep 2003 20:42:17 -0400

CVSROOT:        /cvsroot/hurd
Module name:    hurd-l4
Branch:         
Changes by:     Marcus Brinkmann <address@hidden>       03/09/15 20:42:17

Modified files:
        physmem        : output.c physmem.c 
        wortel         : ia32-cmain.c loader.c output.c shutdown.h 
                         wortel.c wortel.h 

Log message:
        Add some more bootstrap code, that will eventually lead to physmem
        requesting its memory from wortel.   Doesn't work yet, maybe a sigma0 
bug.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/physmem/output.c.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/physmem/physmem.c.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/ia32-cmain.c.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.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/output.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/shutdown.h.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/wortel.c.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/wortel.h.diff?tr1=1.6&tr2=1.7&r1=text&r2=text

Patches:
Index: hurd-l4/physmem/output.c
diff -u hurd-l4/physmem/output.c:1.2 hurd-l4/physmem/output.c:1.3
--- hurd-l4/physmem/output.c:1.2        Mon Sep 15 14:18:58 2003
+++ hurd-l4/physmem/output.c    Mon Sep 15 20:42:17 2003
@@ -43,6 +43,8 @@
   /* FIXME: Hard coded message label.  */
 #define WORTEL_MSG_PUTCHAR 1
   l4_set_msg_label (&msg, WORTEL_MSG_PUTCHAR);
+  /* FIXME: This should be our cap ID.  */
+  l4_msg_append_word (&msg, 0);
   l4_msg_append_word (&msg, (l4_word_t) chr);
   l4_msg_load (&msg);
   /* FIXME: Hard coded thread ID.  */
Index: hurd-l4/physmem/physmem.c
diff -u hurd-l4/physmem/physmem.c:1.1 hurd-l4/physmem/physmem.c:1.2
--- hurd-l4/physmem/physmem.c:1.1       Tue Sep  9 17:43:12 2003
+++ hurd-l4/physmem/physmem.c   Mon Sep 15 20:42:17 2003
@@ -28,12 +28,59 @@
 char *program_name = "physmem";
 
 
+void
+get_all_memory (void)
+{
+  l4_fpage_t fpage;
+
+  do
+    {
+      l4_msg_t msg;
+      l4_msg_tag_t msg_tag;
+      l4_grant_item_t grant_item;
+
+      l4_accept (l4_map_grant_items (l4_complete_address_space));
+      l4_msg_clear (&msg);
+      /* FIXME: 2 is WORTEL_MSG_GET_MEM.  */
+      l4_set_msg_label (&msg, 2);
+      /* FIXME: cap_id */
+      l4_msg_append_word (&msg, 0);
+      l4_msg_load (&msg);
+      /* FIXME: Hard coded wortel thread.  */
+      msg_tag = l4_call (l4_global_id (l4_thread_user_base () + 2, 1));
+      if (l4_ipc_failed (msg_tag))
+       {
+         debug ("get_mem request failed during %s: %u",
+                l4_error_code () & 1 ? "receive" : "send",
+                (l4_error_code () >> 1) & 0x7);
+         l4_sleep (l4_never);
+       }
+      if (l4_untyped_words (msg_tag) != 0
+         || l4_typed_words (msg_tag) != 2)
+       {
+         debug ("Invalid format of wortel get_mem reply");
+         l4_sleep (l4_never);
+       }
+      l4_msg_store (msg_tag, &msg);
+      l4_msg_get_grant_item (&msg, 0, &grant_item);
+      fpage = grant_item.send_fpage;
+
+      if (fpage.raw != l4_nilpage.raw)
+       debug ("%s: Got fpage 0x%x/%u\n", program_name,
+              l4_address (fpage), l4_size_log2 (fpage));
+    }
+  while (fpage.raw != l4_nilpage.raw);
+}
+
+
 int
 main (int argc, char *argv[])
 {
   output_debug = 1;
 
   debug ("%s " PACKAGE_VERSION "\n", program_name);
+
+  get_all_memory ();
 
   while (1)
     l4_sleep (l4_never);
Index: hurd-l4/wortel/ia32-cmain.c
diff -u hurd-l4/wortel/ia32-cmain.c:1.6 hurd-l4/wortel/ia32-cmain.c:1.7
--- hurd-l4/wortel/ia32-cmain.c:1.6     Mon Sep 15 15:24:01 2003
+++ hurd-l4/wortel/ia32-cmain.c Mon Sep 15 20:42:17 2003
@@ -50,7 +50,7 @@
   l4_init_stubs ();
 
   mbi = (multiboot_info_t *) l4_boot_info ();
-  debug ("Multiboot Info: 0x%x\n", mbi);
+  debug ("Multiboot Info: %p\n", mbi);
 
   if (CHECK_FLAG (mbi->flags, 3) && mbi->mods_count > 0)
     {
@@ -101,7 +101,7 @@
       argc = 1;
 
       argv = alloca (sizeof (char *) * 2);
-      argv[0] = program_name;
+      argv[0] = (char *) program_name;
       argv[1] = 0;
     }
 
@@ -124,10 +124,7 @@
 void
 find_components (void)
 {
-  l4_word_t min_page_size = getpagesize ();
   multiboot_info_t *mbi = (multiboot_info_t *) l4_boot_info ();
-  l4_word_t start;
-  l4_word_t end;
 
   /* Load the module information.  */
   if (CHECK_FLAG (mbi->flags, 3))
@@ -143,49 +140,25 @@
 
       for (i = 0; i < mods_count; i++)
        {
+         char *args;
+
          mods[i].name = mod_names[i];
          mods[i].start = mod[i].mod_start;
-         if (mods[i].start & (min_page_size - 1))
-           panic ("Module %s does not start on a page boundary.\n");
-         mods[i].end = (mod[i].mod_end + min_page_size - 1)
-           & ~(min_page_size - 1);
-         mods[i].args = (char *) mod[i].string;
-       }
-    }
-
-  /* Now protect ourselves and the multiboot info (at least the module
-     configuration).  */
-  loader_add_region (program_name, (l4_word_t) &_start, (l4_word_t) &_end);
-
-  start = (l4_word_t) mbi;
-  end = start + sizeof (*mbi);
-  loader_add_region ("grub-mbi", start, end);
-  
-  if (CHECK_FLAG (mbi->flags, 3) && mbi->mods_count)
-    {
-      module_t *mod = (module_t *) mbi->mods_addr;
-      int nr;
+         mods[i].end = mod[i].mod_end;
 
-      start = (l4_word_t) mod;
-      end = ((l4_word_t) mod) + mbi->mods_count * sizeof (*mod);
-      loader_add_region ("grub-mods", start, end);
-
-      start = (l4_word_t) mod[0].string;
-      end = start + 1;
-      for (nr = 0; nr < mbi->mods_count; nr++)
-       {
-         char *str = (char *) mod[nr].string;
-
-         if (str)
-           {
-             if (((l4_word_t) str) < start)
-               start = (l4_word_t) str;
-             while (*str)
-               str++;
-             if (((l4_word_t) str) + 1> end)
-               end = (l4_word_t) str + 1;
-           }
+         /* We copy over the argument lines, so that we don't depend
+            on the multiboot info structure anymore, and can reuse
+            that memory.  */
+         mods[i].args = &mods_args[mods_args_len];
+         args = (char *) mod[i].string;
+         while (*args && mods_args_len < sizeof (mods_args))
+           mods_args[mods_args_len++] = *(args++);
+         if (mods_args_len == sizeof (mods_args))
+           panic ("No space to store the argument lines");
+           mods_args[mods_args_len++] = '\0';
        }
-      loader_add_region ("grub-mods-cmdlines", start, end + 1);
     }
+
+  wortel_start = (l4_word_t) &_start;
+  wortel_end = (l4_word_t) &_end;
 }
Index: hurd-l4/wortel/loader.c
diff -u hurd-l4/wortel/loader.c:1.3 hurd-l4/wortel/loader.c:1.4
--- hurd-l4/wortel/loader.c:1.3 Mon Sep 15 15:24:01 2003
+++ hurd-l4/wortel/loader.c     Mon Sep 15 20:42:17 2003
@@ -18,6 +18,8 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
+#include <string.h>
+
 #include "loader.h"
 #include "output.h"
 #include "shutdown.h"
@@ -28,9 +30,9 @@
 
 /* Verify that the memory region START to END (exclusive) is valid.  */
 static void
-mem_check (const char *name, unsigned long start, unsigned long end)
+mem_check (const char *name, unsigned long long start, unsigned long long end)
 {
-  l4_memory_desc_t memdesc;
+  l4_memory_desc_t memdesc = 0;
   int nr;
   int fits = 0;
   int conflicts = 0;
@@ -66,12 +68,12 @@
        }
     }
   if (conflicts)
-    panic ("%s (0x%x - 0x%x) conflicts with memory of "
+    panic ("%s (0x%llx - 0x%llx) conflicts with memory of "
           "type %i/%i (0x%x - 0x%x)", name, start, end,
           memdesc->type, memdesc->subtype,
           memdesc->low << 10, memdesc->high << 10);
   if (!fits)
-    panic ("%s (0x%x - 0x%x) does not fit into memory",
+    panic ("%s (0x%llx - 0x%llx) does not fit into memory",
           name, start, end);
 }
 
@@ -121,6 +123,9 @@
 
   if (nr_regions == MAX_REGIONS)
     panic ("Too many memory regions, region %s doesn't fit", name);
+
+  if (start >= end)
+    panic ("Region %s has a start address following the end address", name);
 
   check_region (name, start, end);
 
Index: hurd-l4/wortel/output.c
diff -u hurd-l4/wortel/output.c:1.3 hurd-l4/wortel/output.c:1.4
--- hurd-l4/wortel/output.c:1.3 Mon Sep 15 14:18:58 2003
+++ hurd-l4/wortel/output.c     Mon Sep 15 20:42:17 2003
@@ -23,6 +23,7 @@
 #endif
 
 #include <stdarg.h>
+#include <string.h>
 
 #include "output.h"
 
@@ -248,6 +249,8 @@
          break;
 
        case 'p':
+         putchar ('0');
+         putchar ('x');
          print_nr ((unsigned int) va_arg (ap, void *), 16);
          p++;
          break;
Index: hurd-l4/wortel/shutdown.h
diff -u hurd-l4/wortel/shutdown.h:1.3 hurd-l4/wortel/shutdown.h:1.4
--- hurd-l4/wortel/shutdown.h:1.3       Mon Sep  8 10:40:37 2003
+++ hurd-l4/wortel/shutdown.h   Mon Sep 15 20:42:17 2003
@@ -43,7 +43,7 @@
 void shutdown (void);
 
 /* The program name.  */
-extern char *program_name;
+extern const char program_name[];
 
 /* Print an error message and fail.  */
 #define panic(...)                             \
Index: hurd-l4/wortel/wortel.c
diff -u hurd-l4/wortel/wortel.c:1.8 hurd-l4/wortel/wortel.c:1.9
--- hurd-l4/wortel/wortel.c:1.8 Mon Sep 15 15:24:01 2003
+++ hurd-l4/wortel/wortel.c     Mon Sep 15 20:42:17 2003
@@ -21,13 +21,26 @@
 #include <config.h>
 #endif
 
+#include <unistd.h>
 #include <alloca.h>
 
 #include "wortel.h"
 
 
 /* The program name.  */
-char *program_name = "wortel";
+const char program_name[] = "wortel";
+
+/* The region of wortel itself.  */
+l4_word_t wortel_start;
+l4_word_t wortel_end;
+
+
+/* Room for the arguments.  1 KB is a cramped half-screen full, which
+   should be more than enough.  */
+char mods_args[1024];
+
+/* The number of bytes in mods_args already consumed.  */
+unsigned mods_args_len;
 
 const char *mod_names[] = { "physmem-mod", "task-mod", "root-fs-mod" };
 
@@ -39,6 +52,38 @@
 unsigned int mods_count;
 
 
+/* The maximum number of tasks allowed to use the rootserver.  */
+#define MAX_USERS 16
+
+/* FIXME: Needs to be somewhere else.  */
+typedef l4_word_t hurd_task_id_t;
+#define HURD_TASK_ID_NULL 0
+
+/* The allowed user tasks.  */
+static hurd_task_id_t cap_list[MAX_USERS];
+
+/* Register TASK as allowed user and return the capability ID, or -1
+   if there is no space.  */
+static int
+wortel_add_user (hurd_task_id_t task)
+{
+  unsigned int i;
+
+  for (i = 0; i < MAX_USERS; i++)
+    if (cap_list[i] == HURD_TASK_ID_NULL)
+      break;
+
+  if (i == MAX_USERS)
+    return -1;
+
+  cap_list[i] = task;
+  return i;
+}
+
+#define WORTEL_CAP_VALID(capnr, task) \
+  (capnr >= 0 && capnr < MAX_USERS && cap_list[capnr] == task)
+
+
 /* Return the number of memory descriptors.  */
 l4_word_t
 loader_get_num_memory_desc (void)
@@ -56,25 +101,6 @@
 }
 
 
-static void
-load_components (void)
-{
-  unsigned int i;
-
-  for (i = 0; i < mods_count; i++)
-    loader_add_region (mods[i].name, mods[i].start, mods[i].end);
-
-  if (!mods[MOD_PHYSMEM].start)
-    panic ("No physical memory server found");
-
-  loader_elf_load ("physmem-server", mods[MOD_PHYSMEM].start,
-                  mods[MOD_PHYSMEM].end,
-                  &mods[MOD_PHYSMEM].start, &mods[MOD_PHYSMEM].end,
-                  &mods[MOD_PHYSMEM].ip);
-  loader_remove_region ("physmem-mod");
-}
-
-
 /* The maximum number of fpages required to cover a page aligned range
    of memory.  This is k if the maximum memory range size to cover is
    2^(k + min_page_size_log2), which can be easily proved by
@@ -82,57 +108,177 @@
 #define MAX_FPAGES (sizeof (l4_word_t) * 8 - 10)
 
 
-/* Determine the fpages required to cover the bytes from START to END,
-   which must be aligned to the minimal page size supported by the
-   system.  Returns the number of fpages required to cover the range,
-   and returns that many fpages (with maximum accessibility) in
-   FPAGES.  At most MAX_FPAGES fpages will be returned.  */
-unsigned int
-make_fpages (l4_word_t start, l4_word_t size, l4_fpage_t *fpages)
+/* Determine the fpages required to cover the bytes from START to END
+   (exclusive).  START must be aligned to the minimal page size
+   supported by the system.  Returns the number of fpages required to
+   cover the range, and returns that many fpages (with maximum
+   accessibility) in FPAGES.  At most MAX_FPAGES fpages will be
+   returned.  */
+static unsigned int
+make_fpages (l4_word_t start, l4_word_t end, l4_fpage_t *fpages)
 {
   l4_word_t min_page_size = getpagesize ();
-  l4_word_t end = start + size;
   unsigned int nr_fpages = 0;
-  if (!size)
+
+  if (start >= end)
     return 0;
 
   if (start & (min_page_size - 1))
     panic ("make_fpages: START is not aligned to minimum page size");
-  if (size & (min_page_size - 1))
-    panic ("make_fpages: SIZE is not aligned to minimum page size");
 
-  debug ("Make fpages from 0x%x (size 0x%x): ", start, size);
-  /* END is at least one MIN_PAGE_SIZE larger than START.  */
+  end = (end + min_page_size - 1) & ~(min_page_size - 1);
+  /* END is now at least one MIN_PAGE_SIZE larger than START.  */
   nr_fpages = 0;
   while (start < end)
     {
-      fpages[nr_fpages] = l4_fpage (start, end - start);
-      debug ("0x%x/%u ", start, l4_size_log2 (fpages[nr_fpages]));
+      fpages[nr_fpages] = l4_fpage_add_rights (l4_fpage (start, end - start),
+                                              l4_fully_accessible);
       start += l4_size (fpages[nr_fpages]);
       nr_fpages++;
     }
-  debug ("\n");
   return nr_fpages;
 }
 
 
+/* Request the fpage FPAGE from sigma0.  */
 static void
-start_components (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)
+{
+  l4_fpage_t fpages[MAX_FPAGES];
+  unsigned int nr_fpages;
   l4_word_t min_page_size = getpagesize ();
-  l4_word_t ret;
-  l4_word_t control;
+  unsigned int i;
+
+  /* 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
+     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
+     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).  */
+
+  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]);
+
+  /* First protect all pages covered by the modules.  This will also
+     show if each module starts (and ends) on its own page.  */
+  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);
+    }
+
+  /* Now load the physical memory server to its destination
+     address.  */
+  if (!mods[MOD_PHYSMEM].start)
+    panic ("No physical memory server found");
+  loader_elf_load ("physmem-server", mods[MOD_PHYSMEM].start,
+                  mods[MOD_PHYSMEM].end,
+                  &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]);
+    }
+}
+
+
+static void
+start_components (void)
+{
   l4_msg_t msg;
   l4_msg_tag_t msg_tag;
+  l4_word_t ret;
+  l4_word_t control;
+  int cap_id;
   
-  if (mods[MOD_PHYSMEM].start & (min_page_size - 1))
-    panic ("physmem is not page aligned on this architecture");
   if (mods[MOD_PHYSMEM].start > mods[MOD_PHYSMEM].end)
     panic ("physmem has invalid memory range");
   if (mods[MOD_PHYSMEM].ip < mods[MOD_PHYSMEM].start
       || 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,
      version part is 2 (rootserver is 1).  */
   l4_thread_id_t physmem_server
@@ -174,15 +320,13 @@
   {
     l4_fpage_t fpages[MAX_FPAGES];
     unsigned int nr_fpages;
-    l4_word_t size = (mods[MOD_PHYSMEM].end - mods[MOD_PHYSMEM].start
-                     + min_page_size - 1) & ~(min_page_size - 1);
 
     /* We want to grant all the memory for the physmem binary image
        with the first page fault, but we might have to send several
        fpages.  So we first create a list of all fpages we need, then
        we serve one after another, providing the one containing the
        fault address last.  */
-    nr_fpages = make_fpages (mods[MOD_PHYSMEM].start, size,
+    nr_fpages = make_fpages (mods[MOD_PHYSMEM].start, mods[MOD_PHYSMEM].end,
                             fpages);
 
     /* Now serve page requests.  */
@@ -217,35 +361,15 @@
        if (i == nr_fpages)
          panic ("Could not find suitable fpage");
 
-       fpage = l4_fpage_add_rights (fpages[i], l4_fully_accessible);
-       debug ("Granting Fpage: 0x%x/%u\n", l4_address (fpage),
-              l4_size_log2 (fpage));
-
+       fpage = fpages[i];
        if (i != 0)
          fpages[i] = fpages[nr_fpages - 1];
        nr_fpages--;
 
-       /* First we have to request the fpage from sigma0.  */
-       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);
-       if (l4_msg_word (&msg, 1) == l4_nilpage.raw)
-         panic ("sigma0 rejected mapping");
-
-       /* Now we can grant the mapping to the physmem server.
-          FIXME: Should use the fpage returned by sigma0.  */
+       /* The memory was already requested from sigma0 by
+          load_components, so grant it right away.  */
+       debug ("Granting fpage: 0x%x/%u\n", l4_address (fpage),
+              l4_size_log2 (fpage));
        l4_msg_clear (&msg);
        l4_set_msg_label (&msg, 0);
        /* FIXME: Keep track of mappings already provided.  Possibly
@@ -257,35 +381,124 @@
       }
   }
 
+  /* Now we have kicked off the boot process.  The rest will be done
+     in the normal server loop.  */
+}
+
+
+/* Serve rootserver bootstrap requests.  */
+static void
+serve_bootstrap_requests (void)
+{
+  /* 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;
+
   do
     {
+      l4_thread_id_t from;
       l4_word_t label;
+      l4_msg_t msg;
+      l4_msg_tag_t msg_tag;
 
-      msg_tag = l4_receive (physmem_server);
+      msg_tag = l4_wait (&from);
       if (l4_ipc_failed (msg_tag))
-       panic ("Receiving messages from physmemserver thread failed: %u",
-              (l4_error_code () >> 1) & 0x7);
+       panic ("Receiving message failed: %u", (l4_error_code () >> 1) & 0x7);
 
       label = l4_label (msg_tag);
       l4_msg_store (msg_tag, &msg);
+      /* We don't do any access control in the bootstrap loop.  */
 
 #define WORTEL_MSG_PUTCHAR 1
+#define WORTEL_MSG_GET_MEM 2
       if (label == WORTEL_MSG_PUTCHAR)
        {
          int chr;
 
          /* This is a putchar() message.  */
+         if (l4_untyped_words (msg_tag) != 2
+             || l4_typed_words (msg_tag) != 0)
+           panic ("Invalid format of putchar msg");
+
+         chr = (int) l4_msg_word (&msg, 1);
+         putchar (chr);
+         /* No reply needed.  */
+         continue;
+       }
+      else if (WORTEL_MSG_GET_MEM)
+       {
+         l4_fpage_t fpage;
+         l4_grant_item_t grant_item;
+
          if (l4_untyped_words (msg_tag) != 1
              || l4_typed_words (msg_tag) != 0)
+           panic ("Invalid format of get_mem msg");
+
+         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);
+
+         grant_item = l4_grant_item (fpage, l4_address (fpage));
+         l4_msg_clear (&msg);
+         l4_msg_append_grant_item (&msg, grant_item);
+         l4_msg_load (&msg);
+         l4_reply (from);
+       }
+      else
+       panic ("Invalid message with tag 0x%x", msg_tag.raw);
+    }
+  while (1);
+}
+
+
+/* Serve rootserver requests.  */
+static void
+serve_requests (void)
+{
+  do
+    {
+      l4_thread_id_t from;
+      l4_word_t label;
+      l4_msg_t msg;
+      l4_msg_tag_t msg_tag;
+
+      msg_tag = l4_wait (&from);
+      if (l4_ipc_failed (msg_tag))
+       panic ("Receiving message failed: %u", (l4_error_code () >> 1) & 0x7);
+
+      label = l4_label (msg_tag);
+      /* FIXME: Shouldn't store the whole msg before checking access
+        rights.  */
+      l4_msg_store (msg_tag, &msg);
+      if (!WORTEL_CAP_VALID (l4_msg_word (&msg, 0), l4_version (from)))
+       /* FIXME: Shouldn't be a panic of course.  */
+       panic ("Unprivileged user attemps to access wortel rootserver");
+
+#define WORTEL_MSG_PUTCHAR 1
+      if (label == WORTEL_MSG_PUTCHAR)
+       {
+         int chr;
+
+         /* This is a putchar() message.  */
+         if (l4_untyped_words (msg_tag) != 2
+             || l4_typed_words (msg_tag) != 0)
            panic ("Invalid format of putchar msg");
 
-         chr = (int) l4_msg_word (&msg, 0);
+         chr = (int) l4_msg_word (&msg, 1);
          putchar (chr);
          /* No reply needed.  */
          continue;
        }
       else
-       panic ("Invalid message with tag 0x%x", msg_tag);
+       panic ("Invalid message with tag 0x%x", msg_tag.raw);
     }
   while (1);
 }
@@ -339,7 +552,7 @@
                printf (".\n\n");
            }
 
-         printf ("Report bugs to " BUG_ADDRESS ".\n", argv[0]);
+         printf ("Report bugs to " BUG_ADDRESS ".\n");
          shutdown ();    
        }
       else if (!strcmp (argv[i], "--version"))
@@ -395,7 +608,7 @@
 
       tag = l4_wait (&from);
       debug ("EXCEPTION HANDLER: Received message from: ");
-      debug ("0x%x", from);
+      debug ("0x%x", from.raw);
       debug ("\n");
       debug ("Tag: 0x%x", tag.raw);
       debug ("Label: %u  Untyped: %u  Typed: %u\n",
@@ -417,7 +630,7 @@
   debug ("EXCEPTION HANDLER: Too many exceptions.\n");
 
   while (1)
-    l4_yield ();
+    l4_sleep (l4_never);
 }
 
 
@@ -466,8 +679,7 @@
 
   start_components ();
 
-  while (1)
-    l4_yield ();
+  serve_bootstrap_requests ();
 
   return 0;
 }
Index: hurd-l4/wortel/wortel.h
diff -u hurd-l4/wortel/wortel.h:1.6 hurd-l4/wortel/wortel.h:1.7
--- hurd-l4/wortel/wortel.h:1.6 Mon Sep 15 14:09:45 2003
+++ hurd-l4/wortel/wortel.h     Mon Sep 15 20:42:17 2003
@@ -33,42 +33,67 @@
 #include "loader.h"
 
 
+#define BUG_ADDRESS    "<address@hidden>"
+
 /* The program name.  */
-extern char *program_name;
+extern const char program_name[];
 
-#define BUG_ADDRESS    "<address@hidden>"
+/* The region of wortel itself.  */
+extern l4_word_t wortel_start;
+extern l4_word_t wortel_end;
 
 
+/* Room for the arguments.  1 KB is a cramped half-screen full, which
+   should be more than enough.  Arguments need to be copied here by
+   the architecture dependent find_components, so all precious data is
+   gathered in the wortel binary region.  */
+extern char mods_args[1024];
+
+/* The number of bytes in mods_args already consumed.  */
+extern unsigned mods_args_len;
+
 struct wortel_module
 {
   const char *name;
 
-  /* Low and high address of the module.  */
+  /* Low and high address of the module.  Initialized by
+     find_components.  */
   l4_word_t start;
   l4_word_t end;
 
-  /* The command line, in raw, uninterpreted form.  */
+  /* The command line, in raw, uninterpreted form.  This points into
+     mods_args.  Initialized by find_components.  */
   char *args;
 
   /* The container capability in the physical memory server for this
      module.  Valid for all modules except for the physical memory
-     server itself.  */
+     server itself.  Initialized after the physical memory server
+     starts up.  */
   hurd_cap_scid_t mem_cont;
 
   /* The following informartion is only valid if a task will be
      created from the module.  */
 
-  /* The entry point of the executable.  */
+  /* The entry point of the executable.  Initialized just before the
+     task is started.  */
   l4_word_t ip;
 
+  /* The program header location and size.  Initialized just before
+     the task is started.  */
+  l4_word_t header_loc;
+  l4_word_t header_size;
+
   /* The task control capability for this module.  Only valid if this
-     is not the task server task itself.  */
+     is not the task server task itself.  Initialized after the task
+     server starts up.  */
   hurd_cap_scid_t task_ctrl;
 
-  /* Main thread of the task made from this module.  */
+  /* Main thread of the task made from this module.  Initialized just
+     before the task is started.  */
   l4_thread_id_t main_thread;
 
-  /* Server thread of the task made from this module.  */
+  /* Server thread of the task made from this module.  Initialized
+     just before the task is started.  */
   l4_thread_id_t server_thread;
 };
 
@@ -89,9 +114,11 @@
    one more than the last byte in the image.  */
 extern struct wortel_module mods[MOD_NUMBER];
 
+/* The number of modules present.  Only the first MODS_COUNT modules
+   in MODS are properly initialized.  */
 extern unsigned int mods_count;
 
-/* Find the module information required for booting (start, end, args).  */
+/* Find the module information required for booting.  */
 void find_components (void);
 
 int main (int argc, char *argv[]);




reply via email to

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