commit-hurd
[Top][All Lists]
Advanced

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

hurd-l4 ./Makefile.am ./configure.ac doc/posix....


From: Marcus Brinkmann
Subject: hurd-l4 ./Makefile.am ./configure.ac doc/posix....
Date: Mon, 15 Sep 2003 14:09:46 -0400

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

Modified files:
        .              : Makefile.am configure.ac 
        doc            : posix.tex 
        libhurd-cap    : cap-move.c cap-user.c cap.c cap.h 
        wortel         : ia32-cmain.c loader.c loader.h wortel.c 
                         wortel.h 

Log message:
        doc/
        Add more info on exec
        
        wortel/
        Make more generic.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/Makefile.am.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/configure.ac.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/doc/posix.tex.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/libhurd-cap/cap-move.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/libhurd-cap/cap-user.c.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/libhurd-cap/cap.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/libhurd-cap/cap.h.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/ia32-cmain.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/loader.c.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/loader.h.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/wortel.c.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/wortel/wortel.h.diff?tr1=1.5&tr2=1.6&r1=text&r2=text

Patches:
Index: hurd-l4/Makefile.am
diff -u hurd-l4/Makefile.am:1.6 hurd-l4/Makefile.am:1.7
--- hurd-l4/Makefile.am:1.6     Fri Sep 12 20:25:50 2003
+++ hurd-l4/Makefile.am Mon Sep 15 14:09:45 2003
@@ -1 +1,3 @@
-SUBDIRS = libl4 libc-parts laden wortel physmem libhurd-slab libhurd-ihash
+SUBDIRS = libl4 libhurd-ihash libhurd-slab libhurd-cap \
+       libc-parts laden wortel physmem \
+       doc
Index: hurd-l4/configure.ac
diff -u hurd-l4/configure.ac:1.8 hurd-l4/configure.ac:1.9
--- hurd-l4/configure.ac:1.8    Fri Sep 12 20:25:50 2003
+++ hurd-l4/configure.ac        Mon Sep 15 14:09:45 2003
@@ -85,6 +85,7 @@
 m4_include([libl4/headers.m4])
 m4_include([libhurd-ihash/headers.m4])
 m4_include([libhurd-slab/headers.m4])
+m4_include([libhurd-cap/headers.m4])
 
 if test "x$missing_progs" != "x"; then
   AC_MSG_ERROR([The following programs were not found:$missing_progs])
@@ -94,10 +95,11 @@
 AC_CONFIG_FILES([Makefile
                 libl4/ia32/Makefile libl4/Makefile
                 libc-parts/Makefile
+                libhurd-ihash/Makefile
+                libhurd-slab/Makefile
+                libhurd-cap/Makefile
                  laden/Makefile
                  wortel/Makefile
                  physmem/Makefile
-                libhurd-slab/Makefile
-                libhurd-ihash/Makefile
                 doc/Makefile])
 AC_OUTPUT
Index: hurd-l4/doc/posix.tex
diff -u hurd-l4/doc/posix.tex:1.2 hurd-l4/doc/posix.tex:1.3
--- hurd-l4/doc/posix.tex:1.2   Sun Sep  7 18:24:06 2003
+++ hurd-l4/doc/posix.tex       Mon Sep 15 14:09:45 2003
@@ -248,26 +248,26 @@
 To be written.
 
 
-\subsection{The \texttt{exec()} function}
+\subsection{The \texttt{exec} functions}
 \label{exec}
 
-The \texttt{exec()} operation will be done locally in a task.
-Traditionally, \texttt{exec()} overlays the same task with a new
+The \texttt{exec} operation will be done locally in a task.
+Traditionally, \texttt{exec} overlays the same task with a new
 process image, because creating a new task and transferring the
 associated state is expensive.  In L4, only the threads and virtual
 memory mappings are actually kernel state associated with a task, and
-exactly those have to be destroyed by \texttt{exec()} anyway.  There
+exactly those have to be destroyed by \texttt{exec} anyway.  There
 is a lot of Hurd specific state associated with a task (capabilities,
 for example), but it is difficult to preserve that.  There are
 security concerns, because POSIX programs do not know about Hurd
 features like capabilities, so inheriting all capabilities across
-\texttt{exec()} unconditionally seems dangerous.
+\texttt{exec} unconditionally seems dangerous.
 
 \begin{comment}
   One could think that if a program is not Hurd-aware, then it will
   not make any use of capabilities except through the normal POSIX
   API, and thus there are no capabilities except those that the GNU C
