aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/ChangeLog586
-rw-r--r--boot/Makefile15
-rw-r--r--boot/boot.c852
-rw-r--r--boot/boot_script.c199
-rw-r--r--boot/boot_script.h40
-rw-r--r--boot/tcattr.c592
-rw-r--r--boot/userland-boot.c108
7 files changed, 712 insertions, 1680 deletions
diff --git a/boot/ChangeLog b/boot/ChangeLog
deleted file mode 100644
index 19d13d51..00000000
--- a/boot/ChangeLog
+++ /dev/null
@@ -1,586 +0,0 @@
-Thu Aug 1 14:38:38 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
-
- * boot_script.h (safe_gets): Declare second parm as type `int'.
- * boot.c (safe_gets): Likewise.
-
-Sun Jul 7 21:10:08 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * boot.c (S_io_reauthenticate): Don't use unsafe MOVE_SEND in
- auth_server_authenticate.
-
-Fri May 10 16:11:49 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * boot.c (S_io_identity): Typo.
-
-Fri May 10 09:18:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * boot.c (S_io_identity): New function.
-
-Thu May 9 18:57:34 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * boot.c (S_io_select): No longer has TAG parm.
-
- * boot.c (S_io_reauthenticate): Use new interface.
-
-Sun Apr 28 22:50:38 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * boot.c (main): Use select instead of SIGIO.
-
-Mon Apr 15 12:57:29 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * Makefile (uxboot): Permit errors because people might not have
- the a.out-mach3 target installed, and that's OK for many users.
-
- * Makefile (uxboot.0): Find frank1.ld in #(srcdir).
-
- * boot_script.h (safe_gets): Add decl.
- * boot_script.c: Include <stdio.h>.
-
-Wed Apr 3 18:54:22 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * ux.c (printf): Add %d.
-
-Wed Mar 27 11:30:29 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * boot.c [notanymore] (S_tioctl_tiocgeta, S_tioctl_tiocseta,
- S_tioctl_tiocsetaf, term_modes, term_ccs, term_speeds):
- Functions & variables removed.
- * Makefile (COMMON-OBJS): Remove tcattr.o.
- (SRCS): Remove tcattr.c.
-
-Thu Mar 14 10:10:20 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
-
- * Makefile (boot): Depend on libthreads.so, nothing wrong with shared
- libs.
- (uxboot.0, uxboot.1): Use automatic vars in cmds instead of gratuitous
- redundancy.
- (LDFLAGS-uxboot.0): Remove useless indirection through variable.
-
-Wed Feb 14 16:50:05 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * boot.c [!UX]
- (orig_tty_state): New variable.
- (init_termstate, restore_termstate): New hurd versions of these funcs.
- * ux.c (init_termstate, restore_termstate, term_sgb, localbits):
- Moved here from boot.c
-
-Tue Feb 13 18:49:26 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * boot.c (load_image, boot_script_read_file, main): Use O_RDONLY,
- not 0 (kind of ironic, this...).
- (load_image): Give the filename with the error message (and a newline).
-
- * ux.h (O_RDONLY, O_WRONLY, O_RDWR): New macros.
-
- * ux.c, ux.h: New files.
- * boot.c: Move all the ux-specific grot into ux.c & ux.h.
- If UX is defined, include "ux.h", else define hurdish stuff.
- (main): Use get_privileged_ports instead of task_by_pid.
- (load_image, boot_script_read_file, main, do_mach_notify_no_senders,
- do_mach_notify_dead_name): Use host_exit instead of uxexit.
- (boot_script_read_file): Use host_stat instead of uxstat.
- (init_termstate, S_tioctl_tiocseta): Use sg_flags fld in struct sgttyb.
-
- * Makefile (all): Depend on `boot' and `uxboot'.
- (COMMON-OBJS, UX-OBJS): New macros.
- (OBJS): Inherit most names from $(COMMON-OBJS).
- (LCLHDRS): Add ux.h.
- (LDFLAGS): Use target-specific value.
- (uxboot.0-LDFLAGS): New macro (with contents from old LDFLAGS).
- (uxboot.o, uxboot.0): New targets.
- (uxboot): Target renamed from boot.a.
-
-Sun Dec 10 18:05:14 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * boot.c (read_reply): Don't call clear_should_read(), just do
- things ourselves.
- (should_read_lock): Variable deleted.
- (service_sigio): Function deleted.
- (main): Use read_reply to service SIGIO again, not service_sigio.
-
- * boot.c (service_sigio): New function, replacing set_should_read.
- Calls read_reply() itself too.
- (unlock_readlock): New function.
- (ds_device_read, ds_device_read_inband, S_io_read): Call
- unlock_readlock instead of directly unlocking READLOCK.
- (request_server, main): Don't call read_reply() anymore.
-
- * boot.c (should_read): New variable.
- (main): SIGIO uses set_should_read instead of read_reply.
- Call read_reply() after sigpause() returns.
- (read_reply): Call clear_should_read(), and don't do anything if
- SHOULD_READ wasn't set.
- (set_should_read): New function.
- (clear_should_read): New function.
- (request_server): Call read_reply() before returning.
-
-Sat Dec 9 19:01:10 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * boot.c (S_io_read, ds_device_read_inband, ds_device_read): Don't
- block SIGIO.
- (main): Don't trap SIGMSG & SIGEMSG.
-
-Mon Dec 4 23:54:18 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c (main): Request no-senders notification on
- pseudo_master_device_port.
- Deallocate our send right to it when we no longer need it.
- (do_mach_notify_no_senders): Exit only when both pseudo_console and
- pseudo_master_device_port have no senders.
- (ds_device_read_inband): Unlock readlock properly.
-
-Thu Nov 30 15:58:47 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * boot.c (readlock): New variable.
- (read_reply): Check FIONREAD before dequeueing QR so that we don't
- abandon requests. Lock READLOCK around FIONREAD/read pair.
- (ds_device_read): Lock READLOCK around FIONREAD/read pair.
- (ds_device_read_inband): Likewise.
- (S_io_read): Likewise.
-
-Nov 22 16:25:01 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c (request_server): Don't call exec_server.
- (S_exec_*): Functions removed.
- (boot_script_task_port): Variable removed.
- (boot_script_task_*, boot_script_port_*): Functions removed.
-
-Tue Nov 14 12:07:24 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * Makefile (OBJS): Remove execServer.o.
-
-Thu Sep 28 14:47:46 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot_script.c (read_file): Pass CMD->path for file name.
- (CHECK_CMDLINE_LEN): Update ARGV pointers after reallocating the line
- buffer.
-
-Wed Sep 27 14:01:03 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c (struct uxstat): New type.
- (uxfstat): Renamed from fstat; use struct uxstat * for arg.
- (boot_script_read_file): Use those.
- Return the memory object port, not zero.
-
- * boot.c (fstat): New syscall function.
-
- * boot_script.c (read_file): New function.
- (builtin_symbols): Add $(read-file) builtin.
- * boot_script.h (boot_script_read_file): Declare it.
- * boot.c (close): New syscall function.
- (defpager): New variable.
- (main): Set it up.
- (boot_script_read_file): New function.
- (useropen_dir): New variable.
- (useropen): New function.
- (load_image): Call it instead of open.
- (main): Grok -D arg to set useropen_dir.
-
-Sat Sep 23 00:53:51 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * syscall.S: Restore entry SP before return.
-
- * boot.c (main): Use static const for constant strings.
- On boot script error, write script line with error msg.
-
- * boot_script.c (boot_script_parse_line): Ignore line beginning
- with #.
-
- * boot.c (S_io_pathconf): New function.
-
- * Makefile (LDFLAGS): Add -static.
-
-Fri Sep 22 14:14:23 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * mach-crt0.c (__data_start): New variable.
-
-Tue Aug 29 10:41:29 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu>
-
- * boot.c (mig_dealloc_reply_port): Remove __ from call to
- mach_port_mod_refs.
- (main): Look for -d in bootstrap_args, not (nonexistent)
- boot_args. Remove `const' keyword from decl of MSG.
-
- * boot.c (sigblock, sigsetmask): New functions.
- (sigmask): New macro.
- (ds_device_read): Block SIGIO around critical section.
- (ds_device_read_inband): Likewise.
- (S_io_read): Likewise.
-
-Mon Aug 28 17:16:48 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot_script.h, boot_script.c: Updated by Shantanu Goel, to
- accept action keywords only inside $(...) and only variable values
- inside ${...}.
- * boot.c: Updated for changes in boot_script.h protocol by
- Shantanu Goel.
- (main): Use boot_script_set_variable instead of magic variables.
- Under -d, pause between parsing bootscript and executing it.
-
-Wed Aug 23 16:08:04 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- New script-driven boot mechanism, mostly implemented by Shantanu Goel.
- * Makefile (SRCS): Add boot_script.c.
- (OBJS): Add boot_script.o.
- (LCLHDRS): New variable.
- (HURDLIBS): Variable removed.
- (boot): Depend on ../libthreads/libthreads.a.
- * boot_script.c, boot_script.h: New files.
- * boot.c (boot_like_kernel, boot_like_cmudef, boot_like_hurd):
- Variables removed.
- (main): Don't interpret switches. Instead of servers, take
- command line argument of boot script file name. Read the file and
- use boot_script functions to parse and execute its directives.
- (boot_script_*): New variables and functions for boot_script callbacks.
-
-Sun Jul 30 23:50:53 1995 Michael I. Bushnell, p/BSG <mib@geech.gnu.ai.mit.edu>
-
- * Makefile: DISTFILES -> DIST_FILES.
-
-Sat Jul 8 11:37:32 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * boot.c (free_reply_ports, free_reply_ports_lock): New variables.
- (__mig_get_reply_port, __mig_put_reply_port, __mig_dealloc_reply_port,
- mig_get_reply_port, mig_put_reply_port, mig_dealloc_reply_port):
- Provide better versions of these routines that won't leak reply ports.
-
-Fri Jul 7 15:55:18 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * mach-crt0.c: New file, from mach4-i386/libmach/standalone.
- * boot.c (mach_init_routine): New variable, wanted by mach-crt0.o.
- (__mig_get_reply_port, __mig_dealloc_reply_port, __mig_put_reply_port):
- New functions, to avoid using hurdish versions.
- * Makefile (OBJS): Add mach-crt0.o.
- (SRCS): Add mach-crt0.c.
- (LDFLAGS): Add -nostartfiles (as we now use mach-crt0.o).
-
-Thu Jul 6 15:30:18 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * Makefile (boot.1, boot.a): Use $(LD) and $(OBJCOPY) instead of
- explicit names.
-
- * boot.c: Include <mach/mig_support.h>.
- (S_io_reauthenticate): Cast first arg to mig_deallocate.
- (load_image): Cast second arg to read.
- * tcattr.c: Undo last change; add private decl of ioctl.
-
- * boot.c (bootdevice): Initialize to hard-coded `sd0a' instead of
- DEFAULT_BOOTDEVICE.
-
- * Makefile (all): Depend on boot.a too.
-
- * Makefile: Removed dependencies that are now automatically
- generated.
-
-Wed May 31 10:02:11 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * Makefile (DISTFILES): New variable; include frank1.ld and
- frankemul.ld.
- (CPPFLAGS): Variable removed.
- (LDFLAGS): Append -T frank1.ld.
- (boot.1, boot.a): New targets.
-
- * syscall.S: Omit .globl decl for errno; it caused some as
- complaint.
-
-Mon May 22 11:48:58 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * sigvec.S: Remove copyright notice.
-
-Wed May 17 13:10:27 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * boot.c (load_image): Make sure we actually allocate enough
- memory to read into, including the offset into the buffer at which
- the segment is read.
-
- * sigvec.S (sigreturn, _sigreturn, sigvec): Remove the explicit
- underscore prefixes from these names, now that we're using elf.
- Instead we use the various macros from <i386/asm.h>. Also, return
- errors correctly. [Also added a copyright notice]
-
-Sat May 13 03:37:24 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c (load_image): Fixed alignment calculation in ELF segment
- loading.
-
- * syscall.S: Include i386/asm.h and use ENTRY and EXT macros,
- instead of explicit _s.
-
-Fri May 12 18:36:39 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c (load_image): Grok ELF executables as well as a.out.
- (main): Load multiple servers. Suspend all but the first.
- The first gets an extra arg, its name for the task port of the
- second.
-
-Wed Apr 12 09:18:50 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * Makefile: Don't try and install boot in /usr/local/bin.
-
-Wed Apr 5 17:25:19 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c: Don't include <errno.h>. Define `errno' variable.
- * Makefile (SRCS): Add syscall.S.
- (OBJS): Add syscall.o.
- * syscall.S: Check for errors.
-
-Thu Jan 19 01:21:24 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c (S_io_select): Updated to new io_select protocol.
-
-Fri Dec 9 01:23:22 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c: Use mach_msg_type_number_t in place of unsigned int and
- int.
-
-Fri Nov 11 14:05:43 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * boot.c (main): Always set `f' flag (signifying "fake" because we
- aren't a real native bootstrap).
-
-Thu Nov 3 17:26:37 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * Makefile (boot.o): Depend on bootstrap_S.h.
-
-Fri Oct 28 17:08:12 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * boot.c (main): Create the thread before setting it up.
- (bootstrap_compat): Make a send right for psuedo_master_device_port.
- (main): Explicitly clear NEWTASK's bootstrap port for boot_like_kernel.
- (main): Format strings for port names for boot_like_kernel.
-
-Fri Oct 28 15:26:48 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
-
- * boot.c (boot_like_kernel, boot_like_cmudef, boot_like_hurd): New
- global vars.
- (set_mach_stack_args): New function.
- (main): If the -k flag is given, set BOOT_LIKE_KERNEL.
- If the -p flag is given, set BOOT_LIKE_CMUDEF. If neither is
- given, set BOOT_LIKE_HURD.
- Only set a bootstrap port if BOOT_LIKE_CMUDEF or BOOT_LIKE_HURD.
- If BOOT_LIKE_KERNEL or BOOT_LIKE_CMUDEF, set up the stack the
- Mach way using set_mach_stack_args.
- (request_server): Declare and call bootstrap_server.
- (do_bootstrap_priveleged_ports, bootstrap_compat): New functions.
- * Makefile (OBJS): Require bootstrapServer.o.
- * bootstrap.defs: New file.
-
-Tue Aug 30 11:41:33 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * boot.c (S_io_reauthenticate): Use new authentication protocol.
-
-Mon Aug 22 13:43:32 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * boot.c: Include <cthreads.h>.
- (main): Run msg_thread fork; don't call
- mach_msg_server_timeout here. Use sigpause instead of getpid.
- (msg_thread): New function.
- (queuelock): New variable.
- (queue_read): Acquire queuelock.
- (read_reply): Acquire queuelock.
- * Makefile (HURDLIBS): New var to get threads.
-
-Thu Aug 18 18:04:36 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * boot.c (restore_termstate): New function.
- (do_mach_notify_no_senders): Call restore_termstate before exiting.
-
- * boot.c (main): New var `usagemsg'; print it if args are wrong.
- Allow flags and disk device to be given on command line.
- New var `bootfile'.
- (bootdevice, bootstrap_args): New vars.
- (load_image): Exit nicely if the startup file can't be found.
- (S_exec_startup): Use `bootdevice' instead of hardcoded name.
- Use `bootstrap_args' instead of hardcoded "-x".
- (main): Only do `pausing' hack if -d was provided.
-
- * Makefile (CPPFLAGS): Define DEFAULT_BOOTDEVICE.
-
- * Makefile (/usr/local/bin/boot): Depend on boot.
-
- * boot.c (S_termctty_open_terminal): New "function".
- (S_io_select): Added `rettype' arg.
-
-Sat Jul 23 02:58:05 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * Makefile (io-MIGSFLAGS): Renamed from ioMIGSFLAGS.
-
-Fri Jul 22 15:10:45 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * boot.c (request_server): Remove S_ from io_server and
- term_server.
-
-Thu Jul 21 19:00:36 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * Makefile: Rewritten to use new scheme.
- * boot.c: Include io_reply_U.h and device_reply_U.h instead
- of io_repl.h and device_reply.h.
-
-Wed Jul 20 13:19:45 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * boot.c: Comment out bits relating to tioctl interface.
- * Makefile: Likewise.
-
-Tue Jul 19 12:41:46 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * Makefile (boot): Don't use variable $(link) anymore.
-
-Tue Jul 5 14:19:36 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * Makefile (SRCS): New variable.
-
-Sun Jul 3 17:20:07 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * tcattr.c: New file.
- * boot.c (S_tioctl_tiocgeta): Call tcgetattr.
- (S_tioctl_tiocseta): Call tcsetattr.
- * Makefile (OBJS): Add tcattr.o.
- (DIST_FILES): Add tcattr.c.
-
-Fri Jul 1 11:16:27 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * boot.c (init_termstate): Enter raw mode here.
-
-Fri Jun 24 14:27:56 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * boot.c (S_term_open_ctty): Renamed from term_become_ctty.
- Deleted SIGPT arg. Add msg type arg for NEWTTY.
-
-Fri Jun 17 13:46:07 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * boot.c (request_server): Remove S_ prefix from exec_server
- and notify_server.
-
-Fri Jun 17 00:12:16 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu)
-
- * Makefile (boot.o): Depend on term_S.h.
-
-Tue Jun 14 01:28:10 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu)
-
- * boot.c (request_server): Add S_ prefix to demuxer functions.
-
-Wed Jun 8 18:02:19 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu)
-
- * boot.c (S_tioctl_tiocseta): Turn off ECHO.
- (S_io_select): Implement.
-
-Tue Jun 7 04:33:42 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu)
-
- * Makefile (tioctlServer.o): Depend on ../hurd/ioctl_types.h.
-
-Mon Jun 6 20:33:39 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu)
-
- * boot.c (authserver): New variable.
- (S_io_reauthenticate): Do auth_server_authenticate and throw away
- the returned info.
- (S_exec_init): Set authserver to the passed port.
-
-Sat Jun 4 02:32:03 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu)
-
- * boot.c: Include term_S.h and tioctl_S.h.
- (S_term_getctty): New function.
- (S_term_*): Stub functions.
- (request_server): Use S_term_server.
-
- * Makefile (termServer.c term_S.h): New rule.
- (OBJS): Add termServer.o.
-
- * boot.c (S_exec_setexecdata, S_exec_exec): Fix prototypes.
-
-Tue May 17 18:44:29 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * boot.c (ds_device_write): DATA arg is char *; don't dereference
- it in call to write.
-
-Mon May 16 14:34:15 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * boot.c (fsname): New variable.
- (main): Set fsname to argv[1].
- (S_exec_startup): Include fsname in child's argv[0].
-
- * boot.c (init_termstate): Add forward declaration.
- (struct sigvec): Make SV_HANDLER member void (*)().
- (sigvec): Add declaration to avoid warning.
-
-Tue May 10 18:14:39 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * boot.c (tioctl_tiocseta, tioctl_tiocsetw, tioctl_tiocsetf,
- tioctl_tiocgeta, init_termstate): New functions.
- (term_modes, term_ccs, term_speeds, term_sgb, localbits): Nev
- vars.
- Also added new bits from ioctl.h.
- (main): Call init_termstate.
- (request_server): Call tioctl_server.
- * Makefile (tioctlServer.c tioctl_S.h): New targets.
- (OBJS): Include tioctlServer.o.
- (boot.o): Depend on tioctl_S.h
-
-Fri May 6 13:56:58 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * boot.c (main): Restore braindamage of yesterday relating to
- signals; that is, restore declaration of VEC and calls to sigvec.
- * Makefile (DIST_FILES): Add sigvec.S.
-
-Thu May 5 13:16:42 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * Makefile (device_replyUser.c): Mention that this build
- device_reply.h as well.
- (boot.o): Add dependency on device_reply.h and io_repl.h.
-
- * boot.c: Include <stdlib.h> for malloc and free prototypes.
- Include <string.h> for bcopy and bzero prototypes.
- Include <stdio.h> for sprintf prototype.
- Include "device_reply.h" for its prototypes.
- Include "io_reply.h" for its prototypes.
- Declare return type for all the server functions that were lacking
- such.
- (sigpause): Declare type of MASK.
- (ioctl): Declare third arg to be generic pointer, not char *.
- (request_server): Declare MiG functions we call.
- (load_image): Delete unused variable STACKADDR.
- (main): Comment out declaration of VEC.
- Comment out calls to sigvec.
- Cast STARTPC in call to __mach_setup_thread.
- Delete unused variable TIMEOUT.
- (read_reply): Cast BUF correctly in call to ds_device_read_reply.
- (S_exec_startup): Delete unused variable DTABLE.
- (ds_device_write): Double cast arg to write to avoid warning.
- (S_io_read): Order args to vm_allocate properly; cast DATA arg.
- Check *datalen properly for unsigned type.
-
- * boot.c: Renamed _exit to uxexit to avoid library name clash.
- (do_mach_notify_dead_name, do_mach_notify_no_senders):
- Call uxexit instead of _exit.
-
- * boot.c (S_io_async, S_io_get_icky_async_id, S_io_map_cntl):
- Expect new type arg for returned port.
- (S_io_prenotify, S_io_postnotify): START and END args are now
- vm_offset_t.
-
- * boot.c: Change error_t to kern_return_t because error_t
- is now unsigned and conflicts with MiG's use of kern_return_t.
-
- * Makefile (io_S.h, ioServer.c): Punt mungio hack; use
- -DREPLY_PORTS.
- * boot.c: Changed all io server stubs to expect reply ports.
-
- * mungio: removed file.
- * Makefile (DIST_FILES): Removed mungio.
-
- * boot.c (load_image): Only read from the image file the actual
- amount being read, not that amount rounded to the nearest page.
- Otherwise, the first bit of the BSS will not be zero, but will be
- whatever is in the front of the symbol section of the a.out.
-
-Thu May 5 07:43:06 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * Makefile: Change uses of $(headers) to $(includedir).
-
-Mon May 2 16:47:49 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * boot.c (S_io_readable): Implement io_readable fully.
-
-Fri Apr 1 17:55:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * Makefile (OBJS): Remove boot_machdep.o.
-
diff --git a/boot/Makefile b/boot/Makefile
index 30838e5d..6c787cfd 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+# Copyright (C) 1993,94,95,96,97,2001 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
@@ -18,16 +18,18 @@
dir := boot
makemode := utility
-SRCS = mach-crt0.c boot.c ux.c sigvec.S syscall.S boot_script.c
+SRCS = mach-crt0.c boot.c ux.c sigvec.S syscall.S \
+ boot_script.c userland-boot.c
COMMON-OBJS = notifyServer.o ourdeviceServer.o \
ioServer.o io_replyUser.o device_replyUser.o \
- termServer.o bootstrapServer.o boot_script.o
+ termServer.o bootstrapServer.o boot_script.o userland-boot.o
OBJS = boot.o $(COMMON-OBJS)
UX-OBJS = mach-crt0.o uxboot.o sigvec.o syscall.o ux.o $(COMMON-OBJS)
LCLHDRS = boot_script.h ux.h
target = boot
io-MIGSFLAGS=-DREPLY_PORTS
DIST_FILES=frank1.ld frankemul.ld
+HURDLIBS=store shouldbeinlibc threads
include ../Makeconf
@@ -36,12 +38,11 @@ include ../Makeconf
#/usr/local/bin/uxboot: uxboot
# cp $< $@
-all: boot uxboot
+all: boot # uxboot
-ourdevice.defs: $(includedir)/device/device.defs
- sed -e '/out device : device_t/s/device_t/mach_port_send_t/' $< > $@
+ourdevice.defs: device.defs
+ $(CPP) $(CPPFLAGS) -x c $< | sed -e '/out[ ]*device[ ]*:[ ]*device_t/s/device_t/mach_port_send_t/' > $@
-boot: ../libthreads/libthreads.so
uxboot.o: boot.c
$(COMPILE.c) -DUX $< -o $@
diff --git a/boot/boot.c b/boot/boot.c
index dcf3bccc..2b143844 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -1,6 +1,7 @@
/* Load a task using the single server, and then run it
as if we were the kernel.
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,2006
+ Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -30,14 +31,16 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include <stdio.h>
#include <cthreads.h>
-#include <varargs.h>
-#include <fcntlbits.h>
+#include <fcntl.h>
#include <elf.h>
#include <mach/mig_support.h>
#include <mach/default_pager.h>
+#include <argp.h>
+#include <hurd/store.h>
+#include <sys/mman.h>
+#include <version.h>
#include "notify_S.h"
-#include "exec_S.h"
#include "ourdevice_S.h"
#include "io_S.h"
#include "device_reply_U.h"
@@ -51,6 +54,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <hurd/auth.h>
#ifdef UX
+#undef STORE /* We can't use libstore when under UX. */
+#else
+#define STORE
+#endif
+
+#ifdef UX
#include "ux.h"
@@ -64,8 +73,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <termios.h>
#include <error.h>
#include <hurd.h>
+#include <assert.h>
static struct termios orig_tty_state;
+static int isig;
+static char *kernel_command_line;
static void
init_termstate ()
@@ -77,6 +89,8 @@ init_termstate ()
orig_tty_state = tty_state;
cfmakeraw (&tty_state);
+ if (isig)
+ tty_state.c_lflag |= ISIG;
if (tcsetattr (0, 0, &tty_state) < 0)
error (11, errno, "tcsetattr");
@@ -97,9 +111,11 @@ typedef struct stat host_stat_t;
mach_port_t privileged_host_port, master_device_port, defpager;
mach_port_t pseudo_master_device_port;
mach_port_t receive_set;
-mach_port_t pseudo_console;
+mach_port_t pseudo_console, pseudo_root;
auth_t authserver;
+struct store *root_store;
+
spin_lock_t queuelock = SPIN_LOCK_INITIALIZER;
spin_lock_t readlock = SPIN_LOCK_INITIALIZER;
@@ -118,10 +134,10 @@ void restore_termstate ();
char *fsname;
-char *bootstrap_args;
-char *bootdevice = "sd0a";
+char bootstrap_args[100] = "-";
+char *bootdevice = 0;
+char *bootscript = 0;
-void set_mach_stack_args ();
void safe_gets (char *buf, int buf_len)
{
@@ -219,7 +235,8 @@ load_image (task_t t,
vm_size_t offs = ph->p_offset & (ph->p_align - 1);
vm_size_t bufsz = round_page (ph->p_filesz + offs);
- vm_allocate (mach_task_self (), &buf, bufsz, 1);
+ buf = (vm_address_t) mmap (0, bufsz,
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
lseek (fd, ph->p_offset, SEEK_SET);
read (fd, (void *)(buf + offs), ph->p_filesz);
@@ -231,7 +248,7 @@ load_image (task_t t,
vm_allocate (t, (vm_address_t*)&ph->p_vaddr, ph->p_memsz, 0);
vm_write (t, ph->p_vaddr, buf, bufsz);
- vm_deallocate (mach_task_self (), buf, bufsz);
+ munmap ((caddr_t) buf, bufsz);
vm_protect (t, ph->p_vaddr, ph->p_memsz, 0,
((ph->p_flags & PF_R) ? VM_PROT_READ : 0) |
((ph->p_flags & PF_W) ? VM_PROT_WRITE : 0) |
@@ -253,15 +270,15 @@ load_image (task_t t,
amount = headercruft + hdr.a.a_text + hdr.a.a_data;
rndamount = round_page (amount);
- vm_allocate (mach_task_self (), (u_int *)&buf, rndamount, 1);
+ buf = mmap (0, rndamount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
lseek (fd, sizeof hdr.a - headercruft, SEEK_SET);
read (fd, buf, amount);
vm_allocate (t, &base, rndamount, 0);
- vm_write (t, base, (u_int) buf, rndamount);
+ vm_write (t, base, (vm_address_t) buf, rndamount);
if (magic != OMAGIC)
vm_protect (t, base, trunc_page (headercruft + hdr.a.a_text),
0, VM_PROT_READ | VM_PROT_EXECUTE);
- vm_deallocate (mach_task_self (), (u_int)buf, rndamount);
+ munmap ((caddr_t) buf, rndamount);
bssstart = base + hdr.a.a_text + hdr.a.a_data + headercruft;
bsspagestart = round_page (bssstart);
@@ -278,18 +295,6 @@ void msg_thread ();
/* Callbacks for boot_script.c; see boot_script.h. */
-void *
-boot_script_malloc (int size)
-{
- return malloc (size);
-}
-
-void
-boot_script_free (void *ptr, int size)
-{
- free (ptr);
-}
-
mach_port_t
boot_script_read_file (const char *filename)
{
@@ -324,116 +329,243 @@ boot_script_read_file (const char *filename)
vm_map (mach_task_self (), &region, round_page (st.st_size),
0, 1, memobj, 0, 0, VM_PROT_ALL, VM_PROT_ALL, VM_INHERIT_NONE);
read (fd, (char *) region, st.st_size);
- vm_deallocate (mach_task_self (), region, round_page (st.st_size));
+ munmap ((caddr_t) region, round_page (st.st_size));
close (fd);
return memobj;
}
int
-boot_script_exec_cmd (mach_port_t task, char *path, int argc,
+boot_script_exec_cmd (void *hook,
+ mach_port_t task, char *path, int argc,
char **argv, char *strings, int stringlen)
{
char *args, *p;
int arg_len, i;
- unsigned reg_size;
+ size_t reg_size;
void *arg_pos;
vm_offset_t stack_start, stack_end;
vm_address_t startpc, str_start;
thread_t thread;
- struct i386_thread_state regs;
write (2, path, strlen (path));
+ for (i = 1; i < argc; ++i)
+ {
+ write (2, " ", 1);
+ write (2, argv[i], strlen (argv[i]));
+ }
write (2, "\r\n", 2);
startpc = load_image (task, path);
- thread_create (task, &thread);
arg_len = stringlen + (argc + 2) * sizeof (char *) + sizeof (integer_t);
arg_len += 5 * sizeof (int);
stack_end = VM_MAX_ADDRESS;
stack_start = VM_MAX_ADDRESS - 16 * 1024 * 1024;
vm_allocate (task, &stack_start, stack_end - stack_start, FALSE);
- reg_size = i386_THREAD_STATE_COUNT;
- thread_get_state (thread, i386_THREAD_STATE,
- (thread_state_t) &regs, &reg_size);
- regs.eip = (int) startpc;
- regs.uesp = (int) ((stack_end - arg_len) & ~(sizeof (int) - 1));
- thread_set_state (thread, i386_THREAD_STATE,
- (thread_state_t) &regs, reg_size);
- arg_pos = (void *) regs.uesp;
- vm_allocate (mach_task_self (), (vm_address_t *) &args,
- stack_end - trunc_page ((vm_offset_t) arg_pos), TRUE);
+ arg_pos = (void *) ((stack_end - arg_len) & ~(sizeof (natural_t) - 1));
+ args = mmap (0, stack_end - trunc_page ((vm_offset_t) arg_pos),
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
str_start = ((vm_address_t) arg_pos
+ (argc + 2) * sizeof (char *) + sizeof (integer_t));
p = args + ((vm_address_t) arg_pos & (vm_page_size - 1));
- *((int *) p)++ = argc;
+ *(int *) p = argc;
+ p = (void *) p + sizeof (int);
for (i = 0; i < argc; i++)
- *((char **) p)++ = argv[i] - strings + (char *) str_start;
- *((char **) p)++ = 0;
- *((char **) p)++ = 0;
+ {
+ *(char **) p = argv[i] - strings + (char *) str_start;
+ p = (void *) p + sizeof (char *);
+ }
+ *(char **) p = 0;
+ p = (void *) p + sizeof (char *);
+ *(char **) p = 0;
+ p = (void *) p + sizeof (char *);
memcpy (p, strings, stringlen);
bzero (args, (vm_offset_t) arg_pos & (vm_page_size - 1));
vm_write (task, trunc_page ((vm_offset_t) arg_pos), (vm_address_t) args,
stack_end - trunc_page ((vm_offset_t) arg_pos));
- vm_deallocate (mach_task_self (), (vm_address_t) args,
- stack_end - trunc_page ((vm_offset_t) arg_pos));
+ munmap ((caddr_t) args,
+ stack_end - trunc_page ((vm_offset_t) arg_pos));
+
+ thread_create (task, &thread);
+#ifdef i386_THREAD_STATE_COUNT
+ {
+ struct i386_thread_state regs;
+ reg_size = i386_THREAD_STATE_COUNT;
+ thread_get_state (thread, i386_THREAD_STATE,
+ (thread_state_t) &regs, &reg_size);
+ regs.eip = (int) startpc;
+ regs.uesp = (int) arg_pos;
+ thread_set_state (thread, i386_THREAD_STATE,
+ (thread_state_t) &regs, reg_size);
+ }
+#elif defined(ALPHA_THREAD_STATE_COUNT)
+ {
+ struct alpha_thread_state regs;
+ reg_size = ALPHA_THREAD_STATE_COUNT;
+ thread_get_state (thread, ALPHA_THREAD_STATE,
+ (thread_state_t) &regs, &reg_size);
+ regs.r30 = (natural_t) arg_pos;
+ regs.pc = (natural_t) startpc;
+ thread_set_state (thread, ALPHA_THREAD_STATE,
+ (thread_state_t) &regs, reg_size);
+ }
+#else
+# error needs to be ported
+#endif
+
thread_resume (thread);
mach_port_deallocate (mach_task_self (), thread);
return 0;
}
+const char *argp_program_version = STANDARD_HURD_VERSION (boot);
+
+static struct argp_option options[] =
+{
+ { "boot-root", 'D', "DIR", 0,
+ "Root of a directory tree in which to find files specified in BOOT-SCRIPT" },
+ { "single-user", 's', 0, 0,
+ "Boot in single user mode" },
+ { "kernel-command-line", 'c', "COMMAND LINE", 0,
+ "Simulated multiboot command line to supply" },
+ { "pause" , 'd', 0, 0,
+ "Pause for user confirmation at various times during booting" },
+ { "isig", 'I', 0, 0,
+ "Do not disable terminal signals, so you can suspend and interrupt boot."},
+ { "device", 'f', "device_name=device_file", 0,
+ "Specify a device file used by subhurd and its virtual name."},
+ { 0 }
+};
+static char args_doc[] = "BOOT-SCRIPT";
+static char doc[] = "Boot a second hurd";
+
+struct dev_map
+{
+ char *name;
+ mach_port_t port;
+ struct dev_map *next;
+};
+
+static struct dev_map *dev_map_head;
+
+static struct dev_map *add_dev_map (char *dev_name, char *dev_file)
+{
+ struct dev_map *map = malloc (sizeof (*map));
+
+ assert (map);
+ map->name = dev_name;
+ map->port = file_name_lookup (dev_file, 0, 0);
+ if (map->port == MACH_PORT_NULL)
+ error (1, errno, "file_name_lookup: %s", dev_file);
+ map->next = dev_map_head;
+ dev_map_head = map;
+ return map;
+}
+
+static struct dev_map *lookup_dev (char *dev_name)
+{
+ struct dev_map *map;
+
+ for (map = dev_map_head; map; map = map->next)
+ {
+ if (strcmp (map->name, dev_name) == 0)
+ return map;
+ }
+ return NULL;
+}
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ char *dev_file;
+
+ switch (key)
+ {
+ size_t len;
+
+ case 'c': kernel_command_line = arg; break;
+
+ case 'D': useropen_dir = arg; break;
+
+ case 'I': isig = 1; break;
+
+ case 's': case 'd':
+ len = strlen (bootstrap_args);
+ if (len >= sizeof bootstrap_args - 1)
+ argp_error (state, "Too many bootstrap args");
+ bootstrap_args[len++] = key;
+ bootstrap_args[len] = '\0';
+ break;
+
+ case 'f':
+ dev_file = strchr (arg, '=');
+ if (dev_file == NULL)
+ return ARGP_ERR_UNKNOWN;
+ *dev_file = 0;
+ add_dev_map (arg, dev_file+1);
+ break;
+
+ case ARGP_KEY_ARG:
+ if (state->arg_num == 0)
+ bootscript = arg;
+ else
+ return ARGP_ERR_UNKNOWN;
+ break;
+
+ case ARGP_KEY_INIT:
+ state->child_inputs[0] = state->input; break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
int
main (int argc, char **argv, char **envp)
{
+ error_t err;
mach_port_t foo;
- static const char usagemsg[]
- = "Usage: boot [-D dir] [SWITCHES] SCRIPT ROOT-DEVICE\n";
char *buf = 0;
- char *bootscript;
int i, len;
- char *newargs;
+ char *root_store_name;
+ const struct argp_child kids[] = { { &store_argp }, { 0 }};
+ struct argp argp = { options, parse_opt, args_doc, doc, kids };
+ struct store_argp_params store_argp_params = { 0 };
+
+ argp_parse (&argp, argc, argv, 0, 0, &store_argp_params);
+ err = store_parsed_name (store_argp_params.result, &root_store_name);
+ if (err)
+ error (2, err, "store_parsed_name");
+
+ err = store_parsed_open (store_argp_params.result, 0, &root_store);
+ if (err)
+ error (4, err, "%s", root_store_name);
get_privileged_ports (&privileged_host_port, &master_device_port);
defpager = MACH_PORT_NULL;
vm_set_default_memory_manager (privileged_host_port, &defpager);
- if (argc < 2 || (argv[1][0] == '-' && argc < 3))
- {
- usage:
- write (2, usagemsg, sizeof usagemsg);
- host_exit (1);
- }
+ strcat (bootstrap_args, "f");
- if (!strcmp (argv[1], "-D"))
- {
- if (argc < 4)
- goto usage;
- useropen_dir = argv[2];
- argv += 2;
- }
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
+ &receive_set);
- if (argv[1][0] != '-')
- {
- bootstrap_args = "-x";
- bootscript = argv[1];
- bootdevice = argv[2];
- }
+ if (root_store->class == &store_device_class && root_store->name
+ && (root_store->flags & STORE_ENFORCED)
+ && root_store->num_runs == 1 && root_store->runs[0].start == 0)
+ /* Let known device nodes pass through directly. */
+ bootdevice = root_store->name;
else
+ /* Pass a magic value that we can use to do I/O to ROOT_STORE. */
{
- bootstrap_args = argv[1];
- bootscript = argv[2];
- bootdevice = argv[3];
+ bootdevice = "pseudo-root";
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_root);
+ mach_port_move_member (mach_task_self (), pseudo_root, receive_set);
}
- newargs = malloc (strlen (bootstrap_args) + 2);
- strcpy (newargs, bootstrap_args);
- strcat (newargs, "f");
- bootstrap_args = newargs;
-
- 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_insert_right (mach_task_self (),
@@ -458,13 +590,21 @@ main (int argc, char **argv, char **envp)
if (foo != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self (), foo);
+ if (kernel_command_line == 0)
+ asprintf (&kernel_command_line, "%s %s root=%s",
+ argv[0], bootstrap_args, bootdevice);
+
/* Initialize boot script variables. */
if (boot_script_set_variable ("host-port", VAL_PORT,
(int) privileged_host_port)
|| boot_script_set_variable ("device-port", VAL_PORT,
- (int) pseudo_master_device_port)
- || boot_script_set_variable ("root-device", VAL_STR, (int) bootdevice)
- || boot_script_set_variable ("boot-args", VAL_STR, (int) bootstrap_args))
+ (integer_t) pseudo_master_device_port)
+ || boot_script_set_variable ("kernel-command-line", VAL_STR,
+ (integer_t) kernel_command_line)
+ || boot_script_set_variable ("root-device",
+ VAL_STR, (integer_t) bootdevice)
+ || boot_script_set_variable ("boot-args",
+ VAL_STR, (integer_t) bootstrap_args))
{
static const char msg[] = "error setting variable";
@@ -472,10 +612,38 @@ main (int argc, char **argv, char **envp)
host_exit (1);
}
+ /* Turn each `FOO=BAR' word in the command line into a boot script
+ variable ${FOO} with value BAR. */
+ {
+ int len = strlen (kernel_command_line) + 1;
+ char *s = memcpy (alloca (len), kernel_command_line, len);
+ char *word;
+
+ while ((word = strsep (&s, " \t")) != 0)
+ {
+ char *eq = strchr (word, '=');
+ if (eq == 0)
+ continue;
+ *eq++ = '\0';
+ err = boot_script_set_variable (word, VAL_STR, (integer_t) eq);
+ if (err)
+ {
+ char *msg;
+ asprintf (&msg, "cannot set boot-script variable %s: %s\n",
+ word, boot_script_error_string (err));
+ assert (msg);
+ write (2, msg, strlen (msg));
+ free (msg);
+ host_exit (1);
+ }
+ }
+ }
+
/* Parse the boot script. */
{
char *p, *line;
- static const char filemsg[] = "Can't open boot script";
+ static const char filemsg[] = "Can't open boot script\n";
+ static const char memmsg[] = "Not enough memory\n";
int amt, fd, err;
fd = open (bootscript, O_RDONLY, 0);
@@ -485,6 +653,11 @@ main (int argc, char **argv, char **envp)
host_exit (1);
}
p = buf = malloc (500);
+ if (!buf)
+ {
+ write (2, memmsg, sizeof (memmsg));
+ host_exit (1);
+ }
len = 500;
amt = 0;
while (1)
@@ -500,6 +673,11 @@ main (int argc, char **argv, char **envp)
len += 500;
newbuf = realloc (buf, len);
+ if (!newbuf)
+ {
+ write (2, memmsg, sizeof (memmsg));
+ host_exit (1);
+ }
p = newbuf + (p - buf);
buf = newbuf;
}
@@ -510,7 +688,7 @@ main (int argc, char **argv, char **envp)
while (p < buf + amt && *p != '\n')
p++;
*p = '\0';
- err = boot_script_parse_line (line);
+ err = boot_script_parse_line (0, line);
if (err)
{
char *str;
@@ -552,6 +730,7 @@ main (int argc, char **argv, char **envp)
int i = strlen (str);
write (2, str, i);
+ write (2, "\n", 1);
host_exit (1);
}
free (buf);
@@ -568,206 +747,13 @@ main (int argc, char **argv, char **envp)
FD_SET (0, &rmask);
if (select (1, &rmask, 0, 0, 0) == 1)
read_reply ();
- else
- { /* We hosed */
- perror ("select");
- exit (5);
- }
+ else /* We hosed */
+ error (5, errno, "select");
}
/* mach_msg_server (request_server, __vm_page_size * 2, receive_set); */
}
-/* Set up stack args the Mach way */
-void
-set_mach_stack_args (user_task,
- user_thread,
- startpc,
- va_alist)
- task_t user_task;
- thread_t user_thread;
- char *startpc;
- va_dcl
-{
- /* This code is lifted from .../mk/bootstrap/load.c. */
- va_list argv_ptr;
- char * arg_ptr;
-
- int arg_len;
- int arg_count;
- char * arg_pos;
- unsigned int arg_item_len;
-
- /*
- * Calculate the size of the argument list.
- */
- va_start(argv_ptr);
- arg_len = 0;
- arg_count = 0;
- for (;;) {
- arg_ptr = va_arg(argv_ptr, char *);
- if (arg_ptr == (char *)0)
- break;
- arg_count++;
- arg_len += strlen(arg_ptr) + 1; /* space for '\0' */
- }
- va_end(argv_ptr);
- /*
- * Add space for:
- * arg_count
- * pointers to arguments
- * trailing 0 pointer
- * dummy 0 pointer to environment variables
- * and align to integer boundary
- */
- arg_len += sizeof(integer_t) + (2 + arg_count) * sizeof(char *);
- arg_len = (arg_len + (sizeof(integer_t) - 1)) & ~(sizeof(integer_t)-1);
-
-
- /* This small piece is from .../mk/bootstrap/i386/exec.c. */
- {
- vm_offset_t stack_start;
- vm_offset_t stack_end;
- struct i386_thread_state regs;
- unsigned int reg_size;
-
-#define STACK_SIZE (1024 * 1024 * 16)
-
- /*
- * Add space for 5 ints to arguments, for
- * PS program. XXX
- */
- arg_len += 5 * sizeof(int);
-
- /*
- * Allocate stack.
- */
- stack_end = VM_MAX_ADDRESS;
- stack_start = VM_MAX_ADDRESS - STACK_SIZE;
- (void)vm_allocate(user_task,
- &stack_start,
- (vm_size_t)(stack_end - stack_start),
- FALSE);
-
- reg_size = i386_THREAD_STATE_COUNT;
- (void)thread_get_state(user_thread,
- i386_THREAD_STATE,
- (thread_state_t)&regs,
- &reg_size);
-
- regs.eip = (int) startpc;
- regs.uesp = (int)((stack_end - arg_len) & ~(sizeof(int)-1));
-
- (void)thread_set_state(user_thread,
- i386_THREAD_STATE,
- (thread_state_t)&regs,
- reg_size);
-
- arg_pos = (void *) regs.uesp;
- }
-
- /*
- * Copy out the arguments.
- */
- {
- vm_offset_t u_arg_start;
- /* user start of argument list block */
- vm_offset_t k_arg_start;
- /* kernel start of argument list block */
- vm_offset_t u_arg_page_start;
- /* user start of args, page-aligned */
- vm_size_t arg_page_size;
- /* page_aligned size of args */
- vm_offset_t k_arg_page_start;
- /* kernel start of args, page-aligned */
-
- register
- char ** k_ap; /* kernel arglist address */
- char * u_cp; /* user argument string address */
- register
- char * k_cp; /* kernel argument string address */
- register
- int i;
-
- /*
- * Get address of argument list in user space
- */
- u_arg_start = (vm_offset_t)arg_pos;
-
- /*
- * Round to page boundaries, and allocate kernel copy
- */
- u_arg_page_start = trunc_page(u_arg_start);
- arg_page_size = (vm_size_t)(round_page(u_arg_start + arg_len)
- - u_arg_page_start);
-
- vm_allocate(mach_task_self(),
- &k_arg_page_start,
- (vm_size_t)arg_page_size,
- TRUE);
-
- /*
- * Set up addresses corresponding to user pointers
- * in the kernel block
- */
- k_arg_start = k_arg_page_start + (u_arg_start - u_arg_page_start);
-
- k_ap = (char **)k_arg_start;
-
- /*
- * Start the strings after the arg-count and pointers
- */
- u_cp = (char *)u_arg_start + arg_count * sizeof(char *)
- + 2 * sizeof(char *)
- + sizeof(integer_t);
- k_cp = (char *)k_arg_start + arg_count * sizeof(char *)
- + 2 * sizeof(char *)
- + sizeof(integer_t);
-
- /*
- * first the argument count
- */
- *k_ap++ = (char *)(natural_t)arg_count;
-
- /*
- * Then the strings and string pointers for each argument
- */
- va_start(argv_ptr);
- for (i = 0; i < arg_count; i++) {
- arg_ptr = va_arg(argv_ptr, char *);
- arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
-
- /* set string pointer */
- *k_ap++ = u_cp;
-
- /* copy string */
- bcopy(arg_ptr, k_cp, arg_item_len);
- k_cp += arg_item_len;
- u_cp += arg_item_len;
- }
- va_end(argv_ptr);
-
- /*
- * last, the trailing 0 argument and a null environment pointer.
- */
- *k_ap++ = (char *)0;
- *k_ap = (char *)0;
-
- /*
- * Now write all of this to user space.
- */
- (void) vm_write(user_task,
- u_arg_page_start,
- k_arg_page_start,
- arg_page_size);
-
- (void) vm_deallocate(mach_task_self(),
- k_arg_page_start,
- arg_page_size);
- }
-}
-
-
void
msg_thread()
{
@@ -793,7 +779,7 @@ struct qr
struct qr *qrhead, *qrtail;
/* Queue a read for later reply. */
-void
+kern_return_t
queue_read (enum read_type type,
mach_port_t reply_port,
mach_msg_type_name_t reply_type,
@@ -801,9 +787,12 @@ queue_read (enum read_type type,
{
struct qr *qr;
+ qr = malloc (sizeof (struct qr));
+ if (!qr)
+ return D_NO_MEMORY;
+
spin_lock (&queuelock);
- qr = malloc (sizeof (struct qr));
qr->type = type;
qr->reply_port = reply_port;
qr->reply_type = reply_type;
@@ -815,6 +804,7 @@ queue_read (enum read_type type,
qrhead = qrtail = qr;
spin_unlock (&queuelock);
+ return D_SUCCESS;
}
/* TRUE if there's data available on stdin, which should be used to satisfy
@@ -837,7 +827,7 @@ read_reply ()
if (! spin_try_lock (&readlock))
return;
- /* Since we're commited to servicing the read, no one else need do so. */
+ /* Since we're committed to servicing the read, no one else need do so. */
should_read = 0;
ioctl (0, FIONREAD, &avail);
@@ -864,7 +854,7 @@ read_reply ()
spin_unlock (&queuelock);
if (qr->type == DEV_READ)
- vm_allocate (mach_task_self (), (vm_address_t *)&buf, qr->amount, 1);
+ buf = mmap (0, qr->amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
else
buf = alloca (qr->amount);
amtread = read (0, buf, qr->amount);
@@ -1000,6 +990,8 @@ ds_device_open (mach_port_t master_port,
mach_port_t *device,
mach_msg_type_name_t *devicetype)
{
+ struct dev_map *map;
+
if (master_port != pseudo_master_device_port)
return D_INVALID_OPERATION;
@@ -1015,6 +1007,20 @@ ds_device_open (mach_port_t master_port,
*devicetype = MACH_MSG_TYPE_MAKE_SEND;
return 0;
}
+ else if (strcmp (name, "pseudo-root") == 0)
+ /* Magic root device. */
+ {
+ *device = pseudo_root;
+ *devicetype = MACH_MSG_TYPE_MAKE_SEND;
+ return 0;
+ }
+
+ map = lookup_dev (name);
+ if (map)
+ {
+ *devicetype = MACH_MSG_TYPE_MOVE_SEND;
+ return device_open (map->port, mode, "", device);
+ }
*devicetype = MACH_MSG_TYPE_MOVE_SEND;
return device_open (master_device_port, mode, name, device);
@@ -1023,7 +1029,7 @@ ds_device_open (mach_port_t master_port,
kern_return_t
ds_device_close (device_t device)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return 0;
}
@@ -1035,24 +1041,34 @@ ds_device_write (device_t device,
dev_mode_t mode,
recnum_t recnum,
io_buf_ptr_t data,
- unsigned int datalen,
+ size_t datalen,
int *bytes_written)
{
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
-
-#if 0
- if (console_send_rights)
+ if (device == pseudo_console)
{
- mach_port_mod_refs (mach_task_self (), pseudo_console,
- MACH_PORT_TYPE_SEND, -console_send_rights);
- console_send_rights = 0;
- }
+#if 0
+ if (console_send_rights)
+ {
+ mach_port_mod_refs (mach_task_self (), pseudo_console,
+ MACH_PORT_TYPE_SEND, -console_send_rights);
+ console_send_rights = 0;
+ }
#endif
- *bytes_written = write (1, data, datalen);
+ *bytes_written = write (1, data, datalen);
- return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+ return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+ }
+ else if (device == pseudo_root)
+ {
+ size_t wrote;
+ if (store_write (root_store, recnum, data, datalen, &wrote) != 0)
+ return D_IO_ERROR;
+ *bytes_written = wrote;
+ return D_SUCCESS;
+ }
+ else
+ return D_NO_SUCH_DEVICE;
}
kern_return_t
@@ -1062,24 +1078,34 @@ ds_device_write_inband (device_t device,
dev_mode_t mode,
recnum_t recnum,
io_buf_ptr_inband_t data,
- unsigned int datalen,
+ size_t datalen,
int *bytes_written)
{
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
-
-#if 0
- if (console_send_rights)
+ if (device == pseudo_console)
{
- mach_port_mod_refs (mach_task_self (), pseudo_console,
- MACH_PORT_TYPE_SEND, -console_send_rights);
- console_send_rights = 0;
- }
+#if 0
+ if (console_send_rights)
+ {
+ mach_port_mod_refs (mach_task_self (), pseudo_console,
+ MACH_PORT_TYPE_SEND, -console_send_rights);
+ console_send_rights = 0;
+ }
#endif
- *bytes_written = write (1, data, datalen);
+ *bytes_written = write (1, data, datalen);
- return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+ return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+ }
+ else if (device == pseudo_root)
+ {
+ size_t wrote;
+ if (store_write (root_store, recnum, data, datalen, &wrote) != 0)
+ return D_IO_ERROR;
+ *bytes_written = wrote;
+ return D_SUCCESS;
+ }
+ else
+ return D_NO_SUCH_DEVICE;
}
kern_return_t
@@ -1090,37 +1116,51 @@ ds_device_read (device_t device,
recnum_t recnum,
int bytes_wanted,
io_buf_ptr_t *data,
- unsigned int *datalen)
+ size_t *datalen)
{
- int avail;
-
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
+ if (device == pseudo_console)
+ {
+ int avail;
#if 0
- if (console_send_rights)
- {
- mach_port_mod_refs (mach_task_self (), pseudo_console,
- MACH_PORT_TYPE_SEND, -console_send_rights);
- console_send_rights = 0;
- }
+ if (console_send_rights)
+ {
+ mach_port_mod_refs (mach_task_self (), pseudo_console,
+ MACH_PORT_TYPE_SEND, -console_send_rights);
+ console_send_rights = 0;
+ }
#endif
- spin_lock (&readlock);
- ioctl (0, FIONREAD, &avail);
- if (avail)
- {
- vm_allocate (mach_task_self (), (pointer_t *)data, bytes_wanted, 1);
- *datalen = read (0, *data, bytes_wanted);
- unlock_readlock ();
- return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+ spin_lock (&readlock);
+ ioctl (0, FIONREAD, &avail);
+ if (avail)
+ {
+ *data = mmap (0, bytes_wanted, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ *datalen = read (0, *data, bytes_wanted);
+ unlock_readlock ();
+ return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+ }
+ else
+ {
+ kern_return_t err;
+
+ unlock_readlock ();
+ err = queue_read (DEV_READ, reply_port, reply_type, bytes_wanted);
+ if (err)
+ return err;
+ return MIG_NO_REPLY;
+ }
}
- else
+ else if (device == pseudo_root)
{
- unlock_readlock ();
- queue_read (DEV_READ, reply_port, reply_type, bytes_wanted);
- return MIG_NO_REPLY;
+ *datalen = 0;
+ return
+ (store_read (root_store, recnum, bytes_wanted, (void **)data, datalen) == 0
+ ? D_SUCCESS
+ : D_IO_ERROR);
}
+ else
+ return D_NO_SUCH_DEVICE;
}
kern_return_t
@@ -1131,43 +1171,70 @@ ds_device_read_inband (device_t device,
recnum_t recnum,
int bytes_wanted,
io_buf_ptr_inband_t data,
- unsigned int *datalen)
+ size_t *datalen)
{
- int avail;
-
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
+ if (device == pseudo_console)
+ {
+ int avail;
#if 0
- if (console_send_rights)
- {
- mach_port_mod_refs (mach_task_self (), pseudo_console,
- MACH_PORT_TYPE_SEND, -console_send_rights);
- console_send_rights = 0;
- }
+ if (console_send_rights)
+ {
+ mach_port_mod_refs (mach_task_self (), pseudo_console,
+ MACH_PORT_TYPE_SEND, -console_send_rights);
+ console_send_rights = 0;
+ }
#endif
- spin_lock (&readlock);
- ioctl (0, FIONREAD, &avail);
- if (avail)
- {
- *datalen = read (0, data, bytes_wanted);
- unlock_readlock ();
- return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+ spin_lock (&readlock);
+ ioctl (0, FIONREAD, &avail);
+ if (avail)
+ {
+ *datalen = read (0, data, bytes_wanted);
+ unlock_readlock ();
+ return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+ }
+ else
+ {
+ kern_return_t err;
+
+ unlock_readlock ();
+ err = queue_read (DEV_READI, reply_port, reply_type, bytes_wanted);
+ if (err)
+ return err;
+ return MIG_NO_REPLY;
+ }
}
- else
+ else if (device == pseudo_root)
{
- unlock_readlock ();
- queue_read (DEV_READI, reply_port, reply_type, bytes_wanted);
- return MIG_NO_REPLY;
+ error_t err;
+ void *returned = data;
+
+ *datalen = bytes_wanted;
+ err =
+ store_read (root_store, recnum, bytes_wanted, (void **)&returned, datalen);
+
+ if (! err)
+ {
+ if (returned != data)
+ {
+ bcopy (returned, (void *)data, *datalen);
+ munmap ((caddr_t) returned, *datalen);
+ }
+ return D_SUCCESS;
+ }
+ else
+ return D_IO_ERROR;
}
+ else
+ return D_NO_SUCH_DEVICE;
}
kern_return_t
ds_xxx_device_set_status (device_t device,
dev_flavor_t flavor,
dev_status_t status,
- u_int statu_cnt)
+ size_t statu_cnt)
{
if (device != pseudo_console)
return D_NO_SUCH_DEVICE;
@@ -1178,9 +1245,9 @@ kern_return_t
ds_xxx_device_get_status (device_t device,
dev_flavor_t flavor,
dev_status_t status,
- u_int *statuscnt)
+ size_t *statuscnt)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1190,9 +1257,9 @@ ds_xxx_device_set_filter (device_t device,
mach_port_t rec,
int pri,
filter_array_t filt,
- unsigned int len)
+ size_t len)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1205,7 +1272,7 @@ ds_device_map (device_t device,
memory_object_t *pager,
int unmap)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1214,9 +1281,9 @@ kern_return_t
ds_device_set_status (device_t device,
dev_flavor_t flavor,
dev_status_t status,
- unsigned int statuslen)
+ size_t statuslen)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1225,11 +1292,25 @@ kern_return_t
ds_device_get_status (device_t device,
dev_flavor_t flavor,
dev_status_t status,
- unsigned int *statuslen)
+ size_t *statuslen)
{
- if (device != pseudo_console)
+ if (device == pseudo_console)
+ return D_INVALID_OPERATION;
+ else if (device == pseudo_root)
+ if (flavor == DEV_GET_SIZE)
+ if (*statuslen < DEV_GET_SIZE_COUNT)
+ return D_INVALID_SIZE;
+ else
+ {
+ status[DEV_GET_SIZE_DEVICE_SIZE] = root_store->size;
+ status[DEV_GET_SIZE_RECORD_SIZE] = root_store->block_size;
+ *statuslen = DEV_GET_SIZE_COUNT;
+ return D_SUCCESS;
+ }
+ else
+ return D_INVALID_OPERATION;
+ else
return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
}
kern_return_t
@@ -1237,9 +1318,9 @@ ds_device_set_filter (device_t device,
mach_port_t receive_port,
int priority,
filter_array_t filter,
- unsigned int filterlen)
+ size_t filterlen)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1383,15 +1464,18 @@ S_io_read (mach_port_t object,
if (avail)
{
if (amount > *datalen)
- vm_allocate (mach_task_self (), (vm_address_t *) data, amount, 1);
+ *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
*datalen = read (0, *data, amount);
unlock_readlock ();
return *datalen == -1 ? errno : 0;
}
else
{
+ kern_return_t err;
unlock_readlock ();
- queue_read (IO_READ, reply_port, reply_type, amount);
+ err = queue_read (IO_READ, reply_port, reply_type, amount);
+ if (err)
+ return err;
return MIG_NO_REPLY;
}
}
@@ -1554,11 +1638,16 @@ S_io_reauthenticate (mach_port_t object,
{
uid_t *gu, *au;
gid_t *gg, *ag;
- unsigned int gulen = 0, aulen = 0, gglen = 0, aglen = 0;
+ size_t gulen = 0, aulen = 0, gglen = 0, aglen = 0;
+ error_t err;
+
+ err = mach_port_insert_right (mach_task_self (), object, object,
+ MACH_MSG_TYPE_MAKE_SEND);
+ assert_perror (err);
if (! auth_server_authenticate (authserver,
rend, MACH_MSG_TYPE_COPY_SEND,
- object, MACH_MSG_TYPE_MAKE_SEND,
+ object, MACH_MSG_TYPE_COPY_SEND,
&gu, &gulen,
&au, &aulen,
&gg, &gglen,
@@ -1570,6 +1659,7 @@ S_io_reauthenticate (mach_port_t object,
mig_deallocate ((vm_address_t) au, aulen * sizeof *gu);
}
mach_port_deallocate (mach_task_self (), rend);
+ mach_port_deallocate (mach_task_self (), object);
return 0;
}
@@ -1581,9 +1671,9 @@ S_io_restrict_auth (mach_port_t object,
mach_port_t *newobject,
mach_msg_type_name_t *newobjtype,
uid_t *uids,
- u_int nuids,
+ size_t nuids,
uid_t *gids,
- u_int ngids)
+ size_t ngids)
{
if (object != pseudo_console)
return EOPNOTSUPP;
@@ -1730,7 +1820,14 @@ S_io_identity (mach_port_t obj,
mach_msg_type_name_t *idtype,
mach_port_t *fsid,
mach_msg_type_name_t *fsidtype,
- int *fileno)
+ ino_t *fileno)
+{
+ return EOPNOTSUPP;
+}
+
+kern_return_t
+S_io_revoke (mach_port_t obj,
+ mach_port_t reply, mach_msg_type_name_t replyPoly)
{
return EOPNOTSUPP;
}
@@ -1791,6 +1888,13 @@ kern_return_t S_term_get_nodename
)
{ return EOPNOTSUPP; }
+kern_return_t S_term_get_peername
+(
+ io_t terminal,
+ string_t name
+)
+{ return EOPNOTSUPP; }
+
kern_return_t S_term_set_filenode
(
io_t terminal,
diff --git a/boot/boot_script.c b/boot/boot_script.c
index 618830f2..6fd449b2 100644
--- a/boot/boot_script.c
+++ b/boot/boot_script.c
@@ -2,15 +2,13 @@
/* Written by Shantanu Goel (goel@cs.columbia.edu). */
-#include <mach.h>
-#include <stdio.h>
+#include <mach/mach_types.h>
+#if !KERNEL || OSKIT_MACH
+#include <string.h>
+#endif
#include "boot_script.h"
-extern void *malloc (int size);
-extern void free (void *ptr);
-
-
/* This structure describes a symbol. */
struct sym
{
@@ -21,7 +19,7 @@ struct sym
int type;
/* Symbol value. */
- int val;
+ integer_t val;
/* For function symbols; type of value returned by function. */
int ret_type;
@@ -35,8 +33,8 @@ struct sym
/* Additional values symbols can take.
These are only used internally. */
-#define VAL_SYM 3 /* symbol table entry */
-#define VAL_FUNC 4 /* function pointer */
+#define VAL_SYM 10 /* symbol table entry */
+#define VAL_FUNC 11 /* function pointer */
/* This structure describes an argument. */
struct arg
@@ -48,7 +46,7 @@ struct arg
int type;
/* Argument value. */
- int val;
+ integer_t val;
};
/* List of commands. */
@@ -68,72 +66,37 @@ static int symtab_alloc = 0;
/* Next available slot in `symtab'. */
static int symtab_index = 0;
-
-void memset (void *str, char c, int size);
-/* Create a task. */
+/* Create a task and suspend it. */
static int
create_task (struct cmd *cmd, int *val)
{
- if (task_create (mach_task_self (), 0, (task_t *) &cmd->task) ||
- task_suspend (cmd->task))
- {
- printf ("(bootstrap): %s: Cannot create task\n", cmd->path);
- return BOOT_SCRIPT_MACH_ERROR;
- }
+ int err = boot_script_task_create (cmd);
*val = (int) cmd->task;
- return 0;
+ return err;
}
/* Resume a task. */
static int
resume_task (struct cmd *cmd, int *val)
{
- if (task_resume (cmd->task))
- {
- printf ("(bootstrap): %s: Cannot resume task\n", cmd->path);
- return BOOT_SCRIPT_MACH_ERROR;
- }
- return 0;
+ return boot_script_task_resume (cmd);
}
/* Resume a task when the user hits return. */
static int
prompt_resume_task (struct cmd *cmd, int *val)
{
- char c;
-
- printf ("Hit return to resume %s...", cmd->path);
- safe_gets (&c, 1);
-
- if (task_resume (cmd->task))
- {
- printf ("(bootstrap): %s: Cannot resume task\n", cmd->path);
- return BOOT_SCRIPT_MACH_ERROR;
- }
-
- return 0;
-}
-
-static int
-read_file (struct cmd *cmd, int *val)
-{
- *val = boot_script_read_file (cmd->path);
- if (*val == 0)
- {
- printf ("(bootstrap): %s: Cannot read boot script\n", cmd->path);
- return BOOT_SCRIPT_MACH_ERROR;
- }
- return 0;
+ return boot_script_prompt_task_resume (cmd);
}
/* List of builtin symbols. */
static struct sym builtin_symbols[] =
{
- { "task-create", VAL_FUNC, (int) create_task, VAL_PORT, 0 },
- { "task-resume", VAL_FUNC, (int) resume_task, VAL_NONE, 1 },
- { "prompt-task-resume", VAL_FUNC, (int) prompt_resume_task, VAL_NONE, 1 },
- { "read-file", VAL_FUNC, (int) read_file, VAL_PORT, 0 },
+ { "task-create", VAL_FUNC, (integer_t) create_task, VAL_TASK, 0 },
+ { "task-resume", VAL_FUNC, (integer_t) resume_task, VAL_NONE, 1 },
+ { "prompt-task-resume",
+ VAL_FUNC, (integer_t) prompt_resume_task, VAL_NONE, 1 },
};
#define NUM_BUILTIN (sizeof (builtin_symbols) / sizeof (builtin_symbols[0]))
@@ -144,23 +107,18 @@ static void
free_cmd (struct cmd *cmd, int aborting)
{
if (cmd->task)
- {
- if (aborting)
- task_terminate (cmd->task);
- else
- mach_port_deallocate (mach_task_self (), cmd->task);
- }
+ boot_script_free_task (cmd->task, aborting);
if (cmd->args)
{
int i;
-
for (i = 0; i < cmd->args_index; i++)
- free (cmd->args[i]);
- free (cmd->args);
+ boot_script_free (cmd->args[i], sizeof *cmd->args[i]);
+ boot_script_free (cmd->args, sizeof cmd->args[0] * cmd->args_alloc);
}
if (cmd->exec_funcs)
- free (cmd->exec_funcs);
- free (cmd);
+ boot_script_free (cmd->exec_funcs,
+ sizeof cmd->exec_funcs[0] * cmd->exec_funcs_alloc);
+ boot_script_free (cmd, sizeof *cmd);
}
/* Free all storage allocated by the parser.
@@ -172,13 +130,13 @@ cleanup (int aborting)
for (i = 0; i < cmds_index; i++)
free_cmd (cmds[i], aborting);
- free (cmds);
+ boot_script_free (cmds, sizeof cmds[0] * cmds_alloc);
cmds = 0;
cmds_index = cmds_alloc = 0;
for (i = 0; i < symtab_index; i++)
- free (symtab[i]);
- free (symtab);
+ boot_script_free (symtab[i], sizeof *symtab[i]);
+ boot_script_free (symtab, sizeof symtab[0] * symtab_alloc);
symtab = 0;
symtab_index = symtab_alloc = 0;
}
@@ -196,7 +154,7 @@ add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr)
void **p;
*alloc += incr;
- p = malloc (*alloc * sizeof (void *));
+ p = boot_script_malloc (*alloc * sizeof (void *));
if (! p)
{
*alloc -= incr;
@@ -205,7 +163,7 @@ add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr)
if (*ptr_list)
{
memcpy (p, *ptr_list, *index * sizeof (void *));
- free (*ptr_list);
+ boot_script_free (*ptr_list, (*alloc - incr) * sizeof (void *));
}
*ptr_list = p;
}
@@ -217,20 +175,20 @@ add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr)
/* Create an argument with TEXT, value type TYPE, and value VAL.
Add the argument to the argument list of CMD. */
static struct arg *
-add_arg (struct cmd *cmd, char *text, int type, int val)
+add_arg (struct cmd *cmd, const char *text, int textlen, int type, int val)
{
struct arg *arg;
- arg = malloc (sizeof (struct arg));
+ arg = boot_script_malloc (sizeof (struct arg) + textlen);
if (arg)
{
- arg->text = text;
+ arg->text = text == 0 ? 0 : memcpy (arg + 1, text, textlen);
arg->type = type;
arg->val = val;
if (add_list (arg, (void ***) &cmd->args,
&cmd->args_alloc, &cmd->args_index, 5))
{
- free (arg);
+ boot_script_free (arg, sizeof *arg);
return 0;
}
}
@@ -255,14 +213,14 @@ sym_enter (const char *name)
{
struct sym *sym;
- sym = malloc (sizeof (struct sym));
+ sym = boot_script_malloc (sizeof (struct sym));
if (sym)
{
memset (sym, 0, sizeof (struct sym));
sym->name = name;
if (add_list (sym, (void ***) &symtab, &symtab_alloc, &symtab_index, 20))
{
- free (sym);
+ boot_script_free (sym, sizeof *sym);
return 0;
}
}
@@ -271,7 +229,7 @@ sym_enter (const char *name)
/* Parse the command line CMDLINE. */
int
-boot_script_parse_line (char *cmdline)
+boot_script_parse_line (void *hook, char *cmdline)
{
char *p, *q;
int error;
@@ -285,22 +243,28 @@ boot_script_parse_line (char *cmdline)
/* Ignore comment line. */
return 0;
+#if 0
if (*p && *p != ' ' && *p != '\t' && *p != '\n')
- printf ("(bootstrap): %s\n", cmdline);
+ {
+ printf ("(bootstrap): %s\n", cmdline);
+ }
+#endif
for (q = p; *q && *q != ' ' && *q != '\t' && *q != '\n'; q++)
;
if (p == q)
- return 0;
- *q = '\0';
+ return 0;
+
+ *q++ = '\0';
/* Allocate a command structure. */
- cmd = malloc (sizeof (struct cmd));
+ cmd = boot_script_malloc (sizeof (struct cmd) + (q - p));
if (! cmd)
return BOOT_SCRIPT_NOMEM;
memset (cmd, 0, sizeof (struct cmd));
- cmd->path = p;
- p = q + 1;
+ cmd->hook = hook;
+ cmd->path = memcpy (cmd + 1, p, q - p);
+ p = q;
for (arg = 0;;)
{
@@ -333,7 +297,8 @@ boot_script_parse_line (char *cmdline)
for (p += 2;;)
{
char c;
- int i, val, type;
+ int i, type;
+ integer_t val;
struct sym *s;
/* Parse symbol name. */
@@ -388,7 +353,7 @@ boot_script_parse_line (char *cmdline)
if (! s->run_on_exec)
{
(error
- = ((*((int (*) (struct cmd *, int *)) s->val))
+ = ((*((int (*) (struct cmd *, integer_t *)) s->val))
(cmd, &val)));
if (error)
goto bad;
@@ -410,7 +375,7 @@ boot_script_parse_line (char *cmdline)
else if (s->type == VAL_NONE)
{
type = VAL_SYM;
- val = (int) s;
+ val = (integer_t) s;
}
else
{
@@ -443,7 +408,7 @@ boot_script_parse_line (char *cmdline)
associated with an argument. */
if (! arg && end_char == '}')
{
- if (! add_arg (cmd, 0, type, val))
+ if (! add_arg (cmd, 0, 0, type, val))
{
error = BOOT_SCRIPT_NOMEM;
goto bad;
@@ -472,7 +437,7 @@ boot_script_parse_line (char *cmdline)
*q = '\0';
/* Add argument to list. */
- arg = add_arg (cmd, p, VAL_NONE, 0);
+ arg = add_arg (cmd, p, q + 1 - p, VAL_NONE, 0);
if (! arg)
{
error = BOOT_SCRIPT_NOMEM;
@@ -491,6 +456,7 @@ boot_script_parse_line (char *cmdline)
}
}
+
bad:
free_cmd (cmd, 1);
cleanup (1);
@@ -505,7 +471,7 @@ boot_script_parse_line (char *cmdline)
char *ptr; \
int alloc, i; \
alloc = cmdline_alloc + len - (cmdline_alloc - cmdline_index) + 100; \
- ptr = malloc (alloc); \
+ ptr = boot_script_malloc (alloc); \
if (! ptr) \
{ \
error = BOOT_SCRIPT_NOMEM; \
@@ -514,7 +480,7 @@ boot_script_parse_line (char *cmdline)
memcpy (ptr, cmdline, cmdline_index); \
for (i = 0; i < argc; ++i) \
argv[i] = ptr + (argv[i] - cmdline); \
- free (cmdline); \
+ boot_script_free (cmdline, cmdline_alloc); \
cmdline = ptr; \
cmdline_alloc = alloc; \
} \
@@ -540,7 +506,7 @@ boot_script_exec ()
/* Allocate a command line and copy command name. */
cmdline_index = strlen (cmd->path) + 1;
cmdline_alloc = cmdline_index + 100;
- cmdline = malloc (cmdline_alloc);
+ cmdline = boot_script_malloc (cmdline_alloc);
if (! cmdline)
{
cleanup (1);
@@ -549,10 +515,10 @@ boot_script_exec ()
memcpy (cmdline, cmd->path, cmdline_index);
/* Allocate argument vector. */
- argv = malloc (sizeof (char *) * (cmd->args_index + 2));
+ argv = boot_script_malloc (sizeof (char *) * (cmd->args_index + 2));
if (! argv)
{
- free (cmdline);
+ boot_script_free (cmdline, cmdline_alloc);
cleanup (1);
return BOOT_SCRIPT_NOMEM;
}
@@ -582,6 +548,7 @@ boot_script_exec ()
{
char *p, buf[50];
int len;
+ mach_port_t name;
if (arg->type == VAL_SYM)
{
@@ -607,19 +574,21 @@ boot_script_exec ()
len = strlen (p);
break;
+ case VAL_TASK:
case VAL_PORT:
- /* Insert send right. */
- if ((mach_port_insert_right
- (cmd->task, (mach_port_t) arg->val,
- (mach_port_t) arg->val, MACH_MSG_TYPE_COPY_SEND)))
- {
- printf ("(bootstrap): %s: Cannot insert port right %d\n",
- cmd->path, arg->val);
- error = BOOT_SCRIPT_MACH_ERROR;
- goto done;
- }
-
- i = arg->val;
+ if (arg->type == VAL_TASK)
+ /* Insert send right to task port. */
+ error = boot_script_insert_task_port
+ (cmd, (task_t) arg->val, &name);
+ else
+ /* Insert send right. */
+ error = boot_script_insert_right (cmd,
+ (mach_port_t) arg->val,
+ &name);
+ if (error)
+ goto done;
+
+ i = name;
p = buf + sizeof (buf);
len = 0;
do
@@ -648,7 +617,7 @@ boot_script_exec ()
argv[argc] = 0;
/* Execute the command. */
- if (boot_script_exec_cmd (cmd->task, cmd->path,
+ if (boot_script_exec_cmd (cmd->hook, cmd->task, cmd->path,
argc, argv, cmdline, cmdline_index))
{
error = BOOT_SCRIPT_EXEC_ERROR;
@@ -658,8 +627,8 @@ boot_script_exec ()
error = 0;
done:
- free (cmdline);
- free (argv);
+ boot_script_free (cmdline, cmdline_alloc);
+ boot_script_free (argv, sizeof (char *) * (cmd->args_index + 2));
if (error)
{
cleanup (1);
@@ -676,7 +645,7 @@ boot_script_exec ()
for (i = 0; i < cmd->exec_funcs_index; i++)
{
struct sym *sym = cmd->exec_funcs[i];
- int error = ((*((int (*) (struct cmd *, int *)) sym->val))
+ int error = ((*((int (*) (struct cmd *, integer_t *)) sym->val))
(cmd, 0));
if (error)
{
@@ -693,7 +662,7 @@ boot_script_exec ()
/* Create an entry for the variable NAME with TYPE and value VAL,
in the symbol table. */
int
-boot_script_set_variable (const char *name, int type, int val)
+boot_script_set_variable (const char *name, int type, integer_t val)
{
struct sym *sym = sym_enter (name);
@@ -709,14 +678,15 @@ boot_script_set_variable (const char *name, int type, int val)
/* Define the function NAME, which will return type RET_TYPE. */
int
boot_script_define_function (const char *name, int ret_type,
- int (*func) (const struct cmd *cmd, int *val))
+ int (*func) (const struct cmd *cmd,
+ integer_t *val))
{
struct sym *sym = sym_enter (name);
if (sym)
{
sym->type = VAL_FUNC;
- sym->val = (int) func;
+ sym->val = (integer_t) func;
sym->ret_type = ret_type;
sym->run_on_exec = ret_type == VAL_NONE;
}
@@ -761,7 +731,8 @@ boot_script_error_string (int err)
#include <stdio.h>
int
-boot_script_exec_cmd (mach_port_t task, char *path, int argc,
+boot_script_exec_cmd (void *hook,
+ mach_port_t task, char *path, int argc,
char **argv, char *strings, int stringlen)
{
int i;
@@ -805,7 +776,7 @@ main (int argc, char **argv)
int i, err;
i = strlen (p) + 1;
- err = boot_script_parse_line (p);
+ err = boot_script_parse_line (0, p);
if (err)
{
fprintf (stderr, "error %s\n", boot_script_error_string (err));
diff --git a/boot/boot_script.h b/boot/boot_script.h
index d2db1a14..62458693 100644
--- a/boot/boot_script.h
+++ b/boot/boot_script.h
@@ -1,5 +1,8 @@
/* Definitions for boot script parser for Mach. */
+#ifndef _boot_script_h
+#define _boot_script_h
+
/* Written by Shantanu Goel (goel@cs.columbia.edu). */
/* Error codes returned by boot_script_parse_line()
@@ -18,15 +21,19 @@
#define VAL_NONE 0 /* none -- function runs at exec time */
#define VAL_STR 1 /* string */
#define VAL_PORT 2 /* port */
+#define VAL_TASK 3 /* task port */
/* This structure describes a command. */
struct cmd
{
+ /* Cookie passed in to boot_script_parse_line. */
+ void *hook;
+
/* Path of executable. */
char *path;
/* Task port. */
- mach_port_t task;
+ task_t task;
/* Argument list. */
struct arg **args;
@@ -48,19 +55,37 @@ struct cmd
};
+/* The user must define these functions, we work like malloc and free. */
+void *boot_script_malloc (unsigned int);
+void boot_script_free (void *, unsigned int);
+
/* The user must define this function. Load the image of the
executable specified by PATH in TASK. Create a thread
in TASK and point it at the executable's entry point. Initialize
TASK's stack with argument vector ARGV of length ARGC whose
strings are STRINGS. STRINGS has length STRINGLEN.
Return 0 for success, non-zero otherwise. */
-int boot_script_exec_cmd (mach_port_t task, char *path, int argc,
+int boot_script_exec_cmd (void *hook,
+ task_t task, char *path, int argc,
char **argv, char *strings, int stringlen);
/* The user must define this function. Load the contents of FILE
into a fresh anonymous memory object and return the memory object port. */
mach_port_t boot_script_read_file (const char *file);
+/* The user must define this functions to perform the corresponding
+ Mach task manipulations. */
+int boot_script_task_create (struct cmd *); /* task_create + task_suspend */
+int boot_script_task_resume (struct cmd *);
+int boot_script_prompt_task_resume (struct cmd *);
+int boot_script_insert_right (struct cmd *, mach_port_t, mach_port_t *namep);
+int boot_script_insert_task_port (struct cmd *, task_t, mach_port_t *namep);
+
+/* The user must define this function to clean up the `task_t'
+ returned by boot_script_task_create. */
+void boot_script_free_task (task_t task, int aborting);
+
+
/* Parse the command line LINE. This causes the command line to be
converted into an internal format. Returns 0 for success, non-zero
otherwise.
@@ -68,7 +93,7 @@ mach_port_t boot_script_read_file (const char *file);
NOTE: The parser writes into the line so it must not be a string constant.
It is also the responsibility of the caller not to deallocate the line
across calls to the parser. */
-int boot_script_parse_line (char *cmdline);
+int boot_script_parse_line (void *hook, char *cmdline);
/* Execute the command lines prevously parsed.
Returns 0 for success, non-zero otherwise. */
@@ -77,14 +102,15 @@ int boot_script_exec (void);
/* Create an entry in the symbol table for variable NAME,
whose type is TYPE and value is VAL. Returns 0 on success,
non-zero otherwise. */
-int boot_script_set_variable (const char *name, int type, int val);
+int boot_script_set_variable (const char *name, int type, integer_t val);
/* Define the function NAME, which will return type RET_TYPE. */
int boot_script_define_function (const char *name, int ret_type,
- int (*func) (const struct cmd *cmd, int *val));
+ int (*func) (const struct cmd *cmd,
+ integer_t *val));
/* Returns a string describing the error ERR. */
char *boot_script_error_string (int err);
-
-void safe_gets (char *, int);
+
+#endif /* _boot_script_h */
diff --git a/boot/tcattr.c b/boot/tcattr.c
deleted file mode 100644
index fcd3293e..00000000
--- a/boot/tcattr.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library 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 C 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include <errno.h>
-#include <stddef.h>
-#include <termios.h>
-
-#undef B0
-#undef B50
-#undef B75
-#undef B110
-#undef B134
-#undef B150
-#undef B200
-#undef B300
-#undef B600
-#undef B1200
-#undef B1800
-#undef B2400
-#undef B4800
-#undef B9600
-#undef B19200
-#undef B38400
-#undef EXTA
-#undef EXTB
-#undef ECHO
-#undef TOSTOP
-#undef NOFLSH
-#undef MDMBUF
-#undef FLUSHO
-#undef PENDIN
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-#undef CERASE
-#undef CKILL
-#undef CINTR
-#undef CQUIT
-#undef CSTART
-#undef CSTOP
-#undef CEOF
-#undef CEOT
-#undef CBRK
-#undef CSUSP
-#undef CDSUSP
-#undef CRPRNT
-#undef CFLUSH
-#undef CWERASE
-#undef CLNEXT
-#undef CSTATUS
-
-#define IOCPARM_MASK 0x7f
-#define IOC_OUT 0x40000000
-#define IOC_IN 0x80000000
-#define _IOR(x,y,t) (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
-#define _IOW(x,y,t) (IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
-#define FIONREAD _IOR('f', 127, int)
-#define FIOASYNC _IOW('f', 125, int)
-#define TIOCGETP _IOR('t', 8, struct sgttyb)
-#define TIOCLGET _IOR('t', 124, int)
-#define TIOCLSET _IOW('t', 125, int)
-#define TIOCSETN _IOW('t', 10, struct sgttyb)
-#define TIOCSETP _IOW('t', 9,struct sgttyb)/* set parameters -- stty */
-#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */
-#define TIOCSETC _IOW('t',17,struct tchars)/* set special characters */
-#define TIOCGETC _IOR('t',18,struct tchars)/* get special characters */
-#define TANDEM 0x00000001 /* send stopc on out q full */
-#define CBREAK 0x00000002 /* half-cooked mode */
-#define LCASE 0x00000004 /* simulate lower case */
-#define ECHO 0x00000008 /* echo input */
-#define CRMOD 0x00000010 /* map \r to \r\n on output */
-#define RAW 0x00000020 /* no i/o processing */
-#define ODDP 0x00000040 /* get/send odd parity */
-#define EVENP 0x00000080 /* get/send even parity */
-#define ANYP 0x000000c0 /* get any parity/send none */
-#define PRTERA 0x00020000 /* \ ... / erase */
-#define CRTERA 0x00040000 /* " \b " to wipe out char */
-#define TILDE 0x00080000 /* hazeltine tilde kludge */
-#define MDMBUF 0x00100000 /* start/stop output on carrier intr */
-#define LITOUT 0x00200000 /* literal output */
-#define TOSTOP 0x00400000 /* SIGSTOP on background output */
-#define FLUSHO 0x00800000 /* flush output to terminal */
-#define NOHANG 0x01000000 /* no SIGHUP on carrier drop */
-#define L001000 0x02000000
-#define CRTKIL 0x04000000 /* kill line with " \b " */
-#define PASS8 0x08000000
-#define CTLECH 0x10000000 /* echo control chars as ^X */
-#define PENDIN 0x20000000 /* tp->t_rawq needs reread */
-#define DECCTQ 0x40000000 /* only ^Q starts after ^S */
-#define NOFLSH 0x80000000 /* no output flush on signal */
-#define TIOCLSET _IOW('t', 125, int) /* set entire local mode word */
-#define TIOCLGET _IOR('t', 124, int) /* get local modes */
-#define LCRTBS (CRTBS>>16)
-#define LPRTERA (PRTERA>>16)
-#define LCRTERA (CRTERA>>16)
-#define LTILDE (TILDE>>16)
-#define LMDMBUF (MDMBUF>>16)
-#define LLITOUT (LITOUT>>16)
-#define LTOSTOP (TOSTOP>>16)
-#define LFLUSHO (FLUSHO>>16)
-#define LNOHANG (NOHANG>>16)
-#define LCRTKIL (CRTKIL>>16)
-#define LPASS8 (PASS8>>16)
-#define LCTLECH (CTLECH>>16)
-#define LPENDIN (PENDIN>>16)
-#define LDECCTQ (DECCTQ>>16)
-#define LNOFLSH (NOFLSH>>16)
-#define TIOCSLTC _IOW('t',117,struct ltchars)/* set local special chars */
-#define TIOCGLTC _IOR('t',116,struct ltchars)/* get local special chars */
-
-
-#if defined(TIOCGETC) || defined(TIOCSETC)
-/* Type of ARG for TIOCGETC and TIOCSETC requests. */
-struct tchars
-{
- char t_intrc; /* Interrupt character. */
- char t_quitc; /* Quit character. */
- char t_startc; /* Start-output character. */
- char t_stopc; /* Stop-output character. */
- char t_eofc; /* End-of-file character. */
- char t_brkc; /* Input delimiter character. */
-};
-
-#define _IOT_tchars /* Hurd ioctl type field. */ \
- _IOT (_IOTS (char), 6, 0, 0, 0, 0)
-#endif
-
-#if defined(TIOCGLTC) || defined(TIOCSLTC)
-/* Type of ARG for TIOCGLTC and TIOCSLTC requests. */
-struct ltchars
-{
- char t_suspc; /* Suspend character. */
- char t_dsuspc; /* Delayed suspend character. */
- char t_rprntc; /* Reprint-line character. */
- char t_flushc; /* Flush-output character. */
- char t_werasc; /* Word-erase character. */
- char t_lnextc; /* Literal-next character. */
-};
-
-#define _IOT_ltchars /* Hurd ioctl type field. */ \
- _IOT (_IOTS (char), 6, 0, 0, 0, 0)
-#endif
-
-/* Type of ARG for TIOCGETP and TIOCSETP requests (and gtty and stty). */
-struct sgttyb
-{
- char sg_ispeed; /* Input speed. */
- char sg_ospeed; /* Output speed. */
- char sg_erase; /* Erase character. */
- char sg_kill; /* Kill character. */
- short int sg_flags; /* Mode flags. */
-};
-
-
-
-
-const speed_t __bsd_speeds[] =
- {
- 0,
- 50,
- 75,
- 110,
- 134,
- 150,
- 200,
- 300,
- 600,
- 1200,
- 1800,
- 2400,
- 4800,
- 9600,
- 19200,
- 38400,
- };
-
-extern int ioctl ();
-
-/* Set the state of FD to *TERMIOS_P. */
-int
-tcsetattr (int fd, int optional_actions, const struct termios *termios_p)
-{
- struct sgttyb buf;
- struct tchars tchars;
- struct ltchars ltchars;
- int local;
-#ifdef TIOCGETX
- int extra;
-#endif
- size_t i;
-
- if (ioctl(fd, TIOCGETP, &buf) < 0 ||
- ioctl(fd, TIOCGETC, &tchars) < 0 ||
- ioctl(fd, TIOCGLTC, &ltchars) < 0 ||
-#ifdef TIOCGETX
- ioctl(fd, TIOCGETX, &extra) < 0 ||
-#endif
- ioctl(fd, TIOCLGET, &local) < 0)
- return -1;
-
- if (termios_p == NULL)
- {
- errno = EINVAL;
- return -1;
- }
-
- buf.sg_ispeed = buf.sg_ospeed = -1;
- for (i = 0; i <= sizeof (__bsd_speeds) / sizeof (__bsd_speeds[0]); ++i)
- {
- if (__bsd_speeds[i] == termios_p->__ispeed)
- buf.sg_ispeed = i;
- if (__bsd_speeds[i] == termios_p->__ospeed)
- buf.sg_ospeed = i;
- }
- if (buf.sg_ispeed == -1 || buf.sg_ospeed == -1)
- {
- errno = EINVAL;
- return -1;
- }
-
- buf.sg_flags &= ~(CBREAK|RAW);
- if (!(termios_p->c_lflag & ICANON))
- buf.sg_flags |= (termios_p->c_cflag & ISIG) ? CBREAK : RAW;
-#ifdef LPASS8
- if (termios_p->c_oflag & CS8)
- local |= LPASS8;
- else
- local &= ~LPASS8;
-#endif
- if (termios_p->c_lflag & _NOFLSH)
- local |= LNOFLSH;
- else
- local &= ~LNOFLSH;
- if (termios_p->c_oflag & OPOST)
- local &= ~LLITOUT;
- else
- local |= LLITOUT;
-#ifdef TIOCGETX
- if (termios_p->c_lflag & ISIG)
- extra &= ~NOISIG;
- else
- extra |= NOISIG;
- if (termios_p->c_cflag & CSTOPB)
- extra |= STOPB;
- else
- extra &= ~STOPB;
-#endif
- if (termios_p->c_iflag & ICRNL)
- buf.sg_flags |= CRMOD;
- else
- buf.sg_flags &= ~CRMOD;
- if (termios_p->c_iflag & IXOFF)
- buf.sg_flags |= TANDEM;
- else
- buf.sg_flags &= ~TANDEM;
-
- buf.sg_flags &= ~(ODDP|EVENP);
- if (!(termios_p->c_cflag & PARENB))
- buf.sg_flags |= ODDP | EVENP;
- else if (termios_p->c_cflag & PARODD)
- buf.sg_flags |= ODDP;
- else
- buf.sg_flags |= EVENP;
-
- if (termios_p->c_lflag & _ECHO)
- buf.sg_flags |= ECHO;
- else
- buf.sg_flags &= ~ECHO;
- if (termios_p->c_lflag & ECHOE)
- local |= LCRTERA;
- else
- local &= ~LCRTERA;
- if (termios_p->c_lflag & ECHOK)
- local |= LCRTKIL;
- else
- local &= ~LCRTKIL;
- if (termios_p->c_lflag & _TOSTOP)
- local |= LTOSTOP;
- else
- local &= ~LTOSTOP;
-
- buf.sg_erase = termios_p->c_cc[VERASE];
- buf.sg_kill = termios_p->c_cc[VKILL];
- tchars.t_eofc = termios_p->c_cc[VEOF];
- tchars.t_intrc = termios_p->c_cc[VINTR];
- tchars.t_quitc = termios_p->c_cc[VQUIT];
- ltchars.t_suspc = termios_p->c_cc[VSUSP];
- tchars.t_startc = termios_p->c_cc[VSTART];
- tchars.t_stopc = termios_p->c_cc[VSTOP];
-
- if (ioctl(fd, TIOCSETP, &buf) < 0 ||
- ioctl(fd, TIOCSETC, &tchars) < 0 ||
- ioctl(fd, TIOCSLTC, &ltchars) < 0 ||
-#ifdef TIOCGETX
- ioctl(fd, TIOCSETX, &extra) < 0 ||
-#endif
- ioctl(fd, TIOCLSET, &local) < 0)
- return -1;
- return 0;
-}
-
-
-#undef tcgetattr
-
-/* Put the state of FD into *TERMIOS_P. */
-int
-tcgetattr (int fd, struct termios *termios_p)
-{
- struct sgttyb buf;
- struct tchars tchars;
- struct ltchars ltchars;
- int local;
-#ifdef TIOCGETX
- int extra;
-#endif
-
- if (termios_p == NULL)
- {
- errno = EINVAL;
- return -1;
- }
-
- if (ioctl(fd, TIOCGETP, &buf) < 0 ||
- ioctl(fd, TIOCGETC, &tchars) < 0 ||
- ioctl(fd, TIOCGLTC, &ltchars) < 0 ||
-#ifdef TIOCGETX
- ioctl(fd, TIOCGETX, &extra) < 0 ||
-#endif
- ioctl(fd, TIOCLGET, &local) < 0)
- return -1;
-
- termios_p->__ispeed = __bsd_speeds[(unsigned char) buf.sg_ispeed];
- termios_p->__ospeed = __bsd_speeds[(unsigned char) buf.sg_ospeed];
-
- termios_p->c_iflag = 0;
- termios_p->c_oflag = 0;
- termios_p->c_cflag = 0;
- termios_p->c_lflag = 0;
- termios_p->c_oflag |= CREAD | HUPCL;
-#ifdef LPASS8
- if (local & LPASS8)
- termios_p->c_oflag |= CS8;
- else
-#endif
- termios_p->c_oflag |= CS7;
- if (!(buf.sg_flags & RAW))
- {
- termios_p->c_iflag |= IXON;
- termios_p->c_cflag |= OPOST;
-#ifndef NOISIG
- termios_p->c_lflag |= ISIG;
-#endif
- }
- if ((buf.sg_flags & (CBREAK|RAW)) == 0)
- termios_p->c_lflag |= ICANON;
- if (!(buf.sg_flags & RAW) && !(local & LLITOUT))
- termios_p->c_oflag |= OPOST;
- if (buf.sg_flags & CRMOD)
- termios_p->c_iflag |= ICRNL;
- if (buf.sg_flags & TANDEM)
- termios_p->c_iflag |= IXOFF;
-#ifdef TIOCGETX
- if (!(extra & NOISIG))
- termios_p->c_lflag |= ISIG;
- if (extra & STOPB)
- termios_p->c_cflag |= CSTOPB;
-#endif
-
- switch (buf.sg_flags & (EVENP|ODDP))
- {
- case EVENP|ODDP:
- break;
- case ODDP:
- termios_p->c_cflag |= PARODD;
- default:
- termios_p->c_cflag |= PARENB;
- termios_p->c_iflag |= IGNPAR | INPCK;
- break;
- }
- if (buf.sg_flags & ECHO)
- termios_p->c_lflag |= _ECHO;
- if (local & LCRTERA)
- termios_p->c_lflag |= ECHOE;
- if (local & LCRTKIL)
- termios_p->c_lflag |= ECHOK;
- if (local & LTOSTOP)
- termios_p->c_lflag |= _TOSTOP;
- if (local & LNOFLSH)
- termios_p->c_lflag |= _NOFLSH;
-
- termios_p->c_cc[VEOF] = tchars.t_eofc;
- termios_p->c_cc[VEOL] = '\n';
- termios_p->c_cc[VERASE] = buf.sg_erase;
- termios_p->c_cc[VKILL] = buf.sg_kill;
- termios_p->c_cc[VINTR] = tchars.t_intrc;
- termios_p->c_cc[VQUIT] = tchars.t_quitc;
- termios_p->c_cc[VSTART] = tchars.t_startc;
- termios_p->c_cc[VSTOP] = tchars.t_stopc;
- termios_p->c_cc[VSUSP] = ltchars.t_suspc;
- termios_p->c_cc[VMIN] = -1;
- termios_p->c_cc[VTIME] = -1;
-
- return 0;
-}
diff --git a/boot/userland-boot.c b/boot/userland-boot.c
new file mode 100644
index 00000000..d048c00e
--- /dev/null
+++ b/boot/userland-boot.c
@@ -0,0 +1,108 @@
+/* boot_script.c support functions for running in a Mach user task.
+ Copyright (C) 2001 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <mach.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include "boot_script.h"
+
+void *
+boot_script_malloc (unsigned int size)
+{
+ return malloc (size);
+}
+
+void
+boot_script_free (void *ptr, unsigned int size)
+{
+ free (ptr);
+}
+
+
+int
+boot_script_task_create (struct cmd *cmd)
+{
+ error_t err = task_create (mach_task_self (), 0, &cmd->task);
+ if (err)
+ {
+ error (0, err, "%s: task_create", cmd->path);
+ return BOOT_SCRIPT_MACH_ERROR;
+ }
+ err = task_suspend (cmd->task);
+ if (err)
+ {
+ error (0, err, "%s: task_resume", cmd->path);
+ return BOOT_SCRIPT_MACH_ERROR;
+ }
+ return 0;
+}
+
+int
+boot_script_task_resume (struct cmd *cmd)
+{
+ error_t err = task_resume (cmd->task);
+ if (err)
+ {
+ error (0, err, "%s: task_resume", cmd->path);
+ return BOOT_SCRIPT_MACH_ERROR;
+ }
+ return 0;
+}
+
+int
+boot_script_prompt_task_resume (struct cmd *cmd)
+{
+ char xx[5];
+
+ printf ("Hit return to resume %s...", cmd->path);
+ fgets (xx, sizeof xx, stdin);
+
+ return boot_script_task_resume (cmd);
+}
+
+void
+boot_script_free_task (task_t task, int aborting)
+{
+ if (aborting)
+ task_terminate (task);
+ else
+ mach_port_deallocate (mach_task_self (), task);
+}
+
+int
+boot_script_insert_right (struct cmd *cmd, mach_port_t port, mach_port_t *name)
+{
+ error_t err = mach_port_insert_right (cmd->task,
+ port, port, MACH_MSG_TYPE_COPY_SEND);
+ if (err)
+ {
+ error (0, err, "%s: mach_port_insert_right", cmd->path);
+ return BOOT_SCRIPT_MACH_ERROR;
+ }
+ *name = port;
+ return 0;
+}
+
+int
+boot_script_insert_task_port (struct cmd *cmd, task_t task, mach_port_t *name)
+{
+ return boot_script_insert_right (cmd, task, name);
+}