summaryrefslogtreecommitdiff
path: root/boot/boot.c
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1993-11-03 19:52:26 +0000
committerMichael I. Bushnell <mib@gnu.org>1993-11-03 19:52:26 +0000
commitc40087796e06f79c58365fb86e9f0c024a565759 (patch)
tree8ebd6929feb6dacad1e3889ef21c73bf7c37e66a /boot/boot.c
parent90a79b6fef204a7b0118a1368f9406aa3c775b37 (diff)
Initial revision
Diffstat (limited to 'boot/boot.c')
-rw-r--r--boot/boot.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/boot/boot.c b/boot/boot.c
new file mode 100644
index 00000000..e93d766c
--- /dev/null
+++ b/boot/boot.c
@@ -0,0 +1,130 @@
+/* Load a task using the single server, and then run it
+ as if we were the kernel. */
+ Copyright (C) 1993 Free Software Foundation
+
+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 the GNU Hurd; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by Michael I. Bushnell. */
+
+
+/* These will prevent the Hurd-ish versions from being used */
+
+#define task_by_pid(foo) syscall (-33, foo)
+#define myfork() syscall (2)
+#define execve(foo1, foo2, foo3) syscall (59, foo1, foo2, foo3)
+#define write(foo1, foo2, foo3) syscall (4, foo1, foo2, foo3)
+#define read(foo1, foo2, foo3) syscall (3, foo1, foo2, foo3)
+#define getpid() syscall (20)
+
+int
+main (int argc, char **argv, char **envp)
+{
+ task_t newtask;
+ thread_t newthread;
+ mach_port_t bootport;
+ vm_address_t startpc;
+
+ task_create (mach_task_self (), 0, &newtask);
+
+ startpc = load_image (newtask, argv[1]);
+
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &bootport);
+ mach_port_insert_right (mach_task_self (), bootport, bootport,
+ MACH_MSG_TYPE_MAKE_SEND);
+ task_set_bootstrap_port (newtask, bootport);
+ mach_port_deallocate (mach_task_self (), bootport);
+
+ thread_create (newtask, &newthread);
+ start_thread (newtask, newthread, startpc);
+
+ request_server ();
+}
+
+
+ mach_port_t boot, recset;
+ int parpid;
+ int otherpid;
+ int err;
+ int i;
+
+ err = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE,
+ &boot);
+
+ if (err)
+ write (1, "err1\n", 5);
+
+ device_master = task_by_pid (-2);
+
+ parpid = getpid ();
+
+ otherpid = myfork ();
+
+ write (1, "after fork\n", 11);
+ if (otherpid == -1)
+ {
+ write (1, "error!\n", 7);
+ /* perror ("fork"); */
+ exit (1);
+ }
+ else if (otherpid == parpid)
+ {
+ __mach_init ();
+ for (i = 0; i < 100000; i++);
+ write (1, "execing ", 8);
+ write (1, argv[1], strlen (argv[1]));
+ write (1, "\n", 1);
+ execve (argv[1], &argv[1], envp);
+ write (1, "exec failed\n", 12);
+ /* perror (argv[1]);*/
+ exit (1);
+ }
+ else
+ {
+ write (1, "parent?\n", 8);
+ err = mach_port_insert_right (mach_task_self (), boot, boot,
+ MACH_MSG_TYPE_MAKE_SEND);
+
+ if (err)
+ write (1, "err2\n", 5);
+ err = task_set_bootstrap_port (task_by_pid (otherpid), boot);
+ if (err)
+ write (1, "err3\n", 5);
+
+ write (1, "parent ", 7);
+ writenum (parpid);
+ write (1, "\nchild ", 7);
+ writenum (otherpid);
+ write (1, "\n", 1);
+
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_master);
+ mach_port_insert_right (mach_task_self (), pseudo_master,
+ pseudo_master, MACH_MSG_TYPE_MAKE_SEND);
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_console);
+ mach_port_insert_right (mach_task_self (), pseudo_console,
+ pseudo_console, MACH_MSG_TYPE_MAKE_SEND);
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
+ &recset);
+ mach_port_move_member (mach_task_self (), pseudo_master, recset);
+ mach_port_move_member (mach_task_self (), pseudo_console, recset);
+ mach_port_move_member (mach_task_self (), boot, recset);
+
+ mach_msg_server (my_server, 10000, recset);
+ }
+}