-  library uses itself, which \texttt{exec()} can take care of.
+  library uses itself, which \texttt{exec} can take care of.
   However, this is only true if code that is not Hurd-aware is never
   mixed with Hurd specific code, even libraries (unless the library
   intimately cooperates with the GNU C library).  This would be a high
@@ -280,9 +280,9 @@
   executable.
   
   For \verb/posix_spawn()/, this is straight-forward.  For
-  \texttt{exec()}, it is not. either specific capabilities could be
-  markes as ``do not close on \texttt{exec()}'', or variants of the
-  \texttt{exec()} function could be provided which take further
+  \texttt{exec}, it is not. either specific capabilities could be
+  markes as ``do not close on \texttt{exec}'', or variants of the
+  \texttt{exec} function could be provided which take further
   arguments.
 \end{comment}
 
@@ -294,16 +294,16 @@
 snippet that runs during the transition).
 
 So the decision was made to always create a new task with
-\texttt{exec()}, and copy the desired state from the current task to
-the new task.  This is a clean solution, because a new task will
-always start out without any capabilities in servers, etc, and thus
-there is no need for the old task to try to destroy all unneeded
-capabilities and other local state before \texttt{exec()}.  Also, in
-case the exec fails, the old program can continue to run, even if the
-exec fails at a very late point (there is no ``point of no return''
-until the new task is actually up and running).
+\texttt{exec}, and copy the desired state from the current task to the
+new task.  This is a clean solution, because a new task will always
+start out without any capabilities in servers, etc, and thus there is
+no need for the old task to try to destroy all unneeded capabilities
+and other local state before \texttt{exec}.  Also, in case the
+\texttt{exec} fails, the old program can continue to run, even if the
+\texttt{exec} fails at a very late point (there is no ``point of no
+return'' until the new task is actually up and running).
 
-For suid and sgid applications, the actual \texttt{exec()} has to be
+For suid and sgid applications, the actual \texttt{exec} has to be
 done by the filesystem.  However, the filesystem can not be bothered
 to also transfer all the user state into the new task.  It can not
 even do that, because it can not accept capabilities implemented by
@@ -313,7 +313,7 @@
 
 \begin{enumerate}
 \item The user creates a new task and a container with a single
-  physical page, and makes the \texttt{exec()} call to the file
+  physical page, and makes the \texttt{exec} call to the file
   capability, providing the task control capability.  Before that, it
   creates a task info capability from it for its own use.
 \item The filesystem checks permission and then revokes all other
@@ -354,6 +354,63 @@
 idea.  The details will depend a lot on the actual implementation.
 
 
+\subsubsection{The startup information}
+
+The following information is passed to the new task by the parent (the
+filesystem in the suid case).  Every item is a machine word.
+
+\begin{enumerate}
+\item \texttt{magic}
+  
+  The first four bytes are \texttt{E}, \texttt{X}, \texttt{E},
+  \texttt{C}.
+
+\item \texttt{program header location}
+\item \texttt{program header size}
+  
+  The location and size of the program header.  The meaning of this
+  field depends on the binary format.
+
+\item \texttt{feature flags}
+  
+  This bit-field indicates which of the following information is
+  present.  If the information is not present, the corresponding
+  machine words are undefined.  This provides simple version control.
+
+  \begin{comment}
+    They could also be undefined.
+  \end{comment}
+
+\item \texttt{wortel thread ID}
+\item \texttt{wortel control cap ID}
+  
+  The thread ID of the \texttt{wortel} rootserver, and the local ID of
+  the \texttt{wortel} control cap.  The \texttt{wortel} control cap
+  allows the user to make privileged system calls.  This field is only
+  present if the user has this capability.  Usually, this is only the
+  case for some initial servers at bootstrap.
+
+\item \texttt{physmem thread ID}
+\item \texttt{physmem control cap ID}
+  
+  The thread ID physical memory server, and the local ID of the
+  \texttt{physmem} control cap.  This cap can be used to manage the
+  physical memory of this task.
+
+\item \texttt{physmem startup page container cap ID}
+  
+  The container cap ID for the startup code, containing this
+  information, the initial pager, and other startup code.  This
+  container is mapped into the address space of the task outside of
+  the actual program, and can be unmapped by the program after it has
+  used this information and installed its own pager, by destroying
+  this container, to reclaim the virtual address space and physical
+  memory it occupies.
+
+\item (More to come.)
+\end{enumerate}
+
+
 \section{Unix Domain Sockets}
 \label{unixdomainsockets}
 
