summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/boot.c443
1 files changed, 376 insertions, 67 deletions
diff --git a/boot/boot.c b/boot/boot.c
index e93d766c..95478f22 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -1,5 +1,5 @@
/* Load a task using the single server, and then run it
- as if we were the kernel. */
+ as if we were the kernel.
Copyright (C) 1993 Free Software Foundation
This file is part of the GNU Hurd.
@@ -20,6 +20,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Michael I. Bushnell. */
+#include <mach.h>
+#include <mach/notify.h>
+#include <errno.h>
+#include <device/device.h>
+
+#include "notify_S.h"
+#include "exec_S.h"
+#include "device_S.h"
+
/* These will prevent the Hurd-ish versions from being used */
@@ -30,101 +39,401 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define read(foo1, foo2, foo3) syscall (3, foo1, foo2, foo3)
#define getpid() syscall (20)
+mach_port_t privileged_host_port, master_device_port;
+mach_port_t pseudo_master_device_port;
+mach_port_t receive_set;
+mach_port_t pseudo_console;
+
+mach_port_t php_child_name, psmdp_child_name;
+
+task_t child_task;
+mach_port_t bootport;
+
+int
+request_server (mach_msg_header_t *inp,
+ mach_msg_header_t *outp)
+{
+ return (exec_server (inp, outp)
+ || device_server (inp, outp)
+ || notify_server (inp, outp));
+}
+
int
main (int argc, char **argv, char **envp)
{
task_t newtask;
thread_t newthread;
- mach_port_t bootport;
+ mach_port_t foo;
vm_address_t startpc;
+ privileged_host_port = task_by_pid (-1);
+ master_device_port = task_by_pid (-2);
+
task_create (mach_task_self (), 0, &newtask);
startpc = load_image (newtask, argv[1]);
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
+ &receive_set);
+
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_master_device_port);
+ mach_port_move_member (mach_task_self (), pseudo_master_device_port,
+ receive_set);
+
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_console);
+ mach_port_move_member (mach_task_self (), pseudo_console, receive_set);
+ 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_RECEIVE, &bootport);
+ mach_port_move_member (mach_task_self (), bootport, receive_set);
+
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);
+
+ mach_port_request_notification (mach_task_self (), newtask,
+ MACH_NOTIFY_DEAD_NAME, 1, bootport,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE, &foo);
+ if (foo)
+ mach_port_deallocate (mach_task_self (), foo);
+ child_task = newtask;
+
+ php_child_name = 100;
+ psmdp_child_name = 101;
+ mach_port_insert_right (newtask, php_child_name, privileged_host_port,
+ MACH_MSG_TYPE_COPY_SEND);
+ mach_port_insert_right (newtask, psmdp_child_name, pseudo_master_device_port,
+ MACH_MSG_TYPE_MAKE_SEND);
thread_create (newtask, &newthread);
start_thread (newtask, newthread, startpc);
- request_server ();
+ mach_msg_server (request_server, __vm_page_size * 2, receive_set);
}
+
+/* Implementation of exec interface */
- 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);
+S_exec_exec (
+ mach_port_t execserver,
+ mach_port_t file,
+ mach_port_t oldtask,
+ int flags,
+ data_t argv,
+ mach_msg_type_number_t argvCnt,
+ boolean_t argvSCopy,
+ data_t envp,
+ mach_msg_type_number_t envpCnt,
+ boolean_t envpSCopy,
+ portarray_t dtable,
+ mach_msg_type_number_t dtableCnt,
+ portarray_t portarray,
+ mach_msg_type_number_t portarrayCnt,
+ intarray_t intarray,
+ mach_msg_type_number_t intarrayCnt,
+ mach_port_array_t deallocnames,
+ mach_msg_type_number_t deallocnamesCnt,
+ mach_port_array_t destroynames,
+ mach_msg_type_number_t destroynamesCnt)
+{
+ return EOPNOTSUPP;
+}
- device_master = task_by_pid (-2);
+S_exec_init (
+ mach_port_t execserver,
+ auth_t auth_handle,
+ process_t proc_server)
+{
+ return EOPNOTSUPP;
+}
- parpid = getpid ();
+S_exec_setexecdata (
+ mach_port_t execserver,
+ portarray_t ports,
+ mach_msg_type_number_t portsCnt,
+ intarray_t ints,
+ mach_msg_type_number_t intsCnt)
+{
+ return EOPNOTSUPP;
+}
- 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);
- }
+error_t
+S_exec_startup (mach_port_t port,
+ u_int *base_addr,
+ vm_size_t *stack_size,
+ int *flags,
+ char **argvP,
+ u_int *argvlen,
+ char **envpP,
+ u_int *envplen,
+ mach_port_t **dtableP,
+ mach_msg_type_name_t *dtablepoly,
+ u_int *dtablelen,
+ mach_port_t **portarrayP,
+ mach_msg_type_name_t *portarraypoly,
+ u_int *portarraylen,
+ int **intarrayP,
+ u_int *intarraylen)
+{
+ mach_port_t *portarray, *dtable;
+ int *intarray, nc;
+ char argv[100];
+
+ /* The argv string has nulls in it; so we use %c for the nulls
+ and fill with constant zero. */
+ nc = sprintf (argv, "-x%c%d%c%d%c%s%c", '\0', php_child_name, '\0',
+ psmdp_child_name, "hd0a", '\0');
+
+ if (nc > *argvlen)
+ vm_allocate (mach_task_self (), (vm_address_t *)argvP, nc, 1);
else
+ bcopy (argv, *argvP, nc);
+ *argvlen = nc;
+
+ *base_addr = *stack_size = 0;
+
+ *flags = 0;
+
+ *argvlen = 0;
+
+ *envplen = 0;
+
+ if (*portarraylen < INIT_PORT_MAX)
+ vm_allocate (mach_task_self (), (u_int *)portarrayP,
+ (INIT_PORT_MAX * sizeof (mach_port_t)), 1);
+ portarray = *portarrayP;
+ *portarraylen = INIT_PORT_MAX;
+ *portarraypoly = MACH_MSG_TYPE_COPY_SEND;
+
+ *dtablelen = 0;
+ *dtablepoly = MACH_MSG_TYPE_COPY_SEND;
+
+ if (*intarraylen < INIT_INT_MAX)
+ vm_allocate (mach_task_self (), (u_int *)intarrayP,
+ (INIT_INT_MAX * sizeof (mach_port_t)), 1);
+ intarray = *intarrayP;
+ *intarraylen = INIT_INT_MAX;
+
+ bzero (portarray, INIT_PORT_MAX * sizeof (mach_port_t));
+ bzero (intarray, INIT_INT_MAX * sizeof (int));
+
+ return 0;
+}
+
+
+
+/* Implementation of device interface */
+
+ds_device_open (mach_port_t master_port,
+ mach_port_t reply_port,
+ mach_msg_type_name_t reply_type,
+ dev_mode_t mode,
+ dev_name_t name,
+ device_t *device)
+{
+ if (master_port != pseudo_master_device_port)
+ return D_INVALID_OPERATION;
+
+ if (!strcmp (name, "console"))
{
- 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);
+ *device = pseudo_console;
+ return 0;
}
+
+ return device_open (master_device_port, mode, name, device);
+}
+
+ds_device_close (device_t device)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+ return 0;
+}
+
+ds_device_write (device_t device,
+ mach_port_t reply_port,
+ mach_msg_type_name_t reply_type,
+ dev_mode_t mode,
+ recnum_t recnum,
+ io_buf_ptr_t data,
+ unsigned int datalen,
+ int *bytes_written)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+
+ *bytes_written = write (1, *data, datalen);
+
+ return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
}
+
+ds_device_write_inband (device_t device,
+ mach_port_t reply_port,
+ mach_msg_type_name_t reply_type,
+ dev_mode_t mode,
+ recnum_t recnum,
+ io_buf_ptr_inband_t data,
+ unsigned int datalen,
+ int *bytes_written)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+
+ *bytes_written = write (1, data, datalen);
+
+ return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+}
+
+ds_device_read (device_t device,
+ mach_port_t reply_port,
+ mach_msg_type_name_t reply_type,
+ dev_mode_t mode,
+ recnum_t recnum,
+ int bytes_wanted,
+ io_buf_ptr_t *data,
+ unsigned int *datalen)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+
+ vm_allocate (mach_task_self (), (pointer_t *)data, bytes_wanted, 1);
+ *datalen = read (0, *data, bytes_wanted);
+
+ return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+}
+
+ds_device_read_inband (device_t device,
+ mach_port_t reply_port,
+ mach_msg_type_name_t reply_type,
+ dev_mode_t mode,
+ recnum_t recnum,
+ int bytes_wanted,
+ io_buf_ptr_inband_t data,
+ unsigned int *datalen)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+
+ *datalen = read (0, data, bytes_wanted);
+
+ return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+}
+
+ds_xxx_device_set_status (device_t device,
+ dev_flavor_t flavor,
+ dev_status_t status,
+ u_int statu_cnt)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+ return D_INVALID_OPERATION;
+}
+
+ds_xxx_device_get_status (device_t device,
+ dev_flavor_t flavor,
+ dev_status_t status,
+ u_int *statuscnt)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+ return D_INVALID_OPERATION;
+}
+
+ds_xxx_device_set_filter (device_t device,
+ mach_port_t rec,
+ int pri,
+ filter_array_t filt,
+ unsigned int len)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+ return D_INVALID_OPERATION;
+}
+
+ds_device_map (device_t device,
+ vm_prot_t prot,
+ vm_offset_t offset,
+ vm_size_t size,
+ memory_object_t *pager,
+ int unmap)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+ return D_INVALID_OPERATION;
+}
+
+ds_device_set_status (device_t device,
+ dev_flavor_t flavor,
+ dev_status_t status,
+ unsigned int statuslen)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+ return D_INVALID_OPERATION;
+}
+
+ds_device_get_status (device_t device,
+ dev_flavor_t flavor,
+ dev_status_t status,
+ unsigned int *statuslen)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+ return D_INVALID_OPERATION;
+}
+
+ds_device_set_filter (device_t device,
+ mach_port_t receive_port,
+ int priority,
+ filter_array_t filter,
+ unsigned int filterlen)
+{
+ if (device != pseudo_console)
+ return D_NO_SUCH_DEVICE;
+ return D_INVALID_OPERATION;
+}
+
+
+/* Implementation of notify interface */
+do_mach_notify_port_deleted (mach_port_t notify,
+ mach_port_t name)
+{
+ return EOPNOTSUPP;
+}
+
+do_mach_notify_msg_accepted (mach_port_t notify,
+ mach_port_t name)
+{
+ return EOPNOTSUPP;
+}
+
+do_mach_notify_port_destroyed (mach_port_t notify,
+ mach_port_t port)
+{
+ return EOPNOTSUPP;
+}
+
+do_mach_notify_no_senders (mach_port_t notify,
+ mach_port_mscount_t mscount)
+{
+ return EOPNOTSUPP;
+}
+
+do_mach_notify_send_once (mach_port_t notify)
+{
+ return EOPNOTSUPP;
+}
+
+do_mach_notify_dead_name (mach_port_t notify,
+ mach_port_t name)
+{
+ if (name == child_task && notify == bootport)
+ exit ();
+}
+