summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac5
-rw-r--r--libl4/l4/compat/types.h150
-rw-r--r--physmem/Makefile.am36
-rw-r--r--physmem/README6
-rw-r--r--physmem/ia32-cmain.c55
-rw-r--r--physmem/ia32-crt0.S47
-rw-r--r--physmem/output.c206
-rw-r--r--physmem/output.h35
-rw-r--r--physmem/physmem.c42
-rw-r--r--physmem/physmem.h31
-rw-r--r--wortel/README9
-rw-r--r--wortel/ia32-cmain.c76
-rw-r--r--wortel/wortel.c256
-rw-r--r--wortel/wortel.h12
14 files changed, 892 insertions, 74 deletions
diff --git a/configure.ac b/configure.ac
index fe6dc87..44429a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,9 +76,10 @@ fi
# Checks for library functions.
AC_CONFIG_FILES([Makefile
- laden/Makefile
- wortel/Makefile
libl4/ia32/Makefile libl4/Makefile
+ laden/Makefile
+ wortel/Makefile
+ physmem/Makefile
libhurd-slab/Makefile
libhurd-ihash/Makefile
doc/Makefile])
diff --git a/libl4/l4/compat/types.h b/libl4/l4/compat/types.h
index 9f7d0fd..a8df02b 100644
--- a/libl4/l4/compat/types.h
+++ b/libl4/l4/compat/types.h
@@ -1,86 +1,98 @@
-/*********************************************************************
- *
- * Copyright (C) 2001, 2002, 2003, Karlsruhe University
- *
- * File path: l4/types.h
- * Description: Commonly used L4 types
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: types.h,v 1.1 2003/07/26 17:26:09 marcus Exp $
- *
- ********************************************************************/
+/* types.h - Public interface for L4 compatibility types.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann <marcus@gnu.org>.
-#if defined(__cplusplus)
-static inline L4_Clock_t operator + (const L4_Clock_t &l, const int r)
-{
- return (L4_Clock_t) { raw : l.raw + r };
-}
+ This file is part of the GNU L4 library.
+
+ The GNU L4 library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ The GNU L4 library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU L4 library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
-static inline L4_Clock_t operator + (const L4_Clock_t & l, const L4_Uint64 t)
-{
- return (L4_Clock_t) { raw : l.raw + t };
-}
+#ifndef _L4_TYPES_H
+# error "Never use <l4/compat/types.h> directly; include <l4/types.h> instead."
+#endif
+
+typedef l4_word_t L4_Word_t;
+typedef l4_uint64_t L4_Word64_t;
+typedef l4_word_t L4_Bool_t;
-static inline L4_Clock_t operator - (const L4_Clock_t & c, const int r)
-{
- return (L4_Clock_t) { raw : c.raw - r };
+
+/* Clock interface. */
+
+typedef _L4_RAW
+(L4_Word64_t, _L4_STRUCT1
+ ({
+ l4_clock_t clock;
+ })) L4_Clock_t;
+
+
+
+#define _L4_CLOCK_OP(name, op) \
+static inline L4_Clock_t \
+L4_Clock ## name ## Usec (const L4_Clock_t clock, const L4_Word64_t usec) \
+{ \
+ return ((L4_Clock_t) { .clock = clock.clock op usec }); \
}
-static inline L4_Clock_t operator - (const L4_Clock_t & c, const L4_Uint64 r)
-{
- return (L4_Clock_t) { raw : c.raw - r };
+_L4_CLOCK_OP(Add, +)
+_L4_CLOCK_OP(Sub, -)
+#undef _L4_CLOCK_OP
+
+
+#define _L4_CLOCK_OP(name, op) \
+static inline L4_Bool_t \
+L4_Clock ## name (const L4_Clock_t clock1, const L4_Clock_t clock2) \
+{ \
+ return clock1.clock op clock2.clock; \
}
-#endif /* __cplusplus */
+_L4_CLOCK_OP(Earlier, <)
+_L4_CLOCK_OP(Later, >)
+_L4_CLOCK_OP(Equal, =)
+_L4_CLOCK_OP(NotEqual, !=)
+#undef _L4_CLOCK_OP
+
#if defined(__cplusplus)
-static inline L4_Bool_t operator < (const L4_Clock_t &l, const L4_Clock_t &r)
-{
- return l.raw < r.raw;
-}
-static inline L4_Bool_t operator > (const L4_Clock_t &l, const L4_Clock_t &r)
-{
- return l.raw > r.raw;
+#define _L4_CLOCK_OP(op, type) \
+static inline L4_Clock_t \
+operator ## op ## (const L4_Clock_t& clock, const type usec) \
+{ \
+ return ((L4_Clock_t) { .clock = clock.clock op usec }); \
}
-static inline L4_Bool_t operator <= (const L4_Clock_t &l, const L4_Clock_t &r)
-{
- return l.raw <= r.raw;
-}
+_L4_CLOCK_OP(+, int)
+_L4_CLOCK_OP(+, L4_Word64_t)
+_L4_CLOCK_OP(-, int)
+_L4_CLOCK_OP(-, L4_Word64_t)
+#undef _L4_CLOCK_OP
-static inline L4_Bool_t operator >= (const L4_Clock_t &l, const L4_Clock_t &r)
-{
- return l.raw >= r.raw;
-}
-static inline L4_Bool_t operator == (const L4_Clock_t &l, const L4_Clock_t &r)
-{
- return l.raw == r.raw;
+#define _L4_CLOCK_OP(op) \
+static inline L4_Bool_t \
+operator ## op ## (const L4_Clock_t& clock1, const L4_Clock_t& clock2) \
+{ \
+ return clock1.clock op clock2.clock; \
}
-static inline L4_Bool_t operator != (const L4_Clock_t &l, const L4_Clock_t &r)
-{
- return l.raw != r.raw;
-}
+_L4_CLOCK_OP(<)
+_L4_CLOCK_OP(>)
+_L4_CLOCK_OP(<=)
+_L4_CLOCK_OP(>=)
+_L4_CLOCK_OP(==)
+_L4_CLOCK_OP(!=)
+#undef _L4_CLOCK_OP
+
#endif /* __cplusplus */
diff --git a/physmem/Makefile.am b/physmem/Makefile.am
new file mode 100644
index 0000000..a81ab8a
--- /dev/null
+++ b/physmem/Makefile.am
@@ -0,0 +1,36 @@
+# Makefile.am - Makefile template for the physical memory server.
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Written by Marcus Brinkmann.
+#
+# This file is part of the GNU Hurd.
+#
+# The GNU Hurd is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# The GNU Hurd is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+if ARCH_IA32
+ ARCH_SOURCES = ia32-crt0.S ia32-cmain.c
+endif
+
+noinst_PROGRAMS = physmem
+
+physmem_CFLAGS = -I$(srcdir) $(AM_CFLAGS)
+
+physmem_SOURCES = $(ARCH_SOURCES) \
+ output.h output.c \
+ physmem.h physmem.c
+
+/* FIXME: Make linkbase configurable. */
+physmem_LDFLAGS = -u_start -e_start -N -nostdlib -Ttext=0x350000
+
+physmem_LDADD = -lgcc \ No newline at end of file
diff --git a/physmem/README b/physmem/README
new file mode 100644
index 0000000..5239e80
--- /dev/null
+++ b/physmem/README
@@ -0,0 +1,6 @@
+physmem
+=======
+
+For now, this is only a small dummy program, not the real physical
+memory server.
+
diff --git a/physmem/ia32-cmain.c b/physmem/ia32-cmain.c
new file mode 100644
index 0000000..cc628a6
--- /dev/null
+++ b/physmem/ia32-cmain.c
@@ -0,0 +1,55 @@
+/* ia32-cmain.c - Startup code for the ia32.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <alloca.h>
+#include <stdint.h>
+
+#include <l4/globals.h>
+#include <l4/stubs.h>
+#include <l4/stubs-init.h>
+
+#include "physmem.h"
+
+
+/* Initialize libl4, setup the argument vector, and pass control over
+ to the main function. */
+void
+cmain (void)
+{
+ int argc = 0;
+ char **argv = 0;
+
+ l4_init ();
+ l4_init_stubs ();
+
+ argc = 1;
+ argv = alloca (sizeof (char *) * 2);
+ argv[0] = program_name;
+ argv[1] = 0;
+
+ /* Now invoke the main function. */
+ main (argc, argv);
+
+ /* Never reached. */
+}
diff --git a/physmem/ia32-crt0.S b/physmem/ia32-crt0.S
new file mode 100644
index 0000000..2b34590
--- /dev/null
+++ b/physmem/ia32-crt0.S
@@ -0,0 +1,47 @@
+/* ia32-crt0.S - Startup code for ia32.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#define ASM 1
+#include "multiboot.h"
+
+/* The size of our stack (4KB). */
+#define STACK_SIZE 0x1000
+
+ .text
+
+ .globl start, _start
+start:
+_start:
+ /* Initialize the stack pointer. */
+ movl $(stack + STACK_SIZE), %esp
+
+ /* Reset EFLAGS. */
+ pushl $0
+ popf
+
+ /* Now enter the cmain function. */
+ call cmain
+
+ /* Not reached. */
+loop: hlt
+ jmp loop
+
+ /* Our stack area. */
+ .comm stack, STACK_SIZE
diff --git a/physmem/output.c b/physmem/output.c
new file mode 100644
index 0000000..60dbcb1
--- /dev/null
+++ b/physmem/output.c
@@ -0,0 +1,206 @@
+/* output.c - Output routines.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+
+#include <l4.h>
+
+#include "output.h"
+
+
+/* True if debugging is enabled. */
+int output_debug;
+
+
+/* Print the single character CHR on the output device. */
+void
+putchar (int chr)
+{
+ l4_msg_t msg;
+
+ l4_msg_clear (&msg);
+ /* FIXME: Hard coded message label. */
+#define WORTEL_MSG_PUTCHAR 1
+ l4_set_msg_label (&msg, WORTEL_MSG_PUTCHAR);
+ l4_msg_append_word (&msg, (l4_word_t) chr);
+ l4_msg_load (&msg);
+ /* FIXME: Hard coded thread ID. */
+ l4_send (l4_global_id (l4_thread_user_base () + 2, 1));
+ /* FIXME: No error handling. */
+}
+
+
+static void
+print_nr (unsigned long long nr, int base)
+{
+ static char *digits = "0123456789abcdef";
+ char str[30];
+ int i = 0;
+
+ do
+ {
+ str[i++] = digits[nr % base];
+ nr = nr / base;
+ }
+ while (nr);
+
+ i--;
+ while (i >= 0)
+ putchar (str[i--]);
+}
+
+
+static void
+print_signed_nr (long long nr, int base)
+{
+ unsigned long long unr;
+
+ if (nr < 0)
+ {
+ putchar ('-');
+ unr = -nr;
+ }
+ else
+ unr = nr;
+
+ print_nr (unr, base);
+}
+
+
+void
+printf (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ const char *p = fmt;
+
+ while (*p != '\0')
+ {
+ if (*p != '%')
+ {
+ putchar (*(p++));
+ continue;
+ }
+
+ p++;
+ switch (*p)
+ {
+ case '%':
+ putchar ('%');
+ p++;
+ break;
+
+ case 'l':
+ p++;
+ if (*p != 'l')
+ {
+ putchar ('%');
+ putchar ('l');
+ putchar (*(p++));
+ continue;
+ }
+ p++;
+ switch (*p)
+ {
+ case 'o':
+ print_nr (va_arg (ap, unsigned long long), 8);
+ p++;
+ break;
+
+ case 'd':
+ case 'i':
+ print_signed_nr (va_arg (ap, long long), 10);
+ p++;
+ break;
+
+ case 'x':
+ case 'X':
+ print_nr (va_arg (ap, unsigned long long), 16);
+ p++;
+ break;
+
+ case 'u':
+ print_nr (va_arg (ap, unsigned long long), 10);
+ p++;
+ break;
+
+ default:
+ putchar ('%');
+ putchar ('l');
+ putchar ('l');
+ putchar (*(p++));
+ break;
+ }
+ break;
+
+ case 'o':
+ print_nr (va_arg (ap, unsigned int), 8);
+ p++;
+ break;
+
+ case 'd':
+ case 'i':
+ print_signed_nr (va_arg (ap, int), 10);
+ p++;
+ break;
+
+ case 'x':
+ case 'X':
+ print_nr (va_arg (ap, unsigned int), 16);
+ p++;
+ break;
+
+ case 'u':
+ print_nr (va_arg (ap, unsigned int), 10);
+ p++;
+ break;
+
+ case 'c':
+ putchar (va_arg (ap, int));
+ p++;
+ break;
+
+ case 's':
+ {
+ char *str = va_arg (ap, char *);
+ while (*str)
+ putchar (*(str++));
+ }
+ p++;
+ break;
+
+ case 'p':
+ print_nr ((unsigned int) va_arg (ap, void *), 16);
+ p++;
+ break;
+
+ default:
+ putchar ('%');
+ putchar (*p);
+ p++;
+ break;
+ }
+ }
+}
diff --git a/physmem/output.h b/physmem/output.h
new file mode 100644
index 0000000..247ea98
--- /dev/null
+++ b/physmem/output.h
@@ -0,0 +1,35 @@
+/* output.h - Output routines interfaces.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#ifndef _OUTPUT_H
+#define _OUTPUT_H 1
+
+/* Print the single character CHR on the output device. */
+void putchar (int chr);
+
+void printf (const char *fmt, ...);
+
+/* True if debug mode is enabled. */
+extern int output_debug;
+
+/* Print a debug message. */
+#define debug(...) do { if (output_debug) printf (__VA_ARGS__); } while (0)
+
+#endif /* _OUTPUT_H */
diff --git a/physmem/physmem.c b/physmem/physmem.c
new file mode 100644
index 0000000..cef9958
--- /dev/null
+++ b/physmem/physmem.c
@@ -0,0 +1,42 @@
+/* Main function for physical memory server.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "physmem.h"
+
+
+/* The program name. */
+char *program_name = "physmem";
+
+
+int
+main (int argc, char *argv[])
+{
+ output_debug = 1;
+
+ debug ("%s " PACKAGE_VERSION "\n", program_name);
+
+ while (1)
+ l4_sleep (l4_never);
+
+ return 0;
+}
diff --git a/physmem/physmem.h b/physmem/physmem.h
new file mode 100644
index 0000000..8e0fea4
--- /dev/null
+++ b/physmem/physmem.h
@@ -0,0 +1,31 @@
+/* physmem.h - Generic definitions.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <l4.h>
+#include "string.h"
+#include "output.h"
+
+
+/* The program name. */
+extern char *program_name;
+
+#define BUG_ADDRESS "<bug-hurd@gnu.org>"
+
+int main (int argc, char *argv[]);
diff --git a/wortel/README b/wortel/README
new file mode 100644
index 0000000..6dc0af8
--- /dev/null
+++ b/wortel/README
@@ -0,0 +1,9 @@
+wortel
+======
+
+wortel is the rootserver of the Hurd on L4. It is responsible for
+booting up the system and wrapping privileged L4 operations.
+
+For now, only a rudimentary part of the loader is written, and the
+only useful thing wortel can do is to start the dummy physmem server
+for a small demonstration.
diff --git a/wortel/ia32-cmain.c b/wortel/ia32-cmain.c
index d801836..a8b58e6 100644
--- a/wortel/ia32-cmain.c
+++ b/wortel/ia32-cmain.c
@@ -124,3 +124,79 @@ cmain (void)
/* Never reached. */
}
+
+
+/* The following must be defined and are used to calculate the extents
+ of the laden binary itself. */
+extern char _start;
+extern char _end;
+
+
+/* Find the kernel, the initial servers and the other information
+ required for booting. */
+void
+find_components (void)
+{
+ multiboot_info_t *mbi = (multiboot_info_t *) l4_boot_info ();
+ 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++;
+ }
+
+ if (mbi->mods_count > 1)
+ {
+ physmem.low = mod->mod_start;
+ physmem.high = mod->mod_end;
+ mod++;
+ }
+ }
+
+ /* Now protect ourselves and the mulitboot 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) - 1;
+ 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;
+
+ 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;
+ 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) > end)
+ end = (l4_word_t) str;
+ }
+ }
+ loader_add_region ("grub-mods-cmdlines", start, end);
+ }
+}
diff --git a/wortel/wortel.c b/wortel/wortel.c
index 246a11a..cc72381 100644
--- a/wortel/wortel.c
+++ b/wortel/wortel.c
@@ -27,6 +27,8 @@
/* The program name. */
char *program_name = "wortel";
+rootserver_t physmem;
+
/* Return the number of memory descriptors. */
l4_word_t
@@ -45,10 +47,178 @@ loader_get_memory_desc (l4_word_t nr)
}
-/* True if debug mode is enabled. */
-int debug;
+static void
+load_components (void)
+{
+ if (!physmem.low)
+ 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_remove_region ("physmem-mod");
+}
+
+
+static void
+start_components (void)
+{
+ l4_word_t ret;
+ l4_word_t control;
+ l4_msg_t msg;
+ l4_msg_tag_t msg_tag;
+ unsigned int io_map = 0;
+
+ /* 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);
+ /* 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.
+ This can also be used to actually create these threads up
+ front. */
+ ret = l4_thread_control (physmem_server, physmem_server, l4_myself (),
+ l4_nilthread, (void *) 0x2000000);
+ if (!ret)
+ panic ("Creation of initial physmem thread failed");
+
+ /* The UTCB area must be controllable in some way, see above. Same
+ for KIP area. */
+ ret = l4_space_control (physmem_server, 0,
+ l4_fpage_log2 (0x2400000, l4_kip_area_size_log2 ()),
+ l4_fpage_log2 (0x2000000, 14),
+ l4_anythread, &control);
+ if (!ret)
+ panic ("Creation of physmem address space failed");
+
+ ret = l4_thread_control (physmem_server, physmem_server, l4_nilthread,
+ l4_myself (), (void *) -1);
+ if (!ret)
+ panic ("Activation of initial physmem thread failed");
+
+ l4_msg_clear (&msg);
+ l4_set_msg_label (&msg, 0);
+ l4_msg_append_word (&msg, physmem.ip);
+ l4_msg_append_word (&msg, 0);
+ l4_msg_load (&msg);
+ msg_tag = l4_send (physmem_server);
+ if (l4_ipc_failed (msg_tag))
+ panic ("Sending startup message to physmemserver thread failed: %u",
+ l4_error_code ());
+
+ do
+ {
+ l4_word_t label;
+
+ msg_tag = l4_receive (physmem_server);
+ if (l4_ipc_failed (msg_tag))
+ panic ("Receiving messages from physmemserver thread failed: %u",
+ (l4_error_code () >> 1) & 0x7);
+
+ /* FIXME: Check sender, etc. */
+
+ label = l4_label (msg_tag);
+ l4_msg_store (msg_tag, &msg);
+ if ((label >> 4) == 0xffe)
+ {
+ l4_grant_item_t grant_item;
+ l4_fpage_t fpage;
+ l4_word_t addr;
+
+ /* This is a page fault. */
+ if (l4_untyped_words (msg_tag) != 2
+ || l4_typed_words (msg_tag) != 0)
+ panic ("Invalid format of page fault msg");
+
+ if (!io_map)
+ {
+ l4_map_item_t map_item;
+
+ /* FIXME: This is a hack. The first time we map the I/O
+ ports into the task. The kernel will repeat the page
+ fault. */
+ io_map = 1;
+
+ /* Now we can grant the mapping to the physmem server.
+ FIXME: Should use the fpage returned by sigma0. */
+ l4_msg_clear (&msg);
+ l4_set_msg_label (&msg, 0);
+ /* FIXME: Try to use largest fpage possible for the image.
+ Keep track of mappings already provided. Possibly map
+ text section rx and data rw. */
+ map_item = l4_map_item (l4_fpage_add_rights
+ (l4_io_fpage (0, 10),
+ l4_fully_accessible), 0);
+ l4_msg_append_map_item (&msg, map_item);
+ l4_msg_load (&msg);
+ l4_reply (physmem_server);
+ continue;
+ }
+
+ addr = l4_msg_word (&msg, 0) & ~((1 << 12) - 1);
+ fpage = l4_fpage_add_rights (l4_fpage_log2 (addr, 12),
+ l4_fully_accessible);
+ debug ("Serving Page Fault: %c%c%c at 0x%x (IP: 0x%x)\n",
+ label & 4 ? 'x' : '-', label & 2 ? 'w' : '-',
+ label & 1 ? 'r' : '-', addr,
+ l4_msg_word (&msg, 1));
+
+ /* 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. */
+ l4_msg_clear (&msg);
+ l4_set_msg_label (&msg, 0);
+ /* FIXME: Try to use largest fpage possible for the image.
+ Keep track of mappings already provided. Possibly map
+ text section rx and data rw. */
+ grant_item = l4_grant_item (fpage, addr);
+ l4_msg_append_grant_item (&msg, grant_item);
+ l4_msg_load (&msg);
+ }
+#define WORTEL_MSG_PUTCHAR 1
+ else if (label == WORTEL_MSG_PUTCHAR)
+ {
+ int chr;
+ /* This is a putchar() message. */
+ if (l4_untyped_words (msg_tag) != 1
+ || l4_typed_words (msg_tag) != 0)
+ panic ("Invalid format of putchar msg");
+ chr = (int) l4_msg_word (&msg, 0);
+ putchar (chr);
+ /* No reply needed. */
+ continue;
+ }
+ else
+ panic ("Invalid message with tag 0x%x", msg_tag);
+
+ l4_reply (physmem_server);
+ }
+ while (1);
+}
+
+
static void
parse_args (int argc, char *argv[])
{
@@ -126,7 +296,7 @@ parse_args (int argc, char *argv[])
else if (!strcmp (argv[i], "-D") || !strcmp (argv[i], "--debug"))
{
i++;
- debug = 1;
+ output_debug = 1;
}
else if (argv[i][0] == '-')
panic ("Unsupported option %s", argv[i]);
@@ -137,6 +307,78 @@ parse_args (int argc, char *argv[])
+#define STACK_SIZE 4096
+char exception_handler_stack[STACK_SIZE];
+
+void
+exception_handler (void)
+{
+ int count = 0;
+
+ while (count < 10)
+ {
+ l4_msg_tag_t tag;
+ l4_thread_id_t from;
+ l4_word_t mr[12];
+
+ tag = l4_wait (&from);
+ debug ("EXCEPTION HANDLER: Received message from: ");
+ debug ("0x%x", from);
+ debug ("\n");
+ debug ("Tag: 0x%x", tag.raw);
+ debug ("Label: %u Untyped: %u Typed: %u\n",
+ l4_label (tag), l4_untyped_words (tag), l4_typed_words (tag));
+
+ l4_store_mrs (1, 12, mr);
+ debug ("Succeeded: %u Propagated: %u Redirected: %u Xcpu: %u\n",
+ l4_ipc_succeeded (tag), l4_ipc_propagated (tag),
+ l4_ipc_redirected (tag), l4_ipc_xcpu (tag));
+ debug ("Error Code: 0x%x\n", l4_error_code ());
+ debug ("EIP: 0x%x EFLAGS: 0x%x Exception: %u ErrCode: %u\n",
+ mr[0], mr[1], mr[2], mr[3]);
+ debug ("EDI: 0x%x ESI: 0x%x EBP: 0x%x ESP: 0x%x\n",
+ mr[4], mr[5], mr[6], mr[7]);
+ debug ("EAX: 0x%x EBX: 0x%x ECX: 0x%x EDX: 0x%x\n",
+ mr[11], mr[8], mr[10], mr[9]);
+ }
+
+ debug ("EXCEPTION HANDLER: Too many exceptions.\n");
+
+ while (1)
+ l4_yield ();
+}
+
+
+static void
+setup (void)
+{
+ l4_thread_id_t thread;
+ l4_word_t result;
+ void *utcb;
+
+ /* FIXME: This is not specified by the standard. We don't know
+ where and how much space we have for other thread's UTCB
+ areas in the root server. */
+ utcb = (void *) ((l4_my_local_id ().raw & ~(l4_utcb_size () - 1))
+ + l4_utcb_size ());
+ thread = l4_global_id (l4_thread_no (l4_myself ()) + 1, 1);
+ debug ("Creating exception handler thread at utcb 0x%x: ",
+ (l4_word_t) utcb);
+ result = l4_thread_control (thread, l4_myself (), l4_myself (),
+ l4_global_id (l4_thread_no (l4_myself()) - 2, 1),
+ utcb);
+ debug ("%s\n", result ? "successful" : "failed");
+ /* Set the priority of the other thread to our priority. Otherwise
+ it is 100 and will never be scheduled as long as we are not in a
+ blocking receive. */
+ l4_set_priority (thread, 255);
+ l4_start_sp_ip (thread, ((l4_word_t) exception_handler_stack)
+ + sizeof (exception_handler_stack),
+ (l4_word_t) exception_handler);
+ l4_set_exception_handler (thread);
+}
+
+
int
main (int argc, char *argv[])
{
@@ -144,6 +386,14 @@ main (int argc, char *argv[])
debug ("%s " PACKAGE_VERSION "\n", program_name);
+ setup ();
+
+ find_components ();
+
+ load_components ();
+
+ start_components ();
+
while (1)
l4_yield ();
diff --git a/wortel/wortel.h b/wortel/wortel.h
index e576855..670ac7f 100644
--- a/wortel/wortel.h
+++ b/wortel/wortel.h
@@ -30,4 +30,16 @@ extern char *program_name;
#define BUG_ADDRESS "<bug-hurd@gnu.org>"
+
+typedef __l4_rootserver_t rootserver_t;
+
+/* 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;
+
+/* Find the kernel, the initial servers and the other information
+ required for booting. */
+void find_components (void);
+
int main (int argc, char *argv[]);