@@ -489,18 +546,18 @@
 \end{comment}
 
 The actual creation of the child filesystem can be performed much like
-a suid exec, just without any client to follow up with further
-capabilities and startup info.  The only problem that remains is how
-the parent filesystem can know which thread in the child filesystem
-implements the initial handshake protocol for the clients to use.  The
-only safe way here seems to be that the parent filesystem requires the
-child to use the main thread for that, or that the parent filesystem
-creates a second thread in the child at startup (passing its thread ID
-in the startup data), requiring that this second thread is used.  In
-either case the parent filesystem will know the thread ID in advance
-because it created the thread in the first place.  This looks a bit
-ugly, and violates good taste, so we might try to look for alternative
-solutions.
+a suid \texttt{exec}, just without any client to follow up with
+further capabilities and startup info.  The only problem that remains
+is how the parent filesystem can know which thread in the child
+filesystem implements the initial handshake protocol for the clients
+to use.  The only safe way here seems to be that the parent filesystem
+requires the child to use the main thread for that, or that the parent
+filesystem creates a second thread in the child at startup (passing
+its thread ID in the startup data), requiring that this second thread
+is used.  In either case the parent filesystem will know the thread ID
+in advance because it created the thread in the first place.  This
+looks a bit ugly, and violates good taste, so we might try to look for
+alternative solutions.
 
 
 \subsection{Reparenting}
Index: hurd-l4/libhurd-cap/cap-move.c
diff -u hurd-l4/libhurd-cap/cap-move.c:1.3 hurd-l4/libhurd-cap/cap-move.c:1.4
--- hurd-l4/libhurd-cap/cap-move.c:1.3  Sat Aug 30 00:21:31 2003
+++ hurd-l4/libhurd-cap/cap-move.c      Mon Sep 15 14:09:45 2003
@@ -19,6 +19,11 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
 /* FIXME:  This is only some pseudo code to get the hang of it.  */
 
 /* Sender side.  */
Index: hurd-l4/libhurd-cap/cap-user.c
diff -u hurd-l4/libhurd-cap/cap-user.c:1.7 hurd-l4/libhurd-cap/cap-user.c:1.8
--- hurd-l4/libhurd-cap/cap-user.c:1.7  Wed Aug 27 20:13:27 2003
+++ hurd-l4/libhurd-cap/cap-user.c      Mon Sep 15 14:09:45 2003
@@ -19,10 +19,15 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdlib.h>
 #include <pthread.h>
 #include <assert.h>
 #include <errno.h>
+#include <stdint.h>
 
 #include <hurd/cap.h>
 
@@ -69,15 +74,15 @@
     }
 
   /* Now we can remove the object.  */
-  hurd_ihash_remove (&server_to_sconn, sconn->server_thread);
+  hurd_ihash_remove (&server_to_sconn, sconn->server_thread.raw);
   pthread_mutex_unlock (&server_to_sconn_lock);
 
   /* Finally, we can destroy it.  */
   pthread_mutex_unlock (&sconn->lock);
   pthread_mutex_destroy (&sconn->lock);
   hurd_ihash_destroy (&sconn->id_to_cap);
-  if (sconn->server_task_id)
-    hurd_cap_deallocate (sconn->server_task_id);
+  if (sconn->server_task_info)
+    hurd_cap_deallocate (sconn->server_task_info);
   free (sconn);
 }
 
@@ -86,10 +91,11 @@
    connection SCONN.  SCONN is locked.  Afterwards, SCONN is
    unlocked.  */
 void
