[Top][All Lists]
[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[]);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- hurd-l4 physmem/output.c physmem/physmem.c wort...,
Marcus Brinkmann <=