-_hurd_cap_sconn_remove (sconn, scid)
+_hurd_cap_sconn_remove (hurd_cap_sconn_t sconn, l4_word_t scid)
 {
   /* Remove the capability object pointer, which is now invalid.  */
   hurd_ihash_remove (&sconn->id_to_cap, scid);
+
   /* FIXME: The following should be some low level RPC to deallocate
      the capability on the server side.  If it fails, then what can we
      do at this point?  */
@@ -100,7 +106,7 @@
 
 
 /* Enter a new send capability provided by the server SERVER_THREAD
-   (with the task ID reference SERVER_TASK_ID) and the cap ID SCID.
+   (with the task ID reference SERVER_TASK_INFO) and the cap ID SCID.
    SCONN is the server connection for SERVER_THREAD, if known.  It
    should be unlocked.  If SCONN is NULL, then SERVER_TASK_INFO should
    be the task info capability for the server SERVER_THREAD, otherwise
@@ -118,12 +124,12 @@
   int sconn_created = 0;
 
   if (sconn)
-    assert (sconn->server_thread == server_thread);
+    assert (l4_is_thread_equal (sconn->server_thread, server_thread));
   else
     {
       /* It might have become available by now.  */
       pthread_mutex_lock (&server_to_sconn_lock);
-      sconn = hurd_ihash_find (&server_to_sconn, server_thread);
+      sconn = hurd_ihash_find (&server_to_sconn, server_thread.raw);
       if (sconn)
        hurd_cap_deallocate (server_task_info);
       else
@@ -146,20 +152,20 @@
              return errno;
            }
 
-         hurd_ihash_init (&sconn->id_to_cap);
+         hurd_ihash_init (&sconn->id_to_cap, HURD_IHASH_NO_LOCP);
          sconn->server_thread = server_thread;
-         sconn->server_task_id = server_task_info;
+         sconn->server_task_info = server_task_info;
          sconn->refs = 0;
 
          /* Enter the new server connection object.  */
-         err = hurd_ihash_add (&server_to_sconn, server_thread, sconn);
+         err = hurd_ihash_add (&server_to_sconn, server_thread.raw, sconn);
          if (err)
            {
              pthread_mutex_destroy (&sconn->lock);
              hurd_ihash_destroy (&sconn->id_to_cap);
              free (sconn);
              pthread_mutex_unlock (&server_to_sconn_lock);
-             hurd_cap_deallocate (server_task_id);
+             hurd_cap_deallocate (server_task_info);
              return errno;
            }
        }
@@ -167,30 +173,32 @@
   pthread_mutex_lock (&sconn->lock);
   pthread_mutex_unlock (&server_to_sconn_lock);
 
-  cap = hurd_ihash_find (&sconn->id_to_cap, scid);
+  (*cap) = hurd_ihash_find (&sconn->id_to_cap, scid);
   if (!cap)
     {
-      error_t err = hurd_slab_alloc (cap_space, &cap);
+      error_t err = hurd_slab_alloc (cap_space, cap);
       if (err)
        {
          _hurd_cap_sconn_dealloc (sconn);
          return err;
        }
 
-      cap->sconn = sconn;
-      cap->scid = scid;
-      cap->dead_cb = NULL;
+      (*cap)->sconn = sconn;
+      (*cap)->scid = scid;
+#if 0
+      (*cap)->dead_cb = NULL;
+#endif
 
-      err = hurd_ihash_add (&sconn->id_to_cap, scid, cap);
+      err = hurd_ihash_add (&sconn->id_to_cap, scid, *cap);
       if (err)
        {
          _hurd_cap_sconn_dealloc (sconn);
-         hurd_slab_dealloc (cap_space, cap);
+         hurd_slab_dealloc (cap_space, *cap);
          return err;
        }
     }
-  pthread_mutex_lock (&cap->lock);
-  cap->srefs++;
+  pthread_mutex_lock (&(*cap)->lock);
+  (*cap)->srefs++;
   /* We have to add a reference for the capability we have added,
      unless we are consuming the reference that was provided.  */
   if (!sconn_provided)
Index: hurd-l4/libhurd-cap/cap.c
diff -u hurd-l4/libhurd-cap/cap.c:1.3 hurd-l4/libhurd-cap/cap.c:1.4
--- hurd-l4/libhurd-cap/cap.c:1.3       Sat Aug 16 17:11:00 2003
+++ hurd-l4/libhurd-cap/cap.c   Mon Sep 15 14:09:45 2003
@@ -18,9 +18,14 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdlib.h>
 #include <assert.h>
 #include <errno.h>
+#include <stdint.h>
 
 #include <pthread.h>
 
@@ -71,7 +76,7 @@
 hurd_cap_init (void)
 {
   return hurd_slab_create (sizeof (struct hurd_cap),
-                          cap_constructor, cap_deconstructor, &cap_space);
+                          cap_constructor, cap_destructor, &cap_space);
 }
 
 
@@ -190,7 +195,7 @@
      get a temporary reference and acquire the user list lock while
      the capability is temporarily unlocked.  Then we can check if we
      still have to deallocate the capabilty.  */
-  ulist = cap->ulist;
+  ulist = cap->ouser;
 
   cap->orefs = 1;
   pthread_mutex_unlock (&cap->lock);
@@ -200,7 +205,7 @@
   pthread_mutex_lock (&ulist->lock);
   pthread_mutex_lock (&cap->lock);
 
-  assert (cap->ulist == ulist);
+  assert (cap->ouser == ulist);
   assert (cap->orefs != 0);
   cap->orefs--;
   if (cap->orefs != 0)
@@ -208,7 +213,7 @@
       /* Someone else came in and got a reference to the almost dead
         capability object.  Give up.  */
       pthread_mutex_unlock (&cap->lock);
-      pthread_mutex_unlock (&sconn->lock);
+      pthread_mutex_unlock (&ulist->lock);
       return 0;
     }
   
Index: hurd-l4/libhurd-cap/cap.h
diff -u hurd-l4/libhurd-cap/cap.h:1.5 hurd-l4/libhurd-cap/cap.h:1.6
--- hurd-l4/libhurd-cap/cap.h:1.5       Wed Aug 27 18:51:59 2003
+++ hurd-l4/libhurd-cap/cap.h   Mon Sep 15 14:09:45 2003
@@ -25,6 +25,7 @@
 #include <hurd/slab.h>
 #include <l4/types.h>
 
+typedef l4_word_t hurd_task_info_t;
 
 /* Initialize the capability system.  */
 error_t hurd_cap_init (void);
@@ -38,7 +39,7 @@
 
   /* A reference for the servers task ID to prevent reuse.  This is 0
      if this is the connection to the task server itself.  */
-  task_id_t server_task_id;
+  hurd_task_info_t server_task_info;
 
   /* The lock protecting the variable members of the server connection
      object.  */
@@ -50,6 +51,7 @@
   /* A hash mapping the capability IDs to capability objects.  */
   struct hurd_ihash id_to_cap;
 };
+typedef struct hurd_cap_sconn *hurd_cap_sconn_t;
 
 
 /* User capabilities.  */
@@ -57,10 +59,10 @@
 /* The task-specific ID for this capability.  */
 typedef l4_word_t hurd_cap_scid_t;
 
-
-/* Remove the entry for the capability CAP from the user list ULIST.
-   ULIST (and the capability CAP) are locked.  */
-void _hurd_cap_ulist_remove (ulist, cap);
+
+/* Forward reference.  */
+struct hurd_cap_ulist;
+typedef struct hurd_cap_ulist *hurd_cap_ulist_t;
 
 
 /* The capability structure.  */
@@ -88,8 +90,9 @@
 
   /* A callback for the user of the capability, invoked when the
      capability is destroyed.  */
+#if 0
   hurd_cap_dead_t dead_cb;
-
+#endif
 
   /* Information for local capabilities.  */
 
@@ -104,10 +107,26 @@
   hurd_cap_ulist_t ouser;
 
   /* A callback invoked when the capability is destroyed.  */
+#if 0
   hurd_cap_odead_cb_t odead_cb;
+#endif
 
   /* A callback to be invoked when the capability has no more
      senders.  */
+#if 0
   hurd_cap_no_sender_cb_t no_sender_cb;
+#endif
+};
+typedef struct hurd_cap *hurd_cap_t;
+
+
+struct hurd_cap_ulist
+{
+  /* The lock protecting the variable members of the object.  */
+  pthread_mutex_t lock;
 };
-typedef struct hurd_cap hurd_cap_t;
+
+
+/* Remove the entry for the capability CAP from the user list ULIST.
+   ULIST (and the capability CAP) are locked.  */
+void _hurd_cap_ulist_remove (hurd_cap_ulist_t ulist, hurd_cap_t cap);
Index: hurd-l4/wortel/ia32-cmain.c
diff -u hurd-l4/wortel/ia32-cmain.c:1.3 hurd-l4/wortel/ia32-cmain.c:1.4
--- hurd-l4/wortel/ia32-cmain.c:1.3     Tue Sep  9 17:43:12 2003
+++ hurd-l4/wortel/ia32-cmain.c Mon Sep 15 14:09:45 2003
@@ -52,20 +52,6 @@
   mbi = (multiboot_info_t *) l4_boot_info ();
   debug ("Multiboot Info: 0x%x\n", mbi);
 
-#if 0
-  if (CHECK_FLAG (mbi->flags, 3))
-    {
-      module_t *mod = (module_t *) mbi->mods_addr;
-      int nr;
-
-      /* FIXME: Should add all modules that we need to start up to the
-        global, architecture independent module list.  */
-      for (nr = 0; nr < mbi->mods_count; nr++)
-       debug ("Module %i: Start 0x%x, End 0x%x, Cmd %s\n",
-              nr + 1, mod[nr].mod_start, mod[nr].mod_end, mod[nr].string);
-    }
-#endif
-
   if (CHECK_FLAG (mbi->flags, 3) && mbi->mods_count > 0)
     {
       /* A command line is available.  */
@@ -141,31 +127,31 @@
   l4_word_t start;
   l4_word_t end;
 
-#if 0
-  debug_dump ();
-#endif
-
   /* Load the module information.  */
   if (CHECK_FLAG (mbi->flags, 3))
     {
       module_t *mod = (module_t *) mbi->mods_addr;
-      
-      if (mbi->mods_count > 0)
-       {
-         /* Skip the entry for the rootserver.  */
-         mod++;
-       }
+      unsigned int nr_mods;
+      unsigned int i;
+
+      mods_count = mbi->mods_count - 1;
+      if (mods_count > MOD_NUMBER)
+       mods_count = MOD_NUMBER;
+      /* Skip the entry for the rootserver.  */
+      mod++;
 
-      if (mbi->mods_count > 1)
+      for (i = 0; i < nr_mods; i++)
        {
-         physmem.low = mod->mod_start;
-         physmem.high = mod->mod_end;
+         mods[i].name = mod_names[i];
+         mods[i].start = mod[i].mod_start;
+         mods[i].end = mod[i].mod_end;
+         mods[i].args = (char *) mod[i].string;
          mod++;
        }
     }
 
-  /* Now protect ourselves and the mulitboot info (at least the module
-     configuration.  */
+  /* 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;
Index: hurd-l4/wortel/loader.c
diff -u hurd-l4/wortel/loader.c:1.1 hurd-l4/wortel/loader.c:1.2
--- hurd-l4/wortel/loader.c:1.1 Mon Sep  8 10:40:37 2003
+++ hurd-l4/wortel/loader.c     Mon Sep 15 14:09:45 2003
@@ -82,7 +82,7 @@
 
 static struct
 {
-  char *name;
+  const char *name;
   l4_word_t start;
   l4_word_t end;
 } used_regions[MAX_REGIONS];
@@ -93,7 +93,7 @@
 /* Check that the region with the name NAME from START to END does not
    overlap with an existing region.  */
 static void
-check_region (char *name, l4_word_t start, l4_word_t end)
+check_region (const char *name, l4_word_t start, l4_word_t end)
 {
   int i;
 
@@ -115,7 +115,7 @@
    regions to check against.  Before doing that, check for overlaps
    with existing regions.  */
 void
-loader_add_region (char *name, l4_word_t start, l4_word_t end)
+loader_add_region (const char *name, l4_word_t start, l4_word_t end)
 {
   debug ("Protected Region: %s (0x%x - 0x%x)\n", name, start, end);
 
@@ -142,7 +142,7 @@
       break;
 
   if (i == nr_regions)
-    panic ("Assertion failure: Could not find region %s for removal");
+    panic ("Assertion failure: Could not find region %s for removal", name);
 
   while (i < nr_regions - 1)
     {
@@ -159,7 +159,7 @@
    program in NEW_START_P and NEW_END_P, and the entry point in
    ENTRY.  */
 void
-loader_elf_load (char *name, l4_word_t start, l4_word_t end,
+loader_elf_load (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 *entry)
 {
Index: hurd-l4/wortel/loader.h
diff -u hurd-l4/wortel/loader.h:1.1 hurd-l4/wortel/loader.h:1.2
--- hurd-l4/wortel/loader.h:1.1 Mon Sep  8 10:40:37 2003
+++ hurd-l4/wortel/loader.h     Mon Sep 15 14:09:45 2003
@@ -38,7 +38,7 @@
 /* Add the region with the name NAME from START to END to the table of
    regions to check against.  Before doing that, check for overlaps
    with existing regions.  */
-void loader_add_region (char *name, l4_word_t start, l4_word_t end);
+void loader_add_region (const char *name, l4_word_t start, l4_word_t end);
 
 /* Remove the region with the name NAME from the table.  */
 void loader_remove_region (const char *name);
@@ -48,7 +48,7 @@
    program).  Return the lowest and highest address used by the
    program in NEW_START_P and NEW_END_P, and the entry point in
    ENTRY.  */
-void loader_elf_load (char *name, l4_word_t start, l4_word_t end,
+void loader_elf_load (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 *entry);
 
Index: hurd-l4/wortel/wortel.c
diff -u hurd-l4/wortel/wortel.c:1.5 hurd-l4/wortel/wortel.c:1.6
--- hurd-l4/wortel/wortel.c:1.5 Tue Sep  9 19:43:48 2003
+++ hurd-l4/wortel/wortel.c     Mon Sep 15 14:09:45 2003
@@ -29,7 +29,14 @@
 /* The program name.  */
 char *program_name = "wortel";
 
-rootserver_t physmem;
+const char *mod_names[] = { "physmem-mod", "task-mod", "root-fs-mod" };
+
+/* For the boot components, find_components() must fill in the start
+   and end address of the ELF images in memory.  The end address is
+   one more than the last byte in the image.  */
+struct wortel_module mods[MOD_NUMBER];
+
+unsigned int mods_count;
 
 
 /* Return the number of memory descriptors.  */
@@ -52,16 +59,61 @@
 static void
 load_components (void)
 {
-  if (!physmem.low)
+  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_add_region ("physmem-mod", physmem.low, physmem.high);
 
-  loader_elf_load ("physmem-server", physmem.low, physmem.high,
-                  &physmem.low, &physmem.high, &physmem.ip);
+  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
+   induction.  The minimum page size in L4 is at least 2^10.  */
+#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)
+{
+  l4_word_t min_page_size = getpagesize ();
+  l4_word_t end = (start + size + min_page_size - 1) & ~(min_page_size - 1);
+  unsigned int nr_fpages = 0;
+
+  if (!size)
+    return 0;
+
+  if (start & ~(min_page_size - 1))    
+    panic ("make_fpages: START is not aligned to minimum page size");
+  if (end & ~(min_page_size - 1))    
+    panic ("make_fpages: START is not aligned to minimum page size");
+
+  /* END is at least one MIN_PAGE_SIZE larger than START.  */
+  nr_fpages = 0;
+  while (start < end)
+    {
+      fpages[nr_fpages] = l4_fpage (start, end - start);
+      start += l4_size (fpages[nr_fpages]);
+      nr_fpages++;
+    }
+  return nr_fpages;
+}
+
+
 static void
 start_components (void)
 {
@@ -71,18 +123,18 @@
   l4_msg_t msg;
   l4_msg_tag_t msg_tag;
   
-  if (physmem.low & (min_page_size - 1))
+  if (mods[MOD_PHYSMEM].start & (min_page_size - 1))
     panic ("physmem is not page aligned on this architecture");
-  if (physmem.low > physmem.high)
+  if (mods[MOD_PHYSMEM].start > mods[MOD_PHYSMEM].end)
     panic ("physmem has invalid memory range");
-  if (physmem.ip < physmem.low || physmem.ip > physmem.high)
+  if (mods[MOD_PHYSMEM].ip < mods[MOD_PHYSMEM].start
+      || mods[MOD_PHYSMEM].ip > mods[MOD_PHYSMEM].end)
     panic ("physmem has invalid IP");
 
   /* Thread nr is next available after rootserver thread nr,
      version part is 2 (rootserver is 1).  */
   l4_thread_id_t physmem_server
-    = l4_global_id (l4_thread_no (l4_myself ()) + 2,
-                   2);
+    = l4_global_id (l4_thread_no (l4_myself ()) + 2, 2);
   /* The UTCB location below is only a hack.  We also need a way to
      specify the maximum number of threads (ie the size of the UTCB
      area), for example via ELF symbols, or via the command line.
@@ -109,7 +161,7 @@
 
   l4_msg_clear (&msg);
   l4_set_msg_label (&msg, 0);
-  l4_msg_append_word (&msg, physmem.ip);
+  l4_msg_append_word (&msg, mods[MOD_PHYSMEM].ip);
   l4_msg_append_word (&msg, 0);
   l4_msg_load (&msg);
   msg_tag = l4_send (physmem_server);
@@ -118,36 +170,18 @@
           l4_error_code ());
 
   {
-    l4_fpage_t *fpages;
-    unsigned int nr_fpages = 0;
-    l4_word_t start = physmem.low;
-    l4_word_t end = (physmem.high + min_page_size) & ~(min_page_size - 1);
-    l4_word_t region;
+    l4_fpage_t fpages[MAX_FPAGES];
+    unsigned int nr_fpages;
+    l4_word_t start = mods[MOD_PHYSMEM].start;
+    l4_word_t size = (mods[MOD_PHYSMEM].end - start + min_page_size)
+      & ~(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.  */
-
-    /* A page-aligned region of size up to 2^k * min_page_size can be
-       covered by k fpages at most (proof by induction).  At this
-       point, END is at least one MIN_PAGE_SIZE larger than START.  */
-    region = (end - start) / min_page_size;
-    while (region > 0)
-      {
-       nr_fpages++;
-       region >>= 1;
-      }
-    fpages = alloca (sizeof (l4_fpage_t) * nr_fpages);
-
-    nr_fpages = 0;
-    while (start < end)
-      {
-       fpages[nr_fpages] = l4_fpage (start, end - start);
-       start += l4_size (fpages[nr_fpages]);
-       nr_fpages++;
-      }
+    nr_fpages = make_fpages (start, size, fpages);
 
     /* Now serve page requests.  */
     while (nr_fpages)
@@ -167,9 +201,9 @@
        if (l4_untyped_words (msg_tag) != 2 || l4_typed_words (msg_tag) != 0)
          panic ("Invalid format of page fault message");
        addr = l4_msg_word (&msg, 0);
-       if (addr != physmem.ip)
+       if (addr != mods[MOD_PHYSMEM].ip)
          panic ("Page fault at unexpected address 0x%x (expected 0x%x)",
-                addr, physmem.ip);
+                addr, mods[MOD_PHYSMEM].ip);
 
        if (nr_fpages == 1)
          i = 0;
Index: hurd-l4/wortel/wortel.h
diff -u hurd-l4/wortel/wortel.h:1.5 hurd-l4/wortel/wortel.h:1.6
--- hurd-l4/wortel/wortel.h:1.5 Fri Sep 12 20:25:51 2003
+++ hurd-l4/wortel/wortel.h     Mon Sep 15 14:09:45 2003
@@ -24,6 +24,8 @@
 
 #include <string.h>
 
+#include <hurd/cap.h>
+
 #include <l4.h>
 
 #include "output.h"
@@ -37,15 +39,59 @@
 #define BUG_ADDRESS    "<address@hidden>"
 
 
-typedef __l4_rootserver_t rootserver_t;
+struct wortel_module
+{
+  const char *name;
+
+  /* Low and high address of the module.  */
+  l4_word_t start;
+  l4_word_t end;
+
+  /* The command line, in raw, uninterpreted form.  */
+  char *args;
+
+  /* The container capability in the physical memory server for this
+     module.  Valid for all modules except for the physical memory
+     server itself.  */
+  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.  */
+  l4_word_t ip;
+
+  /* The task control capability for this module.  Only valid if this
+     is not the task server task itself.  */
+  hurd_cap_scid_t task_ctrl;
+
+  /* Main thread of the task made from this module.  */
+  l4_thread_id_t main_thread;
+
+  /* Server thread of the task made from this module.  */
+  l4_thread_id_t server_thread;
+};
+
+
+enum wortel_module_type
+  {
+    MOD_PHYSMEM = 0,
+    MOD_TASK,
+    MOD_ROOT_FS,
+    MOD_NUMBER
+  };
+
+
+extern const char *mod_names[MOD_NUMBER];
 
 /* For the boot components, find_components() must fill in the start
    and end address of the ELF images in memory.  The end address is
    one more than the last byte in the image.  */
-extern rootserver_t physmem;
+extern struct wortel_module mods[MOD_NUMBER];
+
+extern unsigned int mods_count;
 
-/* Find the kernel, the initial servers and the other information
-   required for booting.  */
+/* Find the module information required for booting (start, end, args).  */
 void find_components (void);
 
 int main (int argc, char *argv[]);




reply via email to

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