summaryrefslogtreecommitdiff
path: root/serverboot
diff options
context:
space:
mode:
Diffstat (limited to 'serverboot')
-rw-r--r--serverboot/Makefile53
-rw-r--r--serverboot/assert.h50
-rw-r--r--serverboot/bootstrap.c438
-rw-r--r--serverboot/bunzip2.c169
-rw-r--r--serverboot/def_pager_setup.c152
-rw-r--r--serverboot/default_pager.c3921
-rw-r--r--serverboot/defs.h95
-rw-r--r--serverboot/dir.h142
-rw-r--r--serverboot/disk_inode.h101
-rw-r--r--serverboot/disk_inode_ffs.h99
-rw-r--r--serverboot/elf-load.c143
-rw-r--r--serverboot/exec.c147
-rw-r--r--serverboot/ext2_file_io.c983
-rw-r--r--serverboot/ffs_compat.c65
-rw-r--r--serverboot/ffs_compat.h54
-rw-r--r--serverboot/ffs_file_io.c969
-rw-r--r--serverboot/file_io.c317
-rw-r--r--serverboot/file_io.h200
-rw-r--r--serverboot/fs.h455
-rw-r--r--serverboot/gets.c90
-rw-r--r--serverboot/gunzip.c188
-rw-r--r--serverboot/kalloc.c291
-rw-r--r--serverboot/load.c555
-rw-r--r--serverboot/mach-exec.h130
-rw-r--r--serverboot/minix_ffs_compat.c62
-rw-r--r--serverboot/minix_ffs_compat.h43
-rw-r--r--serverboot/minix_file_io.c851
-rw-r--r--serverboot/minix_fs.h107
-rw-r--r--serverboot/minix_super.h49
-rw-r--r--serverboot/panic.c58
-rw-r--r--serverboot/queue.h316
-rw-r--r--serverboot/strfcns.c74
-rw-r--r--serverboot/wiring.c175
-rw-r--r--serverboot/wiring.h35
34 files changed, 0 insertions, 11577 deletions
diff --git a/serverboot/Makefile b/serverboot/Makefile
deleted file mode 100644
index 653d5963..00000000
--- a/serverboot/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 1997,99,2001,02 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 the GNU Hurd; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-dir := serverboot
-makemode := utility
-
-SRCS = bootstrap.c ffs_compat.c load.c wiring.c \
- ffs_file_io.c minix_ffs_compat.c file_io.c \
- minix_file_io.c ext2_file_io.c strfcns.c exec.c \
- panic.c elf-load.c gunzip.c bunzip2.c
-LCLHDRS = assert.h disk_inode_ffs.h fs.h queue.h defs.h \
- minix_ffs_compat.h wiring.h dir.h ffs_compat.h minix_fs.h \
- disk_inode.h file_io.h minix_super.h mach-exec.h
-EXTRA_DIST = def_pager_setup.c default_pager.c kalloc.c
-target = serverboot
-HURDLIBS = threads
-installationdir = $(bootdir)
-
-UNZIP_OBJS = unzip.o inflate.o util.o do-bunzip2.o
-OBJS = $(subst .c,.o,$(SRCS)) \
- boot_script.o userland-boot.o \
- $(UNZIP_OBJS)
-
-include ../Makeconf
-
-vpath boot_script.c $(srcdir)/../boot
-vpath userland-boot.c $(srcdir)/../boot
-
-# Look for zip stuff
-vpath %.c $(srcdir) $(srcdir)/../exec
-
-# If SMALL_BZIP2 is defined, use relatively small memory.
-# It's crucial for serverboot, because swap is not enabled yet.
-CPPFLAGS += -I$(srcdir)/../exec -DGZIP -DBZIP2 -DSMALL_BZIP2
-
-LDFLAGS += -static
-
-# Don't even bother.
-CFLAGS := $(filter-out -Wall,$(CFLAGS))
diff --git a/serverboot/assert.h b/serverboot/assert.h
deleted file mode 100644
index 9f70aec3..00000000
--- a/serverboot/assert.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#ifndef _ASSERT_H_
-#define _ASSERT_H_
-
-#ifdef ASSERTIONS
-extern void Assert();
-
-#define assert(ex) \
- do { \
- if (!(ex)) \
- Assert(__FILE__, __LINE__); \
- } while (0)
-
-#ifdef lint
-#define assert_static(x)
-#else /* lint */
-#define assert_static(x) assert(x)
-#endif /* lint */
-
-#else /* ASSERTIONS */
-#define assert(ex)
-#define assert_static(ex)
-#endif /* ASSERTIONS */
-
-#endif /* _ASSERT_H_ */
diff --git a/serverboot/bootstrap.c b/serverboot/bootstrap.c
deleted file mode 100644
index 64f7c5eb..00000000
--- a/serverboot/bootstrap.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * Bootstrap the various built-in servers.
- */
-
-#include <mach.h>
-#include <mach/message.h>
-#include <sys/reboot.h>
-
-#include <file_io.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include "../boot/boot_script.h"
-
-#if 0
-/*
- * Use 8 Kbyte stacks instead of the default 64K.
- * Use 4 Kbyte waiting stacks instead of the default 8K.
- */
-#if defined(alpha)
-vm_size_t cthread_stack_size = 16 * 1024;
-#else
-vm_size_t cthread_stack_size = 8 * 1024;
-#endif
-#endif
-
-extern
-vm_size_t cthread_wait_stack_size;
-
-mach_port_t bootstrap_master_device_port; /* local name */
-mach_port_t bootstrap_master_host_port; /* local name */
-
-int boot_load_program();
-
-char *root_name;
-char boot_script_name[MAXPATHLEN];
-
-extern void default_pager();
-extern void default_pager_initialize();
-extern void default_pager_setup();
-
-/*
- * Convert ASCII to integer.
- */
-int atoi(str)
- register const char *str;
-{
- register int n;
- register int c;
- int is_negative = 0;
-
- n = 0;
- while (*str == ' ')
- str++;
- if (*str == '-') {
- is_negative = 1;
- str++;
- }
- while ((c = *str++) >= '0' && c <= '9') {
- n = n * 10 + (c - '0');
- }
- if (is_negative)
- n = -n;
- return (n);
-}
-
-__main ()
-{
-}
-
-static void
-boot_panic (kern_return_t err)
-{
-#define PFX "bootstrap: "
- char *err_string = boot_script_error_string (err);
- char panic_string[strlen (err_string) + sizeof (PFX)];
- strcpy (panic_string, PFX);
- strcat (panic_string, err_string);
- panic (panic_string);
-#undef PFX
-}
-
-void
-safe_gets (char *str, int maxlen)
-{
- char *c = fgets (str, maxlen, stdin);
- if (c == 0) {
- perror ("fgets");
- panic ("cannot read from console");
- }
- c = strchr (c, '\n');
- if (c)
- *c = '\0';
- printf ("\r\n");
-}
-
-printf_init (device_t master)
-{
- mach_port_t cons;
- kern_return_t rc;
- rc = device_open (master, D_READ|D_WRITE, "console", &cons);
- if (rc)
- while (1) {
- volatile int x = 0;
- (void) host_reboot(bootstrap_master_host_port, RB_DEBUGGER);
- x = x / x;
- }
- stdin = mach_open_devstream (cons, "r");
- stdout = stderr = mach_open_devstream (cons, "w");
- mach_port_deallocate (mach_task_self (), cons);
- setbuf (stdout, 0);
-}
-
-/*
- * Bootstrap task.
- * Runs in user spacep.
- *
- * Called as 'boot -switches host_port device_port root_name'
- *
- */
-main(argc, argv)
- int argc;
- char **argv;
-{
- int die = 0;
- int script_paging_file (const struct cmd *cmd, integer_t *val)
- {
- printf ("*** paging files no longer supported in boot scripts ***\n\a"
- "*** use swapon %s and/or /etc/fstab instead ***\n",
- cmd->path);
- return 0;
- }
- int script_serverboot_ctl (const struct cmd *cmd, integer_t *val)
- {
- const char *const ctl = cmd->path;
- if (!strcmp (ctl, "die"))
- die = 1;
- else
- printf ("(serverboot): Unknown control word `%s' ignored\n", ctl);
- return 0;
- }
-
- void prompt_for_root ()
- {
- static char new_root[MAXPATHLEN/2];
-
- if (!root_name)
- root_name = "UNKNOWN";
- printf ("Root device name? [%s] ", root_name);
- safe_gets(new_root, sizeof(new_root));
-
- if (new_root[0] != '\0') {
- root_name = new_root;
- (void) strbuild(boot_script_name,
- "/dev/",
- root_name,
- "/boot/servers.boot",
- (char *)0);
- }
- }
-
- register kern_return_t result;
- struct file scriptf;
-
- task_t my_task = mach_task_self();
-
- char *flag_string;
-
- boolean_t ask_boot_script = 0;
- boolean_t ask_root_name = 0;
-
- /*
- * Use 4Kbyte cthread wait stacks.
- */
- cthread_wait_stack_size = 4 * 1024;
-
- /*
- * Arg 1 is flags
- */
- if (argv[1][0] != '-')
- panic("bootstrap: no flags");
-
- flag_string = argv[1];
-
- /*
- * Parse the arguments.
- */
- if (argc >= 5)
- {
- /*
- * Arg 0 is program name
- */
-
- /*
- * Arg 2 is host port number
- */
- bootstrap_master_host_port = atoi(argv[2]);
-
- /*
- * Arg 3 is device port number
- */
- bootstrap_master_device_port = atoi(argv[3]);
-
- /*
- * Arg 4 is root name
- */
- root_name = argv[4];
- }
- else if (argc == 3)
- {
- root_name = argv[2];
-
- get_privileged_ports (&bootstrap_master_host_port,
- &bootstrap_master_device_port);
- }
-
- printf_init(bootstrap_master_device_port);
-#ifdef pleasenoXXX
- panic_init(bootstrap_master_host_port);
-#endif
-
-
- /*
- * If the '-a' (ask) switch was specified, or if no
- * root device was specificed, ask for the root device.
- */
-
- if (!root_name || root_name [0] == '\0' || index(flag_string, 'a'))
- prompt_for_root ();
-
- (void) strbuild(boot_script_name,
- "/dev/",
- root_name,
- "/boot/servers.boot",
- (char *)0);
- /*
- * If the '-q' (query) switch was specified, ask for the
- * server boot script.
- */
-
- if (index(flag_string, 'q'))
- ask_boot_script = TRUE;
-
- while (TRUE) {
- if (ask_root_name)
- prompt_for_root ();
-
- if (ask_boot_script) {
- char new_boot_script[MAXPATHLEN];
-
- printf("Server boot script? [%s] ", boot_script_name);
- safe_gets(new_boot_script, sizeof(new_boot_script));
- if (new_boot_script[0] != '\0')
- strcpy(boot_script_name, new_boot_script);
- }
-
- result = open_file(bootstrap_master_device_port,
- boot_script_name,
- &scriptf);
- if (result == D_NO_SUCH_DEVICE)
- {
- printf ("Root device `%s' does not exist!\n", root_name);
- ask_root_name = ask_boot_script = TRUE;
- continue;
- }
- else
- ask_root_name = FALSE;
- if (result != 0) {
- printf("Can't open server boot script %s: %s\n",
- boot_script_name,
- strerror (result));
- ask_boot_script = TRUE;
- continue;
- }
- break;
- }
-
- /*
- * If the server boot script name was changed,
- * then use the new device name as the root device.
- */
- {
- char *dev, *end;
- int len;
-
- dev = boot_script_name;
- if (strncmp(dev, "/dev/", 5) == 0)
- dev += 5;
- end = strchr(dev, '/');
- len = end ? end-dev : strlen(dev);
- memcpy(root_name, dev, len);
- root_name[len] = 0;
- }
-
- {
- char *cmdline;
-
- /* Initialize boot script variables. */
- if (boot_script_set_variable ("host-port", VAL_PORT,
- (integer_t) bootstrap_master_host_port)
- || boot_script_set_variable ("device-port", VAL_PORT,
- (integer_t) bootstrap_master_device_port)
- || boot_script_set_variable ("root-device", VAL_STR,
- (integer_t) root_name)
- || boot_script_set_variable ("boot-args", VAL_STR,
- (integer_t) flag_string)
- || boot_script_define_function ("add-paging-file", VAL_NONE,
- &script_paging_file)
- || boot_script_define_function ("add-raw-paging-file", VAL_NONE,
- &script_paging_file)
- || boot_script_define_function ("add-linux-paging-file",
- VAL_NONE,
- &script_paging_file)
- || boot_script_define_function ("serverboot",
- VAL_NONE,
- &script_serverboot_ctl)
- )
- panic ("bootstrap: error setting boot script variables");
-
- cmdline = getenv ("MULTIBOOT_CMDLINE");
- if (cmdline != NULL
- && boot_script_set_variable ("kernel-command-line",
- VAL_STR,
- (integer_t) cmdline))
- panic ("bootstrap: error setting boot script variables");
-
- parse_script (&scriptf);
- close_file (&scriptf);
- }
-
- if (index (flag_string, 'd'))
- {
- char xx[5];
- printf ("Hit return to boot...");
- safe_gets (xx, sizeof xx);
- }
-
- result = boot_script_exec ();
-
- if (result)
- boot_panic (result);
-
-#if 0
- {
- /*
- * Delete the old stack (containing only the arguments).
- */
- vm_offset_t addr = (vm_offset_t) argv;
-
- vm_offset_t r_addr;
- vm_size_t r_size;
- vm_prot_t r_protection, r_max_protection;
- vm_inherit_t r_inheritance;
- boolean_t r_is_shared;
- memory_object_name_t r_object_name;
- vm_offset_t r_offset;
- kern_return_t kr;
-
- r_addr = addr;
-
- kr = vm_region(my_task,
- &r_addr,
- &r_size,
- &r_protection,
- &r_max_protection,
- &r_inheritance,
- &r_is_shared,
- &r_object_name,
- &r_offset);
- if ((kr == KERN_SUCCESS) && MACH_PORT_VALID(r_object_name))
- (void) mach_port_deallocate(my_task, r_object_name);
- if ((kr == KERN_SUCCESS) &&
- (r_addr <= addr) &&
- ((r_protection & (VM_PROT_READ|VM_PROT_WRITE)) ==
- (VM_PROT_READ|VM_PROT_WRITE)))
- (void) vm_deallocate(my_task, r_addr, r_size);
- }
-#endif
-
- printf ("(serverboot): terminating\n");
- while (1)
- task_terminate (mach_task_self ());
- /*NOTREACHED*/
-}
-
-/* Parse the boot script. */
-parse_script (struct file *f)
-{
- char *p, *line, *buf;
- int amt, fd, err;
- int n = 0;
-
- buf = malloc (f->f_size + 1); /* add one for null terminator we will write */
- err = read_file (f, 0, buf, f->f_size, 0);
- if (err)
- panic ("bootstrap: error reading boot script file: %s", strerror (err));
-
- line = p = buf;
- while (1)
- {
- while (p < buf + f->f_size && *p != '\n')
- p++;
- *p = '\0';
- err = boot_script_parse_line (0, line);
- if (err)
- boot_panic (err);
- if (p == buf + f->f_size)
- break;
- line = ++p;
- }
- free (buf);
-}
diff --git a/serverboot/bunzip2.c b/serverboot/bunzip2.c
deleted file mode 100644
index 9f79ade5..00000000
--- a/serverboot/bunzip2.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Modified by okuji@kuicr.kyoto-u.ac.jp for use in serverboot. */
-/* Decompressing store backend
-
- Copyright (C) 1997 Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include <stdio.h>
-#include <string.h>
-#include <setjmp.h>
-#include <cthreads.h>
-#include <errno.h>
-
-#include <file_io.h>
-
-#define IN_BUFFERING (256*1024)
-#define OUT_BUFFERING (512*1024)
-
-static struct mutex bunzip2_lock = MUTEX_INITIALIZER;
-
-/* Uncompress the contents of FROM, which should contain a valid bzip2 file,
- into memory, returning the result buffer in BUF & BUF_LEN. */
-int
-serverboot_bunzip2 (struct file *from, void **buf, size_t *buf_len)
-{
- /* Callbacks from do_bunzip2 for I/O and error interface. */
- extern int (*unzip_read) (char *buf, size_t maxread);
- extern void (*unzip_write) (const char *buf, size_t nwrite);
- extern void (*unzip_read_error) (void);
- extern void (*unzip_error) (const char *msg);
-
- /* How we return errors from our hook functions. */
- jmp_buf zerr_jmp_buf;
- int zerr;
-
- size_t offset = 0; /* Offset of read point in FROM. */
-
- /* Read at most MAXREAD (or 0 if eof) bytes into BUF from our current
- position in FROM. */
- int zread (char *buf, size_t maxread)
- {
- vm_size_t resid;
- size_t did_read;
-
- if (from->f_size - offset < maxread)
- did_read = from->f_size - offset;
- else
- did_read = maxread;
-
- zerr = read_file (from, offset, buf, did_read, &resid);
- if (zerr)
- longjmp (zerr_jmp_buf, 1);
-
- did_read -= resid;
- offset += did_read;
-
- return did_read;
- }
-
- size_t out_buf_offs = 0; /* Position in the output buffer. */
-
- /* Write uncompress data to our output buffer. */
- void zwrite (const char *wbuf, size_t nwrite)
- {
- size_t old_buf_len = *buf_len;
-
- if (out_buf_offs + nwrite > old_buf_len)
- /* Have to grow the output buffer. */
- {
- void *old_buf = *buf;
- void *new_buf = old_buf + old_buf_len; /* First try. */
- size_t new_buf_len = round_page (old_buf_len + old_buf_len + nwrite);
-
- /* Try to grow the buffer. */
- zerr =
- vm_allocate (mach_task_self (),
- (vm_address_t *)&new_buf, new_buf_len - old_buf_len,
- 0);
- if (zerr)
- /* Can't do that, try to make a bigger buffer elsewhere. */
- {
- new_buf = old_buf;
- zerr =
- vm_allocate (mach_task_self (),
- (vm_address_t *)&new_buf, new_buf_len, 1);
- if (zerr)
- longjmp (zerr_jmp_buf, 1);
-
- if (out_buf_offs > 0)
- /* Copy the old buffer into the start of the new & free it. */
- bcopy (old_buf, new_buf, out_buf_offs);
-
- vm_deallocate (mach_task_self (),
- (vm_address_t)old_buf, old_buf_len);
-
- *buf = new_buf;
- }
-
- *buf_len = new_buf_len;
- }
-
- bcopy (wbuf, *buf + out_buf_offs, nwrite);
- out_buf_offs += nwrite;
- }
-
- void zreaderr (void)
- {
- zerr = EIO;
- longjmp (zerr_jmp_buf, 1);
- }
- void zerror (const char *msg)
- {
- zerr = EINVAL;
- longjmp (zerr_jmp_buf, 2);
- }
-
- /* Try to guess a reasonable output buffer size. */
- *buf_len = round_page (from->f_size * 2);
- zerr = vm_allocate (mach_task_self (), (vm_address_t *)buf, *buf_len, 1);
- if (zerr)
- return zerr;
-
- mutex_lock (&bunzip2_lock);
-
- unzip_read = zread;
- unzip_write = zwrite;
- unzip_read_error = zreaderr;
- unzip_error = zerror;
-
- if (! setjmp (zerr_jmp_buf))
- {
- /* Call the bunzip2 engine. */
- do_bunzip2 ();
- zerr = 0;
- }
-
- mutex_unlock (&bunzip2_lock);
-
- if (zerr)
- {
- if (*buf_len > 0)
- vm_deallocate (mach_task_self (), (vm_address_t)*buf, *buf_len);
- }
- else if (out_buf_offs < *buf_len)
- /* Trim the output buffer to be the right length. */
- {
- size_t end = round_page (out_buf_offs);
- if (end < *buf_len)
- vm_deallocate (mach_task_self (),
- (vm_address_t)(*buf + end), *buf_len - end);
- *buf_len = out_buf_offs;
- }
-
- return zerr;
-}
diff --git a/serverboot/def_pager_setup.c b/serverboot/def_pager_setup.c
deleted file mode 100644
index 5e2073ec..00000000
--- a/serverboot/def_pager_setup.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-#include <mach.h>
-#include <mach/mig_errors.h>
-#include <mach/default_pager_types.h>
-
-#include <file_io.h>
-
-extern void *kalloc();
-
-/*
- * Create a paging partition given a file name
- */
-extern void create_paging_partition();
-
-kern_return_t
-add_paging_file(master_device_port, file_name, linux_signature)
- mach_port_t master_device_port;
- char *file_name;
- int linux_signature;
-{
- register struct file_direct *fdp;
- register kern_return_t result;
- struct file pfile;
- boolean_t isa_file;
-
- bzero((char *) &pfile, sizeof(struct file));
-
- result = open_file(master_device_port, file_name, &pfile);
- if (result != KERN_SUCCESS)
- return result;
-
- fdp = (struct file_direct *) kalloc(sizeof *fdp);
- bzero((char *) fdp, sizeof *fdp);
-
- isa_file = file_is_structured(&pfile);
-
- result = open_file_direct(pfile.f_dev, fdp, isa_file);
- if (result)
- panic("Can't open paging file %s: %s\n",
- file_name, strerror (result));
-
- result = add_file_direct(fdp, &pfile);
- if (result)
- panic("Can't read disk addresses: %s\n", strerror (result));
-
- close_file(&pfile);
-
- /*
- * Set up the default paging partition
- */
- create_paging_partition(file_name, fdp, isa_file, linux_signature);
-
- return result;
-}
-
-/*
- * Destroy a paging_partition given a file name
- */
-kern_return_t
-remove_paging_file(file_name)
- char *file_name;
-{
- struct file_direct *fdp = 0;
- kern_return_t kr;
-
- kr = destroy_paging_partition(file_name, &fdp);
- if (kr == KERN_SUCCESS) {
- remove_file_direct(fdp);
- kfree(fdp, sizeof(*fdp));
- }
- return kr;
-}
-
-kern_return_t
-default_pager_paging_storage (mach_port_t pager,
- mach_port_t device,
- recnum_t *runs, mach_msg_type_number_t nrun,
- default_pager_filename_t name,
- boolean_t add)
-{
- return MIG_BAD_ID;
-}
-
-#if 0 /* no longer used */
-/*
- * Set up default pager
- */
-extern char *strbuild();
-
-boolean_t
-default_pager_setup(master_device_port, server_dir_name)
- mach_port_t master_device_port;
- char *server_dir_name;
-{
- register kern_return_t result;
-
- char paging_file_name[MAXPATHLEN+1];
-
- (void) strbuild(paging_file_name,
- server_dir_name,
- "/paging_file",
- (char *)0);
-
- while (TRUE) {
- result = add_paging_file(master_device_port, paging_file_name);
- if (result == KERN_SUCCESS)
- break;
- printf("Can't open paging file %s: %d\n",
- paging_file_name,
- result);
-
- bzero(paging_file_name, sizeof(paging_file_name));
- printf("Paging file name ? ");
- safe_gets(paging_file_name, sizeof(paging_file_name));
-
- if (paging_file_name[0] == 0) {
- printf("*** WARNING: running without paging area!\n");
- return FALSE;
- }
- }
-
- /*
- * Our caller will become the default pager - later
- */
-
- return TRUE;
-}
-#endif
diff --git a/serverboot/default_pager.c b/serverboot/default_pager.c
deleted file mode 100644
index 41c2768d..00000000
--- a/serverboot/default_pager.c
+++ /dev/null
@@ -1,3921 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Default pager. Pages to paging partition.
- *
- * MUST BE ABLE TO ALLOCATE WIRED-DOWN MEMORY!!!
- */
-
-#include <mach.h>
-#include <mach/message.h>
-#include <mach/notify.h>
-#include <mach/mig_errors.h>
-#include <mach/thread_switch.h>
-#include <mach/task_info.h>
-#include <mach/default_pager_types.h>
-
-#include <cthreads.h>
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <queue.h>
-#include <wiring.h>
-
-#include <assert.h>
-#include <stdio.h>
-
-#include <file_io.h>
-
-#include "default_pager_S.h"
-
-#define debug 0
-
-extern void *kalloc();
-
-static char my_name[] = "(default pager):";
-
-static struct mutex printf_lock = MUTEX_INITIALIZER;
-
-#define dprintf(f, x...) \
- ({ mutex_lock (&printf_lock); printf (f , ##x); fflush (stdout); mutex_unlock (&printf_lock); })
-#define ddprintf(f, x...) ((void)0)
-
-/*
- * parallel vs serial switch
- */
-#define PARALLEL 1
-
-#if 0
-#define CHECKSUM 1
-#endif
-
-#define USE_PRECIOUS 1
-
-#define ptoa(p) ((p)*vm_page_size)
-#define atop(a) ((a)/vm_page_size)
-
-/*
-
- */
-/*
- * Bitmap allocation.
- */
-typedef unsigned int bm_entry_t;
-#define NB_BM 32
-#define BM_MASK 0xffffffff
-
-#define howmany(a,b) (((a) + (b) - 1)/(b))
-
-/*
- * Value to indicate no block assigned
- */
-#define NO_BLOCK ((vm_offset_t)-1)
-
-/*
- * 'Partition' structure for each paging area.
- * Controls allocation of blocks within paging area.
- */
-struct part {
- struct mutex p_lock; /* for bitmap/free */
- vm_size_t total_size; /* total number of blocks */
- vm_size_t free; /* number of blocks free */
- unsigned int id; /* named lookup */
- bm_entry_t *bitmap; /* allocation map */
- boolean_t going_away; /* destroy attempt in progress */
- struct file_direct *file; /* file paged to */
-};
-typedef struct part *partition_t;
-
-struct {
- struct mutex lock;
- int n_partitions;
- partition_t *partition_list;/* array, for quick mapping */
-} all_partitions; /* list of all such */
-
-typedef unsigned char p_index_t;
-
-#define P_INDEX_INVALID ((p_index_t)-1)
-
-#define no_partition(x) ((x) == P_INDEX_INVALID)
-
-partition_t partition_of(x)
- int x;
-{
- if (x >= all_partitions.n_partitions || x < 0)
- panic("partition_of x%x", x);
- return all_partitions.partition_list[x];
-}
-
-void set_partition_of(x, p)
- int x;
- partition_t p;
-{
- if (x >= all_partitions.n_partitions || x < 0)
- panic("set_partition_of x%x", x);
- all_partitions.partition_list[x] = p;
-}
-
-/*
- * Simple mapping from (file)NAME to id
- * Saves space, filenames can be long.
- */
-unsigned int
-part_id(const unsigned char *name)
-{
- register unsigned int len, id, xorid;
-
- len = strlen(name);
- id = xorid = 0;
- while (len--) {
- xorid ^= *name;
- id += *name++;
- }
- return (id << 8) | xorid;
-}
-
-partition_init()
-{
- mutex_init(&all_partitions.lock);
- all_partitions.n_partitions = 0;
-}
-
-static partition_t
-new_partition (const char *name, struct file_direct *fdp,
- int check_linux_signature)
-{
- register partition_t part;
- register vm_size_t size, bmsize;
- vm_offset_t raddr;
- mach_msg_type_number_t rsize;
- int rc;
- unsigned int id = part_id(name);
-
- mutex_lock(&all_partitions.lock);
- {
- unsigned int i;
- for (i = 0; i < all_partitions.n_partitions; i++)
- {
- part = partition_of(i);
- if (part && part->id == id)
- {
- printf ("(default pager): Already paging to partition %s!\n",
- name);
- mutex_unlock(&all_partitions.lock);
- return 0;
- }
- }
- }
- mutex_unlock(&all_partitions.lock);
-
- size = atop(fdp->fd_size * fdp->fd_bsize);
- bmsize = howmany(size, NB_BM) * sizeof(bm_entry_t);
-
- part = (partition_t) kalloc(sizeof(struct part));
- mutex_init(&part->p_lock);
- part->total_size = size;
- part->free = size;
- part->id = id;
- part->bitmap = (bm_entry_t *)kalloc(bmsize);
- part->going_away= FALSE;
- part->file = fdp;
-
- bzero((char *)part->bitmap, bmsize);
-
- if (check_linux_signature < 0)
- {
- if (check_linux_signature != -3)
- printf("(default pager): "
- "Paging to raw partition %s (%uk paging space)\n",
- name, part->total_size * (vm_page_size / 1024));
- return part;
- }
-
-#define LINUX_PAGE_SIZE 4096 /* size of pages in Linux swap partitions */
- rc = page_read_file_direct(part->file,
- 0, LINUX_PAGE_SIZE,
- &raddr,
- &rsize);
- if (rc)
- panic("(default pager): cannot read first page of %s! rc=%#x\n",
- name, rc);
- while (rsize < LINUX_PAGE_SIZE)
- {
- /* Filesystem block size is smaller than page size,
- so we must do several reads to get the whole page. */
- vm_address_t baddr, bsize;
- rc = page_read_file_direct(part->file,
- rsize, LINUX_PAGE_SIZE-rsize,
- &baddr,
- &bsize);
- if (rc)
- panic("(default pager): "
- "cannot read first page of %s! rc=%#x at %#x\n",
- name, rc, rsize);
-
- memcpy ((char *) raddr + rsize, (void *) baddr, bsize);
- rsize += bsize;
- vm_deallocate (mach_task_self (), baddr, bsize);
- }
-
- if (!memcmp("SWAP-SPACE", (char *) raddr + LINUX_PAGE_SIZE-10, 10))
- {
- /* The partition's first page has a Linux swap signature.
- This means the beginning of the page contains a bitmap
- of good pages, and all others are bad. */
- unsigned int i, j, bad, max;
- int waste;
-
- printf("(default pager): Found Linux 2.0 swap signature in %s\n",
- name);
-
- /* The first page, and the pages corresponding to the bits
- occupied by the signature in the final 10 bytes of the page,
- are always unavailable ("bad"). */
- *(u_int32_t *)raddr &= ~(u_int32_t) 1;
- memset((char *) raddr + LINUX_PAGE_SIZE-10, 0, 10);
-
- max = LINUX_PAGE_SIZE / sizeof(u_int32_t);
- if (max > (part->total_size + 31) / 32)
- max = (part->total_size + 31) / 32;
-
- bad = 0;
- for (i = 0; i < max; ++i)
- {
- u_int32_t bm = ((u_int32_t *) raddr)[i];
- if (bm == ~(u_int32_t) 0)
- continue;
- /* There are some zero bits in this word. */
- for (j = 0; j < 32; ++j)
- if ((bm & (1 << j)) == 0)
- {
- unsigned int p = i*32 + j;
- if (p >= part->total_size)
- break;
- ++bad;
- part->bitmap[p / NB_BM] |= 1 << (p % NB_BM);
- }
- }
- part->free -= bad;
-
- --bad; /* Don't complain about first page. */
- waste = part->total_size - (8 * (LINUX_PAGE_SIZE-10));
- if (waste > 0)
- {
- /* The wasted pages were already marked "bad". */
- bad -= waste;
- if (bad > 0)
- printf("\
-(default pager): Paging to %s, %dk swap-space (%dk bad, %dk wasted at end)\n",
- name,
- part->free * (LINUX_PAGE_SIZE / 1024),
- bad * (LINUX_PAGE_SIZE / 1024),
- waste * (LINUX_PAGE_SIZE / 1024));
- else
- printf("\
-(default pager): Paging to %s, %dk swap-space (%dk wasted at end)\n",
- name,
- part->free * (LINUX_PAGE_SIZE / 1024),
- waste * (LINUX_PAGE_SIZE / 1024));
- }
- else if (bad > 0)
- printf("\
-(default pager): Paging to %s, %dk swap-space (excludes %dk marked bad)\n",
- name,
- part->free * (LINUX_PAGE_SIZE / 1024),
- bad * (LINUX_PAGE_SIZE / 1024));
- else
- printf("\
-(default pager): Paging to %s, %dk swap-space\n",
- name,
- part->free * (LINUX_PAGE_SIZE / 1024));
- }
- else if (!memcmp("SWAPSPACE2",
- (char *) raddr + LINUX_PAGE_SIZE-10, 10))
- {
- struct
- {
- u_int8_t bootbits[1024];
- u_int32_t version;
- u_int32_t last_page;
- u_int32_t nr_badpages;
- u_int32_t padding[125];
- u_int32_t badpages[1];
- } *hdr = (void *) raddr;
-
- printf("\
-(default pager): Found Linux 2.2 swap signature (v%u) in %s...",
- hdr->version, name);
-
- part->bitmap[0] |= 1; /* first page unusable */
- part->free--;
-
- switch (hdr->version)
- {
- default:
- if (check_linux_signature)
- {
- printf ("version %u unknown! SKIPPING %s!\n",
- hdr->version,
- name);
- vm_deallocate(mach_task_self(), raddr, rsize);
- kfree(part->bitmap, bmsize);
- kfree(part, sizeof *part);
- return 0;
- }
- else
- printf ("version %u unknown! IGNORING SIGNATURE PAGE!"
- " %dk swap-space\n",
- hdr->version,
- part->free * (LINUX_PAGE_SIZE / 1024));
- break;
-
- case 1:
- {
- unsigned int waste, i;
- if (hdr->last_page > part->total_size)
- {
- printf ("signature says %uk, partition has only %uk! ",
- hdr->last_page * (LINUX_PAGE_SIZE / 1024),
- part->total_size * (LINUX_PAGE_SIZE / 1024));
- waste = 0;
- }
- else
- {
- waste = part->total_size - hdr->last_page;
- part->total_size = hdr->last_page;
- part->free = part->total_size - 1;
- }
- for (i = 0; i < hdr->nr_badpages; ++i)
- {
- const u_int32_t bad = hdr->badpages[i];
- part->bitmap[bad / NB_BM] |= 1 << (bad % NB_BM);
- part->free--;
- }
- printf ("%uk swap-space",
- part->free * (LINUX_PAGE_SIZE / 1024));
- if (hdr->nr_badpages != 0)
- printf (" (excludes %uk marked bad)",
- hdr->nr_badpages * (LINUX_PAGE_SIZE / 1024));
- if (waste != 0)
- printf (" (excludes %uk at end of partition)",
- waste * (LINUX_PAGE_SIZE / 1024));
- printf ("\n");
- }
- }
- }
- else if (check_linux_signature)
- {
- printf ("(default pager): "
- "Cannot find Linux swap signature page! "
- "SKIPPING %s (%uk partition)!",
- name, part->total_size * (vm_page_size / 1024));
- kfree(part->bitmap, bmsize);
- kfree(part, sizeof *part);
- part = 0;
- }
- else
- printf("(default pager): "
- "Paging to raw partition %s (%uk paging space)\n",
- name, part->total_size * (vm_page_size / 1024));
-
- vm_deallocate(mach_task_self(), raddr, rsize);
-
- return part;
-}
-
-/*
- * Create a partition descriptor,
- * add it to the list of all such.
- * size is in BYTES.
- */
-void
-create_paging_partition(const char *name,
- struct file_direct *fdp, int isa_file,
- int linux_signature)
-{
- register partition_t part;
-
- part = new_partition (name, fdp, linux_signature);
- if (!part)
- return;
-
- mutex_lock(&all_partitions.lock);
- {
- register int i;
-
- for (i = 0; i < all_partitions.n_partitions; i++)
- if (partition_of(i) == 0) break;
-
- if (i == all_partitions.n_partitions) {
- register partition_t *new_list, *old_list;
- register int n;
-
- n = i ? (i<<1) : 2;
- new_list = (partition_t *)
- kalloc( n * sizeof(partition_t) );
- if (new_list == 0) no_paging_space(TRUE);
- bzero(new_list, n*sizeof(partition_t));
- if (i) {
- old_list = all_partitions.partition_list;
- bcopy(old_list, new_list, i*sizeof(partition_t));
- }
- all_partitions.partition_list = new_list;
- all_partitions.n_partitions = n;
- if (i) kfree(old_list, i*sizeof(partition_t));
- }
- set_partition_of(i, part);
- }
- mutex_unlock(&all_partitions.lock);
-
-#if 0
- dprintf("%s Added paging %s %s\n", my_name,
- (isa_file) ? "file" : "device", name);
-#endif
- overcommitted(TRUE, part->free);
-}
-
-/*
- * Choose the most appropriate default partition
- * for an object of SIZE bytes.
- * Return the partition locked, unless
- * the object has no CUR_PARTition.
- */
-p_index_t
-choose_partition(size, cur_part)
- unsigned int size;
- register p_index_t cur_part;
-{
- register partition_t part;
- register boolean_t found = FALSE;
- register int i;
-
- mutex_lock(&all_partitions.lock);
- for (i = 0; i < all_partitions.n_partitions; i++) {
-
- /* the undesireable one ? */
- if (i == cur_part)
- continue;
-
-ddprintf ("choose_partition(%x,%d,%d)\n",size,cur_part,i);
- /* one that was removed ? */
- if ((part = partition_of(i)) == 0)
- continue;
-
- /* one that is being removed ? */
- if (part->going_away)
- continue;
-
- /* is it big enough ? */
- mutex_lock(&part->p_lock);
- if (ptoa(part->free) >= size) {
- if (cur_part != P_INDEX_INVALID) {
- mutex_unlock(&all_partitions.lock);
- return (p_index_t)i;
- } else
- found = TRUE;
- }
- mutex_unlock(&part->p_lock);
-
- if (found) break;
- }
- mutex_unlock(&all_partitions.lock);
- return (found) ? (p_index_t)i : P_INDEX_INVALID;
-}
-
-/*
- * Allocate a page in a paging partition
- * The partition is returned unlocked.
- */
-vm_offset_t
-pager_alloc_page(pindex, lock_it)
- p_index_t pindex;
-{
- register int bm_e;
- register int bit;
- register int limit;
- register bm_entry_t *bm;
- partition_t part;
- static char here[] = "%spager_alloc_page";
-
- if (no_partition(pindex))
- return (NO_BLOCK);
-ddprintf ("pager_alloc_page(%d,%d)\n",pindex,lock_it);
- part = partition_of(pindex);
-
- /* unlikely, but possible deadlock against destroy_partition */
- if (!part || part->going_away)
- return (NO_BLOCK);
-
- if (lock_it)
- mutex_lock(&part->p_lock);
-
- if (part->free == 0) {
- /* out of paging space */
- mutex_unlock(&part->p_lock);
- return (NO_BLOCK);
- }
-
- limit = howmany(part->total_size, NB_BM);
- bm = part->bitmap;
- for (bm_e = 0; bm_e < limit; bm_e++, bm++)
- if (*bm != BM_MASK)
- break;
-
- if (bm_e == limit)
- panic(here,my_name);
-
- /*
- * Find and set the proper bit
- */
- {
- register bm_entry_t b = *bm;
-
- for (bit = 0; bit < NB_BM; bit++)
- if ((b & (1<<bit)) == 0)
- break;
- if (bit == NB_BM)
- panic(here,my_name);
-
- *bm = b | (1<<bit);
- part->free--;
-
- }
-
- mutex_unlock(&part->p_lock);
-
- return (bm_e*NB_BM+bit);
-}
-
-/*
- * Deallocate a page in a paging partition
- */
-void
-pager_dealloc_page(pindex, page, lock_it)
- p_index_t pindex;
- register vm_offset_t page;
-{
- register partition_t part;
- register int bit, bm_e;
-
- /* be paranoid */
- if (no_partition(pindex))
- panic("%sdealloc_page",my_name);
-ddprintf ("pager_dealloc_page(%d,%x,%d)\n",pindex,page,lock_it);
- part = partition_of(pindex);
-
- if (page >= part->total_size)
- panic("%sdealloc_page",my_name);
-
- bm_e = page / NB_BM;
- bit = page % NB_BM;
-
- if (lock_it)
- mutex_lock(&part->p_lock);
-
- part->bitmap[bm_e] &= ~(1<<bit);
- part->free++;
-
- if (lock_it)
- mutex_unlock(&part->p_lock);
-}
-
-/*
-
- */
-/*
- * Allocation info for each paging object.
- *
- * Most operations, even pager_write_offset and pager_put_checksum,
- * just need a read lock. Higher-level considerations prevent
- * conflicting operations on a single page. The lock really protects
- * the underlying size and block map memory, so pager_extend needs a
- * write lock.
- *
- * An object can now span multiple paging partitions. The allocation
- * info we keep is a pair (offset,p_index) where the index is in the
- * array of all partition ptrs, and the offset is partition-relative.
- * Size wise we are doing ok fitting the pair into a single integer:
- * the offset really is in pages so we have vm_page_size bits available
- * for the partition index.
- */
-#define DEBUG_READER_CONFLICTS 0
-
-#if DEBUG_READER_CONFLICTS
-int default_pager_read_conflicts = 0;
-#endif
-
-union dp_map {
-
- struct {
- unsigned int p_offset : 24,
- p_index : 8;
- } block;
-
- union dp_map *indirect;
-};
-typedef union dp_map *dp_map_t;
-
-/* quick check for part==block==invalid */
-#define no_block(e) ((e).indirect == (dp_map_t)NO_BLOCK)
-#define invalidate_block(e) ((e).indirect = (dp_map_t)NO_BLOCK)
-
-struct dpager {
- struct mutex lock; /* lock for extending block map */
- /* XXX should be read-write lock */
-#if DEBUG_READER_CONFLICTS
- int readers;
- boolean_t writer;
-#endif
- dp_map_t map; /* block map */
- vm_size_t size; /* size of paging object, in pages */
- vm_size_t limit; /* limit (bytes) allowed to grow to */
- p_index_t cur_partition;
-#ifdef CHECKSUM
- vm_offset_t *checksum; /* checksum - parallel to block map */
-#define NO_CHECKSUM ((vm_offset_t)-1)
-#endif /* CHECKSUM */
-};
-typedef struct dpager *dpager_t;
-
-/*
- * A paging object uses either a one- or a two-level map of offsets
- * into a paging partition.
- */
-#define PAGEMAP_ENTRIES 64
- /* number of pages in a second-level map */
-#define PAGEMAP_SIZE(npgs) ((npgs)*sizeof(vm_offset_t))
-
-#define INDIRECT_PAGEMAP_ENTRIES(npgs) \
- ((((npgs)-1)/PAGEMAP_ENTRIES) + 1)
-#define INDIRECT_PAGEMAP_SIZE(npgs) \
- (INDIRECT_PAGEMAP_ENTRIES(npgs) * sizeof(vm_offset_t *))
-#define INDIRECT_PAGEMAP(size) \
- (size > PAGEMAP_ENTRIES)
-
-#define ROUNDUP_TO_PAGEMAP(npgs) \
- (((npgs) + PAGEMAP_ENTRIES - 1) & ~(PAGEMAP_ENTRIES - 1))
-
-/*
- * Object sizes are rounded up to the next power of 2,
- * unless they are bigger than a given maximum size.
- */
-vm_size_t max_doubled_size = 4 * 1024 * 1024; /* 4 meg */
-
-/*
- * Attach a new paging object to a paging partition
- */
-void
-pager_alloc(pager, part, size)
- register dpager_t pager;
- p_index_t part;
- register vm_size_t size; /* in BYTES */
-{
- register int i;
- register dp_map_t mapptr, emapptr;
-
- mutex_init(&pager->lock);
-#if DEBUG_READER_CONFLICTS
- pager->readers = 0;
- pager->writer = FALSE;
-#endif
- pager->cur_partition = part;
-
- /*
- * Convert byte size to number of pages, then increase to the nearest
- * power of 2.
- */
- size = atop(size);
- if (size <= atop(max_doubled_size)) {
- i = 1;
- while (i < size)
- i <<= 1;
- size = i;
- } else
- size = ROUNDUP_TO_PAGEMAP(size);
-
- /*
- * Allocate and initialize the block map
- */
- {
- register vm_size_t alloc_size;
- dp_map_t init_value;
-
- if (INDIRECT_PAGEMAP(size)) {
- alloc_size = INDIRECT_PAGEMAP_SIZE(size);
- init_value = (dp_map_t)0;
- } else {
- alloc_size = PAGEMAP_SIZE(size);
- init_value = (dp_map_t)NO_BLOCK;
- }
-
- mapptr = (dp_map_t) kalloc(alloc_size);
- for (emapptr = &mapptr[(alloc_size-1) / sizeof(vm_offset_t)];
- emapptr >= mapptr;
- emapptr--)
- emapptr->indirect = init_value;
-
- }
- pager->map = mapptr;
- pager->size = size;
- pager->limit = (vm_size_t)-1;
-
-#ifdef CHECKSUM
- if (INDIRECT_PAGEMAP(size)) {
- mapptr = (vm_offset_t *)
- kalloc(INDIRECT_PAGEMAP_SIZE(size));
- for (i = INDIRECT_PAGEMAP_ENTRIES(size); --i >= 0;)
- mapptr[i] = 0;
- } else {
- mapptr = (vm_offset_t *) kalloc(PAGEMAP_SIZE(size));
- for (i = 0; i < size; i++)
- mapptr[i] = NO_CHECKSUM;
- }
- pager->checksum = mapptr;
-#endif /* CHECKSUM */
-}
-
-/*
- * Return size (in bytes) of space actually allocated to this pager.
- * The pager is read-locked.
- */
-
-vm_size_t
-pager_allocated(pager)
- register dpager_t pager;
-{
- vm_size_t size;
- register dp_map_t map, emap;
- vm_size_t asize;
-
- size = pager->size; /* in pages */
- asize = 0; /* allocated, in pages */
- map = pager->map;
-
- if (INDIRECT_PAGEMAP(size)) {
- for (emap = &map[INDIRECT_PAGEMAP_ENTRIES(size)];
- map < emap; map++) {
-
- register dp_map_t map2, emap2;
-
- if ((map2 = map->indirect) == 0)
- continue;
-
- for (emap2 = &map2[PAGEMAP_ENTRIES];
- map2 < emap2; map2++)
- if ( ! no_block(*map2) )
- asize++;
-
- }
- } else {
- for (emap = &map[size]; map < emap; map++)
- if ( ! no_block(*map) )
- asize++;
- }
-
- return ptoa(asize);
-}
-
-/*
- * Find offsets (in the object) of pages actually allocated to this pager.
- * Returns the number of allocated pages, whether or not they all fit.
- * The pager is read-locked.
- */
-
-unsigned int
-pager_pages(pager, pages, numpages)
- dpager_t pager;
- register default_pager_page_t *pages;
- unsigned int numpages;
-{
- vm_size_t size;
- dp_map_t map, emap;
- unsigned int actual;
- vm_offset_t offset;
-
- size = pager->size; /* in pages */
- map = pager->map;
- actual = 0;
- offset = 0;
-
- if (INDIRECT_PAGEMAP(size)) {
- for (emap = &map[INDIRECT_PAGEMAP_ENTRIES(size)];
- map < emap; map++) {
-
- register dp_map_t map2, emap2;
-
- if ((map2 = map->indirect) == 0) {
- offset += vm_page_size * PAGEMAP_ENTRIES;
- continue;
- }
- for (emap2 = &map2[PAGEMAP_ENTRIES];
- map2 < emap2; map2++)
- if ( ! no_block(*map2) ) {
- if (actual++ < numpages)
- pages++->dpp_offset = offset;
- }
- offset += vm_page_size;
- }
- } else {
- for (emap = &map[size]; map < emap; map++)
- if ( ! no_block(*map) ) {
- if (actual++ < numpages)
- pages++->dpp_offset = offset;
- }
- offset += vm_page_size;
- }
- return actual;
-}
-
-/*
- * Extend the map for a paging object.
- *
- * XXX This implementation can allocate an arbitrary large amount
- * of wired memory when extending a big block map. Because vm-privileged
- * threads call pager_extend, this can crash the system by exhausting
- * system memory.
- */
-void
-pager_extend(pager, new_size)
- register dpager_t pager;
- register vm_size_t new_size; /* in pages */
-{
- register dp_map_t new_mapptr;
- register dp_map_t old_mapptr;
- register int i;
- register vm_size_t old_size;
-
- mutex_lock(&pager->lock); /* XXX lock_write */
-#if DEBUG_READER_CONFLICTS
- pager->writer = TRUE;
-#endif
- /*
- * Double current size until we cover new size.
- * If object is 'too big' just use new size.
- */
- old_size = pager->size;
-
- if (new_size <= atop(max_doubled_size)) {
- i = old_size;
- while (i < new_size)
- i <<= 1;
- new_size = i;
- } else
- new_size = ROUNDUP_TO_PAGEMAP(new_size);
-
- if (INDIRECT_PAGEMAP(old_size)) {
- /*
- * Pager already uses two levels. Allocate
- * a larger indirect block.
- */
- new_mapptr = (dp_map_t)
- kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
- old_mapptr = pager->map;
- for (i = 0; i < INDIRECT_PAGEMAP_ENTRIES(old_size); i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
- new_mapptr[i].indirect = (dp_map_t)0;
- kfree((char *)old_mapptr, INDIRECT_PAGEMAP_SIZE(old_size));
- pager->map = new_mapptr;
- pager->size = new_size;
-#ifdef CHECKSUM
- new_mapptr = (vm_offset_t *)
- kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
- old_mapptr = pager->checksum;
- for (i = 0; i < INDIRECT_PAGEMAP_ENTRIES(old_size); i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
- new_mapptr[i] = 0;
- kfree((char *)old_mapptr, INDIRECT_PAGEMAP_SIZE(old_size));
- pager->checksum = new_mapptr;
-#endif /* CHECKSUM */
-#if DEBUG_READER_CONFLICTS
- pager->writer = FALSE;
-#endif
- mutex_unlock(&pager->lock);
-#if 0
- ddprintf ("pager_extend 1 mapptr %x [3b] = %x\n", new_mapptr,
- new_mapptr[0x3b]);
- if (new_mapptr[0x3b].indirect > 0x10000
- && new_mapptr[0x3b].indirect != NO_BLOCK)
- panic ("debug panic");
-#endif
- return;
- }
-
- if (INDIRECT_PAGEMAP(new_size)) {
- /*
- * Changing from direct map to indirect map.
- * Allocate both indirect and direct map blocks,
- * since second-level (direct) block must be
- * full size (PAGEMAP_SIZE(PAGEMAP_ENTRIES)).
- */
-
- /*
- * Allocate new second-level map first.
- */
- new_mapptr = (dp_map_t) kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- old_mapptr = pager->map;
- for (i = 0; i < old_size; i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < PAGEMAP_ENTRIES; i++)
- invalidate_block(new_mapptr[i]);
- kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
- old_mapptr = new_mapptr;
-
-#if 0
- ddprintf ("pager_extend 2 mapptr %x [3b] = %x\n", new_mapptr,
- new_mapptr[0x3b]);
- if (new_mapptr[0x3b].indirect > 0x10000
- && new_mapptr[0x3b].indirect != NO_BLOCK)
- panic ("debug panic");
-#endif
-
- /*
- * Now allocate indirect map.
- */
- new_mapptr = (dp_map_t)
- kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
- new_mapptr[0].indirect = old_mapptr;
- for (i = 1; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
- new_mapptr[i].indirect = 0;
- pager->map = new_mapptr;
- pager->size = new_size;
-#ifdef CHECKSUM
- /*
- * Allocate new second-level map first.
- */
- new_mapptr = (vm_offset_t *)kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- old_mapptr = pager->checksum;
- for (i = 0; i < old_size; i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < PAGEMAP_ENTRIES; i++)
- new_mapptr[i] = NO_CHECKSUM;
- kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
- old_mapptr = new_mapptr;
-
- /*
- * Now allocate indirect map.
- */
- new_mapptr = (vm_offset_t *)
- kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
- new_mapptr[0] = (vm_offset_t) old_mapptr;
- for (i = 1; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
- new_mapptr[i] = 0;
- pager->checksum = new_mapptr;
-#endif /* CHECKSUM */
-#if DEBUG_READER_CONFLICTS
- pager->writer = FALSE;
-#endif
- mutex_unlock(&pager->lock);
- return;
- }
- /*
- * Enlarging a direct block.
- */
- new_mapptr = (dp_map_t) kalloc(PAGEMAP_SIZE(new_size));
- old_mapptr = pager->map;
- for (i = 0; i < old_size; i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < new_size; i++)
- invalidate_block(new_mapptr[i]);
- kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
- pager->map = new_mapptr;
- pager->size = new_size;
-#ifdef CHECKSUM
- new_mapptr = (vm_offset_t *)
- kalloc(PAGEMAP_SIZE(new_size));
- old_mapptr = pager->checksum;
- for (i = 0; i < old_size; i++)
- new_mapptr[i] = old_mapptr[i];
- for (; i < new_size; i++)
- new_mapptr[i] = NO_CHECKSUM;
- kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
- pager->checksum = new_mapptr;
-#endif /* CHECKSUM */
-#if DEBUG_READER_CONFLICTS
- pager->writer = FALSE;
-#endif
- mutex_unlock(&pager->lock);
-}
-
-/* Truncate a memory object. First, any pages between the new size
- and the (larger) old size are deallocated. Then, the size of
- the pagemap may be reduced, an indirect map may be turned into
- a direct map.
-
- The pager must be locked by the caller. */
-static void
-pager_truncate(dpager_t pager, vm_size_t new_size) /* in pages */
-{
- dp_map_t new_mapptr;
- dp_map_t old_mapptr;
- int i;
- vm_size_t old_size;
-
- /* This deallocates the pages necessary to truncate a direct map
- previously of size NEW_SIZE to the smaller size OLD_SIZE. */
- inline void dealloc_direct (dp_map_t mapptr,
- vm_size_t old_size, vm_size_t new_size)
- {
- vm_size_t i;
- for (i = new_size; i < old_size; ++i)
- {
- const union dp_map entry = mapptr[i];
- pager_dealloc_page(entry.block.p_index, entry.block.p_offset,
- TRUE);
- invalidate_block(mapptr[i]);
- }
- }
-
- old_size = pager->size;
-
- if (INDIRECT_PAGEMAP(old_size))
- {
- /* First handle the entire second-levels blocks that are being freed. */
- for (i = INDIRECT_PAGEMAP_ENTRIES(new_size);
- i < INDIRECT_PAGEMAP_ENTRIES(old_size);
- ++i)
- {
- const dp_map_t mapptr = pager->map[i].indirect;
- pager->map[i].indirect = (dp_map_t)0;
- dealloc_direct (mapptr, PAGEMAP_ENTRIES, 0);
- kfree ((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- }
-
- /* Now truncate what's now the final nonempty direct block. */
- dealloc_direct (pager->map[(new_size - 1) / PAGEMAP_ENTRIES].indirect,
- old_size & (PAGEMAP_ENTRIES - 1),
- new_size & (PAGEMAP_ENTRIES - 1));
-
- if (INDIRECT_PAGEMAP (new_size))
- {
- if (INDIRECT_PAGEMAP_SIZE (new_size) >= vm_page_size)
- /* XXX we know how kalloc.c works; avoid copying. */
- kfree ((char *) round_page ((vm_address_t) pager->map
- + INDIRECT_PAGEMAP_SIZE (new_size)),
- round_page (INDIRECT_PAGEMAP_SIZE (old_size))
- - round_page (INDIRECT_PAGEMAP_SIZE (new_size)));
- else
- {
- const dp_map_t old_mapptr = pager->map;
- pager->map = (dp_map_t) kalloc (INDIRECT_PAGEMAP_SIZE(new_size));
- memcpy (pager->map, old_mapptr, INDIRECT_PAGEMAP_SIZE(old_size));
- kfree ((char *) old_mapptr, INDIRECT_PAGEMAP_SIZE (old_size));
- }
- }
- else
- {
- /* We are truncating to a size small enough that it goes to using
- a one-level map. We already have that map, as the first and only
- nonempty element in our indirect map. */
- const dp_map_t mapptr = pager->map[0].indirect;
- kfree((char *)pager->map, INDIRECT_PAGEMAP_SIZE(old_size));
- pager->map = mapptr;
- old_size = PAGEMAP_ENTRIES;
- }
- }
-
- if (new_size == 0)
- new_size = 1;
-
- if (! INDIRECT_PAGEMAP(old_size))
- {
- /* First deallocate pages in the truncated region. */
- dealloc_direct (pager->map, old_size, new_size);
- /* Now reduce the size of the direct map itself. We don't bother
- with kalloc/kfree if it's not shrinking enough that kalloc.c
- would actually use less. */
- if (PAGEMAP_SIZE (new_size) <= PAGEMAP_SIZE (old_size) / 2)
- {
- const dp_map_t old_mapptr = pager->map;
- pager->map = (dp_map_t) kalloc (PAGEMAP_SIZE (new_size));
- memcpy (pager->map, old_mapptr, PAGEMAP_SIZE (old_size));
- kfree ((char *) old_mapptr, PAGEMAP_SIZE (old_size));
- }
- }
-
- pager->size = new_size;
-
-#ifdef CHECKSUM
-#error write me
-#endif /* CHECKSUM */
-}
-
-
-/*
- * Given an offset within a paging object, find the
- * corresponding block within the paging partition.
- * Return NO_BLOCK if none allocated.
- */
-union dp_map
-pager_read_offset(pager, offset)
- register dpager_t pager;
- vm_offset_t offset;
-{
- register vm_offset_t f_page;
- union dp_map pager_offset;
-
- f_page = atop(offset);
-
-#if DEBUG_READER_CONFLICTS
- if (pager->readers > 0)
- default_pager_read_conflicts++; /* would have proceeded with
- read/write lock */
-#endif
- mutex_lock(&pager->lock); /* XXX lock_read */
-#if DEBUG_READER_CONFLICTS
- pager->readers++;
-#endif
- if (f_page >= pager->size)
- {
- ddprintf ("%spager_read_offset pager %x: bad page %d >= size %d",
- my_name, pager, f_page, pager->size);
- mutex_unlock(&pager->lock);
- return (union dp_map) (union dp_map *) NO_BLOCK;
-#if 0
- panic("%spager_read_offset",my_name);
-#endif
- }
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- register dp_map_t mapptr;
-
- mapptr = pager->map[f_page/PAGEMAP_ENTRIES].indirect;
- if (mapptr == 0)
- invalidate_block(pager_offset);
- else
- pager_offset = mapptr[f_page%PAGEMAP_ENTRIES];
- }
- else {
- pager_offset = pager->map[f_page];
- }
-
-#if DEBUG_READER_CONFLICTS
- pager->readers--;
-#endif
- mutex_unlock(&pager->lock);
- return (pager_offset);
-}
-
-#if USE_PRECIOUS
-/*
- * Release a single disk block.
- */
-pager_release_offset(pager, offset)
- register dpager_t pager;
- vm_offset_t offset;
-{
- register union dp_map entry;
-
- offset = atop(offset);
-
- mutex_lock(&pager->lock); /* XXX lock_read */
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- register dp_map_t mapptr;
-
- mapptr = pager->map[offset / PAGEMAP_ENTRIES].indirect;
- entry = mapptr[offset % PAGEMAP_ENTRIES];
- invalidate_block(mapptr[offset % PAGEMAP_ENTRIES]);
- } else {
- entry = pager->map[offset];
- invalidate_block(pager->map[offset]);
- }
-
- mutex_unlock(&pager->lock);
-
- pager_dealloc_page(entry.block.p_index, entry.block.p_offset, TRUE);
-}
-#endif /*USE_PRECIOUS*/
-
-
-/*
- * Move a page from one partition to another
- * New partition is locked, old partition is
- * locked unless LOCK_OLD sez otherwise.
- */
-union dp_map
-pager_move_page(block)
- union dp_map block;
-{
- partition_t old_part, new_part;
- p_index_t old_pindex, new_pindex;
- union dp_map ret;
- vm_size_t size;
- vm_offset_t raddr, offset, new_offset;
- kern_return_t rc;
- static char here[] = "%spager_move_page";
-
- old_pindex = block.block.p_index;
- invalidate_block(ret);
-
- /* See if we have room to put it anywhere else */
- new_pindex = choose_partition( ptoa(1), old_pindex);
- if (no_partition(new_pindex))
- return ret;
-
- /* this unlocks the new partition */
- new_offset = pager_alloc_page(new_pindex, FALSE);
- if (new_offset == NO_BLOCK)
- panic(here,my_name);
-
- /*
- * Got the resources, now move the data
- */
-ddprintf ("pager_move_page(%x,%d,%d)\n",block.block.p_offset,old_pindex,new_pindex);
- old_part = partition_of(old_pindex);
- offset = ptoa(block.block.p_offset);
- rc = page_read_file_direct (old_part->file,
- offset,
- vm_page_size,
- &raddr,
- &size);
- if (rc != 0)
- panic(here,my_name);
-
- /* release old */
- pager_dealloc_page(old_pindex, block.block.p_offset, FALSE);
-
- new_part = partition_of(new_pindex);
- offset = ptoa(new_offset);
- rc = page_write_file_direct (new_part->file,
- offset,
- raddr,
- size,
- &size);
- if (rc != 0)
- panic(here,my_name);
-
- (void) vm_deallocate( mach_task_self(), raddr, size);
-
- ret.block.p_offset = new_offset;
- ret.block.p_index = new_pindex;
-
- return ret;
-}
-
-#ifdef CHECKSUM
-/*
- * Return the checksum for a block.
- */
-int
-pager_get_checksum(pager, offset)
- register dpager_t pager;
- vm_offset_t offset;
-{
- register vm_offset_t f_page;
- int checksum;
-
- f_page = atop(offset);
-
- mutex_lock(&pager->lock); /* XXX lock_read */
- if (f_page >= pager->size)
- panic("%spager_get_checksum",my_name);
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- register vm_offset_t *mapptr;
-
- mapptr = (vm_offset_t *)pager->checksum[f_page/PAGEMAP_ENTRIES];
- if (mapptr == 0)
- checksum = NO_CHECKSUM;
- else
- checksum = mapptr[f_page%PAGEMAP_ENTRIES];
- }
- else {
- checksum = pager->checksum[f_page];
- }
-
- mutex_unlock(&pager->lock);
- return (checksum);
-}
-
-/*
- * Remember the checksum for a block.
- */
-int
-pager_put_checksum(pager, offset, checksum)
- register dpager_t pager;
- vm_offset_t offset;
- int checksum;
-{
- register vm_offset_t f_page;
- static char here[] = "%spager_put_checksum";
-
- f_page = atop(offset);
-
- mutex_lock(&pager->lock); /* XXX lock_read */
- if (f_page >= pager->size)
- panic(here,my_name);
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- register vm_offset_t *mapptr;
-
- mapptr = (vm_offset_t *)pager->checksum[f_page/PAGEMAP_ENTRIES];
- if (mapptr == 0)
- panic(here,my_name);
-
- mapptr[f_page%PAGEMAP_ENTRIES] = checksum;
- }
- else {
- pager->checksum[f_page] = checksum;
- }
- mutex_unlock(&pager->lock);
-}
-
-/*
- * Compute a checksum - XOR each 32-bit word.
- */
-int
-compute_checksum(addr, size)
- vm_offset_t addr;
- vm_size_t size;
-{
- register int checksum = NO_CHECKSUM;
- register int *ptr;
- register int count;
-
- ptr = (int *)addr;
- count = size / sizeof(int);
-
- while (--count >= 0)
- checksum ^= *ptr++;
-
- return (checksum);
-}
-#endif /* CHECKSUM */
-
-/*
- * Given an offset within a paging object, find the
- * corresponding block within the paging partition.
- * Allocate a new block if necessary.
- *
- * WARNING: paging objects apparently may be extended
- * without notice!
- */
-union dp_map
-pager_write_offset(pager, offset)
- register dpager_t pager;
- vm_offset_t offset;
-{
- register vm_offset_t f_page;
- register dp_map_t mapptr;
- register union dp_map block;
-
- invalidate_block(block);
-
- f_page = atop(offset);
-
-#if DEBUG_READER_CONFLICTS
- if (pager->readers > 0)
- default_pager_read_conflicts++; /* would have proceeded with
- read/write lock */
-#endif
- mutex_lock(&pager->lock); /* XXX lock_read */
-#if DEBUG_READER_CONFLICTS
- pager->readers++;
-#endif
-
- /* Catch the case where we had no initial fit partition
- for this object, but one was added later on */
- if (no_partition(pager->cur_partition)) {
- p_index_t new_part;
- vm_size_t size;
-
- size = (f_page > pager->size) ? f_page : pager->size;
- new_part = choose_partition(ptoa(size), P_INDEX_INVALID);
- if (no_partition(new_part))
- new_part = choose_partition(ptoa(1), P_INDEX_INVALID);
- if (no_partition(new_part))
- /* give up right now to avoid confusion */
- goto out;
- else
- pager->cur_partition = new_part;
- }
-
- while (f_page >= pager->size) {
- ddprintf ("pager_write_offset: extending: %x %x\n", f_page, pager->size);
-
- /*
- * Paging object must be extended.
- * Remember that offset is 0-based, but size is 1-based.
- */
-#if DEBUG_READER_CONFLICTS
- pager->readers--;
-#endif
- mutex_unlock(&pager->lock);
- pager_extend(pager, f_page + 1);
-#if DEBUG_READER_CONFLICTS
- if (pager->readers > 0)
- default_pager_read_conflicts++; /* would have proceeded with
- read/write lock */
-#endif
- mutex_lock(&pager->lock); /* XXX lock_read */
-#if DEBUG_READER_CONFLICTS
- pager->readers++;
-#endif
- ddprintf ("pager_write_offset: done extending: %x %x\n", f_page, pager->size);
- }
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- ddprintf ("pager_write_offset: indirect\n");
- mapptr = pager->map[f_page/PAGEMAP_ENTRIES].indirect;
- if (mapptr == 0) {
- /*
- * Allocate the indirect block
- */
- register int i;
- ddprintf ("pager_write_offset: allocating indirect\n");
-
- mapptr = (dp_map_t) kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- if (mapptr == 0) {
- /* out of space! */
- no_paging_space(TRUE);
- goto out;
- }
- pager->map[f_page/PAGEMAP_ENTRIES].indirect = mapptr;
- for (i = 0; i < PAGEMAP_ENTRIES; i++)
- invalidate_block(mapptr[i]);
-#ifdef CHECKSUM
- {
- register vm_offset_t *cksumptr;
- register int j;
-
- cksumptr = (vm_offset_t *)
- kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- if (cksumptr == 0) {
- /* out of space! */
- no_paging_space(TRUE);
- goto out;
- }
- pager->checksum[f_page/PAGEMAP_ENTRIES]
- = (vm_offset_t)cksumptr;
- for (j = 0; j < PAGEMAP_ENTRIES; j++)
- cksumptr[j] = NO_CHECKSUM;
- }
-#endif /* CHECKSUM */
- }
- f_page %= PAGEMAP_ENTRIES;
- }
- else {
- mapptr = pager->map;
- }
-
- block = mapptr[f_page];
- ddprintf ("pager_write_offset: block starts as %x[%x] %x\n", mapptr, f_page, block);
- if (no_block(block)) {
- vm_offset_t off;
-
- /* get room now */
- off = pager_alloc_page(pager->cur_partition, TRUE);
- if (off == NO_BLOCK) {
- /*
- * Before giving up, try all other partitions.
- */
- p_index_t new_part;
-
- ddprintf ("pager_write_offset: could not allocate block\n");
- /* returns it locked (if any one is non-full) */
- new_part = choose_partition( ptoa(1), pager->cur_partition);
- if ( ! no_partition(new_part) ) {
-
-#if debug
-dprintf("%s partition %x filled,", my_name, pager->cur_partition);
-dprintf("extending object %x (size %x) to %x.\n",
- pager, pager->size, new_part);
-#endif
-
- /* this one tastes better */
- pager->cur_partition = new_part;
-
- /* this unlocks the partition too */
- off = pager_alloc_page(pager->cur_partition, FALSE);
-
- }
-
- if (off == NO_BLOCK) {
- /*
- * Oh well.
- */
- overcommitted(FALSE, 1);
- goto out;
- }
- ddprintf ("pager_write_offset: decided to allocate block\n");
- }
- block.block.p_offset = off;
- block.block.p_index = pager->cur_partition;
- mapptr[f_page] = block;
- ddprintf ("pager_write_offset: mapptr %x [3b] = %x\n", mapptr,
- mapptr[0x3b]);
- ddprintf ("pager_write_offset: block is finally %x\n", block);
- }
-
-out:
-
-#if DEBUG_READER_CONFLICTS
- pager->readers--;
-#endif
- mutex_unlock(&pager->lock);
- return (block);
-}
-
-/*
- * Deallocate all of the blocks belonging to a paging object.
- * No locking needed because no other operations can be in progress.
- */
-void
-pager_dealloc(pager)
- register dpager_t pager;
-{
- register int i, j;
- register dp_map_t mapptr;
- register union dp_map block;
-
- if (INDIRECT_PAGEMAP(pager->size)) {
- for (i = INDIRECT_PAGEMAP_ENTRIES(pager->size); --i >= 0; ) {
- mapptr = pager->map[i].indirect;
- if (mapptr != 0) {
- for (j = 0; j < PAGEMAP_ENTRIES; j++) {
- block = mapptr[j];
- if ( ! no_block(block) )
- pager_dealloc_page(block.block.p_index,
- block.block.p_offset, TRUE);
- }
- kfree((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- }
- }
- kfree((char *)pager->map, INDIRECT_PAGEMAP_SIZE(pager->size));
-#ifdef CHECKSUM
- for (i = INDIRECT_PAGEMAP_ENTRIES(pager->size); --i >= 0; ) {
- mapptr = (vm_offset_t *)pager->checksum[i];
- if (mapptr) {
- kfree((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
- }
- }
- kfree((char *)pager->checksum,
- INDIRECT_PAGEMAP_SIZE(pager->size));
-#endif /* CHECKSUM */
- }
- else {
- mapptr = pager->map;
- for (i = 0; i < pager->size; i++ ) {
- block = mapptr[i];
- if ( ! no_block(block) )
- pager_dealloc_page(block.block.p_index,
- block.block.p_offset, TRUE);
- }
- kfree((char *)pager->map, PAGEMAP_SIZE(pager->size));
-#ifdef CHECKSUM
- kfree((char *)pager->checksum, PAGEMAP_SIZE(pager->size));
-#endif /* CHECKSUM */
- }
-}
-
-/*
- * Move all the pages of a PAGER that live in a
- * partition PINDEX somewhere else.
- * Pager should be write-locked, partition too.
- * Returns FALSE if it could not do it, but
- * some pages might have been moved nonetheless.
- */
-boolean_t
-pager_realloc(pager, pindex)
- register dpager_t pager;
- p_index_t pindex;
-{
- register dp_map_t map, emap;
- vm_size_t size;
- union dp_map block;
-
- size = pager->size; /* in pages */
- map = pager->map;
-
- if (INDIRECT_PAGEMAP(size)) {
- for (emap = &map[INDIRECT_PAGEMAP_ENTRIES(size)];
- map < emap; map++) {
-
- register dp_map_t map2, emap2;
-
- if ((map2 = map->indirect) == 0)
- continue;
-
- for (emap2 = &map2[PAGEMAP_ENTRIES];
- map2 < emap2; map2++)
- if ( map2->block.p_index == pindex) {
-
- block = pager_move_page(*map2);
- if (!no_block(block))
- *map2 = block;
- else
- return FALSE;
- }
-
- }
- goto ok;
- }
-
- /* A small one */
- for (emap = &map[size]; map < emap; map++)
- if (map->block.p_index == pindex) {
- block = pager_move_page(*map);
- if (!no_block(block))
- *map = block;
- else
- return FALSE;
- }
-ok:
- pager->cur_partition = choose_partition(0, P_INDEX_INVALID);
- return TRUE;
-}
-
-/*
-
- */
-
-/*
- * Read/write routines.
- */
-#define PAGER_SUCCESS 0
-#define PAGER_ABSENT 1
-#define PAGER_ERROR 2
-
-/*
- * Read data from a default pager. Addr is the address of a buffer
- * to fill. Out_addr returns the buffer that contains the data;
- * if it is different from <addr>, it must be deallocated after use.
- */
-int
-default_read(ds, addr, size, offset, out_addr, deallocate, external)
- register dpager_t ds;
- vm_offset_t addr; /* pointer to block to fill */
- register vm_size_t size;
- register vm_offset_t offset;
- vm_offset_t *out_addr;
- /* returns pointer to data */
- boolean_t deallocate;
- boolean_t external;
-{
- register union dp_map block;
- vm_offset_t raddr;
- vm_size_t rsize;
- register int rc;
- boolean_t first_time;
- register partition_t part;
-#ifdef CHECKSUM
- vm_size_t original_size = size;
-#endif /* CHECKSUM */
- vm_offset_t original_offset = offset;
-
- /*
- * Find the block in the paging partition
- */
- block = pager_read_offset(ds, offset);
- if ( no_block(block) ) {
- if (external) {
- /*
- * An external object is requesting unswapped data,
- * zero fill the page and return.
- */
- bzero((char *) addr, vm_page_size);
- *out_addr = addr;
- return (PAGER_SUCCESS);
- }
- return (PAGER_ABSENT);
- }
-
- /*
- * Read it, trying for the entire page.
- */
- offset = ptoa(block.block.p_offset);
-ddprintf ("default_read(%x,%x,%x,%d)\n",addr,size,offset,block.block.p_index);
- part = partition_of(block.block.p_index);
- first_time = TRUE;
- *out_addr = addr;
-
- do {
- rc = page_read_file_direct(part->file,
- offset,
- size,
- &raddr,
- &rsize);
- if (rc != 0)
- return (PAGER_ERROR);
-
- /*
- * If we got the entire page on the first read, return it.
- */
- if (first_time && rsize == size) {
- *out_addr = raddr;
- break;
- }
- /*
- * Otherwise, copy the data into the
- * buffer we were passed, and try for
- * the next piece.
- */
- first_time = FALSE;
- bcopy((char *)raddr, (char *)addr, rsize);
- addr += rsize;
- offset += rsize;
- size -= rsize;
- } while (size != 0);
-
-#if USE_PRECIOUS
- if (deallocate)
- pager_release_offset(ds, original_offset);
-#endif /*USE_PRECIOUS*/
-
-#ifdef CHECKSUM
- {
- int write_checksum,
- read_checksum;
-
- write_checksum = pager_get_checksum(ds, original_offset);
- read_checksum = compute_checksum(*out_addr, original_size);
- if (write_checksum != read_checksum) {
- panic(
- "PAGER CHECKSUM ERROR: offset 0x%x, written 0x%x, read 0x%x",
- original_offset, write_checksum, read_checksum);
- }
- }
-#endif /* CHECKSUM */
- return (PAGER_SUCCESS);
-}
-
-int
-default_write(ds, addr, size, offset)
- register dpager_t ds;
- register vm_offset_t addr;
- register vm_size_t size;
- register vm_offset_t offset;
-{
- register union dp_map block;
- partition_t part;
- vm_size_t wsize;
- register int rc;
-
- ddprintf ("default_write: pager offset %x\n", offset);
-
- /*
- * Find block in paging partition
- */
- block = pager_write_offset(ds, offset);
- if ( no_block(block) )
- return (PAGER_ERROR);
-
-#ifdef CHECKSUM
- /*
- * Save checksum
- */
- {
- int checksum;
-
- checksum = compute_checksum(addr, size);
- pager_put_checksum(ds, offset, checksum);
- }
-#endif /* CHECKSUM */
- offset = ptoa(block.block.p_offset);
-ddprintf ("default_write(%x,%x,%x,%d)\n",addr,size,offset,block.block.p_index);
- part = partition_of(block.block.p_index);
-
- /*
- * There are various assumptions made here,we
- * will not get into the next disk 'block' by
- * accident. It might well be non-contiguous.
- */
- do {
- rc = page_write_file_direct(part->file,
- offset,
- addr,
- size,
- &wsize);
- if (rc != 0) {
- dprintf("*** PAGER ERROR: default_write: ");
- dprintf("ds=0x%x addr=0x%x size=0x%x offset=0x%x resid=0x%x\n",
- ds, addr, size, offset, wsize);
- return (PAGER_ERROR);
- }
- addr += wsize;
- offset += wsize;
- size -= wsize;
- } while (size != 0);
- return (PAGER_SUCCESS);
-}
-
-boolean_t
-default_has_page(ds, offset)
- dpager_t ds;
- vm_offset_t offset;
-{
- return ( ! no_block(pager_read_offset(ds, offset)) );
-}
-/*
-
- */
-
-/*
- * Mapping between pager port and paging object.
- */
-struct dstruct {
- queue_chain_t links; /* Link in pager-port list */
-
- struct mutex lock; /* Lock for the structure */
- struct condition
- waiting_seqno, /* someone waiting on seqno */
- waiting_read, /* someone waiting on readers */
- waiting_write, /* someone waiting on writers */
- waiting_refs; /* someone waiting on refs */
-
- memory_object_t pager; /* Pager port */
- mach_port_seqno_t seqno; /* Pager port sequence number */
- mach_port_t pager_request; /* Request port */
- mach_port_urefs_t request_refs; /* Request port user-refs */
- mach_port_t pager_name; /* Name port */
- mach_port_urefs_t name_refs; /* Name port user-refs */
- boolean_t external; /* Is an external object? */
-
- unsigned int readers; /* Reads in progress */
- unsigned int writers; /* Writes in progress */
-
- /* This is the reply port of an outstanding
- default_pager_object_set_size call. */
- mach_port_t lock_request;
-
- unsigned int errors; /* Pageout error count */
- struct dpager dpager; /* Actual pager */
-};
-typedef struct dstruct * default_pager_t;
-#define DEFAULT_PAGER_NULL ((default_pager_t)0)
-
-#if PARALLEL
-#define dstruct_lock_init(ds) mutex_init(&ds->lock)
-#define dstruct_lock(ds) mutex_lock(&ds->lock)
-#define dstruct_unlock(ds) mutex_unlock(&ds->lock)
-#else /* PARALLEL */
-#define dstruct_lock_init(ds)
-#define dstruct_lock(ds)
-#define dstruct_unlock(ds)
-#endif /* PARALLEL */
-
-/*
- * List of all pagers. A specific pager is
- * found directly via its port, this list is
- * only used for monitoring purposes by the
- * default_pager_object* calls
- */
-struct pager_port {
- queue_head_t queue;
- struct mutex lock;
- int count; /* saves code */
- queue_head_t leak_queue;
-} all_pagers;
-
-#define pager_port_list_init() \
-{ \
- mutex_init(&all_pagers.lock); \
- queue_init(&all_pagers.queue); \
- queue_init(&all_pagers.leak_queue); \
- all_pagers.count = 0; \
-}
-
-void pager_port_list_insert(port, ds)
- mach_port_t port;
- default_pager_t ds;
-{
- mutex_lock(&all_pagers.lock);
- queue_enter(&all_pagers.queue, ds, default_pager_t, links);
- all_pagers.count++;
- mutex_unlock(&all_pagers.lock);
-}
-
-/* given a data structure return a good port-name to associate it to */
-#define pnameof(_x_) (((vm_offset_t)(_x_))+1)
-/* reverse, assumes no-odd-pointers */
-#define dnameof(_x_) (((vm_offset_t)(_x_))&~1)
-
-/* The magic typecast */
-#define pager_port_lookup(_port_) \
- ((! MACH_PORT_VALID(_port_) || \
- ((default_pager_t)dnameof(_port_))->pager != (_port_)) ? \
- DEFAULT_PAGER_NULL : (default_pager_t)dnameof(_port_))
-
-void pager_port_list_delete(ds)
- default_pager_t ds;
-{
- mutex_lock(&all_pagers.lock);
- queue_remove(&all_pagers.queue, ds, default_pager_t, links);
- all_pagers.count--;
- mutex_unlock(&all_pagers.lock);
-}
-
-/*
- * Destroy a paging partition.
- * XXX this is not re-entrant XXX
- */
-kern_return_t
-destroy_paging_partition(name, pp_private)
- char *name;
- void **pp_private;
-{
- register unsigned int id = part_id(name);
- register partition_t part;
- boolean_t all_ok = TRUE;
- default_pager_t entry;
- int pindex;
-
- /*
- * Find and take partition out of list
- * This prevents choose_partition from
- * getting in the way.
- */
- mutex_lock(&all_partitions.lock);
- for (pindex = 0; pindex < all_partitions.n_partitions; pindex++) {
- part = partition_of(pindex);
- if (part && (part->id == id)) break;
- }
- if (pindex == all_partitions.n_partitions) {
- mutex_unlock(&all_partitions.lock);
- return KERN_INVALID_ARGUMENT;
- }
- part->going_away = TRUE;
- mutex_unlock(&all_partitions.lock);
-
- /*
- * This might take a while..
- */
-all_over_again:
-#if debug
-dprintf("Partition x%x (id x%x) for %s, all_ok %d\n", part, id, name, all_ok);
-#endif
- all_ok = TRUE;
- mutex_lock(&part->p_lock);
-
- mutex_lock(&all_pagers.lock);
- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) {
-
- dstruct_lock(entry);
-
- if (!mutex_try_lock(&entry->dpager.lock)) {
-
- dstruct_unlock(entry);
- mutex_unlock(&all_pagers.lock);
- mutex_unlock(&part->p_lock);
-
- /* yield the processor */
- (void) thread_switch(MACH_PORT_NULL,
- SWITCH_OPTION_NONE, 0);
-
- goto all_over_again;
-
- }
-
- /*
- * See if we can relocate all the pages of this object
- * currently on this partition on some other partition
- */
- all_ok = pager_realloc(&entry->dpager, pindex);
-
- mutex_unlock(&entry->dpager.lock);
- dstruct_unlock(entry);
-
- if (!all_ok) break;
-
- }
- mutex_unlock(&all_pagers.lock);
-
- if (all_ok) {
- /* No need to unlock partition, there are no refs left */
-
- set_partition_of(pindex, 0);
- *pp_private = part->file;
- kfree(part->bitmap, howmany(part->total_size, NB_BM) * sizeof(bm_entry_t));
- kfree(part, sizeof(struct part));
- dprintf("%s Removed paging partition %s\n", my_name, name);
- return KERN_SUCCESS;
- }
-
- /*
- * Put partition back in.
- */
- part->going_away = FALSE;
-
- return KERN_FAILURE;
-}
-
-
-/*
- * We use the sequence numbers on requests to regulate
- * our parallelism. In general, we allow multiple reads and writes
- * to proceed in parallel, with the exception that reads must
- * wait for previous writes to finish. (Because the kernel might
- * generate a data-request for a page on the heels of a data-write
- * for the same page, and we must avoid returning stale data.)
- * terminate requests wait for proceeding reads and writes to finish.
- */
-
-unsigned int default_pager_total = 0; /* debugging */
-unsigned int default_pager_wait_seqno = 0; /* debugging */
-unsigned int default_pager_wait_read = 0; /* debugging */
-unsigned int default_pager_wait_write = 0; /* debugging */
-unsigned int default_pager_wait_refs = 0; /* debugging */
-
-#if PARALLEL
-/*
- * Waits for correct sequence number. Leaves pager locked.
- */
-void pager_port_lock(ds, seqno)
- default_pager_t ds;
- mach_port_seqno_t seqno;
-{
- default_pager_total++;
-ddprintf ("pager_port_lock <%p>: <%p>: %d: 1\n", &ds, ds, seqno);
- dstruct_lock(ds);
-ddprintf ("pager_port_lock <%p>: <%p>: %d: 2\n", &ds, ds, seqno);
- while (ds->seqno != seqno) {
-ddprintf ("pager_port_lock <%p>: <%p>: %d: 3\n", &ds, ds, seqno);
- default_pager_wait_seqno++;
- condition_wait(&ds->waiting_seqno, &ds->lock);
-ddprintf ("pager_port_lock <%p>: <%p>: %d: 4\n", &ds, ds, seqno);
- }
-}
-
-/*
- * Increments sequence number and unlocks pager.
- */
-void pager_port_unlock(ds)
- default_pager_t ds;
-{
- ds->seqno++;
-ddprintf ("pager_port_unlock <%p>: <%p>: seqno => %d\n", &ds, ds, ds->seqno);
- dstruct_unlock(ds);
-ddprintf ("pager_port_unlock <%p>: <%p>: 2\n", &ds, ds);
- condition_broadcast(&ds->waiting_seqno);
-ddprintf ("pager_port_unlock <%p>: <%p>: 3\n", &ds, ds);
-}
-
-/*
- * Start a read - one more reader. Pager must be locked.
- */
-void pager_port_start_read(ds)
- default_pager_t ds;
-{
- ds->readers++;
-}
-
-/*
- * Wait for readers. Unlocks and relocks pager if wait needed.
- */
-void pager_port_wait_for_readers(ds)
- default_pager_t ds;
-{
- while (ds->readers != 0) {
- default_pager_wait_read++;
- condition_wait(&ds->waiting_read, &ds->lock);
- }
-}
-
-/*
- * Finish a read. Pager is unlocked and returns unlocked.
- */
-void pager_port_finish_read(ds)
- default_pager_t ds;
-{
- dstruct_lock(ds);
- if (--ds->readers == 0) {
- dstruct_unlock(ds);
- condition_broadcast(&ds->waiting_read);
- }
- else {
- dstruct_unlock(ds);
- }
-}
-
-/*
- * Start a write - one more writer. Pager must be locked.
- */
-void pager_port_start_write(ds)
- default_pager_t ds;
-{
- ds->writers++;
-}
-
-/*
- * Wait for writers. Unlocks and relocks pager if wait needed.
- */
-void pager_port_wait_for_writers(ds)
- default_pager_t ds;
-{
- while (ds->writers != 0) {
- default_pager_wait_write++;
- condition_wait(&ds->waiting_write, &ds->lock);
- }
-}
-
-/*
- * Finish a write. Pager is unlocked and returns unlocked.
- */
-void pager_port_finish_write(ds)
- default_pager_t ds;
-{
- dstruct_lock(ds);
- if (--ds->writers == 0) {
- dstruct_unlock(ds);
- condition_broadcast(&ds->waiting_write);
- }
- else {
- dstruct_unlock(ds);
- }
-}
-
-/*
- * Wait for concurrent default_pager_objects.
- * Unlocks and relocks pager if wait needed.
- */
-void pager_port_wait_for_refs(ds)
- default_pager_t ds;
-{
- while (ds->name_refs == 0) {
- default_pager_wait_refs++;
- condition_wait(&ds->waiting_refs, &ds->lock);
- }
-}
-
-/*
- * Finished creating name refs - wake up waiters.
- */
-void pager_port_finish_refs(ds)
- default_pager_t ds;
-{
- condition_broadcast(&ds->waiting_refs);
-}
-
-#else /* PARALLEL */
-
-#define pager_port_lock(ds,seqno)
-#define pager_port_unlock(ds)
-#define pager_port_start_read(ds)
-#define pager_port_wait_for_readers(ds)
-#define pager_port_finish_read(ds)
-#define pager_port_start_write(ds)
-#define pager_port_wait_for_writers(ds)
-#define pager_port_finish_write(ds)
-#define pager_port_wait_for_refs(ds)
-#define pager_port_finish_refs(ds)
-
-#endif /* PARALLEL */
-
-/*
- * Default pager.
- */
-task_t default_pager_self; /* Our task port. */
-
-mach_port_t default_pager_default_port; /* Port for memory_object_create. */
-
-/* We catch exceptions on ourself & startup using this port. */
-mach_port_t default_pager_exception_port;
-
-mach_port_t default_pager_internal_set; /* Port set for internal objects. */
-mach_port_t default_pager_external_set; /* Port set for external objects. */
-mach_port_t default_pager_default_set; /* Port set for "default" thread. */
-
-typedef struct default_pager_thread {
- cthread_t dpt_thread; /* Server thread. */
- vm_offset_t dpt_buffer; /* Read buffer. */
- boolean_t dpt_internal; /* Do we handle internal objects? */
-} default_pager_thread_t;
-
-#if PARALLEL
- /* determine number of threads at run time */
-#define DEFAULT_PAGER_INTERNAL_COUNT (0)
-
-#else /* PARALLEL */
-#define DEFAULT_PAGER_INTERNAL_COUNT (1)
-#endif /* PARALLEL */
-
-/* Memory created by default_pager_object_create should mostly be resident. */
-#define DEFAULT_PAGER_EXTERNAL_COUNT (1)
-
-unsigned int default_pager_internal_count = DEFAULT_PAGER_INTERNAL_COUNT;
- /* Number of "internal" threads. */
-unsigned int default_pager_external_count = DEFAULT_PAGER_EXTERNAL_COUNT;
- /* Number of "external" threads. */
-
-default_pager_t pager_port_alloc(size)
- vm_size_t size;
-{
- default_pager_t ds;
- p_index_t part;
-
- ds = (default_pager_t) kalloc(sizeof *ds);
- if (ds == DEFAULT_PAGER_NULL)
- panic("%spager_port_alloc",my_name);
- bzero((char *) ds, sizeof *ds);
-
- dstruct_lock_init(ds);
-
- /*
- * Get a suitable partition. If none big enough
- * just pick one and overcommit. If no partitions
- * at all.. well just fake one so that we will
- * kill specific objects on pageouts rather than
- * panicing the system now.
- */
- part = choose_partition(size, P_INDEX_INVALID);
- if (no_partition(part)) {
- overcommitted(FALSE, atop(size));
- part = choose_partition(0,P_INDEX_INVALID);
-#if debug
- if (no_partition(part))
- dprintf("%s No paging space at all !!\n", my_name);
-#endif
- }
- pager_alloc(&ds->dpager, part, size);
-
- return ds;
-}
-
-mach_port_urefs_t default_pager_max_urefs = 10000;
-
-/*
- * Check user reference count on pager_request port.
- * Pager must be locked.
- * Unlocks and re-locks pager if needs to call kernel.
- */
-void pager_port_check_request(ds, pager_request)
- default_pager_t ds;
- mach_port_t pager_request;
-{
- mach_port_delta_t delta;
- kern_return_t kr;
-
- assert(ds->pager_request == pager_request);
-
- if (++ds->request_refs > default_pager_max_urefs) {
- delta = 1 - ds->request_refs;
- ds->request_refs = 1;
-
- dstruct_unlock(ds);
-
- /*
- * Deallocate excess user references.
- */
-
- kr = mach_port_mod_refs(default_pager_self, pager_request,
- MACH_PORT_RIGHT_SEND, delta);
- if (kr != KERN_SUCCESS)
- panic("%spager_port_check_request",my_name);
-
- dstruct_lock(ds);
- }
-}
-
-void default_pager_add(ds, internal)
- default_pager_t ds;
- boolean_t internal;
-{
- mach_port_t pager = ds->pager;
- mach_port_t pset;
- mach_port_mscount_t sync;
- mach_port_t previous;
- kern_return_t kr;
- static char here[] = "%sdefault_pager_add";
-
- /*
- * The port currently has a make-send count of zero,
- * because either we just created the port or we just
- * received the port in a memory_object_create request.
- */
-
- if (internal) {
- /* possibly generate an immediate no-senders notification */
- sync = 0;
- pset = default_pager_internal_set;
- ds->external = FALSE;
- } else {
- /* delay notification till send right is created */
- sync = 1;
- pset = default_pager_external_set;
- ds->external = TRUE;
- }
-
- kr = mach_port_request_notification(default_pager_self, pager,
- MACH_NOTIFY_NO_SENDERS, sync,
- pager, MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &previous);
- if ((kr != KERN_SUCCESS) || (previous != MACH_PORT_NULL))
- panic(here,my_name);
-
- kr = mach_port_move_member(default_pager_self, pager, pset);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-}
-
-/*
- * Routine: memory_object_create
- * Purpose:
- * Handle requests for memory objects from the
- * kernel.
- * Notes:
- * Because we only give out the default memory
- * manager port to the kernel, we don't have to
- * be so paranoid about the contents.
- */
-kern_return_t
-seqnos_memory_object_create(old_pager, seqno, new_pager, new_size,
- new_pager_request, new_pager_name, new_page_size)
- mach_port_t old_pager;
- mach_port_seqno_t seqno;
- mach_port_t new_pager;
- vm_size_t new_size;
- mach_port_t new_pager_request;
- mach_port_t new_pager_name;
- vm_size_t new_page_size;
-{
- register default_pager_t ds;
- kern_return_t kr;
-
- assert(old_pager == default_pager_default_port);
- assert(MACH_PORT_VALID(new_pager_request));
- assert(MACH_PORT_VALID(new_pager_name));
- assert(new_page_size == vm_page_size);
-
- ds = pager_port_alloc(new_size);
-rename_it:
- kr = mach_port_rename( default_pager_self,
- new_pager, (mach_port_t)pnameof(ds));
- if (kr != KERN_SUCCESS) {
- default_pager_t ds1;
-
- if (kr != KERN_NAME_EXISTS)
- panic("%s m_o_create", my_name);
- ds1 = (default_pager_t) kalloc(sizeof *ds1);
- *ds1 = *ds;
- mutex_lock(&all_pagers.lock);
- queue_enter(&all_pagers.leak_queue, ds, default_pager_t, links);
- mutex_unlock(&all_pagers.lock);
- ds = ds1;
- goto rename_it;
- }
-
- new_pager = (mach_port_t) pnameof(ds);
-
- /*
- * Set up associations between these ports
- * and this default_pager structure
- */
-
- ds->pager = new_pager;
- ds->pager_request = new_pager_request;
- ds->request_refs = 1;
- ds->pager_name = new_pager_name;
- ds->name_refs = 1;
-
- /*
- * After this, other threads might receive requests
- * for this memory object or find it in the port list.
- */
-
- pager_port_list_insert(new_pager, ds);
- default_pager_add(ds, TRUE);
-
- return(KERN_SUCCESS);
-}
-
-memory_object_copy_strategy_t default_pager_copy_strategy =
- MEMORY_OBJECT_COPY_DELAY;
-
-kern_return_t
-seqnos_memory_object_init(pager, seqno, pager_request, pager_name,
- pager_page_size)
- mach_port_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- mach_port_t pager_name;
- vm_size_t pager_page_size;
-{
- register default_pager_t ds;
- kern_return_t kr;
- static char here[] = "%sinit";
-
- assert(MACH_PORT_VALID(pager_request));
- assert(MACH_PORT_VALID(pager_name));
- assert(pager_page_size == vm_page_size);
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here, my_name);
- pager_port_lock(ds, seqno);
-
- if (ds->pager_request != MACH_PORT_NULL)
- panic(here, my_name);
-
- ds->pager_request = pager_request;
- ds->request_refs = 1;
- ds->pager_name = pager_name;
- ds->name_refs = 1;
-
- /*
- * Even if the kernel immediately terminates the object,
- * the pager_request port won't be destroyed until
- * we process the terminate request, which won't happen
- * until we unlock the object.
- */
-
- kr = memory_object_set_attributes(pager_request,
- TRUE,
- FALSE, /* do not cache */
- default_pager_copy_strategy);
- if (kr != KERN_SUCCESS)
- panic(here, my_name);
-
- pager_port_unlock(ds);
-
- return(KERN_SUCCESS);
-}
-
-kern_return_t
-seqnos_memory_object_terminate(pager, seqno, pager_request, pager_name)
- mach_port_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- mach_port_t pager_name;
-{
- register default_pager_t ds;
- mach_port_urefs_t request_refs, name_refs;
- kern_return_t kr;
- static char here[] = "%sterminate";
-
- /*
- * pager_request and pager_name are receive rights,
- * not send rights.
- */
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here, my_name);
-ddprintf ("seqnos_memory_object_terminate <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
- &kr, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
- pager_port_lock(ds, seqno);
-
- /*
- * Wait for read and write requests to terminate.
- */
-
- pager_port_wait_for_readers(ds);
- pager_port_wait_for_writers(ds);
-
- /*
- * After memory_object_terminate both memory_object_init
- * and a no-senders notification are possible, so we need
- * to clean up the request and name ports but leave
- * the pager port.
- *
- * A concurrent default_pager_objects might be allocating
- * more references for the name port. In this case,
- * we must first wait for it to finish.
- */
-
- pager_port_wait_for_refs(ds);
-
- ds->pager_request = MACH_PORT_NULL;
- request_refs = ds->request_refs;
- ds->request_refs = 0;
- assert(ds->pager_name == pager_name);
- ds->pager_name = MACH_PORT_NULL;
- name_refs = ds->name_refs;
- ds->name_refs = 0;
-ddprintf ("seqnos_memory_object_terminate <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
- &kr, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
- pager_port_unlock(ds);
-
- /*
- * Now we deallocate our various port rights.
- */
-
- kr = mach_port_mod_refs(default_pager_self, pager_request,
- MACH_PORT_RIGHT_SEND, -request_refs);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_request,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_name,
- MACH_PORT_RIGHT_SEND, -name_refs);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_name,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- return (KERN_SUCCESS);
-}
-
-void default_pager_no_senders(pager, seqno, mscount)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_mscount_t mscount;
-{
- register default_pager_t ds;
- kern_return_t kr;
- static char here[] = "%sno_senders";
-
- /*
- * Because we don't give out multiple send rights
- * for a memory object, there can't be a race
- * between getting a no-senders notification
- * and creating a new send right for the object.
- * Hence we don't keep track of mscount.
- */
-
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here,my_name);
- pager_port_lock(ds, seqno);
-
- /*
- * We shouldn't get a no-senders notification
- * when the kernel has the object cached.
- */
-
- if (ds->pager_request != MACH_PORT_NULL)
- panic(here,my_name);
-
- /*
- * Unlock the pager (though there should be no one
- * waiting for it).
- */
- dstruct_unlock(ds);
-
- /*
- * Remove the memory object port association, and then
- * the destroy the port itself. We must remove the object
- * from the port list before deallocating the pager,
- * because of default_pager_objects.
- */
-
- pager_port_list_delete(ds);
- pager_dealloc(&ds->dpager);
-
- kr = mach_port_mod_refs(default_pager_self, pager,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- /*
- * Do this *after* deallocating the port name
- */
- kfree((char *) ds, sizeof(*ds));
-
- /*
- * Recover memory that we might have wasted because
- * of name conflicts
- */
- mutex_lock(&all_pagers.lock);
-
- while (!queue_empty(&all_pagers.leak_queue)) {
-
- ds = (default_pager_t) queue_first(&all_pagers.leak_queue);
- queue_remove_first(&all_pagers.leak_queue, ds, default_pager_t, links);
- kfree((char *) ds, sizeof(*ds));
- }
-
- mutex_unlock(&all_pagers.lock);
-}
-
-int default_pager_pagein_count = 0;
-int default_pager_pageout_count = 0;
-
-kern_return_t
-seqnos_memory_object_data_request(pager, seqno, reply_to, offset,
- length, protection_required)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t reply_to;
- vm_offset_t offset;
- vm_size_t length;
- vm_prot_t protection_required;
-{
- default_pager_thread_t *dpt;
- default_pager_t ds;
- vm_offset_t addr;
- unsigned int errors;
- kern_return_t rc;
- static char here[] = "%sdata_request";
-
- dpt = (default_pager_thread_t *) cthread_data(cthread_self());
-
- if (length != vm_page_size)
- panic(here,my_name);
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here,my_name);
-ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
- &ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
- pager_port_lock(ds, seqno);
- pager_port_check_request(ds, reply_to);
- pager_port_wait_for_writers(ds);
- pager_port_start_read(ds);
-
- /*
- * Get error count while pager locked.
- */
- errors = ds->errors;
-
-ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
- &ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
- pager_port_unlock(ds);
-
- if (errors) {
- dprintf("%s %s\n", my_name,
- "dropping data_request because of previous paging errors");
- (void) memory_object_data_error(reply_to,
- offset, vm_page_size,
- KERN_FAILURE);
- goto done;
- }
-
- if (offset >= ds->dpager.limit)
- rc = PAGER_ERROR;
- else
- rc = default_read(&ds->dpager, dpt->dpt_buffer,
- vm_page_size, offset,
- &addr, protection_required & VM_PROT_WRITE,
- ds->external);
-
- switch (rc) {
- case PAGER_SUCCESS:
- if (addr != dpt->dpt_buffer) {
- /*
- * Deallocates data buffer
- */
- (void) memory_object_data_supply(
- reply_to, offset,
- addr, vm_page_size, TRUE,
- VM_PROT_NONE,
- FALSE, MACH_PORT_NULL);
- } else {
- (void) memory_object_data_provided(
- reply_to, offset,
- addr, vm_page_size,
- VM_PROT_NONE);
- }
- break;
-
- case PAGER_ABSENT:
- (void) memory_object_data_unavailable(
- reply_to,
- offset,
- vm_page_size);
- break;
-
- case PAGER_ERROR:
- (void) memory_object_data_error(
- reply_to,
- offset,
- vm_page_size,
- KERN_FAILURE);
- break;
- }
-
- default_pager_pagein_count++;
-
- done:
- pager_port_finish_read(ds);
- return(KERN_SUCCESS);
-}
-
-/*
- * memory_object_data_initialize: check whether we already have each page, and
- * write it if we do not. The implementation is far from optimized, and
- * also assumes that the default_pager is single-threaded.
- */
-kern_return_t
-seqnos_memory_object_data_initialize(pager, seqno, pager_request,
- offset, addr, data_cnt)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- register
- vm_offset_t offset;
- register
- pointer_t addr;
- vm_size_t data_cnt;
-{
- vm_offset_t amount_sent;
- default_pager_t ds;
- static char here[] = "%sdata_initialize";
-
-#ifdef lint
- pager_request++;
-#endif /* lint */
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- panic(here,my_name);
-ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
- &ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
- pager_port_lock(ds, seqno);
- pager_port_check_request(ds, pager_request);
- pager_port_start_write(ds);
-ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
- &ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
- pager_port_unlock(ds);
-
- for (amount_sent = 0;
- amount_sent < data_cnt;
- amount_sent += vm_page_size) {
-
- if (!default_has_page(&ds->dpager, offset + amount_sent)) {
- if (default_write(&ds->dpager,
- addr + amount_sent,
- vm_page_size,
- offset + amount_sent)
- != PAGER_SUCCESS) {
- dprintf("%s%s write error\n", my_name, here);
- dstruct_lock(ds);
- ds->errors++;
- dstruct_unlock(ds);
- }
- }
- }
-
- pager_port_finish_write(ds);
- if (vm_deallocate(default_pager_self, addr, data_cnt) != KERN_SUCCESS)
- panic(here,my_name);
-
- return(KERN_SUCCESS);
-}
-
-/*
- * memory_object_data_write: split up the stuff coming in from
- * a memory_object_data_write call
- * into individual pages and pass them off to default_write.
- */
-kern_return_t
-seqnos_memory_object_data_write(pager, seqno, pager_request,
- offset, addr, data_cnt)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- register
- vm_offset_t offset;
- register
- pointer_t addr;
- vm_size_t data_cnt;
-{
- register
- vm_size_t amount_sent;
- default_pager_t ds;
- static char here[] = "%sdata_write";
- int err;
-
-#ifdef lint
- pager_request++;
-#endif /* lint */
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 1\n", &err);
- if ((data_cnt % vm_page_size) != 0)
- {
- ddprintf ("fail 1: %d %d\n", data_cnt, vm_page_size);
- panic(here,my_name);
- }
-
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 2\n", &err);
- ds = pager_port_lookup(pager);
-ddprintf ("seqnos_memory_object_data_write <%p>: 3\n", &err);
- if (ds == DEFAULT_PAGER_NULL)
- {
- ddprintf ("fail 2: %d %d\n", pager, ds);
- panic(here,my_name);
- }
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 4\n", &err);
-ddprintf ("seqnos_memory_object_data_write <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
- &err, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
- pager_port_lock(ds, seqno);
-ddprintf ("seqnos_memory_object_data_write <%p>: 5\n", &err);
- pager_port_check_request(ds, pager_request);
-ddprintf ("seqnos_memory_object_data_write <%p>: 6\n", &err);
- pager_port_start_write(ds);
-ddprintf ("seqnos_memory_object_data_write <%p>: 7\n", &err);
-ddprintf ("seqnos_memory_object_data_write <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
- &err, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
- pager_port_unlock(ds);
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 8\n", &err);
- for (amount_sent = 0;
- amount_sent < data_cnt;
- amount_sent += vm_page_size) {
-
- register int result;
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 9\n", &err);
- result = default_write(&ds->dpager,
- addr + amount_sent,
- vm_page_size,
- offset + amount_sent);
-ddprintf ("seqnos_memory_object_data_write <%p>: 10\n", &err);
- if (result != KERN_SUCCESS) {
-ddprintf ("seqnos_memory_object_data_write <%p>: 11\n", &err);
-#if debug
- dprintf("%s WRITE ERROR on default_pageout:", my_name);
- dprintf(" pager=%x, offset=0x%x, length=0x%x, result=%d\n",
- pager, offset+amount_sent, vm_page_size, result);
-#endif
- dstruct_lock(ds);
- ds->errors++;
- dstruct_unlock(ds);
- }
- default_pager_pageout_count++;
- }
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 12\n", &err);
- pager_port_finish_write(ds);
-ddprintf ("seqnos_memory_object_data_write <%p>: 13\n", &err);
- err = vm_deallocate(default_pager_self, addr, data_cnt);
-ddprintf ("seqnos_memory_object_data_write <%p>: 14\n", &err);
- if (err != KERN_SUCCESS)
- {
- ddprintf ("fail 3: %s %s %s %s\n", default_pager_self, addr, data_cnt, &err);
-
- panic(here,my_name);
- }
-
-
-ddprintf ("seqnos_memory_object_data_write <%p>: 15\n", &err);
- return(KERN_SUCCESS);
-}
-
-/*ARGSUSED*/
-kern_return_t
-seqnos_memory_object_copy(old_memory_object, seqno, old_memory_control,
- offset, length, new_memory_object)
- memory_object_t old_memory_object;
- mach_port_seqno_t seqno;
- memory_object_control_t
- old_memory_control;
- vm_offset_t offset;
- vm_size_t length;
- memory_object_t new_memory_object;
-{
- panic("%scopy", my_name);
- return KERN_FAILURE;
-}
-
-/* We get this when our memory_object_lock_request has completed
- after we truncated an object. */
-kern_return_t
-seqnos_memory_object_lock_completed (memory_object_t pager,
- mach_port_seqno_t seqno,
- mach_port_t pager_request,
- vm_offset_t offset,
- vm_size_t length)
-{
- default_pager_t ds;
-
- ds = pager_port_lookup(pager);
- assert(ds != DEFAULT_PAGER_NULL);
-
- pager_port_lock(ds, seqno);
- pager_port_wait_for_readers(ds);
- pager_port_wait_for_writers(ds);
-
- /* Now that any in-core pages have been flushed, we can apply
- the limit to prevent any new page-ins. */
- assert (page_aligned (offset));
- ds->dpager.limit = offset;
-
- default_pager_object_set_size_reply (ds->lock_request, KERN_SUCCESS);
- ds->lock_request = MACH_PORT_NULL;
-
- if (ds->dpager.size > ds->dpager.limit / vm_page_size)
- /* Deallocate the old backing store pages and shrink the page map. */
- pager_truncate (&ds->dpager, ds->dpager.limit / vm_page_size);
-
- pager_port_unlock(ds, seqno);
-
- return KERN_SUCCESS;
-}
-
-kern_return_t
-seqnos_memory_object_data_unlock(pager, seqno, pager_request,
- offset, addr, data_cnt)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- vm_offset_t offset;
- pointer_t addr;
- vm_size_t data_cnt;
-{
- panic("%sdata_unlock",my_name);
- return(KERN_FAILURE);
-}
-
-kern_return_t
-seqnos_memory_object_supply_completed(pager, seqno, pager_request,
- offset, length,
- result, error_offset)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- vm_offset_t offset;
- vm_size_t length;
- kern_return_t result;
- vm_offset_t error_offset;
-{
- panic("%ssupply_completed",my_name);
- return(KERN_FAILURE);
-}
-
-kern_return_t
-seqnos_memory_object_data_return(pager, seqno, pager_request,
- offset, addr, data_cnt,
- dirty, kernel_copy)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- mach_port_t pager_request;
- vm_offset_t offset;
- pointer_t addr;
- vm_size_t data_cnt;
- boolean_t dirty;
- boolean_t kernel_copy;
-{
- panic("%sdata_return",my_name);
- return(KERN_FAILURE);
-}
-
-kern_return_t
-seqnos_memory_object_change_completed(pager, seqno, may_cache, copy_strategy)
- memory_object_t pager;
- mach_port_seqno_t seqno;
- boolean_t may_cache;
- memory_object_copy_strategy_t copy_strategy;
-{
- panic("%schange_completed",my_name);
- return(KERN_FAILURE);
-}
-
-
-boolean_t default_pager_notify_server(in, out)
- mach_msg_header_t *in, *out;
-{
- register mach_no_senders_notification_t *n =
- (mach_no_senders_notification_t *) in;
-
- /*
- * The only send-once rights we create are for
- * receiving no-more-senders notifications.
- * Hence, if we receive a message directed to
- * a send-once right, we can assume it is
- * a genuine no-senders notification from the kernel.
- */
-
- if ((n->not_header.msgh_bits !=
- MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND_ONCE)) ||
- (n->not_header.msgh_id != MACH_NOTIFY_NO_SENDERS))
- return FALSE;
-
- assert(n->not_header.msgh_size == sizeof *n);
- assert(n->not_header.msgh_remote_port == MACH_PORT_NULL);
-
- assert(n->not_type.msgt_name == MACH_MSG_TYPE_INTEGER_32);
- assert(n->not_type.msgt_size == 32);
- assert(n->not_type.msgt_number == 1);
- assert(n->not_type.msgt_inline);
- assert(! n->not_type.msgt_longform);
-
- default_pager_no_senders(n->not_header.msgh_local_port,
- n->not_header.msgh_seqno, n->not_count);
-
- out->msgh_remote_port = MACH_PORT_NULL;
- return TRUE;
-}
-
-extern boolean_t seqnos_memory_object_server();
-extern boolean_t seqnos_memory_object_default_server();
-extern boolean_t default_pager_server();
-extern boolean_t exc_server();
-extern boolean_t bootstrap_server();
-extern void bootstrap_compat();
-
-mach_msg_size_t default_pager_msg_size_object = 128;
-
-boolean_t
-default_pager_demux_object(in, out)
- mach_msg_header_t *in;
- mach_msg_header_t *out;
-{
- /*
- * We receive memory_object_data_initialize messages in
- * the memory_object_default interface.
- */
-
-int rval;
-ddprintf ("DPAGER DEMUX OBJECT <%p>: %d\n", in, in->msgh_id);
-rval =
- (seqnos_memory_object_server(in, out) ||
- seqnos_memory_object_default_server(in, out) ||
- default_pager_notify_server(in, out) ||
- default_pager_server(in, out));
-ddprintf ("DPAGER DEMUX OBJECT DONE <%p>: %d\n", in, in->msgh_id);
-return rval;
-}
-
-mach_msg_size_t default_pager_msg_size_default = 8 * 1024;
-
-boolean_t
-default_pager_demux_default(in, out)
- mach_msg_header_t *in;
- mach_msg_header_t *out;
-{
- if (in->msgh_local_port == default_pager_default_port) {
- /*
- * We receive memory_object_create messages in
- * the memory_object_default interface.
- */
-
-int rval;
-ddprintf ("DPAGER DEMUX DEFAULT <%p>: %d\n", in, in->msgh_id);
-rval =
- (seqnos_memory_object_default_server(in, out) ||
- default_pager_server(in, out));
-ddprintf ("DPAGER DEMUX DEFAULT DONE <%p>: %d\n", in, in->msgh_id);
-return rval;
- } else if (in->msgh_local_port == default_pager_exception_port) {
- /*
- * We receive exception messages for
- * ourself and the startup task.
- */
-
- return exc_server(in, out);
- } else {
- panic(my_name);
- return FALSE;
- }
-}
-
-/*
- * We use multiple threads, for two reasons.
- *
- * First, memory objects created by default_pager_object_create
- * are "external", instead of "internal". This means the kernel
- * sends data (memory_object_data_write) to the object pageable.
- * To prevent deadlocks, the external and internal objects must
- * be managed by different threads.
- *
- * Second, the default pager uses synchronous IO operations.
- * Spreading requests across multiple threads should
- * recover some of the performance loss from synchronous IO.
- *
- * We have 3+ threads.
- * One receives memory_object_create and
- * default_pager_object_create requests.
- * One or more manage internal objects.
- * One or more manage external objects.
- */
-
-void
-default_pager_thread_privileges()
-{
- /*
- * Set thread privileges.
- */
- cthread_wire(); /* attach kernel thread to cthread */
- wire_thread(); /* grab a kernel stack and memory allocation
- privileges */
-}
-
-any_t
-default_pager_default_thread (arg)
- any_t arg;
-{
- kern_return_t kr;
- default_pager_thread_privileges ();
- for (;;) {
- kr = mach_msg_server(default_pager_demux_default,
- default_pager_msg_size_default,
- default_pager_default_set);
- panic(my_name, kr);
- }
-}
-
-
-
-any_t
-default_pager_thread(arg)
- any_t arg;
-{
- default_pager_thread_t *dpt = (default_pager_thread_t *) arg;
- mach_port_t pset;
- kern_return_t kr;
-
- cthread_set_data(cthread_self(), (any_t) dpt);
-
-
- /*
- * Threads handling external objects cannot have
- * privileges. Otherwise a burst of data-requests for an
- * external object could empty the free-page queue,
- * because the fault code only reserves real pages for
- * requests sent to internal objects.
- */
-
- if (dpt->dpt_internal) {
- default_pager_thread_privileges();
- pset = default_pager_internal_set;
- } else {
- pset = default_pager_external_set;
- }
-
- for (;;) {
- kr = mach_msg_server(default_pager_demux_object,
- default_pager_msg_size_object,
- pset);
- panic(my_name, kr);
- }
-}
-
-void
-start_default_pager_thread(internal)
- boolean_t internal;
-{
- default_pager_thread_t *dpt;
- kern_return_t kr;
-
- dpt = (default_pager_thread_t *) kalloc(sizeof *dpt);
- if (dpt == 0)
- panic(my_name);
-
- dpt->dpt_internal = internal;
-
- kr = vm_allocate(default_pager_self, &dpt->dpt_buffer,
- vm_page_size, TRUE);
- if (kr != KERN_SUCCESS)
- panic(my_name);
- wire_memory(dpt->dpt_buffer, vm_page_size,
- VM_PROT_READ|VM_PROT_WRITE);
-
- dpt->dpt_thread = cthread_fork(default_pager_thread, (any_t) dpt);
-}
-
-void
-default_pager_initialize(host_port)
- mach_port_t host_port;
-{
- memory_object_t DMM;
- kern_return_t kr;
-
- /*
- * This task will become the default pager.
- */
- default_pager_self = mach_task_self();
-
- /*
- * Initialize the "default pager" port.
- */
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_RECEIVE,
- &default_pager_default_port);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- DMM = default_pager_default_port;
- kr = vm_set_default_memory_manager(host_port, &DMM);
- if ((kr != KERN_SUCCESS) || MACH_PORT_VALID(DMM))
- panic(my_name);
-
- /*
- * Initialize the exception port.
- */
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_RECEIVE,
- &default_pager_exception_port);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- /*
- * Arrange for wiring privileges.
- */
- wire_setup(host_port);
-
- /*
- * Find out how many CPUs we have, to determine the number
- * of threads to create.
- */
- if (default_pager_internal_count == 0) {
- host_basic_info_data_t h_info;
- natural_t h_info_count;
-
- h_info_count = HOST_BASIC_INFO_COUNT;
- (void) host_info(host_port, HOST_BASIC_INFO,
- (host_info_t)&h_info, &h_info_count);
-
- /*
- * Random computation to get more parallelism on
- * multiprocessors.
- */
- default_pager_internal_count =
- (h_info.avail_cpus > 32 ? 32 : h_info.avail_cpus) / 4 + 3;
- }
-}
-
-/*
- * Initialize and Run the default pager
- */
-void
-default_pager()
-{
- kern_return_t kr;
- int i;
-
- default_pager_thread_privileges();
-
- /*
- * Wire down code, data, stack
- */
- wire_all_memory();
-
-
- /*
- * Initialize the list of all pagers.
- */
- pager_port_list_init();
-
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
- &default_pager_internal_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
- &default_pager_external_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
- &default_pager_default_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- kr = mach_port_move_member(default_pager_self,
- default_pager_default_port,
- default_pager_default_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- kr = mach_port_move_member(default_pager_self,
- default_pager_exception_port,
- default_pager_default_set);
- if (kr != KERN_SUCCESS)
- panic(my_name);
-
- /*
- * Now we create the threads that will actually
- * manage objects.
- */
-
- for (i = 0; i < default_pager_internal_count; i++)
- start_default_pager_thread(TRUE);
-
- for (i = 0; i < default_pager_external_count; i++)
- start_default_pager_thread(FALSE);
-
- default_pager_default_thread(0); /* Become the default_pager server */
-#if 0
- cthread_fork (default_pager_default_thread, 0);
- /* cthread_exit (cthread_self ()); */
- thread_suspend (mach_thread_self ());
-#endif
-}
-
-/*
- * Create an external object.
- */
-kern_return_t
-S_default_pager_object_create (mach_port_t pager,
- mach_port_t *mem_obj,
- vm_size_t size)
-{
- default_pager_t ds;
- mach_port_t port;
- kern_return_t result;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
- ds = pager_port_alloc(size);
-rename_it:
- port = (mach_port_t) pnameof(ds);
- result = mach_port_allocate_name(default_pager_self,
- MACH_PORT_RIGHT_RECEIVE, port);
- if (result != KERN_SUCCESS) {
- default_pager_t ds1;
-
- if (result != KERN_NAME_EXISTS) return (result);
-
- ds1 = (default_pager_t) kalloc(sizeof *ds1);
- *ds1 = *ds;
- mutex_lock(&all_pagers.lock);
- queue_enter(&all_pagers.leak_queue, ds, default_pager_t, links);
- mutex_unlock(&all_pagers.lock);
- ds = ds1;
- goto rename_it;
- }
-
- /*
- * Set up associations between these ports
- * and this default_pager structure
- */
-
- ds->pager = port;
- pager_port_list_insert(port, ds);
- default_pager_add(ds, FALSE);
-
- *mem_obj = port;
- return (KERN_SUCCESS);
-}
-
-kern_return_t
-S_default_pager_info (mach_port_t pager,
- default_pager_info_t *infop)
-{
- vm_size_t total, free;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
- mutex_lock(&all_partitions.lock);
- paging_space_info(&total, &free);
- mutex_unlock(&all_partitions.lock);
-
- infop->dpi_total_space = ptoa(total);
- infop->dpi_free_space = ptoa(free);
- infop->dpi_page_size = vm_page_size;
- return KERN_SUCCESS;
-}
-
-kern_return_t
-S_default_pager_objects (mach_port_t pager,
- default_pager_object_array_t *objectsp,
- natural_t *ocountp,
- mach_port_array_t *portsp,
- natural_t *pcountp)
-{
- vm_offset_t oaddr; /* memory for objects */
- vm_size_t osize; /* current size */
- default_pager_object_t *objects;
- natural_t opotential;
-
- vm_offset_t paddr; /* memory for ports */
- vm_size_t psize; /* current size */
- mach_port_t *ports;
- natural_t ppotential;
-
- unsigned int actual;
- unsigned int num_pagers;
- kern_return_t kr;
- default_pager_t entry;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
- /* start with the inline memory */
-
- num_pagers = 0;
-
- objects = *objectsp;
- opotential = *ocountp;
-
- ports = *portsp;
- ppotential = *pcountp;
-
- mutex_lock(&all_pagers.lock);
- /*
- * We will send no more than this many
- */
- actual = all_pagers.count;
- mutex_unlock(&all_pagers.lock);
-
- if (opotential < actual) {
- vm_offset_t newaddr;
- vm_size_t newsize;
-
- newsize = 2 * round_page(actual * sizeof *objects);
-
- kr = vm_allocate(default_pager_self, &newaddr, newsize, TRUE);
- if (kr != KERN_SUCCESS)
- goto nomemory;
-
- oaddr = newaddr;
- osize = newsize;
- opotential = osize/sizeof *objects;
- objects = (default_pager_object_t *) oaddr;
- }
-
- if (ppotential < actual) {
- vm_offset_t newaddr;
- vm_size_t newsize;
-
- newsize = 2 * round_page(actual * sizeof *ports);
-
- kr = vm_allocate(default_pager_self, &newaddr, newsize, TRUE);
- if (kr != KERN_SUCCESS)
- goto nomemory;
-
- paddr = newaddr;
- psize = newsize;
- ppotential = psize/sizeof *ports;
- ports = (mach_port_t *) paddr;
- }
-
- /*
- * Now scan the list.
- */
-
- mutex_lock(&all_pagers.lock);
-
- num_pagers = 0;
- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) {
-
- mach_port_t port;
- vm_size_t size;
-
- if ((num_pagers >= opotential) ||
- (num_pagers >= ppotential)) {
- /*
- * This should be rare. In any case,
- * we will only miss recent objects,
- * because they are added at the end.
- */
- break;
- }
-
- /*
- * Avoid interfering with normal operations
- */
- if (!mutex_try_lock(&entry->dpager.lock))
- goto not_this_one;
- size = pager_allocated(&entry->dpager);
- mutex_unlock(&entry->dpager.lock);
-
- dstruct_lock(entry);
-
- port = entry->pager_name;
- if (port == MACH_PORT_NULL) {
- /*
- * The object is waiting for no-senders
- * or memory_object_init.
- */
- dstruct_unlock(entry);
- goto not_this_one;
- }
-
- /*
- * We need a reference for the reply message.
- * While we are unlocked, the bucket queue
- * can change and the object might be terminated.
- * memory_object_terminate will wait for us,
- * preventing deallocation of the entry.
- */
-
- if (--entry->name_refs == 0) {
- dstruct_unlock(entry);
-
- /* keep the list locked, wont take long */
-
- kr = mach_port_mod_refs(default_pager_self,
- port, MACH_PORT_RIGHT_SEND,
- default_pager_max_urefs);
- if (kr != KERN_SUCCESS)
- panic("%sdefault_pager_objects",my_name);
-
- dstruct_lock(entry);
-
- entry->name_refs += default_pager_max_urefs;
- pager_port_finish_refs(entry);
- }
- dstruct_unlock(entry);
-
- /* the arrays are wired, so no deadlock worries */
-
- objects[num_pagers].dpo_object = (vm_offset_t) entry;
- objects[num_pagers].dpo_size = size;
- ports [num_pagers++] = port;
- continue;
-not_this_one:
- /*
- * Do not return garbage
- */
- objects[num_pagers].dpo_object = (vm_offset_t) 0;
- objects[num_pagers].dpo_size = 0;
- ports [num_pagers++] = MACH_PORT_NULL;
-
- }
-
- mutex_unlock(&all_pagers.lock);
-
- /*
- * Deallocate and clear unused memory.
- * (Returned memory will automagically become pageable.)
- */
-
- if (objects == *objectsp) {
- /*
- * Our returned information fit inline.
- * Nothing to deallocate.
- */
-
- *ocountp = num_pagers;
- } else if (actual == 0) {
- (void) vm_deallocate(default_pager_self, oaddr, osize);
-
- /* return zero items inline */
- *ocountp = 0;
- } else {
- vm_offset_t used;
-
- used = round_page(actual * sizeof *objects);
-
- if (used != osize)
- (void) vm_deallocate(default_pager_self,
- oaddr + used, osize - used);
-
- *objectsp = objects;
- *ocountp = num_pagers;
- }
-
- if (ports == *portsp) {
- /*
- * Our returned information fit inline.
- * Nothing to deallocate.
- */
-
- *pcountp = num_pagers;
- } else if (actual == 0) {
- (void) vm_deallocate(default_pager_self, paddr, psize);
-
- /* return zero items inline */
- *pcountp = 0;
- } else {
- vm_offset_t used;
-
- used = round_page(actual * sizeof *ports);
-
- if (used != psize)
- (void) vm_deallocate(default_pager_self,
- paddr + used, psize - used);
-
- *portsp = ports;
- *pcountp = num_pagers;
- }
-
- return KERN_SUCCESS;
-
- nomemory:
-
- {
- register int i;
- for (i = 0; i < num_pagers; i++)
- (void) mach_port_deallocate(default_pager_self, ports[i]);
- }
-
- if (objects != *objectsp)
- (void) vm_deallocate(default_pager_self, oaddr, osize);
-
- if (ports != *portsp)
- (void) vm_deallocate(default_pager_self, paddr, psize);
-
- return KERN_RESOURCE_SHORTAGE;
-}
-
-
-kern_return_t
-S_default_pager_object_pages (mach_port_t pager,
- mach_port_t object,
- default_pager_page_array_t *pagesp,
- natural_t *countp)
-{
- vm_offset_t addr; /* memory for page offsets */
- vm_size_t size; /* current memory size */
- default_pager_page_t *pages;
- natural_t potential, actual;
- kern_return_t kr;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
- /* we start with the inline space */
-
- pages = *pagesp;
- potential = *countp;
-
- for (;;) {
- default_pager_t entry;
-
- mutex_lock(&all_pagers.lock);
- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) {
- dstruct_lock(entry);
- if (entry->pager_name == object) {
- mutex_unlock(&all_pagers.lock);
- goto found_object;
- }
- dstruct_unlock(entry);
- }
- mutex_unlock(&all_pagers.lock);
-
- /* did not find the object */
-
- if (pages != *pagesp)
- (void) vm_deallocate(default_pager_self, addr, size);
- return KERN_INVALID_ARGUMENT;
-
- found_object:
-
- if (!mutex_try_lock(&entry->dpager.lock)) {
- /* oh well bad luck */
-
- dstruct_unlock(entry);
-
- /* yield the processor */
- (void) thread_switch(MACH_PORT_NULL,
- SWITCH_OPTION_NONE, 0);
- continue;
- }
-
- actual = pager_pages(&entry->dpager, pages, potential);
- mutex_unlock(&entry->dpager.lock);
- dstruct_unlock(entry);
-
- if (actual <= potential)
- break;
-
- /* allocate more memory */
-
- if (pages != *pagesp)
- (void) vm_deallocate(default_pager_self, addr, size);
- size = round_page(actual * sizeof *pages);
- kr = vm_allocate(default_pager_self, &addr, size, TRUE);
- if (kr != KERN_SUCCESS)
- return kr;
- pages = (default_pager_page_t *) addr;
- potential = size/sizeof *pages;
- }
-
- /*
- * Deallocate and clear unused memory.
- * (Returned memory will automagically become pageable.)
- */
-
- if (pages == *pagesp) {
- /*
- * Our returned information fit inline.
- * Nothing to deallocate.
- */
-
- *countp = actual;
- } else if (actual == 0) {
- (void) vm_deallocate(default_pager_self, addr, size);
-
- /* return zero items inline */
- *countp = 0;
- } else {
- vm_offset_t used;
-
- used = round_page(actual * sizeof *pages);
-
- if (used != size)
- (void) vm_deallocate(default_pager_self,
- addr + used, size - used);
-
- *pagesp = pages;
- *countp = actual;
- }
- return KERN_SUCCESS;
-}
-
-
-kern_return_t
-S_default_pager_object_set_size (mach_port_t pager,
- mach_port_t reply_to,
- mach_port_seqno_t seqno,
- vm_size_t limit)
-{
- kern_return_t kr;
- default_pager_t ds;
-
- ds = pager_port_lookup(pager);
- if (ds == DEFAULT_PAGER_NULL)
- return KERN_INVALID_ARGUMENT;
-
- pager_port_lock(ds, seqno);
- pager_port_check_request(ds, reply_to);
- pager_port_wait_for_readers(ds);
- pager_port_wait_for_writers(ds);
-
- limit = round_page (limit);
- if (ds->dpager.size <= limit / vm_page_size)
- {
- /* The limit has not been exceeded heretofore. Just change it. */
- ds->dpager.limit = limit;
- kr = KERN_SUCCESS;
- }
- else if (ds->lock_request == MACH_PORT_NULL)
- {
- /* Tell the kernel to flush from core all the pages being removed.
- We will get the memory_object_lock_completed callback when they
- have been flushed. We handle that by completing the limit update
- and posting the reply to the pending truncation. */
- kr = memory_object_lock_request (ds->pager_request,
- limit,
- ds->dpager.size * vm_page_size - limit,
- MEMORY_OBJECT_RETURN_NONE, TRUE,
- VM_PROT_ALL, ds->pager);
- if (kr != KERN_SUCCESS)
- panic ("memory_object_lock_request: %d", kr);
- ds->lock_request = reply_to;
- kr = MIG_NO_REPLY;
- }
- else
- /* There is already another call in progress. Tough titties. */
- kr = KERN_FAILURE;
-
- pager_port_unlock(ds, seqno);
-
- return kr;
-}
-
-/*
- * Add/remove extra paging space
- */
-
-extern mach_port_t bootstrap_master_device_port;
-extern mach_port_t bootstrap_master_host_port;
-
-kern_return_t
-S_default_pager_paging_file (pager, mdport, file_name, add)
- mach_port_t pager;
- mach_port_t mdport;
- default_pager_filename_t file_name;
- boolean_t add;
-{
- kern_return_t kr;
-
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-
-#if 0
-dprintf("bmd %x md %x\n", bootstrap_master_device_port, mdport);
-#endif
- if (add) {
- kr = add_paging_file(bootstrap_master_device_port,
- file_name, 0);
- } else {
- kr = remove_paging_file(file_name);
- }
-
- /* XXXX more code needed */
- if (mdport != bootstrap_master_device_port)
- mach_port_deallocate( mach_task_self(), mdport);
-
- return kr;
-}
-
-default_pager_register_fileserver(pager, fileserver)
- mach_port_t pager;
- mach_port_t fileserver;
-{
- if (pager != default_pager_default_port)
- return KERN_INVALID_ARGUMENT;
-#if notyet
- mach_port_deallocate(mach_task_self(), fileserver);
- if (0) dp_helper_paging_space(0,0,0);/*just linkit*/
-#endif
- return KERN_SUCCESS;
-}
-
-/*
- * When things do not quite workout...
- */
-no_paging_space(out_of_memory)
- boolean_t out_of_memory;
-{
- static char here[] = "%s *** NOT ENOUGH PAGING SPACE ***";
-
- if (out_of_memory)
- dprintf("*** OUT OF MEMORY *** ");
- panic(here, my_name);
-}
-
-overcommitted(got_more_space, space)
- boolean_t got_more_space;
- vm_size_t space; /* in pages */
-{
- vm_size_t pages_free, pages_total;
-
- static boolean_t user_warned = FALSE;
- static vm_size_t pages_shortage = 0;
-
- paging_space_info(&pages_total, &pages_free);
-
- /*
- * If user added more space, see if it is enough
- */
- if (got_more_space) {
- pages_free -= pages_shortage;
- if (pages_free > 0) {
- pages_shortage = 0;
- if (user_warned)
- dprintf("%s paging space ok now.\n", my_name);
- } else
- pages_shortage = pages_free;
- user_warned = FALSE;
- return;
- }
- /*
- * We ran out of gas, let user know.
- */
- pages_free -= space;
- pages_shortage = (pages_free > 0) ? 0 : -pages_free;
- if (!user_warned && pages_shortage) {
- user_warned = TRUE;
- dprintf("%s paging space over-committed.\n", my_name);
- }
-#if debug
- user_warned = FALSE;
- dprintf("%s paging space over-committed [+%d (%d) pages].\n",
- my_name, space, pages_shortage);
-#endif
-}
-
-paging_space_info(totp, freep)
- vm_size_t *totp, *freep;
-{
- register vm_size_t total, free;
- register partition_t part;
- register int i;
-
- total = free = 0;
- for (i = 0; i < all_partitions.n_partitions; i++) {
-
- if ((part = partition_of(i)) == 0) continue;
-
- /* no need to lock: by the time this data
- gets back to any remote requestor it
- will be obsolete anyways */
- total += part->total_size;
- free += part->free;
-#if debug
- dprintf("Partition %d: x%x total, x%x free\n",
- i, part->total_size, part->free);
-#endif
- }
- *totp = total;
- *freep = free;
-}
-
-/*
- * Catch exceptions.
- */
-
-kern_return_t
-catch_exception_raise(exception_port, thread, task, exception, code, subcode)
- mach_port_t exception_port;
- mach_port_t thread, task;
- int exception, code, subcode;
-{
- ddprintf ("(default_pager)catch_exception_raise(%d,%d,%d)\n",
- exception, code, subcode);
- panic(my_name);
-
- /* mach_msg_server will deallocate thread/task for us */
-
- return KERN_FAILURE;
-}
diff --git a/serverboot/defs.h b/serverboot/defs.h
deleted file mode 100644
index 7b872fd6..00000000
--- a/serverboot/defs.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Common definitions for Berkeley Fast File System.
- */
-
-/*
- * Compatibility definitions for disk IO.
- */
-
-/*
- * Disk devices do all IO in 512-byte blocks.
- */
-#define DEV_BSIZE 512
-
-/*
- * Conversion between bytes and disk blocks.
- */
-#define btodb(byte_offset) ((byte_offset) >> 9)
-#define dbtob(block_number) ((block_number) << 9)
-
-/*
- * Compatibility definitions for old type names.
- */
-
-typedef struct _quad_ {
- unsigned int val[2]; /* 2 int values make... */
-} quad; /* an 8-byte item */
-
-#if 0
-typedef unsigned char u_char; /* unsigned char */
-typedef unsigned short u_short; /* unsigned short */
-typedef unsigned int u_int; /* unsigned int */
-
-typedef unsigned int time_t; /* an unsigned int */
-typedef unsigned int daddr_t; /* an unsigned int */
-typedef unsigned int off_t; /* another unsigned int */
-
-typedef unsigned short uid_t;
-typedef unsigned short gid_t;
-typedef unsigned int ino_t;
-#endif
-
-#define NBBY 8
-
-/*
- * The file system is made out of blocks of at most MAXBSIZE units,
- * with smaller units (fragments) only in the last direct block.
- * MAXBSIZE primarily determines the size of buffers in the buffer
- * pool. It may be made larger without any effect on existing
- * file systems; however, making it smaller may make some file
- * systems unmountable.
- *
- * Note that the disk devices are assumed to have DEV_BSIZE "sectors"
- * and that fragments must be some multiple of this size.
- */
-#define MAXBSIZE 8192
-#define MAXFRAG 8
-
-/*
- * MAXPATHLEN defines the longest permissible path length
- * after expanding symbolic links.
- *
- * MAXSYMLINKS defines the maximum number of symbolic links
- * that may be expanded in a path name. It should be set
- * high enough to allow all legitimate uses, but halt infinite
- * loops reasonably quickly.
- */
-
-#define MAXPATHLEN 1024
-#define MAXSYMLINKS 8
-
diff --git a/serverboot/dir.h b/serverboot/dir.h
deleted file mode 100644
index 208df5ce..00000000
--- a/serverboot/dir.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)dir.h 7.6 (Berkeley) 5/9/89
- */
-
-#ifndef _BOOT_UFS_DIR_H_
-#define _BOOT_UFS_DIR_H_
-
-/*
- * A directory consists of some number of blocks of DIRBLKSIZ
- * bytes, where DIRBLKSIZ is chosen such that it can be transferred
- * to disk in a single atomic operation (e.g. 512 bytes on most machines).
- *
- * Each DIRBLKSIZ byte block contains some number of directory entry
- * structures, which are of variable length. Each directory entry has
- * a struct direct at the front of it, containing its inode number,
- * the length of the entry, and the length of the name contained in
- * the entry. These are followed by the name padded to a 4 byte boundary
- * with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- *
- * The macro DIRSIZ(dp) gives the amount of space required to represent
- * a directory entry. Free space in a directory is represented by
- * entries which have dp->d_reclen > DIRSIZ(dp). All DIRBLKSIZ bytes
- * in a directory block are claimed by the directory entries. This
- * usually results in the last entry in a directory having a large
- * dp->d_reclen. When entries are deleted from a directory, the
- * space is returned to the previous entry in the same directory
- * block by increasing its dp->d_reclen. If the first entry of
- * a directory block is free, then its dp->d_ino is set to 0.
- * Entries other than the first in a directory do not normally have
- * dp->d_ino set to 0.
- */
-#define DIRBLKSIZ DEV_BSIZE
-#define MAXNAMLEN 255
-
-struct direct {
- u_int d_ino; /* inode number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
- char d_name[MAXNAMLEN + 1]; /* name with length <= MAXNAMLEN */
-};
-
-/*
- * The DIRSIZ macro gives the minimum record length which will hold
- * the directory entry. This requires the amount of space in struct direct
- * without the d_name field, plus enough space for the name with a terminating
- * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
- */
-#undef DIRSIZ
-#define DIRSIZ(dp) \
- ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
-
-#ifdef KERNEL
-/*
- * Template for manipulating directories.
- * Should use struct direct's, but the name field
- * is MAXNAMLEN - 1, and this just won't do.
- */
-struct dirtemplate {
- u_int dot_ino;
- short dot_reclen;
- short dot_namlen;
- char dot_name[4]; /* must be multiple of 4 */
- u_int dotdot_ino;
- short dotdot_reclen;
- short dotdot_namlen;
- char dotdot_name[4]; /* ditto */
-};
-#endif
-
-/*
- * The following information should be obtained from <dirent.h>
- * and is provided solely (and temporarily) for backward compatibility.
- */
-#ifndef KERNEL
-#define d_fileno d_ino /* compatibility with POSIX */
-#ifndef DEV_BSIZE
-#define DEV_BSIZE 512
-#endif
-/*
- * Definitions for library routines operating on directories.
- */
-typedef struct _dirdesc {
- int dd_fd;
- int dd_loc;
- int dd_size;
- char dd_buf[DIRBLKSIZ];
-} DIR;
-
-#define dirfd(dirp) ((dirp)->dd_fd)
-
-#ifndef NULL
-#define NULL 0
-#endif
-extern DIR *opendir();
-extern struct direct *readdir();
-extern int telldir();
-extern void seekdir();
-#define rewinddir(dirp) seekdir((dirp), (long)0)
-extern void closedir();
-#endif /* not KERNEL */
-#endif /* _BOOT_UFS_DIR_H_ */
diff --git a/serverboot/disk_inode.h b/serverboot/disk_inode.h
deleted file mode 100644
index 6eed9104..00000000
--- a/serverboot/disk_inode.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1982, 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)inode.h 7.5 (Berkeley) 7/3/89
- */
-
-#ifndef _BOOT_UFS_DISK_INODE_H_
-#define _BOOT_UFS_DISK_INODE_H_
-
-/*
- * The I node is the focus of all file activity in the BSD Fast File System.
- * There is a unique inode allocated for each active file,
- * each current directory, each mounted-on file, text file, and the root.
- * An inode is 'named' by its dev/inumber pair. (iget/iget.c)
- * Data in icommon is read in from permanent inode on volume.
- */
-
-#define FFS_NDADDR 12 /* direct addresses in inode */
-#define FFS_NIADDR 3 /* indirect addresses in inode */
-
-#define FFS_MAX_FASTLINK_SIZE ((FFS_NDADDR + FFS_NIADDR) * sizeof(daddr_t))
-
-struct icommon {
- u_short ic_mode; /* 0: mode and type of file */
- short ic_nlink; /* 2: number of links to file */
- short ic_uid; /* 4: owner's user id */
- short ic_gid; /* 6: owner's group id */
- quad ic_size; /* 8: number of bytes in file */
- time_t ic_atime; /* 16: time last accessed */
- int ic_atspare;
- time_t ic_mtime; /* 24: time last modified */
- int ic_mtspare;
- time_t ic_ctime; /* 32: last time inode changed */
- int ic_ctspare;
- union {
- struct {
- daddr_t Mb_db[FFS_NDADDR]; /* 40: disk block addresses */
- daddr_t Mb_ib[FFS_NIADDR]; /* 88: indirect blocks */
- } ic_Mb;
- char ic_Msymlink[FFS_MAX_FASTLINK_SIZE];
- /* 40: symbolic link name */
- } ic_Mun;
-#define ic_db ic_Mun.ic_Mb.Mb_db
-#define ic_ib ic_Mun.ic_Mb.Mb_ib
-#define ic_symlink ic_Mun.ic_Msymlink
- int ic_flags; /* 100: status, currently unused */
- int ic_blocks; /* 104: blocks actually held */
- int ic_gen; /* 108: generation number */
- int ic_spare[4]; /* 112: reserved, currently unused */
-} i_ic;
-
-/*
- * Same structure, but on disk.
- */
-struct dinode {
- union {
- struct icommon di_com;
- char di_char[128];
- } di_un;
-};
-#define di_ic di_un.di_com
-
-#endif /* _BOOT_UFS_DISK_INODE_H_ */
diff --git a/serverboot/disk_inode_ffs.h b/serverboot/disk_inode_ffs.h
deleted file mode 100644
index ab352f84..00000000
--- a/serverboot/disk_inode_ffs.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1982, 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)inode.h 7.5 (Berkeley) 7/3/89
- */
-
-#ifndef _BOOT_UFS_DISK_INODE_FFS_H_
-#define _BOOT_UFS_DISK_INODE_FFS_H_
-
-#define NDADDR FFS_NDADDR
-#define NIADDR FFS_NIADDR
-
-#define MAX_FASTLINK_SIZE FFS_MAX_FASTLINK_SIZE
-
-#define IC_FASTLINK 0x0001 /* Symbolic link in inode */
-
-#define i_mode i_ic.ic_mode
-#define i_nlink i_ic.ic_nlink
-#define i_uid i_ic.ic_uid
-#define i_gid i_ic.ic_gid
-#if BYTE_MSF
-#define i_size i_ic.ic_size.val[1]
-#else /* BYTE_LSF */
-#define i_size i_ic.ic_size.val[0]
-#endif
-#define i_db i_ic.ic_db
-#define i_ib i_ic.ic_ib
-#define i_atime i_ic.ic_atime
-#define i_mtime i_ic.ic_mtime
-#define i_ctime i_ic.ic_ctime
-#define i_blocks i_ic.ic_blocks
-#define i_rdev i_ic.ic_db[0]
-#define i_symlink i_ic.ic_symlink
-#define i_flags i_ic.ic_flags
-#define i_gen i_ic.ic_gen
-
-/* modes */
-#define IFMT 0xf000 /* type of file */
-#define IFCHR 0x2000 /* character special */
-#define IFDIR 0x4000 /* directory */
-#define IFBLK 0x6000 /* block special */
-#define IFREG 0x8000 /* regular */
-#define IFLNK 0xa000 /* symbolic link */
-#define IFSOCK 0xc000 /* socket */
-
-
-#define ISUID 0x0800 /* set user id on execution */
-#define ISGID 0x0400 /* set group id on execution */
-#define ISVTX 0x0200 /* save swapped text even after use */
-#define IREAD 0x0100 /* read, write, execute permissions */
-#define IWRITE 0x0080
-#define IEXEC 0x0040
-
-#define f_fs u.ffs.ffs_fs
-#define i_ic u.ffs.ffs_ic
-#define f_nindir u.ffs.ffs_nindir
-#define f_blk u.ffs.ffs_blk
-#define f_blksize u.ffs.ffs_blksize
-#define f_blkno u.ffs.ffs_blkno
-
-#endif /* _BOOT_UFS_DISK_INODE_FFS_H_ */
diff --git a/serverboot/elf-load.c b/serverboot/elf-load.c
deleted file mode 100644
index 603eadf0..00000000
--- a/serverboot/elf-load.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 1995, 1994, 1993, 1992, 1991, 1990
- * Open Software Foundation, Inc.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation, and that the name of ("OSF") or Open Software
- * Foundation not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior permission.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY
- * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
- */
-/*
- * OSF Research Institute MK6.1 (unencumbered) 1/31/1995
- */
-
-#include <alloca.h>
-#include <mach/machine/vm_types.h>
-#include <elf.h>
-#include "mach-exec.h"
-
-int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec,
- void *handle, exec_info_t *out_info)
-{
- vm_size_t actual;
- union { Elf32_Ehdr h; Elf64_Ehdr h64; } x;
- int i;
- int result;
-
- /* Read the ELF header. */
- if ((result = (*read)(handle, 0, &x, sizeof(x), &actual)) != 0)
- return result;
- if (actual < sizeof(x))
- return EX_NOT_EXECUTABLE;
-
- if ((x.h.e_ident[EI_MAG0] != ELFMAG0) ||
- (x.h.e_ident[EI_MAG1] != ELFMAG1) ||
- (x.h.e_ident[EI_MAG2] != ELFMAG2) ||
- (x.h.e_ident[EI_MAG3] != ELFMAG3))
- return EX_NOT_EXECUTABLE;
-
- /* Make sure the file is of the right architecture. */
-#ifdef i386
-# define MY_CLASS ELFCLASS32
-# define MY_DATA ELFDATA2LSB
-# define MY_MACHINE EM_386
-#elif defined __alpha__
-# define MY_CLASS ELFCLASS64
-# define MY_DATA ELFDATA2LSB
-# define MY_MACHINE EM_ALPHA
-#else
-#error Not ported to this architecture!
-#endif
-
- if ((x.h.e_ident[EI_CLASS] != MY_CLASS) ||
- (x.h.e_ident[EI_DATA] != MY_DATA))
- return EX_WRONG_ARCH;
-
- if (MY_CLASS == ELFCLASS64)
- {
- Elf64_Phdr *phdr, *ph;
- vm_size_t phsize;
-
- if (x.h64.e_machine != MY_MACHINE)
- return EX_WRONG_ARCH;
-
- /* XXX others */
- out_info->entry = (vm_offset_t) x.h64.e_entry;
- out_info->init_dp = 0; /* ? */
-
- phsize = x.h64.e_phnum * x.h64.e_phentsize;
- phdr = (Elf64_Phdr *)alloca(phsize);
-
- result = (*read)(handle, x.h64.e_phoff, phdr, phsize, &actual);
- if (result)
- return result;
- if (actual < phsize)
- return EX_CORRUPT;
-
- for (i = 0; i < x.h64.e_phnum; i++)
- {
- ph = (Elf64_Phdr *)((vm_offset_t)phdr + i * x.h64.e_phentsize);
- if (ph->p_type == PT_LOAD)
- {
- exec_sectype_t type = EXEC_SECTYPE_ALLOC |
- EXEC_SECTYPE_LOAD;
- if (ph->p_flags & PF_R) type |= EXEC_SECTYPE_READ;
- if (ph->p_flags & PF_W) type |= EXEC_SECTYPE_WRITE;
- if (ph->p_flags & PF_X) type |= EXEC_SECTYPE_EXECUTE;
- result = (*read_exec)(handle,
- ph->p_offset, ph->p_filesz,
- ph->p_vaddr, ph->p_memsz, type);
- }
- }
- }
- else
- {
- Elf32_Phdr *phdr, *ph;
- vm_size_t phsize;
-
- if (x.h.e_machine != MY_MACHINE)
- return EX_WRONG_ARCH;
-
- /* XXX others */
- out_info->entry = (vm_offset_t) x.h.e_entry;
- out_info->init_dp = 0; /* ? */
-
- phsize = x.h.e_phnum * x.h.e_phentsize;
- phdr = (Elf32_Phdr *)alloca(phsize);
-
- result = (*read)(handle, x.h.e_phoff, phdr, phsize, &actual);
- if (result)
- return result;
- if (actual < phsize)
- return EX_CORRUPT;
-
- for (i = 0; i < x.h.e_phnum; i++)
- {
- ph = (Elf32_Phdr *)((vm_offset_t)phdr + i * x.h.e_phentsize);
- if (ph->p_type == PT_LOAD)
- {
- exec_sectype_t type = EXEC_SECTYPE_ALLOC |
- EXEC_SECTYPE_LOAD;
- if (ph->p_flags & PF_R) type |= EXEC_SECTYPE_READ;
- if (ph->p_flags & PF_W) type |= EXEC_SECTYPE_WRITE;
- if (ph->p_flags & PF_X) type |= EXEC_SECTYPE_EXECUTE;
- result = (*read_exec)(handle,
- ph->p_offset, ph->p_filesz,
- ph->p_vaddr, ph->p_memsz, type);
- }
- }
- }
-
- return 0;
-}
diff --git a/serverboot/exec.c b/serverboot/exec.c
deleted file mode 100644
index a487fb5d..00000000
--- a/serverboot/exec.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * i386-specific routines for loading a.out files.
- */
-
-#include <mach.h>
-#include <mach/machine/vm_param.h>
-#include "mach-exec.h"
-
-#include <file_io.h>
-
-#ifdef i386
-
-#include <mach/machine/eflags.h>
-
-/*
- * Machine-dependent portions of execve() for the i386.
- */
-
-#define STACK_SIZE (64*1024)
-
-char *set_regs(
- mach_port_t user_task,
- mach_port_t user_thread,
- struct exec_info *info,
- int arg_size)
-{
- vm_offset_t stack_start;
- vm_offset_t stack_end;
- struct i386_thread_state regs;
- unsigned int reg_size;
-
- /*
- * Add space for 5 ints to arguments, for
- * PS program. XXX
- */
- arg_size += 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 = info->entry;
- regs.uesp = (int)((stack_end - arg_size) & ~(sizeof(int)-1));
-
- /* regs.efl |= EFL_TF; trace flag*/
-
- (void)thread_set_state(user_thread,
- i386_THREAD_STATE,
- (thread_state_t)&regs,
- reg_size);
-
- return (char *)regs.uesp;
-}
-
-#elif defined __alpha__
-
-
-/*
- * Object:
- * set_regs EXPORTED function
- *
- * Initialize enough state for a thread to run, including
- * stack memory and stack pointer, and program counter.
- *
- */
-#define STACK_SIZE (vm_size_t)(128*1024)
-
-char *set_regs(
- mach_port_t user_task,
- mach_port_t user_thread,
- struct exec_info *info,
- int arg_size)
-{
- vm_offset_t stack_start;
- vm_offset_t stack_end;
- struct alpha_thread_state regs;
-
- natural_t reg_size;
-
- /*
- * Allocate stack.
- */
- stack_end = VM_MAX_ADDRESS;
- stack_start = stack_end - STACK_SIZE;
- (void)vm_allocate(user_task,
- &stack_start,
- (vm_size_t)(STACK_SIZE),
- FALSE);
-
- reg_size = ALPHA_THREAD_STATE_COUNT;
- (void)thread_get_state(user_thread,
- ALPHA_THREAD_STATE,
- (thread_state_t)&regs,
- &reg_size);
-
- regs.pc = info->entry;
- regs.r29 = info->init_dp;
- regs.r30 = (integer_t)((stack_end - arg_size) & ~(sizeof(integer_t)-1));
-
- (void)thread_set_state(user_thread,
- ALPHA_THREAD_STATE,
- (thread_state_t)&regs,
- reg_size);
-
- return (char *)regs.r30;
-}
-
-#else
-# error "Not ported to this architecture!"
-#endif
diff --git a/serverboot/ext2_file_io.c b/serverboot/ext2_file_io.c
deleted file mode 100644
index cb915c4a..00000000
--- a/serverboot/ext2_file_io.c
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Stand-alone file reading package.
- */
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include "file_io.h"
-#include "ffs_compat.h"
-
-void ext2_close_file(); /* forward */
-
-/*
- * Free file buffers, but don't close file.
- */
-static void
-free_file_buffers(fp)
- register struct file *fp;
-{
- register int level;
-
- /*
- * Free the indirect blocks
- */
- for (level = 0; level < NIADDR; level++) {
- if (fp->f_blk[level] != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_blk[level],
- fp->f_blksize[level]);
- fp->f_blk[level] = 0;
- }
- fp->f_blkno[level] = -1;
- }
-
- /*
- * Free the data block
- */
- if (fp->f_buf != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
- fp->f_buf = 0;
- }
- fp->f_buf_blkno = -1;
-}
-
-/*
- * Read a new inode into a file structure.
- */
-static int
-read_inode(inumber, fp)
- ino_t inumber;
- register struct file *fp;
-{
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- register
- struct ext2_super_block *fs;
- daddr_t disk_block;
- kern_return_t rc;
-
- fs = fp->f_fs;
- disk_block = ino2blk(fs, fp->f_gd, inumber);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fp->f_fs, disk_block),
- (int) EXT2_BLOCK_SIZE(fs),
- (char **)&buf,
- &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- {
- register struct ext2_inode *dp;
-
- dp = (struct ext2_inode *)buf;
- dp += itoo(fs, inumber);
- fp->i_ic = *dp;
- fp->f_size = dp->i_size;
- }
-
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
-
- /*
- * Clear out the old buffers
- */
- free_file_buffers(fp);
-
- return (0);
-}
-
-/*
- * Given an offset in a file, find the disk block number that
- * contains that block.
- */
-static int
-block_map(fp, file_block, disk_block_p)
- struct file *fp;
- daddr_t file_block;
- daddr_t *disk_block_p; /* out */
-{
- int level;
- int idx;
- daddr_t ind_block_num;
- kern_return_t rc;
-
- vm_offset_t olddata[NIADDR+1];
- vm_size_t oldsize[NIADDR+1];
-
- /*
- * Index structure of an inode:
- *
- * i_db[0..NDADDR-1] hold block numbers for blocks
- * 0..NDADDR-1
- *
- * i_ib[0] index block 0 is the single indirect
- * block
- * holds block numbers for blocks
- * NDADDR .. NDADDR + NINDIR(fs)-1
- *
- * i_ib[1] index block 1 is the double indirect
- * block
- * holds block numbers for INDEX blocks
- * for blocks
- * NDADDR + NINDIR(fs) ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
- *
- * i_ib[2] index block 2 is the triple indirect
- * block
- * holds block numbers for double-indirect
- * blocks for blocks
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2
- * + NINDIR(fs)**3 - 1
- */
-
- mutex_lock(&fp->f_lock);
-
- if (file_block < NDADDR) {
- /* Direct block. */
- *disk_block_p = fp->i_ic.i_block[file_block];
- mutex_unlock(&fp->f_lock);
- return (0);
- }
-
- file_block -= NDADDR;
-
- /*
- * nindir[0] = NINDIR
- * nindir[1] = NINDIR**2
- * nindir[2] = NINDIR**3
- * etc
- */
- for (level = 0; level < NIADDR; level++) {
- if (file_block < fp->f_nindir[level])
- break;
- file_block -= fp->f_nindir[level];
- }
- if (level == NIADDR) {
- /* Block number too high */
- mutex_unlock(&fp->f_lock);
- return (FS_NOT_IN_FILE);
- }
-
- ind_block_num = fp->i_ic.i_block[level + NDADDR];
-
- /*
- * Initialize array of blocks to free.
- */
- for (idx = 0; idx < NIADDR; idx++)
- oldsize[idx] = 0;
-
- for (; level >= 0; level--) {
-
- vm_offset_t data;
- mach_msg_type_number_t size;
-
- if (ind_block_num == 0)
- break;
-
- if (fp->f_blkno[level] == ind_block_num) {
- /*
- * Cache hit. Just pick up the data.
- */
-
- data = fp->f_blk[level];
- }
- else {
- /*
- * Drop our lock while doing the read.
- * (The f_dev and f_fs fields don`t change.)
- */
- mutex_unlock(&fp->f_lock);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fp->f_fs, ind_block_num),
- EXT2_BLOCK_SIZE(fp->f_fs),
- (char **)&data,
- &size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- /*
- * See if we can cache the data. Need a write lock to
- * do this. While we hold the write lock, we can`t do
- * *anything* which might block for memory. Otherwise
- * a non-privileged thread might deadlock with the
- * privileged threads. We can`t block while taking the
- * write lock. Otherwise a non-privileged thread
- * blocked in the vm_deallocate (while holding a read
- * lock) will block a privileged thread. For the same
- * reason, we can`t take a read lock and then use
- * lock_read_to_write.
- */
-
- mutex_lock(&fp->f_lock);
-
- olddata[level] = fp->f_blk[level];
- oldsize[level] = fp->f_blksize[level];
-
- fp->f_blkno[level] = ind_block_num;
- fp->f_blk[level] = data;
- fp->f_blksize[level] = size;
-
- /*
- * Return to holding a read lock, and
- * dispose of old data.
- */
-
- }
-
- if (level > 0) {
- idx = file_block / fp->f_nindir[level-1];
- file_block %= fp->f_nindir[level-1];
- }
- else
- idx = file_block;
-
- ind_block_num = ((daddr_t *)data)[idx];
- }
-
- mutex_unlock(&fp->f_lock);
-
- /*
- * After unlocking the file, free any blocks that
- * we need to free.
- */
- for (idx = 0; idx < NIADDR; idx++)
- if (oldsize[idx] != 0)
- (void) vm_deallocate(mach_task_self(),
- olddata[idx],
- oldsize[idx]);
-
- *disk_block_p = ind_block_num;
- return (0);
-}
-
-/*
- * Read a portion of a file into an internal buffer. Return
- * the location in the buffer and the amount in the buffer.
- */
-static int
-buf_read_file(fp, offset, buf_p, size_p)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t *buf_p; /* out */
- vm_size_t *size_p; /* out */
-{
- register
- struct ext2_super_block *fs;
- vm_offset_t off;
- register daddr_t file_block;
- daddr_t disk_block;
- int rc;
- vm_offset_t block_size;
-
- if (offset >= fp->i_ic.i_size)
- return (FS_NOT_IN_FILE);
-
- fs = fp->f_fs;
-
- off = blkoff(fs, offset);
- file_block = lblkno(fs, offset);
- block_size = blksize(fs, fp, file_block);
-
- if (file_block != fp->f_buf_blkno) {
- rc = block_map(fp, file_block, &disk_block);
- if (rc != 0)
- return (rc);
-
- if (fp->f_buf)
- (void)vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
-
- if (disk_block == 0) {
- (void)vm_allocate(mach_task_self(),
- &fp->f_buf,
- block_size,
- TRUE);
- fp->f_buf_size = block_size;
- }
- else {
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fs, disk_block),
- (int) block_size,
- (char **) &fp->f_buf,
- (mach_msg_type_number_t *)&fp->f_buf_size);
- }
- if (rc)
- return (rc);
-
- fp->f_buf_blkno = file_block;
- }
-
- /*
- * Return address of byte in buffer corresponding to
- * offset, and size of remainder of buffer after that
- * byte.
- */
- *buf_p = fp->f_buf + off;
- *size_p = block_size - off;
-
- /*
- * But truncate buffer at end of file.
- */
- if (*size_p > fp->i_ic.i_size - offset)
- *size_p = fp->i_ic.i_size - offset;
-
- return (0);
-}
-
-/*
- * Search a directory for a name and return its
- * i_number.
- */
-static int
-search_directory(name, fp, inumber_p)
- char * name;
- register struct file *fp;
- ino_t *inumber_p; /* out */
-{
- vm_offset_t buf;
- vm_size_t buf_size;
- vm_offset_t offset;
- struct ext2_dir_entry_2 *dp;
- int length;
- kern_return_t rc;
- char tmp_name[256];
-
- length = strlen(name);
-
- offset = 0;
- while (offset < fp->i_ic.i_size) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- dp = (struct ext2_dir_entry_2 *)buf;
- if (dp->inode != 0) {
- strncpy (tmp_name, dp->name, dp->name_len);
- tmp_name[dp->name_len] = '\0';
- if (dp->name_len == length &&
- !strcmp(name, tmp_name))
- {
- /* found entry */
- *inumber_p = dp->inode;
- return (0);
- }
- }
- offset += dp->rec_len;
- }
- return (FS_NO_ENTRY);
-}
-
-static int
-read_fs(dev, fsp, gdp, gd_size_p)
- mach_port_t dev;
- struct ext2_super_block **fsp;
- struct ext2_group_desc **gdp;
- vm_size_t *gd_size_p;
-{
- register
- struct ext2_super_block *fs;
- vm_offset_t buf;
- vm_offset_t buf2;
- mach_msg_type_number_t buf_size;
- mach_msg_type_number_t buf2_size;
- int error;
- int gd_count;
- int gd_blocks;
- int gd_size;
- int gd_location;
- int gd_sector;
-
- /*
- * Read the super block
- */
- error = device_read(dev, 0, (recnum_t) SBLOCK, SBSIZE,
- (char **) &buf, &buf_size);
- if (error)
- return (error);
-
- /*
- * Check the superblock
- */
- fs = (struct ext2_super_block *)buf;
- if (fs->s_magic != EXT2_SUPER_MAGIC) {
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- return (FS_INVALID_FS);
- }
-
- *fsp = fs;
-
- /*
- * Compute the groups informations
- */
- gd_count = (fs->s_blocks_count - fs->s_first_data_block +
- fs->s_blocks_per_group - 1) / fs->s_blocks_per_group;
- gd_blocks = (gd_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
- EXT2_DESC_PER_BLOCK(fs);
- gd_size = gd_blocks * EXT2_BLOCK_SIZE(fs);
- gd_location = fs->s_first_data_block + 1;
- gd_sector = (gd_location * EXT2_BLOCK_SIZE(fs)) / DEV_BSIZE;
-
- /*
- * Read the groups descriptors
- */
- error = device_read(dev, 0, (recnum_t) gd_sector, gd_size,
- (char **) &buf2, &buf2_size);
- if (error) {
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- return error;
- }
-
- *gdp = (struct ext2_group_desc *) buf2;
- *gd_size_p = gd_size;
-
- return 0;
-}
-
-static int
-mount_fs(fp)
- register struct file *fp;
-{
- register struct ext2_super_block *fs;
- int error;
-
- error = read_fs(fp->f_dev, &fp->f_fs, &fp->f_gd, &fp->f_gd_size);
- if (error)
- return (error);
-
- fs = fp->f_fs;
-
- /*
- * Calculate indirect block levels.
- */
- {
- register int mult;
- register int level;
-
- mult = 1;
- for (level = 0; level < NIADDR; level++) {
- mult *= NINDIR(fs);
- fp->f_nindir[level] = mult;
- }
- }
-
- return (0);
-}
-
-static void
-unmount_fs(fp)
- register struct file *fp;
-{
- if (file_is_structured(fp)) {
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fp->f_fs,
- SBSIZE);
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fp->f_gd,
- fp->f_gd_size);
- fp->f_fs = 0;
- }
-}
-
-/*
- * Open a file.
- */
-int
-ext2_open_file(master_device_port, path, fp)
- mach_port_t master_device_port;
- char * path;
- struct file *fp;
-{
-#define RETURN(code) { rc = (code); goto exit; }
-
- register char *cp, *component;
- register int c; /* char */
- register int rc;
- ino_t inumber, parent_inumber;
- int nlinks = 0;
-
- char namebuf[MAXPATHLEN+1];
-
- if (path == 0 || *path == '\0') {
- return FS_NO_ENTRY;
- }
-
- /*
- * Copy name into buffer to allow modifying it.
- */
- strcpy(namebuf, path);
-
- /*
- * Look for '/dev/xxx' at start of path, for
- * root device.
- */
- if (!strprefix(namebuf, "/dev/")) {
- printf("no device name\n");
- return FS_NO_ENTRY;
- }
-
- cp = namebuf + 5; /* device */
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- bzero (fp, sizeof (struct file));
-
- rc = device_open(master_device_port,
- D_READ|D_WRITE,
- component,
- &fp->f_dev);
- if (rc)
- return rc;
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return rc;
-
- inumber = (ino_t) ROOTINO;
- if ((rc = read_inode(inumber, fp)) != 0) {
- printf("can't read root inode\n");
- goto exit;
- }
-
- while (*cp) {
-
- /*
- * Check that current node is a directory.
- */
- if ((fp->i_ic.i_mode & IFMT) != IFDIR)
- RETURN (FS_NOT_DIRECTORY);
-
- /*
- * Remove extra separators
- */
- while (*cp == '/')
- cp++;
-
- /*
- * Get next component of path name.
- */
- component = cp;
- {
- register int len = 0;
-
- while ((c = *cp) != '\0' && c != '/') {
- if (len++ > MAXNAMLEN)
- RETURN (FS_NAME_TOO_LONG);
- if (c & 0200)
- RETURN (FS_INVALID_PARAMETER);
- cp++;
- }
- *cp = 0;
- }
-
- /*
- * Look up component in current directory.
- * Save directory inumber in case we find a
- * symbolic link.
- */
- parent_inumber = inumber;
- rc = search_directory(component, fp, &inumber);
- if (rc) {
- printf("%s: not found\n", path);
- goto exit;
- }
- *cp = c;
-
- /*
- * Open next component.
- */
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
-
- /*
- * Check for symbolic link.
- */
- if ((fp->i_ic.i_mode & IFMT) == IFLNK) {
-
- int link_len = fp->i_ic.i_size;
- int len;
-
- len = strlen(cp) + 1;
-
- if (link_len + len >= MAXPATHLEN - 1)
- RETURN (FS_NAME_TOO_LONG);
-
- if (++nlinks > MAXSYMLINKS)
- RETURN (FS_SYMLINK_LOOP);
-
- memmove(&namebuf[link_len], cp, len);
-
-#ifdef IC_FASTLINK
- if (fp->i_ic.i_blocks == 0) {
- bcopy(fp->i_ic.i_block, namebuf, (unsigned) link_len);
- }
- else
-#endif /* IC_FASTLINK */
- {
- /*
- * Read file for symbolic link
- */
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- daddr_t disk_block;
- register struct ext2_super_block *fs = fp->f_fs;
-
- (void) block_map(fp, (daddr_t)0, &disk_block);
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fs, disk_block),
- (int) blksize(fs, fp, 0),
- (char **) &buf,
- &buf_size);
- if (rc)
- goto exit;
-
- bcopy((char *)buf, namebuf, (unsigned)link_len);
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- }
-
- /*
- * If relative pathname, restart at parent directory.
- * If absolute pathname, restart at root.
- * If pathname begins '/dev/<device>/',
- * restart at root of that device.
- */
- cp = namebuf;
- if (*cp != '/') {
- inumber = parent_inumber;
- }
- else if (!strprefix(cp, "/dev/")) {
- inumber = (ino_t)ROOTINO;
- }
- else {
- cp += 5;
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- /*
- * Unmount current file system and free buffers.
- */
- ext2_close_file(fp);
-
- /*
- * Open new root device.
- */
- rc = device_open(master_device_port,
- D_READ,
- component,
- &fp->f_dev);
- if (rc)
- return (rc);
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return (rc);
-
- inumber = (ino_t)ROOTINO;
- }
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
- }
- }
-
- /*
- * Found terminal component.
- */
- out_ok:
- mutex_init(&fp->f_lock);
- return 0;
-
- /*
- * At error exit, close file to free storage.
- */
- exit:
- ext2_close_file(fp);
- return rc;
-}
-
-/*
- * Close file - free all storage used.
- */
-void
-ext2_close_file(fp)
- register struct file *fp;
-{
- register int i;
-
- /*
- * Free the disk super-block.
- */
- unmount_fs(fp);
-
- /*
- * Free the inode and data buffers.
- */
- free_file_buffers(fp);
-}
-
-int
-ext2_file_is_directory(struct file *fp)
-{
- return (fp->i_ic.i_mode & IFMT) == IFDIR;
-}
-
-int
-ext2_file_is_regular(struct file *fp)
-{
- return (fp->i_ic.i_mode & IFMT) == IFREG;
-}
-
-/*
- * Copy a portion of a file into kernel memory.
- * Cross block boundaries when necessary.
- */
-int
-ext2_read_file(fp, offset, start, size, resid)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t start;
- vm_size_t size;
- vm_size_t *resid; /* out */
-{
- int rc;
- register vm_size_t csize;
- vm_offset_t buf;
- vm_size_t buf_size;
-
- while (size != 0) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc)
- return (rc);
-
- csize = size;
- if (csize > buf_size)
- csize = buf_size;
- if (csize == 0)
- break;
-
- bcopy((char *)buf, (char *)start, csize);
-
- offset += csize;
- start += csize;
- size -= csize;
- }
- if (resid)
- *resid = size;
-
- return (0);
-}
-
-/* simple utility: only works for 2^n */
-static int
-log2(n)
- register unsigned int n;
-{
- register int i = 0;
-
- while ((n & 1) == 0) {
- i++;
- n >>= 1;
- }
- return i;
-}
-
-/*
- * Make an empty file_direct for a device.
- */
-int
-ext2_open_file_direct(dev, fdp, is_structured)
- mach_port_t dev;
- register struct file_direct *fdp;
- boolean_t is_structured;
-{
- struct ext2_super_block *fs;
- struct ext2_group_desc *gd;
- vm_size_t gd_size;
- int rc;
-
- if (!is_structured) {
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_bsize = vm_page_size;
- fdp->fd_bshift = log2(vm_page_size);
- fdp->fd_fsbtodb = 0; /* later */
- fdp->fd_size = 0; /* later */
- return 0;
- }
-
- rc = read_fs(dev, &fs, &gd, &gd_size);
- if (rc)
- return rc;
-
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_size = 0;
- fdp->fd_bsize = EXT2_BLOCK_SIZE(fs);
- fdp->fd_bshift = log2(fdp->fd_bsize);
- fdp->fd_fsbtodb = log2(fdp->fd_bsize / DEV_BSIZE);
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fs,
- SBSIZE);
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) gd,
- gd_size);
-
- return 0;
-}
-
-/*
- * Add blocks from a file to a file_direct.
- */
-int
-ext2_add_file_direct(fdp, fp)
- register struct file_direct *fdp;
- register struct file *fp;
-{
- register struct ext2_super_block *fs;
- long num_blocks, i;
- vm_offset_t buffer;
- vm_size_t size;
- int rc;
-
- /* the file must be on the same device */
-
- if (fdp->fd_dev != fp->f_dev)
- return FS_INVALID_FS;
-
- if (!file_is_structured(fp)) {
- int result[DEV_GET_SIZE_COUNT];
- natural_t count;
-
- count = DEV_GET_SIZE_COUNT;
- rc = device_get_status( fdp->fd_dev, DEV_GET_SIZE,
- result, &count);
- if (rc)
- return rc;
- fdp->fd_size = result[DEV_GET_SIZE_DEVICE_SIZE] >> fdp->fd_bshift;
- fdp->fd_fsbtodb = log2(fdp->fd_bsize/result[DEV_GET_SIZE_RECORD_SIZE]);
- return 0;
- }
-
- /* it must hold a file system */
-
- fs = fp->f_fs;
-/*
- if (fdp->fd_bsize != fs->fs_bsize ||
- fdp->fd_fsbtodb != fs->fs_fsbtodb)
-*/
- if (fdp->fd_bsize != EXT2_BLOCK_SIZE(fs))
- return FS_INVALID_FS;
-
- /* calculate number of blocks in the file, ignoring fragments */
-
- num_blocks = lblkno(fs, fp->i_ic.i_size);
-
- /* allocate memory for a bigger array */
-
- size = (num_blocks + fdp->fd_size) * sizeof(daddr_t);
- rc = vm_allocate(mach_task_self(), &buffer, size, TRUE);
- if (rc != KERN_SUCCESS)
- return rc;
-
- /* lookup new block addresses */
-
- for (i = 0; i < num_blocks; i++) {
- daddr_t disk_block;
-
- rc = block_map(fp, (daddr_t) i, &disk_block);
- if (rc != 0) {
- (void) vm_deallocate(mach_task_self(), buffer, size);
- return rc;
- }
-
- ((daddr_t *) buffer)[fdp->fd_size + i] = disk_block;
- }
-
- /* copy old addresses and install the new array */
-
- if (fdp->fd_blocks != 0) {
- bcopy((char *) fdp->fd_blocks, (char *) buffer,
- fdp->fd_size * sizeof(daddr_t));
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(daddr_t)));
- }
- fdp->fd_blocks = (daddr_t *) buffer;
- fdp->fd_size += num_blocks;
-
- /* deallocate cached blocks */
-
- free_file_buffers(fp);
-
- return 0;
-}
-
-int
-ext2_remove_file_direct(fdp)
- struct file_direct *fdp;
-{
- if (fdp->fd_blocks)
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(daddr_t)));
- fdp->fd_blocks = 0; /* sanity */
- /* xxx should lose a ref to fdp->fd_dev here (and elsewhere) xxx */
-}
diff --git a/serverboot/ffs_compat.c b/serverboot/ffs_compat.c
deleted file mode 100644
index 6e322b63..00000000
--- a/serverboot/ffs_compat.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * BSD FFS like functions used to ease porting bootstrap to Linux ext2 fs
- * Copyright (C) 1994 Remy Card
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include <file_io.h>
-
-#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_inode))
-
-int ino2blk (struct ext2_super_block *fs, struct ext2_group_desc *gd, int ino)
-{
- int group;
- int blk;
-
- group = (ino - 1) / EXT2_INODES_PER_GROUP(fs);
- blk = gd[group].bg_inode_table +
- (((ino - 1) % EXT2_INODES_PER_GROUP(fs)) /
- EXT2_INODES_PER_BLOCK(fs));
- return blk;
-}
-
-int fsbtodb (struct ext2_super_block *fs, int b)
-{
- return (b * EXT2_BLOCK_SIZE(fs)) / DEV_BSIZE;
-}
-
-int itoo (struct ext2_super_block *fs, int ino)
-{
- return (ino - 1) % EXT2_INODES_PER_BLOCK(fs);
-}
-
-int blkoff (struct ext2_super_block * fs, vm_offset_t offset)
-{
- return offset % EXT2_BLOCK_SIZE(fs);
-}
-
-int lblkno (struct ext2_super_block * fs, vm_offset_t offset)
-{
- return offset / EXT2_BLOCK_SIZE(fs);
-}
-
-int blksize (struct ext2_super_block *fs, struct file *fp, daddr_t file_block)
-{
- return EXT2_BLOCK_SIZE(fs); /* XXX - fix for fragments */
-}
diff --git a/serverboot/ffs_compat.h b/serverboot/ffs_compat.h
deleted file mode 100644
index d78840f5..00000000
--- a/serverboot/ffs_compat.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * BSD FFS like declarations used to ease porting bootstrap to Linux ext2 fs
- * Copyright (C) 1994 Remy Card
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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.
- */
-
-#define SBSIZE EXT2_MIN_BLOCK_SIZE /* Size of superblock */
-#define SBLOCK ((daddr_t) 2) /* Location of superblock */
-
-#define NDADDR EXT2_NDIR_BLOCKS
-#define NIADDR (EXT2_N_BLOCKS - EXT2_NDIR_BLOCKS)
-
-#define MAXNAMLEN 255
-
-#define ROOTINO EXT2_ROOT_INO
-
-#define NINDIR(fs) EXT2_ADDR_PER_BLOCK(fs)
-
-#define IC_FASTLINK
-
-#define IFMT 00170000
-#define IFSOCK 0140000
-#define IFLNK 0120000
-#define IFREG 0100000
-#define IFBLK 0060000
-#define IFDIR 0040000
-#define IFCHR 0020000
-#define IFIFO 0010000
-#define ISUID 0004000
-#define ISGID 0002000
-#define ISVTX 0001000
-
-#define f_fs u.ext2.ext2_fs
-#define f_gd u.ext2.ext2_gd
-#define f_gd_size u.ext2.ext2_gd_size
-#define i_ic u.ext2.ext2_ic
-#define f_nindir u.ext2.ext2_nindir
-#define f_blk u.ext2.ext2_blk
-#define f_blksize u.ext2.ext2_blksize
-#define f_blkno u.ext2.ext2_blkno
-
diff --git a/serverboot/ffs_file_io.c b/serverboot/ffs_file_io.c
deleted file mode 100644
index 1105eacc..00000000
--- a/serverboot/ffs_file_io.c
+++ /dev/null
@@ -1,969 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Stand-alone file reading package.
- */
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include "file_io.h"
-#include "fs.h"
-#include "dir.h"
-#include "disk_inode_ffs.h"
-
-void close_file(); /* forward */
-
-/*
- * Free file buffers, but don't close file.
- */
-static void
-free_file_buffers(fp)
- register struct file *fp;
-{
- register int level;
-
- /*
- * Free the indirect blocks
- */
- for (level = 0; level < NIADDR; level++) {
- if (fp->f_blk[level] != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_blk[level],
- fp->f_blksize[level]);
- fp->f_blk[level] = 0;
- }
- fp->f_blkno[level] = -1;
- }
-
- /*
- * Free the data block
- */
- if (fp->f_buf != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
- fp->f_buf = 0;
- }
- fp->f_buf_blkno = -1;
-}
-
-/*
- * Read a new inode into a file structure.
- */
-static int
-read_inode(inumber, fp)
- ino_t inumber;
- register struct file *fp;
-{
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- register struct fs *fs;
- daddr_t disk_block;
- kern_return_t rc;
-
- fs = fp->f_fs;
- disk_block = itod(fs, inumber);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fp->f_fs, disk_block),
- (int) fs->fs_bsize,
- (char **)&buf,
- &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- {
- register struct dinode *dp;
-
- dp = (struct dinode *)buf;
- dp += itoo(fs, inumber);
- fp->i_ic = dp->di_ic;
- fp->f_size = fp->i_size;
- }
-
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
-
- /*
- * Clear out the old buffers
- */
- free_file_buffers(fp);
-
- return (0);
-}
-
-/*
- * Given an offset in a file, find the disk block number that
- * contains that block.
- */
-static int
-block_map(fp, file_block, disk_block_p)
- struct file *fp;
- daddr_t file_block;
- daddr_t *disk_block_p; /* out */
-{
- int level;
- int idx;
- daddr_t ind_block_num;
- kern_return_t rc;
-
- vm_offset_t olddata[NIADDR+1];
- vm_size_t oldsize[NIADDR+1];
-
- /*
- * Index structure of an inode:
- *
- * i_db[0..NDADDR-1] hold block numbers for blocks
- * 0..NDADDR-1
- *
- * i_ib[0] index block 0 is the single indirect
- * block
- * holds block numbers for blocks
- * NDADDR .. NDADDR + NINDIR(fs)-1
- *
- * i_ib[1] index block 1 is the double indirect
- * block
- * holds block numbers for INDEX blocks
- * for blocks
- * NDADDR + NINDIR(fs) ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
- *
- * i_ib[2] index block 2 is the triple indirect
- * block
- * holds block numbers for double-indirect
- * blocks for blocks
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2
- * + NINDIR(fs)**3 - 1
- */
-
- mutex_lock(&fp->f_lock);
-
- if (file_block < NDADDR) {
- /* Direct block. */
- *disk_block_p = fp->i_db[file_block];
- mutex_unlock(&fp->f_lock);
- return (0);
- }
-
- file_block -= NDADDR;
-
- /*
- * nindir[0] = NINDIR
- * nindir[1] = NINDIR**2
- * nindir[2] = NINDIR**3
- * etc
- */
- for (level = 0; level < NIADDR; level++) {
- if (file_block < fp->f_nindir[level])
- break;
- file_block -= fp->f_nindir[level];
- }
- if (level == NIADDR) {
- /* Block number too high */
- mutex_unlock(&fp->f_lock);
- return (FS_NOT_IN_FILE);
- }
-
- ind_block_num = fp->i_ib[level];
-
- /*
- * Initialize array of blocks to free.
- */
- for (idx = 0; idx < NIADDR; idx++)
- oldsize[idx] = 0;
-
- for (; level >= 0; level--) {
-
- vm_offset_t data;
- mach_msg_type_number_t size;
-
- if (ind_block_num == 0)
- break;
-
- if (fp->f_blkno[level] == ind_block_num) {
- /*
- * Cache hit. Just pick up the data.
- */
-
- data = fp->f_blk[level];
- }
- else {
- /*
- * Drop our lock while doing the read.
- * (The f_dev and f_fs fields don`t change.)
- */
- mutex_unlock(&fp->f_lock);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fp->f_fs, ind_block_num),
- fp->f_fs->fs_bsize,
- (char **)&data,
- &size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- /*
- * See if we can cache the data. Need a write lock to
- * do this. While we hold the write lock, we can`t do
- * *anything* which might block for memory. Otherwise
- * a non-privileged thread might deadlock with the
- * privileged threads. We can`t block while taking the
- * write lock. Otherwise a non-privileged thread
- * blocked in the vm_deallocate (while holding a read
- * lock) will block a privileged thread. For the same
- * reason, we can`t take a read lock and then use
- * lock_read_to_write.
- */
-
- mutex_lock(&fp->f_lock);
-
- olddata[level] = fp->f_blk[level];
- oldsize[level] = fp->f_blksize[level];
-
- fp->f_blkno[level] = ind_block_num;
- fp->f_blk[level] = data;
- fp->f_blksize[level] = size;
-
- /*
- * Return to holding a read lock, and
- * dispose of old data.
- */
-
- }
-
- if (level > 0) {
- idx = file_block / fp->f_nindir[level-1];
- file_block %= fp->f_nindir[level-1];
- }
- else
- idx = file_block;
-
- ind_block_num = ((daddr_t *)data)[idx];
- }
-
- mutex_unlock(&fp->f_lock);
-
- /*
- * After unlocking the file, free any blocks that
- * we need to free.
- */
- for (idx = 0; idx < NIADDR; idx++)
- if (oldsize[idx] != 0)
- (void) vm_deallocate(mach_task_self(),
- olddata[idx],
- oldsize[idx]);
-
- *disk_block_p = ind_block_num;
- return (0);
-}
-
-/*
- * Read a portion of a file into an internal buffer. Return
- * the location in the buffer and the amount in the buffer.
- */
-static int
-buf_read_file(fp, offset, buf_p, size_p)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t *buf_p; /* out */
- vm_size_t *size_p; /* out */
-{
- register struct fs *fs;
- vm_offset_t off;
- register daddr_t file_block;
- daddr_t disk_block;
- int rc;
- vm_offset_t block_size;
-
- if (offset >= fp->i_size)
- return (FS_NOT_IN_FILE);
-
- fs = fp->f_fs;
-
- off = blkoff(fs, offset);
- file_block = lblkno(fs, offset);
- block_size = blksize(fs, fp, file_block);
-
- if (file_block != fp->f_buf_blkno) {
- rc = block_map(fp, file_block, &disk_block);
- if (rc != 0)
- return (rc);
-
- if (fp->f_buf)
- (void)vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
-
- if (disk_block == 0) {
- (void)vm_allocate(mach_task_self(),
- &fp->f_buf,
- block_size,
- TRUE);
- fp->f_buf_size = block_size;
- }
- else {
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fs, disk_block),
- (int) block_size,
- (char **) &fp->f_buf,
- (mach_msg_type_number_t *)&fp->f_buf_size);
- }
- if (rc)
- return (rc);
-
- fp->f_buf_blkno = file_block;
- }
-
- /*
- * Return address of byte in buffer corresponding to
- * offset, and size of remainder of buffer after that
- * byte.
- */
- *buf_p = fp->f_buf + off;
- *size_p = block_size - off;
-
- /*
- * But truncate buffer at end of file.
- */
- if (*size_p > fp->i_size - offset)
- *size_p = fp->i_size - offset;
-
- return (0);
-}
-
-/* In 4.4 d_reclen is split into d_type and d_namlen */
-struct dirent_44 {
- unsigned long d_fileno;
- unsigned short d_reclen;
- unsigned char d_type;
- unsigned char d_namlen;
- char d_name[255 + 1];
-};
-
-/*
- * Search a directory for a name and return its
- * i_number.
- */
-static int
-search_directory(name, fp, inumber_p)
- char * name;
- register struct file *fp;
- ino_t *inumber_p; /* out */
-{
- vm_offset_t buf;
- vm_size_t buf_size;
- vm_offset_t offset;
- register struct dirent_44 *dp;
- int length;
- kern_return_t rc;
-
- length = strlen(name);
-
- offset = 0;
- while (offset < fp->i_size) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- dp = (struct dirent_44 *)buf;
- if (dp->d_ino != 0) {
- unsigned short namlen = dp->d_namlen;
- /*
- * If namlen is zero, then either this is a 4.3 file
- * system or the namlen is really zero. In the latter
- * case also the 4.3 d_namlen field is zero
- * interpreted either way.
- */
- if (namlen == 0)
- namlen = ((struct direct *)dp)->d_namlen;
-
- if (namlen == length &&
- !strcmp(name, dp->d_name))
- {
- /* found entry */
- *inumber_p = dp->d_ino;
- return (0);
- }
- }
- offset += dp->d_reclen;
- }
- return (FS_NO_ENTRY);
-}
-
-static int
-read_fs(dev, fsp)
- mach_port_t dev;
- struct fs **fsp;
-{
- register struct fs *fs;
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- int error;
-
- error = device_read(dev, 0, (recnum_t) SBLOCK, SBSIZE,
- (char **) &buf, &buf_size);
- if (error)
- return (error);
-
- fs = (struct fs *)buf;
- if (fs->fs_magic != FS_MAGIC ||
- fs->fs_bsize > MAXBSIZE ||
- fs->fs_bsize < sizeof(struct fs)) {
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- return (FS_INVALID_FS);
- }
- /* don't read cylinder groups - we aren't modifying anything */
-
- *fsp = fs;
- return 0;
-}
-
-static int
-mount_fs(fp)
- register struct file *fp;
-{
- register struct fs *fs;
- int error;
-
- error = read_fs(fp->f_dev, &fp->f_fs);
- if (error)
- return (error);
- fs = fp->f_fs;
-
- /*
- * Calculate indirect block levels.
- */
- {
- register int mult;
- register int level;
-
- mult = 1;
- for (level = 0; level < NIADDR; level++) {
- mult *= NINDIR(fs);
- fp->f_nindir[level] = mult;
- }
- }
-
- return (0);
-}
-
-static void
-unmount_fs(fp)
- register struct file *fp;
-{
- if (file_is_structured(fp)) {
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fp->f_fs,
- SBSIZE);
- fp->f_fs = 0;
- }
-}
-
-/*
- * Open a file.
- */
-int
-ffs_open_file(master_device_port, path, fp)
- mach_port_t master_device_port;
- char * path;
- struct file *fp;
-{
-#define RETURN(code) { rc = (code); goto exit; }
-
- register char *cp, *component;
- register int c; /* char */
- register int rc;
- ino_t inumber, parent_inumber;
- int nlinks = 0;
-
- char namebuf[MAXPATHLEN+1];
-
- if (path == 0 || *path == '\0') {
- return FS_NO_ENTRY;
- }
-
- /*
- * Copy name into buffer to allow modifying it.
- */
- strcpy(namebuf, path);
-
- /*
- * Look for '/dev/xxx' at start of path, for
- * root device.
- */
- if (!strprefix(namebuf, "/dev/")) {
- printf("no device name\n");
- return FS_NO_ENTRY;
- }
-
- cp = namebuf + 5; /* device */
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- bzero (fp, sizeof (struct file));
-
- rc = device_open(master_device_port,
- D_READ|D_WRITE,
- component,
- &fp->f_dev);
- if (rc)
- return rc;
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return rc;
-
- inumber = (ino_t) ROOTINO;
- if ((rc = read_inode(inumber, fp)) != 0) {
- printf("can't read root inode\n");
- goto exit;
- }
-
- while (*cp) {
-
- /*
- * Check that current node is a directory.
- */
- if ((fp->i_mode & IFMT) != IFDIR)
- RETURN (FS_NOT_DIRECTORY);
-
- /*
- * Remove extra separators
- */
- while (*cp == '/')
- cp++;
-
- /*
- * Get next component of path name.
- */
- component = cp;
- {
- register int len = 0;
-
- while ((c = *cp) != '\0' && c != '/') {
- if (len++ > MAXNAMLEN)
- RETURN (FS_NAME_TOO_LONG);
- if (c & 0200)
- RETURN (FS_INVALID_PARAMETER);
- cp++;
- }
- *cp = 0;
- }
-
- /*
- * Look up component in current directory.
- * Save directory inumber in case we find a
- * symbolic link.
- */
- parent_inumber = inumber;
- rc = search_directory(component, fp, &inumber);
- if (rc) {
- printf("%s: not found\n", path);
- goto exit;
- }
- *cp = c;
-
- /*
- * Open next component.
- */
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
-
- /*
- * Check for symbolic link.
- */
- if ((fp->i_mode & IFMT) == IFLNK) {
-
- int link_len = fp->i_size;
- int len;
-
- len = strlen(cp) + 1;
-
- if (link_len + len >= MAXPATHLEN - 1)
- RETURN (FS_NAME_TOO_LONG);
-
- if (++nlinks > MAXSYMLINKS)
- RETURN (FS_SYMLINK_LOOP);
-
- memmove (&namebuf[link_len], cp, len);
-
-#ifdef IC_FASTLINK
- if ((fp->i_flags & IC_FASTLINK) != 0) {
- bcopy(fp->i_symlink, namebuf, (unsigned) link_len);
- }
- else
-#endif /* IC_FASTLINK */
-#if !defined(DISABLE_BSD44_FASTLINKS)
- /*
- * There is no bit for fastlinks in 4.4 but instead
- * all symlinks that fit into the inode are fastlinks.
- * If the second block (ic_db[1]) is zero the symlink
- * can't be a fastlink if its length is at least five.
- * For symlinks of length one to four there is no easy
- * way of knowing whether we are looking at a 4.4
- * fastlink or a 4.3 slowlink. This code always
- * guesses the 4.4 way when in doubt. THIS BREAKS 4.3
- * SLOWLINKS OF LENGTH FOUR OR LESS.
- */
- if ((link_len <= MAX_FASTLINK_SIZE && fp->i_ic.ic_db[1] != 0)
- || (link_len <= 4))
- {
- bcopy(fp->i_symlink, namebuf, (unsigned) link_len);
- }
- else
-#endif /* !DISABLE_BSD44_FASTLINKS */
-
- {
- /*
- * Read file for symbolic link
- */
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- daddr_t disk_block;
- register struct fs *fs = fp->f_fs;
-
- (void) block_map(fp, (daddr_t)0, &disk_block);
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) fsbtodb(fs, disk_block),
- (int) blksize(fs, fp, 0),
- (char **) &buf,
- &buf_size);
- if (rc)
- goto exit;
-
- bcopy((char *)buf, namebuf, (unsigned)link_len);
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- }
-
- /*
- * If relative pathname, restart at parent directory.
- * If absolute pathname, restart at root.
- * If pathname begins '/dev/<device>/',
- * restart at root of that device.
- */
- cp = namebuf;
- if (*cp != '/') {
- inumber = parent_inumber;
- }
- else if (!strprefix(cp, "/dev/")) {
- inumber = (ino_t)ROOTINO;
- }
- else {
- cp += 5;
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- /*
- * Unmount current file system and free buffers.
- */
- close_file(fp);
-
- /*
- * Open new root device.
- */
- rc = device_open(master_device_port,
- D_READ,
- component,
- &fp->f_dev);
- if (rc)
- return (rc);
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return (rc);
-
- inumber = (ino_t)ROOTINO;
- }
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
- }
- }
-
- /*
- * Found terminal component.
- */
- out_ok:
- mutex_init(&fp->f_lock);
- return 0;
-
- /*
- * At error exit, close file to free storage.
- */
- exit:
- close_file(fp);
- return rc;
-}
-
-/*
- * Close file - free all storage used.
- */
-void
-ffs_close_file(fp)
- register struct file *fp;
-{
- register int i;
-
- /*
- * Free the disk super-block.
- */
- unmount_fs(fp);
-
- /*
- * Free the inode and data buffers.
- */
- free_file_buffers(fp);
-}
-
-int
-ffs_file_is_directory(struct file *fp)
-{
- return (fp->i_mode & IFMT) == IFDIR;
-}
-
-int
-ffs_file_is_regular(struct file *fp)
-{
- return (fp->i_mode & IFMT) == IFREG;
-}
-
-/*
- * Copy a portion of a file into kernel memory.
- * Cross block boundaries when necessary.
- */
-int
-ffs_read_file(fp, offset, start, size, resid)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t start;
- vm_size_t size;
- vm_size_t *resid; /* out */
-{
- int rc;
- register vm_size_t csize;
- vm_offset_t buf;
- vm_size_t buf_size;
-
- while (size != 0) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc)
- return (rc);
-
- csize = size;
- if (csize > buf_size)
- csize = buf_size;
- if (csize == 0)
- break;
-
- bcopy((char *)buf, (char *)start, csize);
-
- offset += csize;
- start += csize;
- size -= csize;
- }
- if (resid)
- *resid = size;
-
- return (0);
-}
-
-/* simple utility: only works for 2^n */
-static int
-log2(n)
- register unsigned int n;
-{
- register int i = 0;
-
- while ((n & 1) == 0) {
- i++;
- n >>= 1;
- }
- return i;
-}
-
-/*
- * Make an empty file_direct for a device.
- */
-int
-ffs_open_file_direct(dev, fdp, is_structured)
- mach_port_t dev;
- register struct file_direct *fdp;
- boolean_t is_structured;
-{
- struct fs *fs;
- int rc;
-
- if (!is_structured) {
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_bsize = vm_page_size;
- fdp->fd_bshift = log2(vm_page_size);
- fdp->fd_fsbtodb = 0; /* later */
- fdp->fd_size = 0; /* later */
- return 0;
- }
-
- rc = read_fs(dev, &fs);
- if (rc)
- return rc;
-
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_size = 0;
- fdp->fd_bsize = fs->fs_bsize;
- fdp->fd_bshift = fs->fs_bshift;
- fdp->fd_fsbtodb = fs->fs_fsbtodb;
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fs,
- SBSIZE);
-
- return 0;
-}
-
-/*
- * Add blocks from a file to a file_direct.
- */
-int
-ffs_add_file_direct(fdp, fp)
- register struct file_direct *fdp;
- register struct file *fp;
-{
- register struct fs *fs;
- long num_blocks, i;
- vm_offset_t buffer;
- vm_size_t size;
- int rc;
-
- /* the file must be on the same device */
-
- if (fdp->fd_dev != fp->f_dev)
- return FS_INVALID_FS;
-
- if (!file_is_structured(fp)) {
- int result[DEV_GET_SIZE_COUNT];
- natural_t count;
-
- count = DEV_GET_SIZE_COUNT;
- rc = device_get_status( fdp->fd_dev, DEV_GET_SIZE,
- result, &count);
- if (rc)
- return rc;
- fdp->fd_size = result[DEV_GET_SIZE_DEVICE_SIZE] >> fdp->fd_bshift;
- fdp->fd_fsbtodb = log2(fdp->fd_bsize/result[DEV_GET_SIZE_RECORD_SIZE]);
- return 0;
- }
-
- /* it must hold a file system */
-
- fs = fp->f_fs;
- if (fdp->fd_bsize != fs->fs_bsize ||
- fdp->fd_fsbtodb != fs->fs_fsbtodb)
- return FS_INVALID_FS;
-
- /* calculate number of blocks in the file, ignoring fragments */
-
- num_blocks = lblkno(fs, fp->i_size);
-
- /* allocate memory for a bigger array */
-
- size = (num_blocks + fdp->fd_size) * sizeof(daddr_t);
- rc = vm_allocate(mach_task_self(), &buffer, size, TRUE);
- if (rc != KERN_SUCCESS)
- return rc;
-
- /* lookup new block addresses */
-
- for (i = 0; i < num_blocks; i++) {
- daddr_t disk_block;
-
- rc = block_map(fp, (daddr_t) i, &disk_block);
- if (rc != 0) {
- (void) vm_deallocate(mach_task_self(), buffer, size);
- return rc;
- }
-
- ((daddr_t *) buffer)[fdp->fd_size + i] = disk_block;
- }
-
- /* copy old addresses and install the new array */
-
- if (fdp->fd_blocks != 0) {
- bcopy((char *) fdp->fd_blocks, (char *) buffer,
- fdp->fd_size * sizeof(daddr_t));
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(daddr_t)));
- }
- fdp->fd_blocks = (daddr_t *) buffer;
- fdp->fd_size += num_blocks;
-
- /* deallocate cached blocks */
-
- free_file_buffers(fp);
-
- return 0;
-}
-
-int
-ffs_remove_file_direct(fdp)
- struct file_direct *fdp;
-{
- if (fdp->fd_blocks)
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(daddr_t)));
- fdp->fd_blocks = 0; /* sanity */
- /* xxx should lose a ref to fdp->fd_dev here (and elsewhere) xxx */
-}
diff --git a/serverboot/file_io.c b/serverboot/file_io.c
deleted file mode 100644
index 99966f95..00000000
--- a/serverboot/file_io.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 1994 The University of Utah and
- * the Computer Systems Laboratory at the University of Utah (CSL).
- * All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software is hereby
- * granted provided that (1) source code retains these copyright, permission,
- * and disclaimer notices, and (2) redistributions including binaries
- * reproduce the notices in supporting documentation, and (3) all advertising
- * materials mentioning features or use of this software display the following
- * acknowledgement: ``This product includes software developed by the
- * Computer Systems Laboratory at the University of Utah.''
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-dist@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
- *
- * Author: Bryan Ford, University of Utah CSL
- * MINIX FS patches: Csizmazia Balazs, University ELTE, Hungary
- */
-/* This is just an icky kludgy "VFS layer" (harhar) for ffs and ext2 and minix. */
-
-#include "file_io.h"
-
-int
-open_file(master_device_port, path, fp)
- mach_port_t master_device_port;
- char * path;
- struct file *fp;
-{
- int rc;
-
- if ((rc = ext2_open_file(master_device_port, path, fp))
- != FS_INVALID_FS)
- {
- if (rc == 0)
- fp->f_fstype = EXT2_FS;
- return rc;
- }
- if ( (rc = minix_open_file(master_device_port, path, fp))
- != FS_INVALID_FS )
- {
- if (rc == 0)
- fp->f_fstype = MINIX_FS;
- return rc;
- }
- fp->f_fstype = BSD_FFS;
- return ffs_open_file(master_device_port, path, fp);
-}
-
-void
-close_file(fp)
- register struct file *fp;
-{
- switch (fp->f_fstype) {
- case EXT2_FS:
- ext2_close_file(fp);
- return;
- case MINIX_FS:
- minix_close_file(fp);
- return;
- default:
- ffs_close_file(fp);
- return;
- }
-}
-
-int
-read_file(fp, offset, start, size, resid)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t start;
- vm_size_t size;
- vm_size_t *resid; /* out */
-{
- switch (fp->f_fstype) {
- case EXT2_FS:
- return ext2_read_file(fp, offset, start, size, resid);
- case MINIX_FS:
- return minix_read_file(fp, offset, start, size, resid);
- default:
- return ffs_read_file(fp, offset, start, size, resid);
- }
-
-}
-
-int
-file_is_directory(struct file *f)
-{
- switch (f->f_fstype) {
- case EXT2_FS:
- return ext2_file_is_directory(f);
- case MINIX_FS:
- return minix_file_is_directory(f);
- default:
- return ffs_file_is_directory(f);
- }
-}
-
-int
-file_is_regular(struct file *f)
-{
- switch (f->f_fstype) {
- case EXT2_FS:
- return ext2_file_is_regular(f);
- case MINIX_FS:
- return minix_file_is_regular(f);
- default:
- return ffs_file_is_regular(f);
- }
-
-}
-
-int
-open_file_direct(dev, fdp, is_structured)
- mach_port_t dev;
- register struct file_direct *fdp;
- boolean_t is_structured;
-{
- int rc;
-
-
- if ((rc = ext2_open_file_direct(dev, fdp, is_structured))
- != FS_INVALID_FS)
- {
- if (rc == 0)
- fdp->f_fstype = EXT2_FS;
- return rc;
- }
- if ( (rc = minix_open_file_direct(dev, fdp, is_structured) )
- != FS_INVALID_FS )
- {
- if (rc == 0)
- fdp->f_fstype = MINIX_FS;
- return rc;
- }
- fdp->f_fstype = BSD_FFS;
- return ffs_open_file_direct(dev, fdp, is_structured);
-}
-
-int
-add_file_direct(fdp, fp)
- register struct file_direct *fdp;
- register struct file *fp;
-{
- switch (fp->f_fstype) {
- case EXT2_FS:
- return ext2_add_file_direct(fdp, fp);
- case MINIX_FS:
- return minix_add_file_direct(fdp, fp);
- default:
- return ffs_add_file_direct(fdp, fp);
- }
-}
-
-
-int
-remove_file_direct(fdp)
- struct file_direct *fdp;
-{
- switch (fdp->f_fstype) {
- case EXT2_FS:
- return ext2_remove_file_direct(fdp);
- case MINIX_FS:
- return minix_remove_file_direct(fdp);
- default:
- return ffs_remove_file_direct(fdp);
- }
-}
-
-/*
- * some other stuff, that was previously defined as macro
- */
-
-int
-file_is_structured(fp)
- register struct file *fp;
-{
- switch (fp->f_fstype) {
- case EXT2_FS:
- return (fp)->u.ext2.ext2_fs != 0;
- case MINIX_FS:
- return (fp)->u.minix.minix_fs != 0;
- default:
- return (fp)->u.ffs.ffs_fs != 0;
- }
-}
-
-/*
- * Special read and write routines for default pager.
- * Assume that all offsets and sizes are multiples
- * of DEV_BSIZE.
- */
-
-#define fdir_blkoff(fdp, offset) /* offset % fd_bsize */ \
- ((offset) & ((fdp)->fd_bsize - 1))
-#define fdir_lblkno(fdp, offset) /* offset / fd_bsize */ \
- ((offset) >> (fdp)->fd_bshift)
-
-#define fdir_fsbtodb(fdp, block) /* offset * fd_bsize / DEV_BSIZE */ \
- ((block) << (fdp)->fd_fsbtodb)
-
-/*
- * Read all or part of a data block, and
- * return a pointer to the appropriate part.
- * Caller must deallocate the block when done.
- */
-int
-page_read_file_direct(fdp, offset, size, addr, size_read)
- register struct file_direct *fdp;
- vm_offset_t offset;
- vm_size_t size;
- vm_offset_t *addr; /* out */
- mach_msg_type_number_t *size_read; /* out */
-{
- vm_offset_t off;
- register daddr_t file_block;
- daddr_t disk_block;
-
- if (offset % DEV_BSIZE != 0 ||
- size % DEV_BSIZE != 0)
- panic("page_read_file_direct");
-
- if (offset >= (fdp->fd_size << fdp->fd_bshift))
- return (FS_NOT_IN_FILE);
-
- off = fdir_blkoff(fdp, offset);
- file_block = fdir_lblkno(fdp, offset);
-
- if (file_is_device(fdp)) {
- disk_block = file_block;
- } else {
- disk_block = fdp->fd_blocks[file_block];
- if (disk_block == 0)
- return (FS_NOT_IN_FILE);
-
- if (size > fdp->fd_bsize) {
- /* Read only as much as is contiguous on disk. */
- daddr_t b = file_block + 1;
- while (b < file_block + fdp->fd_size &&
- fdp->fd_blocks[b] == disk_block + fdir_fsbtodb(fdp, 1))
- ++b;
- size = (b - file_block) * fdp->fd_bsize;
- }
- }
-
- return (device_read(fdp->fd_dev,
- 0,
- (recnum_t) (fdir_fsbtodb(fdp, disk_block) + btodb(off)),
- (int) size,
- (char **) addr,
- size_read));
-}
-
-/*
- * Write all or part of a data block, and
- * return the amount written.
- */
-int
-page_write_file_direct(fdp, offset, addr, size, size_written)
- register struct file_direct *fdp;
- vm_offset_t offset;
- vm_offset_t addr;
- vm_size_t size;
- vm_offset_t *size_written; /* out */
-{
- vm_offset_t off;
- register daddr_t file_block;
- daddr_t disk_block;
- int rc, num_written;
- vm_offset_t block_size;
-
- if (offset % DEV_BSIZE != 0 ||
- size % DEV_BSIZE != 0)
- panic("page_write_file");
-
- if (offset >= (fdp->fd_size << fdp->fd_bshift))
- return (FS_NOT_IN_FILE);
-
- off = fdir_blkoff(fdp, offset);
- file_block = fdir_lblkno(fdp, offset);
-
- if (file_is_device(fdp)) {
- disk_block = file_block;
- } else {
- disk_block = fdp->fd_blocks[file_block];
- if (disk_block == 0)
- return (FS_NOT_IN_FILE);
-
- if (size > fdp->fd_bsize) {
- /* Write only as much as is contiguous on disk. */
- daddr_t b = file_block + 1;
- while (b < file_block + fdp->fd_size &&
- fdp->fd_blocks[b] == disk_block + fdir_fsbtodb(fdp, 1))
- ++b;
- size = (b - file_block) * fdp->fd_bsize;
- }
- }
-
- /*
- * Write the data. Wait for completion to keep
- * reads from getting ahead of writes and reading
- * stale data.
- */
- rc = device_write(
- fdp->fd_dev,
- 0,
- (recnum_t) (fdir_fsbtodb(fdp, disk_block) + btodb(off)),
- (char *) addr,
- size,
- &num_written);
- *size_written = num_written;
- return rc;
-}
diff --git a/serverboot/file_io.h b/serverboot/file_io.h
deleted file mode 100644
index 323e4e9a..00000000
--- a/serverboot/file_io.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#ifndef _FILE_IO_H_
-#define _FILE_IO_H_
-
-/*
- * Read-only file IO.
- */
-
-#include <mach.h>
-#include <cthreads.h>
-
-#include <stdint.h>
-#include <device/device_types.h>
-
-/* Types used by the ext2 header files. */
-typedef u_int32_t __u32;
-typedef int32_t __s32;
-typedef u_int16_t __u16;
-typedef int16_t __s16;
-typedef u_int8_t __u8;
-typedef int8_t __s8;
-
-#include <defs.h>
-#include "minix_fs.h"
-#include "../ext2fs/ext2_fs.h" /* snarf stolen linux header from ext2fs */
-#include "disk_inode.h"
-
-#define BSD_FFS 0
-#define EXT2_FS 1
-#define MINIX_FS 2
-
-#define EXT2_NIADDR (EXT2_N_BLOCKS - EXT2_NDIR_BLOCKS)
-
-/*
- * In-core open file.
- */
-struct file {
- struct mutex f_lock; /* lock */
- mach_port_t f_dev; /* port to device */
- vm_offset_t f_buf; /* buffer for data block */
- vm_size_t f_buf_size; /* size of data block */
- daddr_t f_buf_blkno; /* block number of data block */
- vm_size_t f_size; /* size in bytes of the file */
-
- int f_fstype; /* contains fs-id */
-
- union {
- struct {
- struct fs * ffs_fs; /* pointer to super-block */
- struct icommon ffs_ic; /* copy of on-disk inode */
-
- /* number of blocks mapped by
- indirect block at level i */
- int ffs_nindir[FFS_NIADDR+1];
-
- /* buffer for indirect block at level i */
- vm_offset_t ffs_blk[FFS_NIADDR];
-
- /* size of buffer */
- vm_size_t ffs_blksize[FFS_NIADDR];
-
- /* disk address of block in buffer */
- daddr_t ffs_blkno[FFS_NIADDR];
- } ffs;
- struct {
- /* pointer to super-block */
- struct ext2_super_block*ext2_fs;
-
- /* pointer to group descriptors */
- struct ext2_group_desc* ext2_gd;
-
- /* size of group descriptors */
- vm_size_t ext2_gd_size;
-
- /* copy of on-disk inode */
- struct ext2_inode ext2_ic;
-
- /* number of blocks mapped by
- indirect block at level i */
- int ext2_nindir[EXT2_NIADDR+1];
-
- /* buffer for indirect block at level i */
- vm_offset_t ext2_blk[EXT2_NIADDR];
-
- /* size of buffer */
- vm_size_t ext2_blksize[EXT2_NIADDR];
-
- /* disk address of block in buffer */
- daddr_t ext2_blkno[EXT2_NIADDR];
- } ext2;
- struct {
- /* pointer to super-block */
- struct minix_super_block* minix_fs;
-
- /* copy of on-disk inode */
- struct minix_inode minix_ic;
-
- /* number of blocks mapped by
- indirect block at level i */
- int minix_nindir[MINIX_NIADDR+1];
-
- /* buffer for indirect block at level i */
- vm_offset_t minix_blk[MINIX_NIADDR];
-
- /* size of buffer */
- vm_size_t minix_blksize[MINIX_NIADDR];
-
- /* disk address of block in buffer */
- minix_daddr_t minix_blkno[MINIX_NIADDR];
- } minix;
- } u;
-};
-
-/*
- * In-core open file, with in-core block map.
- */
-struct file_direct {
- int f_fstype; /* XXX was: true if ext2, false if ffs */
-
- mach_port_t fd_dev; /* port to device */
- daddr_t * fd_blocks; /* array of disk block addresses */
- long fd_size; /* number of blocks in the array */
- long fd_bsize; /* disk block size */
- long fd_bshift; /* log2(fd_bsize) */
- long fd_fsbtodb; /* log2(fd_bsize / disk sector size) */
-};
-
-#define file_is_device(_fd_) ((_fd_)->fd_blocks == 0)
-
-/*
- * Exported routines.
- */
-
-extern int open_file();
-extern void close_file();
-extern int read_file();
-
-extern int open_file_direct();
-extern int add_file_direct();
-extern int remove_file_direct();
-extern int file_wire_direct();
-extern int page_read_file_direct();
-extern int page_write_file_direct();
-
-/*
- * Error codes for file system errors.
- */
-
-#include <errno.h>
-
-/* Just use the damn Hurd error numbers. This is old CMU/Utah code from
- the days of personality-independent Mach where it made sense for this to
- be a standalone universe. In the Hurd, we compile serverboot against
- the regular C library anyway. */
-
-#define FS_NOT_DIRECTORY ENOTDIR
-#define FS_NO_ENTRY ENOENT
-#define FS_NAME_TOO_LONG ENAMETOOLONG
-#define FS_SYMLINK_LOOP ELOOP
-#define FS_INVALID_FS EFTYPE /* ? */
-#define FS_NOT_IN_FILE EINVAL
-#define FS_INVALID_PARAMETER EINVAL
-
-#if 0
-#define FS_NOT_DIRECTORY 5000 /* not a directory */
-#define FS_NO_ENTRY 5001 /* name not found */
-#define FS_NAME_TOO_LONG 5002 /* name too long */
-#define FS_SYMLINK_LOOP 5003 /* symbolic link loop */
-#define FS_INVALID_FS 5004 /* bad file system */
-#define FS_NOT_IN_FILE 5005 /* offset not in file */
-#define FS_INVALID_PARAMETER 5006 /* bad parameter to routine */
-#endif
-
-
-#endif /* _FILE_IO_H_ */
diff --git a/serverboot/fs.h b/serverboot/fs.h
deleted file mode 100644
index 5809ed93..00000000
--- a/serverboot/fs.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)fs.h 7.7 (Berkeley) 5/9/89
- */
-
-/*
- * Each disk drive contains some number of file systems.
- * A file system consists of a number of cylinder groups.
- * Each cylinder group has inodes and data.
- *
- * A file system is described by its super-block, which in turn
- * describes the cylinder groups. The super-block is critical
- * data and is replicated in each cylinder group to protect against
- * catastrophic loss. This is done at `newfs' time and the critical
- * super-block data does not change, so the copies need not be
- * referenced further unless disaster strikes.
- *
- * For file system fs, the offsets of the various blocks of interest
- * are given in the super block as:
- * [fs->fs_sblkno] Super-block
- * [fs->fs_cblkno] Cylinder group block
- * [fs->fs_iblkno] Inode blocks
- * [fs->fs_dblkno] Data blocks
- * The beginning of cylinder group cg in fs, is given by
- * the ``cgbase(fs, cg)'' macro.
- *
- * The first boot and super blocks are given in absolute disk addresses.
- * The byte-offset forms are preferred, as they don't imply a sector size.
- */
-#define BBSIZE 8192
-#define SBSIZE 8192
-#define BBOFF ((off_t)(0))
-#define SBOFF ((off_t)(BBOFF + BBSIZE))
-#define BBLOCK ((daddr_t)(0))
-#define SBLOCK ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
-
-/*
- * Addresses stored in inodes are capable of addressing fragments
- * of `blocks'. File system blocks of at most size MAXBSIZE can
- * be optionally broken into 2, 4, or 8 pieces, each of which is
- * addressible; these pieces may be DEV_BSIZE, or some multiple of
- * a DEV_BSIZE unit.
- *
- * Large files consist of exclusively large data blocks. To avoid
- * undue wasted disk space, the last data block of a small file may be
- * allocated as only as many fragments of a large block as are
- * necessary. The file system format retains only a single pointer
- * to such a fragment, which is a piece of a single large block that
- * has been divided. The size of such a fragment is determinable from
- * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
- *
- * The file system records space availability at the fragment level;
- * to determine block availability, aligned fragments are examined.
- *
- * The root inode is the root of the file system.
- * Inode 0 can't be used for normal purposes and
- * historically bad blocks were linked to inode 1,
- * thus the root inode is 2. (inode 1 is no longer used for
- * this purpose, however numerous dump tapes make this
- * assumption, so we are stuck with it)
- */
-#define ROOTINO ((ino_t)2) /* i number of all roots */
-
-/*
- * MINBSIZE is the smallest allowable block size.
- * In order to insure that it is possible to create files of size
- * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
- * MINBSIZE must be big enough to hold a cylinder group block,
- * thus changes to (struct cg) must keep its size within MINBSIZE.
- * Note that super blocks are always of size SBSIZE,
- * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
- */
-#define MINBSIZE 4096
-
-/*
- * The path name on which the file system is mounted is maintained
- * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
- * the super block for this name.
- * The limit on the amount of summary information per file system
- * is defined by MAXCSBUFS. It is currently parameterized for a
- * maximum of two million cylinders.
- */
-#define MAXMNTLEN 512
-#define MAXCSBUFS 32
-
-/*
- * Per cylinder group information; summarized in blocks allocated
- * from first cylinder group data blocks. These blocks have to be
- * read in from fs_csaddr (size fs_cssize) in addition to the
- * super block.
- *
- * N.B. sizeof(struct csum) must be a power of two in order for
- * the ``fs_cs'' macro to work (see below).
- */
-struct csum {
- int cs_ndir; /* number of directories */
- int cs_nbfree; /* number of free blocks */
- int cs_nifree; /* number of free inodes */
- int cs_nffree; /* number of free frags */
-};
-
-/*
- * Super block for a file system.
- */
-#define FS_MAGIC 0x011954
-struct fs
-{
- int xxx1; /* struct fs *fs_link;*/
- int xxx2; /* struct fs *fs_rlink;*/
- daddr_t fs_sblkno; /* addr of super-block in filesys */
- daddr_t fs_cblkno; /* offset of cyl-block in filesys */
- daddr_t fs_iblkno; /* offset of inode-blocks in filesys */
- daddr_t fs_dblkno; /* offset of first data after cg */
- int fs_cgoffset; /* cylinder group offset in cylinder */
- int fs_cgmask; /* used to calc mod fs_ntrak */
- time_t fs_time; /* last time written */
- int fs_size; /* number of blocks in fs */
- int fs_dsize; /* number of data blocks in fs */
- int fs_ncg; /* number of cylinder groups */
- int fs_bsize; /* size of basic blocks in fs */
- int fs_fsize; /* size of frag blocks in fs */
- int fs_frag; /* number of frags in a block in fs */
-/* these are configuration parameters */
- int fs_minfree; /* minimum percentage of free blocks */
- int fs_rotdelay; /* num of ms for optimal next block */
- int fs_rps; /* disk revolutions per second */
-/* these fields can be computed from the others */
- int fs_bmask; /* ``blkoff'' calc of blk offsets */
- int fs_fmask; /* ``fragoff'' calc of frag offsets */
- int fs_bshift; /* ``lblkno'' calc of logical blkno */
- int fs_fshift; /* ``numfrags'' calc number of frags */
-/* these are configuration parameters */
- int fs_maxcontig; /* max number of contiguous blks */
- int fs_maxbpg; /* max number of blks per cyl group */
-/* these fields can be computed from the others */
- int fs_fragshift; /* block to frag shift */
- int fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
- int fs_sbsize; /* actual size of super block */
- int fs_csmask; /* csum block offset */
- int fs_csshift; /* csum block number */
- int fs_nindir; /* value of NINDIR */
- int fs_inopb; /* value of INOPB */
- int fs_nspf; /* value of NSPF */
-/* yet another configuration parameter */
- int fs_optim; /* optimization preference, see below */
-/* these fields are derived from the hardware */
- int fs_npsect; /* # sectors/track including spares */
- int fs_interleave; /* hardware sector interleave */
- int fs_trackskew; /* sector 0 skew, per track */
- int fs_headswitch; /* head switch time, usec */
- int fs_trkseek; /* track-to-track seek, usec */
-/* sizes determined by number of cylinder groups and their sizes */
- daddr_t fs_csaddr; /* blk addr of cyl grp summary area */
- int fs_cssize; /* size of cyl grp summary area */
- int fs_cgsize; /* cylinder group size */
-/* these fields are derived from the hardware */
- int fs_ntrak; /* tracks per cylinder */
- int fs_nsect; /* sectors per track */
- int fs_spc; /* sectors per cylinder */
-/* this comes from the disk driver partitioning */
- int fs_ncyl; /* cylinders in file system */
-/* these fields can be computed from the others */
- int fs_cpg; /* cylinders per group */
- int fs_ipg; /* inodes per group */
- int fs_fpg; /* blocks per group * fs_frag */
-/* this data must be re-computed after crashes */
- struct csum fs_cstotal; /* cylinder summary information */
-/* these fields are cleared at mount time */
- char fs_fmod; /* super block modified flag */
- char fs_clean; /* file system is clean flag */
- char fs_ronly; /* mounted read-only flag */
- char fs_flags; /* currently unused flag */
- char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
-/* these fields retain the current block allocation info */
- int fs_cgrotor; /* last cg searched */
-#if 1
- int was_fs_csp[MAXCSBUFS];
-#else
- struct csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
-#endif
- int fs_cpc; /* cyl per cycle in postbl */
- short fs_opostbl[16][8]; /* old rotation block list head */
- long fs_sparecon[50]; /* reserved for future constants */
- long fs_contigsumsize; /* size of cluster summary array */
- long fs_maxsymlinklen; /* max length of an internal symlink */
- long fs_inodefmt; /* format of on-disk inodes */
- quad fs_maxfilesize; /* maximum representable file size */
- quad fs_qbmask; /* ~fs_bmask - for use with quad size */
- quad fs_qfmask; /* ~fs_fmask - for use with quad size */
- long fs_state; /* validate fs_clean field */
- int fs_postblformat; /* format of positional layout tables */
- int fs_nrpos; /* number of rotaional positions */
- int fs_postbloff; /* (short) rotation block list head */
- int fs_rotbloff; /* (u_char) blocks for each rotation */
- int fs_magic; /* magic number */
- u_char fs_space[1]; /* list of blocks for each rotation */
-/* actually longer */
-};
-/*
- * Preference for optimization.
- */
-#define FS_OPTTIME 0 /* minimize allocation time */
-#define FS_OPTSPACE 1 /* minimize disk fragmentation */
-
-/*
- * Rotational layout table format types
- */
-#define FS_42POSTBLFMT -1 /* 4.2BSD rotational table format */
-#define FS_DYNAMICPOSTBLFMT 1 /* dynamic rotational table format */
-/*
- * Macros for access to superblock array structures
- */
-#define fs_postbl(fs, cylno) \
- (((fs)->fs_postblformat == FS_42POSTBLFMT) \
- ? ((fs)->fs_opostbl[cylno]) \
- : ((short *)((char *)(fs) + (fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
-#define fs_rotbl(fs) \
- (((fs)->fs_postblformat == FS_42POSTBLFMT) \
- ? ((fs)->fs_space) \
- : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))
-
-/*
- * Convert cylinder group to base address of its global summary info.
- *
- * N.B. This macro assumes that sizeof(struct csum) is a power of two.
- */
-#define fs_cs(fs, indx) \
- fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask]
-
-/*
- * Cylinder group block for a file system.
- */
-#define CG_MAGIC 0x090255
-struct cg {
- int xxx1; /* struct cg *cg_link;*/
- int cg_magic; /* magic number */
- time_t cg_time; /* time last written */
- int cg_cgx; /* we are the cgx'th cylinder group */
- short cg_ncyl; /* number of cyl's this cg */
- short cg_niblk; /* number of inode blocks this cg */
- int cg_ndblk; /* number of data blocks this cg */
- struct csum cg_cs; /* cylinder summary information */
- int cg_rotor; /* position of last used block */
- int cg_frotor; /* position of last used frag */
- int cg_irotor; /* position of last used inode */
- int cg_frsum[MAXFRAG]; /* counts of available frags */
- int cg_btotoff; /* (long) block totals per cylinder */
- int cg_boff; /* (short) free block positions */
- int cg_iusedoff; /* (char) used inode map */
- int cg_freeoff; /* (u_char) free block map */
- int cg_nextfreeoff; /* (u_char) next available space */
- int cg_sparecon[16]; /* reserved for future use */
- u_char cg_space[1]; /* space for cylinder group maps */
-/* actually longer */
-};
-/*
- * Macros for access to cylinder group array structures
- */
-#define cg_blktot(cgp) \
- (((cgp)->cg_magic != CG_MAGIC) \
- ? (((struct ocg *)(cgp))->cg_btot) \
- : ((int *)((char *)(cgp) + (cgp)->cg_btotoff)))
-#define cg_blks(fs, cgp, cylno) \
- (((cgp)->cg_magic != CG_MAGIC) \
- ? (((struct ocg *)(cgp))->cg_b[cylno]) \
- : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
-#define cg_inosused(cgp) \
- (((cgp)->cg_magic != CG_MAGIC) \
- ? (((struct ocg *)(cgp))->cg_iused) \
- : ((char *)((char *)(cgp) + (cgp)->cg_iusedoff)))
-#define cg_blksfree(cgp) \
- (((cgp)->cg_magic != CG_MAGIC) \
- ? (((struct ocg *)(cgp))->cg_free) \
- : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))
-#define cg_chkmagic(cgp) \
- ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
-
-/*
- * The following structure is defined
- * for compatibility with old file systems.
- */
-struct ocg {
- int xxx1; /* struct ocg *cg_link;*/
- int xxx2; /* struct ocg *cg_rlink;*/
- time_t cg_time; /* time last written */
- int cg_cgx; /* we are the cgx'th cylinder group */
- short cg_ncyl; /* number of cyl's this cg */
- short cg_niblk; /* number of inode blocks this cg */
- int cg_ndblk; /* number of data blocks this cg */
- struct csum cg_cs; /* cylinder summary information */
- int cg_rotor; /* position of last used block */
- int cg_frotor; /* position of last used frag */
- int cg_irotor; /* position of last used inode */
- int cg_frsum[8]; /* counts of available frags */
- int cg_btot[32]; /* block totals per cylinder */
- short cg_b[32][8]; /* positions of free blocks */
- char cg_iused[256]; /* used inode map */
- int cg_magic; /* magic number */
- u_char cg_free[1]; /* free block map */
-/* actually longer */
-};
-
-/*
- * Turn file system block numbers into disk block addresses.
- * This maps file system blocks to device size blocks.
- */
-#define fsbtodb(fs, b) ((b) << (fs)->fs_fsbtodb)
-#define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb)
-
-/*
- * Cylinder group macros to locate things in cylinder groups.
- * They calc file system addresses of cylinder group data structures.
- */
-#define cgbase(fs, c) ((daddr_t)((fs)->fs_fpg * (c)))
-#define cgstart(fs, c) \
- (cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
-#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */
-#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */
-#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */
-#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */
-
-/*
- * Macros for handling inode numbers:
- * inode number to file system block offset.
- * inode number to cylinder group number.
- * inode number to file system block address.
- */
-#define itoo(fs, x) ((x) % INOPB(fs))
-#define itog(fs, x) ((x) / (fs)->fs_ipg)
-#define itod(fs, x) \
- ((daddr_t)(cgimin(fs, itog(fs, x)) + \
- (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
-
-/*
- * Give cylinder group number for a file system block.
- * Give cylinder group block number for a file system block.
- */
-#define dtog(fs, d) ((d) / (fs)->fs_fpg)
-#define dtogd(fs, d) ((d) % (fs)->fs_fpg)
-
-/*
- * Extract the bits for a block from a map.
- * Compute the cylinder and rotational position of a cyl block addr.
- */
-#define blkmap(fs, map, loc) \
- (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
-#define cbtocylno(fs, bno) \
- ((bno) * NSPF(fs) / (fs)->fs_spc)
-#define cbtorpos(fs, bno) \
- (((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \
- (bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \
- (fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)
-
-/*
- * The following macros optimize certain frequently calculated
- * quantities by using shifts and masks in place of divisions
- * modulos and multiplications.
- */
-#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \
- ((loc) & ~(fs)->fs_bmask)
-#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \
- ((loc) & ~(fs)->fs_fmask)
-#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \
- ((loc) >> (fs)->fs_bshift)
-#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \
- ((loc) >> (fs)->fs_fshift)
-#define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \
- (((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask)
-#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \
- (((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask)
-#define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
- ((frags) >> (fs)->fs_fragshift)
-#define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \
- ((blks) << (fs)->fs_fragshift)
-#define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \
- ((fsb) & ((fs)->fs_frag - 1))
-#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \
- ((fsb) &~ ((fs)->fs_frag - 1))
-
-/*
- * Determine the number of available frags given a
- * percentage to hold in reserve
- */
-#define freespace(fs, percentreserved) \
- (blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
- (fs)->fs_cstotal.cs_nffree - ((fs)->fs_dsize * (percentreserved) / 100))
-
-/*
- * Determining the size of a file block in the file system.
- */
-#define blksize(fs, ip, lbn) \
- (((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->fs_bshift) \
- ? (fs)->fs_bsize \
- : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
-#define dblksize(fs, dip, lbn) \
- (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \
- ? (fs)->fs_bsize \
- : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
-
-/*
- * Number of disk sectors per block; assumes DEV_BSIZE byte sector size.
- */
-#define NSPB(fs) ((fs)->fs_nspf << (fs)->fs_fragshift)
-#define NSPF(fs) ((fs)->fs_nspf)
-
-/*
- * INOPB is the number of inodes in a secondary storage block.
- */
-#define INOPB(fs) ((fs)->fs_inopb)
-#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift)
-
-/*
- * NINDIR is the number of indirects in a file system block.
- */
-#define NINDIR(fs) ((fs)->fs_nindir)
-
diff --git a/serverboot/gets.c b/serverboot/gets.c
deleted file mode 100644
index 61d14460..00000000
--- a/serverboot/gets.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University.
- * Copyright (c) 1994 The University of Utah and
- * the Computer Systems Laboratory (CSL).
- * All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
- * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
- * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
- * THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#include <mach.h>
-#include <device/device.h>
-#include <varargs.h>
-
-extern mach_port_t __libmach_console_port;
-
-safe_gets(str, maxlen)
- char *str;
- int maxlen;
-{
- register char *lp;
- register int c;
-
- char inbuf[IO_INBAND_MAX];
- mach_msg_type_number_t count;
- register char *ip;
- char *strmax = str + maxlen - 1; /* allow space for trailing 0 */
-
- lp = str;
- for (;;) {
- count = IO_INBAND_MAX;
- (void) device_read_inband(__libmach_console_port,
- (dev_mode_t)0, (recnum_t)0,
- sizeof(inbuf), inbuf, &count);
- for (ip = inbuf; ip < &inbuf[count]; ip++) {
- c = *ip;
- switch (c) {
- case '\n':
- case '\r':
- printf("\n");
- *lp++ = 0;
- return;
-
- case '\b':
- case '#':
- case '\177':
- if (lp > str) {
- printf("\b \b");
- lp--;
- }
- continue;
- case '@':
- case 'u'&037:
- lp = str;
- printf("\n\r");
- continue;
- default:
- if (c >= ' ' && c < '\177') {
- if (lp < strmax) {
- *lp++ = c;
- printf("%c", c);
- }
- else {
- printf("%c", '\007'); /* beep */
- }
- }
- }
- }
- }
-}
-
diff --git a/serverboot/gunzip.c b/serverboot/gunzip.c
deleted file mode 100644
index f74da111..00000000
--- a/serverboot/gunzip.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Modified by okuji@kuicr.kyoto-u.ac.jp for use in serverboot. */
-/* Decompressing store backend
-
- Copyright (C) 1997 Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include <stdio.h>
-#include <string.h>
-#include <setjmp.h>
-#include <cthreads.h>
-#include <errno.h>
-
-#include <file_io.h>
-
-/* gzip.h makes several annoying defines & decls, which we have to work
- around. */
-#define file_t gzip_file_t
-#include "gzip.h"
-#undef file_t
-#undef head
-
-#define IN_BUFFERING (256*1024)
-#define OUT_BUFFERING (512*1024)
-
-static struct mutex unzip_lock = MUTEX_INITIALIZER;
-
-/* Uncompress the contents of FROM, which should contain a valid gzip file,
- into memory, returning the result buffer in BUF & BUF_LEN. */
-int
-serverboot_gunzip (struct file *from, void **buf, size_t *buf_len)
-{
- /* Entry points to unzip engine. */
- int get_method (int);
- extern long int bytes_out;
- /* Callbacks from unzip for I/O and error interface. */
- extern int (*unzip_read) (char *buf, size_t maxread);
- extern void (*unzip_write) (const char *buf, size_t nwrite);
- extern void (*unzip_read_error) (void);
- extern void (*unzip_error) (const char *msg);
-
- /* How we return errors from our hook functions. */
- jmp_buf zerr_jmp_buf;
- int zerr;
-
- size_t offset = 0; /* Offset of read point in FROM. */
-
- /* Read at most MAXREAD (or 0 if eof) bytes into BUF from our current
- position in FROM. */
- int zread (char *buf, size_t maxread)
- {
- vm_size_t resid;
- size_t did_read;
-
- if (from->f_size - offset < maxread)
- did_read = from->f_size - offset;
- else
- did_read = maxread;
-
- zerr = read_file (from, offset, buf, did_read, &resid);
- if (zerr)
- longjmp (zerr_jmp_buf, 1);
-
- did_read -= resid;
- offset += did_read;
-
- return did_read;
- }
-
- size_t out_buf_offs = 0; /* Position in the output buffer. */
-
- /* Write uncompress data to our output buffer. */
- void zwrite (const char *wbuf, size_t nwrite)
- {
- size_t old_buf_len = *buf_len;
-
- if (out_buf_offs + nwrite > old_buf_len)
- /* Have to grow the output buffer. */
- {
- void *old_buf = *buf;
- void *new_buf = old_buf + old_buf_len; /* First try. */
- size_t new_buf_len = round_page (old_buf_len + old_buf_len + nwrite);
-
- /* Try to grow the buffer. */
- zerr =
- vm_allocate (mach_task_self (),
- (vm_address_t *)&new_buf, new_buf_len - old_buf_len,
- 0);
- if (zerr)
- /* Can't do that, try to make a bigger buffer elsewhere. */
- {
- new_buf = old_buf;
- zerr =
- vm_allocate (mach_task_self (),
- (vm_address_t *)&new_buf, new_buf_len, 1);
- if (zerr)
- longjmp (zerr_jmp_buf, 1);
-
- if (out_buf_offs > 0)
- /* Copy the old buffer into the start of the new & free it. */
- bcopy (old_buf, new_buf, out_buf_offs);
-
- vm_deallocate (mach_task_self (),
- (vm_address_t)old_buf, old_buf_len);
-
- *buf = new_buf;
- }
-
- *buf_len = new_buf_len;
- }
-
- bcopy (wbuf, *buf + out_buf_offs, nwrite);
- out_buf_offs += nwrite;
- }
-
- void zreaderr (void)
- {
- zerr = EIO;
- longjmp (zerr_jmp_buf, 1);
- }
- void zerror (const char *msg)
- {
- zerr = EINVAL;
- longjmp (zerr_jmp_buf, 2);
- }
-
- /* Try to guess a reasonable output buffer size. */
- *buf_len = round_page (from->f_size * 2);
- zerr = vm_allocate (mach_task_self (), (vm_address_t *)buf, *buf_len, 1);
- if (zerr)
- return zerr;
-
- mutex_lock (&unzip_lock);
-
- unzip_read = zread;
- unzip_write = zwrite;
- unzip_read_error = zreaderr;
- unzip_error = zerror;
-
- if (! setjmp (zerr_jmp_buf))
- {
- if (get_method (0) != 0)
- /* Not a happy gzip file. */
- zerr = EINVAL;
- else
- /* Matched gzip magic number. Ready to unzip.
- Set up the output stream and let 'er rip. */
- {
- /* Call the gunzip engine. */
- bytes_out = 0;
- unzip (17, 23); /* Arguments ignored. */
- zerr = 0;
- }
- }
-
- mutex_unlock (&unzip_lock);
-
- if (zerr)
- {
- if (*buf_len > 0)
- vm_deallocate (mach_task_self (), (vm_address_t)*buf, *buf_len);
- }
- else if (out_buf_offs < *buf_len)
- /* Trim the output buffer to be the right length. */
- {
- size_t end = round_page (out_buf_offs);
- if (end < *buf_len)
- vm_deallocate (mach_task_self (),
- (vm_address_t)(*buf + end), *buf_len - end);
- *buf_len = out_buf_offs;
- }
-
- return zerr;
-}
diff --git a/serverboot/kalloc.c b/serverboot/kalloc.c
deleted file mode 100644
index 28c0b55e..00000000
--- a/serverboot/kalloc.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1987 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: kern/kalloc.c
- * Author: Avadis Tevanian, Jr.
- * Date: 1985
- *
- * General kernel memory allocator. This allocator is designed
- * to be used by the kernel to manage dynamic memory fast.
- */
-
-#include <mach.h>
-#include <cthreads.h> /* for spin locks */
-#include <malloc.h> /* for malloc_hook/free_hook */
-
-static void init_hook (void);
-static void *malloc_hook (size_t size, const void *caller);
-static void free_hook (void *ptr, const void *caller);
-
-void (*__malloc_initialize_hook) (void) = init_hook;
-
-
-#define DEBUG
-
-/*
- * All allocations of size less than kalloc_max are rounded to the
- * next highest power of 2.
- */
-vm_size_t kalloc_max; /* max before we use vm_allocate */
-#define MINSIZE 4 /* minimum allocation size */
-
-struct free_list {
- spin_lock_t lock;
- vm_offset_t head; /* head of free list */
-#ifdef DEBUG
- int count;
-#endif /*DEBUG*/
-};
-
-#define KLIST_MAX 13
- /* sizes: 4, 8, 16, 32, 64,
- 128, 256, 512, 1024,
- 2048, 4096, 8192, 16384 */
-struct free_list kfree_list[KLIST_MAX];
-
-spin_lock_t kget_space_lock;
-vm_offset_t kalloc_next_space = 0;
-vm_offset_t kalloc_end_of_space = 0;
-
-vm_size_t kalloc_wasted_space = 0;
-
-boolean_t kalloc_initialized = FALSE;
-
-/*
- * Initialize the memory allocator. This should be called only
- * once on a system wide basis (i.e. first processor to get here
- * does the initialization).
- *
- * This initializes all of the zones.
- */
-
-void kalloc_init(void)
-{
- vm_offset_t min, max;
- vm_size_t size;
- register int i;
-
- /*
- * Support free lists for items up to vm_page_size or
- * 16Kbytes, whichever is less.
- */
-
- if (vm_page_size > 16*1024)
- kalloc_max = 16*1024;
- else
- kalloc_max = vm_page_size;
-
- for (i = 0; i < KLIST_MAX; i++) {
- spin_lock_init(&kfree_list[i].lock);
- kfree_list[i].head = 0;
- }
- spin_lock_init(&kget_space_lock);
-
- /*
- * Do not allocate memory at address 0.
- */
- kalloc_next_space = vm_page_size;
- kalloc_end_of_space = vm_page_size;
-}
-
-/*
- * Contiguous space allocator for items of less than a page size.
- */
-vm_offset_t kget_space(vm_offset_t size)
-{
- vm_size_t space_to_add;
- vm_offset_t new_space = 0;
- vm_offset_t addr;
-
- spin_lock(&kget_space_lock);
- while (kalloc_next_space + size > kalloc_end_of_space) {
- /*
- * Add at least one page to allocation area.
- */
- space_to_add = round_page(size);
-
- if (new_space == 0) {
- /*
- * Unlock and allocate memory.
- * Try to make it contiguous with the last
- * allocation area.
- */
- spin_unlock(&kget_space_lock);
-
- new_space = kalloc_end_of_space;
- if (vm_map(mach_task_self(),
- &new_space, space_to_add, (vm_offset_t) 0, TRUE,
- MEMORY_OBJECT_NULL, (vm_offset_t) 0, FALSE,
- VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT)
- != KERN_SUCCESS)
- return 0;
- wire_memory(new_space, space_to_add,
- VM_PROT_READ|VM_PROT_WRITE);
- spin_lock(&kget_space_lock);
- continue;
- }
-
- /*
- * Memory was allocated in a previous iteration.
- * Check whether the new region is contiguous with the
- * old one.
- */
- if (new_space != kalloc_end_of_space) {
- /*
- * Throw away the remainder of the old space,
- * and start a new one.
- */
- kalloc_wasted_space +=
- kalloc_end_of_space - kalloc_next_space;
- kalloc_next_space = new_space;
- }
- kalloc_end_of_space = new_space + space_to_add;
-
- new_space = 0;
- }
-
- addr = kalloc_next_space;
- kalloc_next_space += size;
- spin_unlock(&kget_space_lock);
-
- if (new_space != 0)
- (void) vm_deallocate(mach_task_self(), new_space, space_to_add);
-
- return addr;
-}
-
-void *kalloc(vm_size_t size)
-{
- register vm_size_t allocsize;
- vm_offset_t addr;
- register struct free_list *fl;
-
- if (!kalloc_initialized) {
- kalloc_init();
- kalloc_initialized = TRUE;
- }
-
- /* compute the size of the block that we will actually allocate */
-
- allocsize = size;
- if (size < kalloc_max) {
- allocsize = MINSIZE;
- fl = kfree_list;
- while (allocsize < size) {
- allocsize <<= 1;
- fl++;
- }
- }
-
- /*
- * If our size is still small enough, check the queue for that size
- * and allocate.
- */
-
- if (allocsize < kalloc_max) {
- spin_lock(&fl->lock);
- if ((addr = fl->head) != 0) {
- fl->head = *(vm_offset_t *)addr;
-#ifdef DEBUG
- fl->count--;
-#endif
- spin_unlock(&fl->lock);
- }
- else {
- spin_unlock(&fl->lock);
- addr = kget_space(allocsize);
- }
- }
- else {
- if (vm_allocate(mach_task_self(), &addr, allocsize, TRUE)
- != KERN_SUCCESS)
- addr = 0;
- }
- return (void *) addr;
-}
-
-void
-kfree( void *data,
- vm_size_t size)
-{
- register vm_size_t freesize;
- register struct free_list *fl;
-
- freesize = size;
- if (size < kalloc_max) {
- freesize = MINSIZE;
- fl = kfree_list;
- while (freesize < size) {
- freesize <<= 1;
- fl++;
- }
- }
-
- if (freesize < kalloc_max) {
- spin_lock(&fl->lock);
- *(vm_offset_t *)data = fl->head;
- fl->head = (vm_offset_t) data;
-#ifdef DEBUG
- fl->count++;
-#endif
- spin_unlock(&fl->lock);
- }
- else {
- (void) vm_deallocate(mach_task_self(), (vm_offset_t)data, freesize);
- }
-}
-
-static void
-init_hook (void)
-{
- __malloc_hook = malloc_hook;
- __free_hook = free_hook;
-}
-
-static void *
-malloc_hook (size_t size, const void *caller)
-{
- return (void *) kalloc ((vm_size_t) size);
-}
-
-static void
-free_hook (void *ptr, const void *caller)
-{
- /* Just ignore harmless attempts at cleanliness. */
- /* panic("free not implemented"); */
-}
-
-void malloc_fork_prepare()
-{
-}
-
-void malloc_fork_parent()
-{
-}
-
-void malloc_fork_child()
-{
-}
diff --git a/serverboot/load.c b/serverboot/load.c
deleted file mode 100644
index aa481943..00000000
--- a/serverboot/load.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#include <stddef.h>
-#include <assert.h>
-#include <mach/mach_interface.h>
-#include "mach-exec.h"
-#include "../boot/boot_script.h"
-
-#include <file_io.h>
-
-
-boolean_t load_protect_text = TRUE;
-
-
-struct stuff
-{
- struct file *fp;
- task_t user_task;
-
- /* uncompressed image */
- vm_offset_t image_addr;
- vm_size_t image_size;
-
- vm_offset_t aout_symtab_ofs;
- vm_size_t aout_symtab_size;
- vm_offset_t aout_strtab_ofs;
- vm_size_t aout_strtab_size;
-};
-
-char *set_regs(
- mach_port_t user_task,
- mach_port_t user_thread,
- struct exec_info *info,
- int arg_size);
-
-static void read_symtab_from_file(
- struct file *fp,
- mach_port_t host_port,
- task_t task,
- char * symtab_name,
- struct stuff *st);
-
-/* Callback functions for reading the executable file. */
-static int prog_read(void *handle, vm_offset_t file_ofs, void *buf, vm_size_t size,
- vm_size_t *out_actual)
-{
- struct stuff *st = handle;
- vm_size_t resid;
- int result;
-
- result = read_file(st->fp, file_ofs, buf, size, &resid);
- if (result)
- return result;
- *out_actual = size - resid;
- return 0;
-}
-
-static int prog_read_exec(void *handle, vm_offset_t file_ofs, vm_size_t file_size,
- vm_offset_t mem_addr, vm_size_t mem_size,
- exec_sectype_t sec_type)
-{
- struct stuff *st = handle;
- vm_offset_t page_start = trunc_page(mem_addr);
- vm_offset_t page_end = round_page(mem_addr + mem_size);
- vm_prot_t mem_prot = sec_type & EXEC_SECTYPE_PROT_MASK;
- vm_offset_t area_start;
- int result;
-
- if (sec_type & EXEC_SECTYPE_AOUT_SYMTAB)
- {
- st->aout_symtab_ofs = file_ofs;
- st->aout_symtab_size = file_size;
- }
- if (sec_type & EXEC_SECTYPE_AOUT_STRTAB)
- {
- st->aout_strtab_ofs = file_ofs;
- st->aout_strtab_size = file_size;
- }
-
- if (!(sec_type & EXEC_SECTYPE_ALLOC))
- return 0;
-
- assert(mem_size > 0);
- assert(mem_size > file_size);
-
- /*
- printf("section %08x-%08x-%08x prot %08x (%08x-%08x)\n",
- mem_addr, mem_addr+file_size, mem_addr+mem_size, mem_prot, page_start, page_end);
- */
-
- result = vm_allocate(mach_task_self(), &area_start, page_end - page_start, TRUE);
- if (result) return (result);
-
- if (file_size > 0)
- {
- vm_size_t resid;
-
- result = read_file(st->fp, file_ofs, area_start + (mem_addr - page_start),
- file_size, &resid);
- if (result) return result;
- if (resid) return EX_CORRUPT;
- }
-
- if (mem_size > file_size)
- {
- bzero((void*)area_start + (mem_addr + file_size - page_start),
- mem_size - file_size);
- }
-
- result = vm_allocate(st->user_task, &page_start, page_end - page_start, FALSE);
- if (result) return (result);
- assert(page_start == trunc_page(mem_addr));
-
- result = vm_write(st->user_task, page_start, area_start, page_end - page_start);
- if (result) return (result);
-
- result = vm_deallocate(mach_task_self(), area_start, page_end - page_start);
- if (result) return (result);
-
- /*
- * Protect the segment.
- */
- if (load_protect_text && (mem_prot != VM_PROT_ALL)) {
- result = vm_protect(st->user_task, page_start, page_end - page_start,
- FALSE, mem_prot);
- if (result) return (result);
- }
-
- return 0;
-}
-
-/* Callback functions for reading the uncompressed image. */
-static int image_read(void *handle, vm_offset_t file_ofs, void *buf,
- vm_size_t size, vm_size_t *out_actual)
-{
- struct stuff *st = handle;
- bcopy(st->image_addr + file_ofs, buf, size);
- *out_actual = size;
- return 0;
-}
-
-static int image_read_exec(void *handle, vm_offset_t file_ofs,
- vm_size_t file_size, vm_offset_t mem_addr,
- vm_size_t mem_size, exec_sectype_t sec_type)
-{
- struct stuff *st = handle;
- vm_offset_t page_start = trunc_page(mem_addr);
- vm_offset_t page_end = round_page(mem_addr + mem_size);
- vm_prot_t mem_prot = sec_type & EXEC_SECTYPE_PROT_MASK;
- vm_offset_t area_start;
- int result;
-
- if (sec_type & EXEC_SECTYPE_AOUT_SYMTAB)
- {
- st->aout_symtab_ofs = file_ofs;
- st->aout_symtab_size = file_size;
- }
- if (sec_type & EXEC_SECTYPE_AOUT_STRTAB)
- {
- st->aout_strtab_ofs = file_ofs;
- st->aout_strtab_size = file_size;
- }
-
- if (!(sec_type & EXEC_SECTYPE_ALLOC))
- return 0;
-
- assert(mem_size > 0);
- assert(mem_size > file_size);
-
- /*
- printf("section %08x-%08x-%08x prot %08x (%08x-%08x)\n",
- mem_addr, mem_addr+file_size, mem_addr+mem_size, mem_prot, page_start, page_end);
- */
-
- result = vm_allocate(mach_task_self(), &area_start, page_end - page_start, TRUE);
- if (result) return (result);
-
- if (file_size > 0)
- {
- bcopy(st->image_addr + file_ofs, area_start + (mem_addr - page_start),
- file_size);
- }
-
- if (mem_size > file_size)
- {
- bzero((void*)area_start + (mem_addr + file_size - page_start),
- mem_size - file_size);
- }
-
- result = vm_allocate(st->user_task, &page_start, page_end - page_start, FALSE);
- if (result) return (result);
- assert(page_start == trunc_page(mem_addr));
-
- result = vm_write(st->user_task, page_start, area_start, page_end - page_start);
- if (result) return (result);
-
- result = vm_deallocate(mach_task_self(), area_start, page_end - page_start);
- if (result) return (result);
-
- /*
- * Protect the segment.
- */
- if (load_protect_text && (mem_prot != VM_PROT_ALL)) {
- result = vm_protect(st->user_task, page_start, page_end - page_start,
- FALSE, mem_prot);
- if (result) return (result);
- }
-
- return 0;
-}
-
-mach_port_t boot_script_read_file (const char *file)
-{ return MACH_PORT_NULL; } /* XXX */
-
-int
-boot_script_exec_cmd (void *hook,
- task_t user_task,
- char *file_name,
- int arg_count, char **argv,
- char *argstrings, int argslen)
-{
- extern mach_port_t bootstrap_master_device_port, bootstrap_master_host_port;
- extern char *root_name;
- extern char **environ;
- int envc, env_len;
-
- int arg_len = argslen;
- char *arg_pos;
-
- kern_return_t result;
- thread_t user_thread;
- struct file file;
- char namebuf[MAXPATHLEN+1];
-
- struct stuff st;
- struct exec_info info;
-
- extern char * strbuild();
-
- if (strcmp (file_name, "/dev/"))
- (void) strbuild(namebuf, "/dev/", root_name, "/", file_name,
- (char *)0);
- else
- strcpy (namebuf, file_name);
-
- /*
- * Open the file
- */
- bzero((char *)&file, sizeof(file));
-
- result = open_file(bootstrap_master_device_port, namebuf, &file);
- if (result != 0) {
- panic ("%s: %s", namebuf, strerror (result));
- }
-
- env_len = 0;
- for (envc = 0; environ[envc]; ++envc)
- env_len += strlen (environ[envc]) + 1;
-
- /*
- * Add space for:
- * arg_count
- * pointers to arguments
- * trailing 0 pointer
- * environment variables
- * trailing 0 pointer
- * and align to integer boundary
- */
- arg_len += sizeof(integer_t) + (envc + 2 + arg_count) * sizeof(char *);
- arg_len += env_len;
- arg_len = (arg_len + (sizeof(integer_t) - 1)) & ~(sizeof(integer_t)-1);
-
- /*
- * We refrain from checking IEXEC bits to make
- * things a little easier when things went bad.
- * Say you have ftp(1) but chmod(1) is gone.
- */
- if (!file_is_regular(&file))
- panic("boot_load_program: %s is not a regular file", namebuf);
-
- /*
- * Load the executable file.
- */
- st.fp = &file;
- st.user_task = user_task;
- st.aout_symtab_size = 0;
- st.aout_strtab_size = 0;
- result = exec_load(prog_read, prog_read_exec, &st, &info);
-#ifdef GZIP
- if (result)
- {
- /*
- * It might be gzip file.
- */
- int err;
- extern int serverboot_gunzip(struct file *,
- vm_offset_t *, size_t *);
-
- err = serverboot_gunzip(st.fp,
- &(st.image_addr),
- &(st.image_size));
- if (!err)
- {
- result = exec_load(image_read,
- image_read_exec,
- &st,
- &info);
- vm_deallocate(mach_task_self(),
- st.image_addr,
- st.image_size);
- }
- }
-#endif /* GZIP */
-#ifdef BZIP2
- if (result)
- {
- /*
- * It might be bzip2 file.
- */
- int err;
- extern int serverboot_bunzip2(struct file *,
- vm_offset_t *, size_t *);
-
- err = serverboot_bunzip2(st.fp,
- &(st.image_addr),
- &(st.image_size));
- if (!err)
- {
- result = exec_load(image_read,
- image_read_exec,
- &st,
- &info);
- vm_deallocate(mach_task_self(),
- st.image_addr,
- st.image_size);
- }
- }
-#endif /* BZIP2 */
- if (result)
- panic ("cannot load %s: %s", namebuf, strerror (result));
-#if 0
- printf("(serverboot): loaded %s; entrypoint %08x\n", namebuf, info.entry);
-#endif
-
- /*
- * Set up the stack and user registers.
- */
- result = thread_create (user_task, &user_thread);
- if (result)
- panic ("can't create user thread for %s: %s", namebuf,
- strerror (result));
- arg_pos = set_regs(user_task, user_thread, &info, arg_len);
-
- /*
- * Read symbols from the executable file.
- */
-#if 0
- printf("(serverboot): loading symbols from %s\n", namebuf);
- read_symtab_from_file(&file, bootstrap_master_host_port, user_task, namebuf, &st);
-#endif
-
- /*
- * 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);
-
- result = vm_allocate(mach_task_self(),
- &k_arg_page_start,
- (vm_size_t)arg_page_size,
- TRUE);
- if (result)
- panic("boot_load_program: arg size");
-
- /*
- * 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 *)
- + envc * sizeof(char *)
- + 2 * sizeof(char *)
- + sizeof(integer_t);
- k_cp = (char *)k_arg_start + arg_count * sizeof(char *)
- + envc * sizeof(char *)
- + 2 * sizeof(char *)
- + sizeof(integer_t);
-
- /*
- * first the argument count
- */
- *k_ap++ = (char *)(intptr_t)arg_count;
-
- /*
- * Then the strings and string pointers for each argument
- */
- for (i = 0; i < arg_count; i++)
- *k_ap++ = argv[i] - argstrings + u_cp;
- *k_ap++ = (char *)0;
- bcopy (argstrings, k_cp, argslen);
- k_cp += argslen;
- u_cp += argslen;
-
- for (i = 0; i < envc; i++)
- *k_ap++ = environ[i] - environ[0] + u_cp;
- *k_ap = (char *)0;
- bcopy (environ[0], k_cp, env_len);
-
- /*
- * 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);
- }
-
- /*
- * Close the file.
- */
- close_file(&file);
-
- /* Resume the thread. */
- thread_resume (user_thread);
- mach_port_deallocate (mach_task_self (), user_thread);
-
- return (0);
-}
-
-/*
- * Load symbols from file into kernel debugger.
- */
-static void read_symtab_from_file(
- struct file *fp,
- mach_port_t host_port,
- task_t task,
- char * symtab_name,
- struct stuff *st)
-{
- vm_size_t resid;
- kern_return_t result;
- vm_size_t table_size;
- vm_offset_t symtab;
-
-#if 0
-
- if (!st->aout_symtab_size || !st->aout_strtab_size)
- return;
-
- /*
- * Allocate space for the symbol table.
- */
- table_size = sizeof(vm_size_t)
- + st->aout_symtab_size
- + st->aout_strtab_size;
- result= vm_allocate(mach_task_self(),
- &symtab,
- table_size,
- TRUE);
- if (result) {
- printf("[ error %d allocating space for %s symbol table ]\n",
- result, symtab_name);
- return;
- }
-
- /*
- * Set the symbol table length word,
- * then read in the symbol table and string table.
- */
- *(vm_size_t*)symtab = st->aout_symtab_size;
- result = read_file(fp, st->aout_symtab_ofs,
- symtab + sizeof(vm_size_t),
- st->aout_symtab_size + st->aout_strtab_size,
- &resid);
- if (result || resid) {
- printf("[ no valid symbol table present for %s ]\n",
- symtab_name);
- }
- else {
- /*
- * Load the symbols into the kernel.
- */
- result = host_load_symbol_table(
- host_port,
- task,
- symtab_name,
- symtab,
- table_size);
- }
- (void) vm_deallocate(mach_task_self(), symtab, table_size);
-#endif
-}
diff --git a/serverboot/mach-exec.h b/serverboot/mach-exec.h
deleted file mode 100644
index 94b234b0..00000000
--- a/serverboot/mach-exec.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#ifndef _MACH_EXEC_H_
-#define _MACH_EXEC_H_
-
-#include <mach/machine/vm_types.h>
-#include <mach/vm_prot.h>
-
-/* XXX */
-typedef enum
-{
- EXEC_ELF = 1,
- EXEC_AOUT = 2,
-} exec_format_t;
-
-typedef struct exec_info
-{
- /* Format of executable loaded - see above. */
- exec_format_t format;
-
- /* Program entrypoint. */
- vm_offset_t entry;
-
- /* Initial data pointer - only some architectures use this. */
- vm_offset_t init_dp;
-
- /* (ELF) Address of interpreter string for loading shared libraries, null if none. */
- vm_offset_t interp;
-
-} exec_info_t;
-
-typedef int exec_sectype_t;
-#define EXEC_SECTYPE_READ VM_PROT_READ
-#define EXEC_SECTYPE_WRITE VM_PROT_WRITE
-#define EXEC_SECTYPE_EXECUTE VM_PROT_EXECUTE
-#define EXEC_SECTYPE_PROT_MASK VM_PROT_ALL
-#define EXEC_SECTYPE_ALLOC ((exec_sectype_t)0x000100)
-#define EXEC_SECTYPE_LOAD ((exec_sectype_t)0x000200)
-#define EXEC_SECTYPE_DEBUG ((exec_sectype_t)0x010000)
-#define EXEC_SECTYPE_AOUT_SYMTAB ((exec_sectype_t)0x020000)
-#define EXEC_SECTYPE_AOUT_STRTAB ((exec_sectype_t)0x040000)
-
-typedef int exec_read_func_t(void *handle, vm_offset_t file_ofs,
- void *buf, vm_size_t size,
- vm_size_t *out_actual);
-
-typedef int exec_read_exec_func_t(void *handle,
- vm_offset_t file_ofs, vm_size_t file_size,
- vm_offset_t mem_addr, vm_size_t mem_size,
- exec_sectype_t section_type);
-
-/*
- * Routines exported from libmach_exec.a
- */
-
-/* Generic function to interpret an executable "file"
- and "load" it into "memory".
- Doesn't really know about files, loading, or memory;
- all file I/O and destination memory accesses
- go through provided functions.
- Thus, this is a very generic loading mechanism.
-
- The read() function is used to read metadata from the file
- into the local address space.
-
- The read_exec() function is used to load the actual sections.
- It is used for all kinds of sections - code, data, bss, debugging data.
- The 'section_type' parameter specifies what type of section is being loaded.
-
- For code, data, and bss, the EXEC_SECTYPE_ALLOC flag will be set.
- For code and data (i.e. stuff that's actually loaded from the file),
- EXEC_SECTYPE_LOAD will also be set.
- The EXEC_SECTYPE_PROT_MASK contains the intended access permissions
- for the section.
- 'file_size' may be less than 'mem_size';
- the remaining data must be zero-filled.
- 'mem_size' is always greater than zero, but 'file_size' may be zero
- (e.g. in the case of a bss section).
- No two read_exec() calls for one executable
- will load data into the same virtual memory page,
- although they may load from arbitrary (possibly overlapping) file positions.
-
- For sections that aren't normally loaded into the process image
- (e.g. debug sections), EXEC_SECTYPE_ALLOC isn't set,
- but some other appropriate flag is set to indicate the type of section.
-
- The 'handle' is an opaque pointer which is simply passed on
- to the read() and read_exec() functions.
-
- On return, the specified info structure is filled in
- with information about the loaded executable.
-*/
-int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec,
- void *handle, exec_info_t *out_info);
-
-/*
- * Error codes
- */
-
-#define EX_NOT_EXECUTABLE 6000 /* not a recognized executable format */
-#define EX_WRONG_ARCH 6001 /* valid executable, but wrong arch. */
-#define EX_CORRUPT 6002 /* recognized executable, but mangled */
-#define EX_BAD_LAYOUT 6003 /* something wrong with the memory or file image layout */
-
-
-#endif /* _MACH_EXEC_H_ */
diff --git a/serverboot/minix_ffs_compat.c b/serverboot/minix_ffs_compat.c
deleted file mode 100644
index 7d493520..00000000
--- a/serverboot/minix_ffs_compat.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * BSD FFS like functions used to ease porting bootstrap to MINIX fs
- * Copyright (C) 1994 Csizmazia Balazs, University ELTE, Hungary
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include <file_io.h>
-
-#define MINIX_BLOCK_SIZE 1024
-
-int minix_ino2blk (struct minix_super_block *fs, int ino)
-{
- int blk;
-
- blk=0 /* it's Mach */+2 /* boot+superblock */ + fs->s_imap_blocks +
- fs->s_zmap_blocks + (ino-1)/MINIX_INODES_PER_BLOCK;
- return blk;
-}
-
-int minix_fsbtodb (struct minix_super_block *fs, int b)
-{
- return (b * MINIX_BLOCK_SIZE) / DEV_BSIZE;
-}
-
-int minix_itoo (struct minix_super_block *fs, int ino)
-{
- return (ino - 1) % MINIX_INODES_PER_BLOCK;
-}
-
-int minix_blkoff (struct minix_super_block * fs, vm_offset_t offset)
-{
- return offset % MINIX_BLOCK_SIZE;
-}
-
-int minix_lblkno (struct minix_super_block * fs, vm_offset_t offset)
-{
- return offset / MINIX_BLOCK_SIZE;
-}
-
-int minix_blksize (struct minix_super_block *fs, struct file *fp, minix_daddr_t file_block)
-{
- return MINIX_BLOCK_SIZE;
-}
diff --git a/serverboot/minix_ffs_compat.h b/serverboot/minix_ffs_compat.h
deleted file mode 100644
index cc038032..00000000
--- a/serverboot/minix_ffs_compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * BSD FFS like declarations used to ease porting bootstrap to MINIX fs
- * Copyright (C) 1994 Csizmazia Balazs, University ELTE, Hungary
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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.
- */
-
-#define MINIX_SBSIZE MINIX_BLOCK_SIZE /* Size of superblock */
-#define MINIX_SBLOCK ((minix_daddr_t) 2) /* Location of superblock */
-
-#define MINIX_NDADDR 7
-#define MINIX_NIADDR 2
-
-#define MINIX_MAXNAMLEN 14
-
-#define MINIX_ROOTINO 1 /* MINIX ROOT INODE */
-
-#define MINIX_NINDIR(fs) 512 /* DISK_ADDRESSES_PER_BLOCKS */
-
-#define IFMT 00170000
-#define IFREG 0100000
-#define IFDIR 0040000
-#define ISVTX 0001000
-
-#define f_fs u.minix.minix_fs
-#define i_ic u.minix.minix_ic
-#define f_nindir u.minix.minix_nindir
-#define f_blk u.minix.minix_blk
-#define f_blksize u.minix.minix_blksize
-#define f_blkno u.minix.minix_blkno
-
diff --git a/serverboot/minix_file_io.c b/serverboot/minix_file_io.c
deleted file mode 100644
index 17beb18c..00000000
--- a/serverboot/minix_file_io.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Stand-alone file reading package.
- */
-
-#include <device/device_types.h>
-#include <device/device.h>
-
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-
-#include "file_io.h"
-#include "minix_ffs_compat.h"
-#include "minix_fs.h"
-
-void minix_close_file(); /* forward */
-
-#define MINIX_NAME_LEN 14
-#define MINIX_BLOCK_SIZE 1024
-
-/*
- * Free file buffers, but don't close file.
- */
-static void
-free_file_buffers(fp)
- register struct file *fp;
-{
- register int level;
-
- /*
- * Free the indirect blocks
- */
- for (level = 0; level < MINIX_NIADDR; level++) {
- if (fp->f_blk[level] != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_blk[level],
- fp->f_blksize[level]);
- fp->f_blk[level] = 0;
- }
- fp->f_blkno[level] = -1;
- }
-
- /*
- * Free the data block
- */
- if (fp->f_buf != 0) {
- (void) vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
- fp->f_buf = 0;
- }
- fp->f_buf_blkno = -1;
-}
-
-/*
- * Read a new inode into a file structure.
- */
-static int
-read_inode(inumber, fp)
- ino_t inumber;
- register struct file *fp;
-{
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- register
- struct minix_super_block *fs;
- minix_daddr_t disk_block;
- kern_return_t rc;
-
- fs = fp->f_fs;
- disk_block = minix_ino2blk(fs, inumber);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) minix_fsbtodb(fp->f_fs, disk_block),
- (int) MINIX_BLOCK_SIZE,
- (char **)&buf,
- &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- {
- register struct minix_inode *dp;
-
- dp = (struct minix_inode *)buf;
- dp += minix_itoo(fs, inumber);
- fp->i_ic = *dp;
- fp->f_size = dp->i_size;
- }
-
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
-
- /*
- * Clear out the old buffers
- */
- free_file_buffers(fp);
-
- return (0);
-}
-
-/*
- * Given an offset in a file, find the disk block number that
- * contains that block.
- */
-static int
-block_map(fp, file_block, disk_block_p)
- struct file *fp;
- minix_daddr_t file_block;
- minix_daddr_t *disk_block_p; /* out */
-{
- int level;
- int idx;
- minix_daddr_t ind_block_num;
- kern_return_t rc;
-
- vm_offset_t olddata[MINIX_NIADDR+1];
- vm_size_t oldsize[MINIX_NIADDR+1];
-
- /*
- * Index structure of an inode:
- *
- * i_db[0..NDADDR-1] hold block numbers for blocks
- * 0..NDADDR-1
- *
- * i_ib[0] index block 0 is the single indirect
- * block
- * holds block numbers for blocks
- * NDADDR .. NDADDR + NINDIR(fs)-1
- *
- * i_ib[1] index block 1 is the double indirect
- * block
- * holds block numbers for INDEX blocks
- * for blocks
- * NDADDR + NINDIR(fs) ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
- *
- * i_ib[2] index block 2 is the triple indirect
- * block
- * holds block numbers for double-indirect
- * blocks for blocks
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
- * NDADDR + NINDIR(fs) + NINDIR(fs)**2
- * + NINDIR(fs)**3 - 1
- */
-
- mutex_lock(&fp->f_lock);
-
- if (file_block < MINIX_NDADDR) {
- /* Direct block. */
- *disk_block_p = fp->i_ic.i_zone[file_block];
- mutex_unlock(&fp->f_lock);
- return (0);
- }
-
- file_block -= MINIX_NDADDR;
-
- /*
- * nindir[0] = NINDIR
- * nindir[1] = NINDIR**2
- * nindir[2] = NINDIR**3
- * etc
- */
- for (level = 0; level < MINIX_NIADDR; level++) {
- if (file_block < fp->f_nindir[level])
- break;
- file_block -= fp->f_nindir[level];
- }
- if (level == MINIX_NIADDR) {
- /* Block number too high */
- mutex_unlock(&fp->f_lock);
- return (FS_NOT_IN_FILE);
- }
-
- ind_block_num = fp->i_ic.i_zone[level + MINIX_NDADDR];
-
- /*
- * Initialize array of blocks to free.
- */
- for (idx = 0; idx < MINIX_NIADDR; idx++)
- oldsize[idx] = 0;
-
- for (; level >= 0; level--) {
-
- vm_offset_t data;
- mach_msg_type_number_t size;
-
- if (ind_block_num == 0)
- break;
-
- if (fp->f_blkno[level] == ind_block_num) {
- /*
- * Cache hit. Just pick up the data.
- */
-
- data = fp->f_blk[level];
- }
- else {
- /*
- * Drop our lock while doing the read.
- * (The f_dev and f_fs fields don`t change.)
- */
- mutex_unlock(&fp->f_lock);
-
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) minix_fsbtodb(fp->f_fs, ind_block_num),
- MINIX_BLOCK_SIZE,
- (char **)&data,
- &size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- /*
- * See if we can cache the data. Need a write lock to
- * do this. While we hold the write lock, we can`t do
- * *anything* which might block for memory. Otherwise
- * a non-privileged thread might deadlock with the
- * privileged threads. We can`t block while taking the
- * write lock. Otherwise a non-privileged thread
- * blocked in the vm_deallocate (while holding a read
- * lock) will block a privileged thread. For the same
- * reason, we can`t take a read lock and then use
- * lock_read_to_write.
- */
-
- mutex_lock(&fp->f_lock);
-
- olddata[level] = fp->f_blk[level];
- oldsize[level] = fp->f_blksize[level];
-
- fp->f_blkno[level] = ind_block_num;
- fp->f_blk[level] = data;
- fp->f_blksize[level] = size;
-
- /*
- * Return to holding a read lock, and
- * dispose of old data.
- */
-
- }
-
- if (level > 0) {
- idx = file_block / fp->f_nindir[level-1];
- file_block %= fp->f_nindir[level-1];
- }
- else
- idx = file_block;
-
- ind_block_num = ((minix_daddr_t *)data)[idx];
- }
-
- mutex_unlock(&fp->f_lock);
-
- /*
- * After unlocking the file, free any blocks that
- * we need to free.
- */
- for (idx = 0; idx < MINIX_NIADDR; idx++)
- if (oldsize[idx] != 0)
- (void) vm_deallocate(mach_task_self(),
- olddata[idx],
- oldsize[idx]);
-
- *disk_block_p = ind_block_num;
- return (0);
-}
-
-/*
- * Read a portion of a file into an internal buffer. Return
- * the location in the buffer and the amount in the buffer.
- */
-static int
-buf_read_file(fp, offset, buf_p, size_p)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t *buf_p; /* out */
- vm_size_t *size_p; /* out */
-{
- register
- struct minix_super_block *fs;
- vm_offset_t off;
- register minix_daddr_t file_block;
- minix_daddr_t disk_block;
- int rc;
- vm_offset_t block_size;
-
- if (offset >= fp->i_ic.i_size)
- return (FS_NOT_IN_FILE);
-
- fs = fp->f_fs;
-
- off = minix_blkoff(fs, offset);
- file_block = minix_lblkno(fs, offset);
- block_size = minix_blksize(fs, fp, file_block);
-
- if (((daddr_t) file_block) != fp->f_buf_blkno) {
- rc = block_map(fp, file_block, &disk_block);
- if (rc != 0)
- return (rc);
-
- if (fp->f_buf)
- (void)vm_deallocate(mach_task_self(),
- fp->f_buf,
- fp->f_buf_size);
-
- if (disk_block == 0) {
- (void)vm_allocate(mach_task_self(),
- &fp->f_buf,
- block_size,
- TRUE);
- fp->f_buf_size = block_size;
- }
- else {
- rc = device_read(fp->f_dev,
- 0,
- (recnum_t) minix_fsbtodb(fs, disk_block),
- (int) block_size,
- (char **) &fp->f_buf,
- (mach_msg_type_number_t *)&fp->f_buf_size);
- }
- if (rc)
- return (rc);
-
- fp->f_buf_blkno = (daddr_t) file_block;
- }
-
- /*
- * Return address of byte in buffer corresponding to
- * offset, and size of remainder of buffer after that
- * byte.
- */
- *buf_p = fp->f_buf + off;
- *size_p = block_size - off;
-
- /*
- * But truncate buffer at end of file.
- */
- if (*size_p > fp->i_ic.i_size - offset)
- *size_p = fp->i_ic.i_size - offset;
-
- return (0);
-}
-
-/*
- * Search a directory for a name and return its
- * i_number.
- */
-static int
-search_directory(name, fp, inumber_p)
- char * name;
- register struct file *fp;
- ino_t *inumber_p; /* out */
-{
- vm_offset_t buf;
- vm_size_t buf_size;
- vm_offset_t offset;
- register struct minix_directory_entry *dp;
- int length;
- kern_return_t rc;
- char tmp_name[15];
-
- length = strlen(name);
-
- offset = 0;
- while (offset < fp->i_ic.i_size) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc != KERN_SUCCESS)
- return (rc);
-
- dp = (struct minix_directory_entry *)buf;
- if (dp->inode != 0) {
- strncpy (tmp_name, dp->name, MINIX_NAME_LEN /* XXX it's 14 */);
- tmp_name[MINIX_NAME_LEN] = '\0';
- if (strlen(tmp_name) == length &&
- !strcmp(name, tmp_name))
- {
- /* found entry */
- *inumber_p = dp->inode;
- return (0);
- }
- }
- offset += 16 /* MINIX dir. entry length - MINIX FS Ver. 1. */;
- }
- return (FS_NO_ENTRY);
-}
-
-static int
-read_fs(dev, fsp)
- mach_port_t dev;
- struct minix_super_block **fsp;
-{
- register
- struct minix_super_block *fs;
- vm_offset_t buf;
- mach_msg_type_number_t buf_size;
- int error;
-
- /*
- * Read the super block
- */
- error = device_read(dev, 0, (recnum_t) MINIX_SBLOCK, MINIX_SBSIZE,
- (char **) &buf, &buf_size);
- if (error)
- return (error);
-
- /*
- * Check the superblock
- */
- fs = (struct minix_super_block *)buf;
- if (fs->s_magic != MINIX_SUPER_MAGIC) {
- (void) vm_deallocate(mach_task_self(), buf, buf_size);
- return (FS_INVALID_FS);
- }
-
-
- *fsp = fs;
-
- return 0;
-}
-
-static int
-mount_fs(fp)
- register struct file *fp;
-{
- register struct minix_super_block *fs;
- int error;
-
- error = read_fs(fp->f_dev, &fp->f_fs);
- if (error)
- return (error);
-
- fs = fp->f_fs;
-
- /*
- * Calculate indirect block levels.
- */
- {
- register int mult;
- register int level;
-
- mult = 1;
- for (level = 0; level < MINIX_NIADDR; level++) {
- mult *= MINIX_NINDIR(fs);
- fp->f_nindir[level] = mult;
- }
- }
-
- return (0);
-}
-
-static void
-unmount_fs(fp)
- register struct file *fp;
-{
- if (file_is_structured(fp)) {
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fp->f_fs,
- MINIX_SBSIZE);
- fp->f_fs = 0;
- }
-}
-
-/*
- * Open a file.
- */
-int
-minix_open_file(master_device_port, path, fp)
- mach_port_t master_device_port;
- char * path;
- struct file *fp;
-{
-#define RETURN(code) { rc = (code); goto exit; }
-
- register char *cp, *component;
- register int c; /* char */
- register int rc;
- ino_t inumber, parent_inumber;
- int nlinks = 0;
-
- char namebuf[MAXPATHLEN+1];
-
- if (path == 0 || *path == '\0') {
- return FS_NO_ENTRY;
- }
-
- /*
- * Copy name into buffer to allow modifying it.
- */
- strcpy(namebuf, path);
-
- /*
- * Look for '/dev/xxx' at start of path, for
- * root device.
- */
- if (!strprefix(namebuf, "/dev/")) {
- printf("no device name\n");
- return FS_NO_ENTRY;
- }
-
- cp = namebuf + 5; /* device */
- component = cp;
- while ((c = *cp) != '\0' && c != '/') {
- cp++;
- }
- *cp = '\0';
-
- bzero (fp, sizeof (struct file));
-
- rc = device_open(master_device_port,
- D_READ|D_WRITE,
- component,
- &fp->f_dev);
- if (rc)
- return rc;
-
- if (c == 0) {
- fp->f_fs = 0;
- goto out_ok;
- }
-
- *cp = c;
-
- rc = mount_fs(fp);
- if (rc)
- return rc;
-
- inumber = (ino_t) MINIX_ROOTINO;
- if ((rc = read_inode(inumber, fp)) != 0) {
- printf("can't read root inode\n");
- goto exit;
- }
-
- while (*cp) {
-
- /*
- * Check that current node is a directory.
- */
- if ((fp->i_ic.i_mode & IFMT) != IFDIR)
- RETURN (FS_NOT_DIRECTORY);
-
- /*
- * Remove extra separators
- */
- while (*cp == '/')
- cp++;
-
- /*
- * Get next component of path name.
- */
- component = cp;
- {
- register int len = 0;
-
- while ((c = *cp) != '\0' && c != '/') {
- if (len++ > MINIX_MAXNAMLEN)
- RETURN (FS_NAME_TOO_LONG);
- if (c & 0200)
- RETURN (FS_INVALID_PARAMETER);
- cp++;
- }
- *cp = 0;
- }
-
- /*
- * Look up component in current directory.
- * Save directory inumber in case we find a
- * symbolic link.
- */
- parent_inumber = inumber;
- rc = search_directory(component, fp, &inumber);
- if (rc) {
- printf("%s: not found\n", path);
- goto exit;
- }
- *cp = c;
-
- /*
- * Open next component.
- */
- if ((rc = read_inode(inumber, fp)) != 0)
- goto exit;
-
- /*
- * Check for symbolic link.
- */
- }
-
- /*
- * Found terminal component.
- */
- out_ok:
- mutex_init(&fp->f_lock);
- return 0;
-
- /*
- * At error exit, close file to free storage.
- */
- exit:
- minix_close_file(fp);
- return rc;
-}
-
-/*
- * Close file - free all storage used.
- */
-void
-minix_close_file(fp)
- register struct file *fp;
-{
- register int i;
-
- /*
- * Free the disk super-block.
- */
- unmount_fs(fp);
-
- /*
- * Free the inode and data buffers.
- */
- free_file_buffers(fp);
-}
-
-int
-minix_file_is_directory(struct file *fp)
-{
- return (fp->i_ic.i_mode & IFMT) == IFDIR;
-}
-
-int
-minix_file_is_regular(struct file *fp)
-{
- return (fp->i_ic.i_mode & IFMT) == IFREG;
-}
-
-/*
- * Copy a portion of a file into kernel memory.
- * Cross block boundaries when necessary.
- */
-int
-minix_read_file(fp, offset, start, size, resid)
- register struct file *fp;
- vm_offset_t offset;
- vm_offset_t start;
- vm_size_t size;
- vm_size_t *resid; /* out */
-{
- int rc;
- register vm_size_t csize;
- vm_offset_t buf;
- vm_size_t buf_size;
-
- while (size != 0) {
- rc = buf_read_file(fp, offset, &buf, &buf_size);
- if (rc)
- return (rc);
-
- csize = size;
- if (csize > buf_size)
- csize = buf_size;
- if (csize == 0)
- break;
-
- bcopy((char *)buf, (char *)start, csize);
-
- offset += csize;
- start += csize;
- size -= csize;
- }
- if (resid)
- *resid = size;
-
- return (0);
-}
-
-/* simple utility: only works for 2^n */
-static int
-log2(n)
- register unsigned int n;
-{
- register int i = 0;
-
- while ((n & 1) == 0) {
- i++;
- n >>= 1;
- }
- return i;
-}
-
-/*
- * Make an empty file_direct for a device.
- */
-int
-minix_open_file_direct(dev, fdp, is_structured)
- mach_port_t dev;
- register struct file_direct *fdp;
- boolean_t is_structured;
-{
- struct minix_super_block *fs;
- int rc;
-
- if (!is_structured) {
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_bsize = vm_page_size;
- fdp->fd_bshift = log2(vm_page_size);
- fdp->fd_fsbtodb = 0; /* later */
- fdp->fd_size = 0; /* later */
- return 0;
- }
-
- rc = read_fs(dev, &fs);
- if (rc)
- return rc;
-
- fdp->fd_dev = dev;
- fdp->fd_blocks = (daddr_t *) 0;
- fdp->fd_size = 0;
- fdp->fd_bsize = MINIX_BLOCK_SIZE;
- fdp->fd_bshift = log2(fdp->fd_bsize);
- fdp->fd_fsbtodb = log2(fdp->fd_bsize / DEV_BSIZE);
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fs,
- MINIX_SBSIZE);
-
- return 0;
-}
-
-/*
- * Add blocks from a file to a file_direct.
- */
-int
-minix_add_file_direct(fdp, fp)
- register struct file_direct *fdp;
- register struct file *fp;
-{
- register struct minix_super_block *fs;
- long num_blocks, i;
- vm_offset_t buffer;
- vm_size_t size;
- int rc;
-
- /* the file must be on the same device */
-
- if (fdp->fd_dev != fp->f_dev)
- return FS_INVALID_FS;
-
- if (!file_is_structured(fp)) {
- int result[DEV_GET_SIZE_COUNT];
- natural_t count;
-
- count = DEV_GET_SIZE_COUNT;
- rc = device_get_status( fdp->fd_dev, DEV_GET_SIZE,
- result, &count);
- if (rc)
- return rc;
- fdp->fd_size = result[DEV_GET_SIZE_DEVICE_SIZE] >> fdp->fd_bshift;
- fdp->fd_fsbtodb = log2(fdp->fd_bsize/result[DEV_GET_SIZE_RECORD_SIZE]);
- return 0;
- }
-
- /* it must hold a file system */
-
- fs = fp->f_fs;
-/*
- if (fdp->fd_bsize != fs->fs_bsize ||
- fdp->fd_fsbtodb != fs->fs_fsbtodb)
-*/
- if (fdp->fd_bsize != MINIX_BLOCK_SIZE)
- return FS_INVALID_FS;
-
- /* calculate number of blocks in the file, ignoring fragments */
-
- num_blocks = minix_lblkno(fs, fp->i_ic.i_size);
-
- /* allocate memory for a bigger array */
-
- size = (num_blocks + fdp->fd_size) * sizeof(minix_daddr_t);
- rc = vm_allocate(mach_task_self(), &buffer, size, TRUE);
- if (rc != KERN_SUCCESS)
- return rc;
-
- /* lookup new block addresses */
-
- for (i = 0; i < num_blocks; i++) {
- minix_daddr_t disk_block;
-
- rc = block_map(fp, (minix_daddr_t) i, &disk_block);
- if (rc != 0) {
- (void) vm_deallocate(mach_task_self(), buffer, size);
- return rc;
- }
-
- ((minix_daddr_t *) buffer)[fdp->fd_size + i] = disk_block;
- }
-
- /* copy old addresses and install the new array */
-
- if (fdp->fd_blocks != 0) {
- bcopy((char *) fdp->fd_blocks, (char *) buffer,
- fdp->fd_size * sizeof(minix_daddr_t));
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(minix_daddr_t)));
- }
- fdp->fd_blocks = (daddr_t *) buffer;
- fdp->fd_size += num_blocks;
-
- /* deallocate cached blocks */
-
- free_file_buffers(fp);
-
- return 0;
-}
-
-int
-minix_remove_file_direct(fdp)
- struct file_direct *fdp;
-{
- if (fdp->fd_blocks)
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) fdp->fd_blocks,
- (vm_size_t) (fdp->fd_size * sizeof(minix_daddr_t)));
- fdp->fd_blocks = 0; /* sanity */
- /* xxx should lose a ref to fdp->fd_dev here (and elsewhere) xxx */
-}
diff --git a/serverboot/minix_fs.h b/serverboot/minix_fs.h
deleted file mode 100644
index 678f3a0d..00000000
--- a/serverboot/minix_fs.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * minix_fs.h
- * stolen (and slightly extended by csb) from the Linux distribution
- * Copyright (C) 1994 Linus Torvalds
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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.
- */
-
-#ifndef _LINUX_MINIX_FS_H
-#define _LINUX_MINIX_FS_H
-
-/*
- * The minix filesystem constants/structures
- */
-
-/*
- * Thanks to Kees J Bot for sending me the definitions of the new
- * minix filesystem (aka V2) with bigger inodes and 32-bit block
- * pointers. It's not actually implemented yet, but I'll look into
- * it.
- */
-
-#define MINIX_ROOT_INO 1
-
-/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
-#define MINIX_LINK_MAX 250
-
-#define MINIX_I_MAP_SLOTS 8
-#define MINIX_Z_MAP_SLOTS 8
-#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
-#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
-#define NEW_MINIX_SUPER_MAGIC 0x2468 /* minix V2 - not implemented */
-#define MINIX_VALID_FS 0x0001 /* Clean fs. */
-#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
-
-#define MINIX_INODES_PER_BLOCK ((MINIX_BLOCK_SIZE)/(sizeof (struct minix_inode)))
-
-struct minix_inode {
- unsigned short i_mode;
- unsigned short i_uid;
- unsigned long i_size;
- unsigned long i_time;
- unsigned char i_gid;
- unsigned char i_nlinks;
- unsigned short i_zone[9];
-};
-
-/*
- * The new minix inode has all the time entries, as well as
- * long block numbers and a third indirect block (7+1+1+1
- * instead of 7+1+1). Also, some previously 8-bit values are
- * now 16-bit. The inode is now 64 bytes instead of 32.
- */
-struct new_minix_inode {
- unsigned short i_mode;
- unsigned short i_nlinks;
- unsigned short i_uid;
- unsigned short i_gid;
- unsigned long i_size;
- unsigned long i_atime;
- unsigned long i_mtime;
- unsigned long i_ctime;
- unsigned long i_zone[10];
-};
-
-/*
- * minix super-block data on disk
- */
-struct minix_super_block {
- unsigned short s_ninodes;
- unsigned short s_nzones;
- unsigned short s_imap_blocks;
- unsigned short s_zmap_blocks;
- unsigned short s_firstdatazone;
- unsigned short s_log_zone_size;
- unsigned long s_max_size;
- unsigned short s_magic;
- unsigned short s_state;
-};
-
-struct minix_dir_entry {
- unsigned short inode;
- char name[0];
-};
-
-struct minix_directory_entry {
- unsigned short inode;
- char name[14];
-};
-
-#define MINIX_NIADDR 2
-
-typedef unsigned short minix_daddr_t;
-
-#endif
diff --git a/serverboot/minix_super.h b/serverboot/minix_super.h
deleted file mode 100644
index 144cf064..00000000
--- a/serverboot/minix_super.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * minix_super.h
- * stolen from the Linux distribution
- * Copyright (C) 1994 Linus Torvalds
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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.
- */
-
-#ifndef _LINUX_MINIX_FS_H
-#define _LINUX_MINIX_FS_H
-
-struct minix_super_block {
- unsigned short s_ninodes;
- unsigned short s_nzones;
- unsigned short s_imap_blocks;
- unsigned short s_zmap_blocks;
- unsigned short s_firstdatazone;
- unsigned short s_log_zone_size;
- unsigned long s_max_size;
- unsigned short s_magic;
- unsigned short s_state;
-};
-
-
-struct minix_inode {
- unsigned short i_mode;
- unsigned short i_uid;
- unsigned long i_size;
- unsigned long i_time;
- unsigned char i_gid;
- unsigned char i_nlinks;
- unsigned short i_zone[9];
-};
-
-#define MINIX_NIADDR 2
-
-#endif
diff --git a/serverboot/panic.c b/serverboot/panic.c
deleted file mode 100644
index 25924099..00000000
--- a/serverboot/panic.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-#include <mach/port.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <errno.h>
-
-static mach_port_t master_host_port;
-
-panic_init(port)
- mach_port_t port;
-{
- master_host_port = port;
-}
-
-/*VARARGS1*/
-panic (const char *s, ...)
-{
- va_list listp;
-
- clearerr (stdout);
- printf("%s: panic: ", program_invocation_name);
- va_start(listp, s);
- vprintf(s, listp);
- va_end(listp);
- printf("\n");
-
-#ifdef PC532
- { int l; for (l=0;l < 1000000;l++) ; }
-#endif /* PC532 */
-#define RB_DEBUGGER 0x1000 /* enter debugger NOW */
- (void) host_reboot(master_host_port, RB_DEBUGGER);
- for (;;);
-}
diff --git a/serverboot/queue.h b/serverboot/queue.h
deleted file mode 100644
index 00619174..00000000
--- a/serverboot/queue.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon rights
- * to redistribute these changes.
- */
-/*
- * File: queue.h
- * Author: Avadis Tevanian, Jr.
- * Date: 1985
- *
- * Type definitions for generic queues.
- *
- */
-
-#ifndef _QUEUE_H_
-#define _QUEUE_H_
-
-/*
- * Queue of abstract objects. Queue is maintained
- * within that object.
- *
- * Supports fast removal from within the queue.
- *
- * How to declare a queue of elements of type "foo_t":
- * In the "*foo_t" type, you must have a field of
- * type "queue_chain_t" to hold together this queue.
- * There may be more than one chain through a
- * "foo_t", for use by different queues.
- *
- * Declare the queue as a "queue_t" type.
- *
- * Elements of the queue (of type "foo_t", that is)
- * are referred to by reference, and cast to type
- * "queue_entry_t" within this module.
- */
-
-/*
- * A generic doubly-linked list (queue).
- */
-
-struct queue_entry {
- struct queue_entry *next; /* next element */
- struct queue_entry *prev; /* previous element */
-};
-
-typedef struct queue_entry *queue_t;
-typedef struct queue_entry queue_head_t;
-typedef struct queue_entry queue_chain_t;
-typedef struct queue_entry *queue_entry_t;
-
-/*
- * Macro: queue_init
- * Function:
- * Initialize the given queue.
- * Header:
- * void queue_init(q)
- * queue_t q; / * MODIFIED * /
- */
-#define queue_init(q) ((q)->next = (q)->prev = q)
-
-/*
- * Macro: queue_first
- * Function:
- * Returns the first entry in the queue,
- * Header:
- * queue_entry_t queue_first(q)
- * queue_t q; / * IN * /
- */
-#define queue_first(q) ((q)->next)
-
-/*
- * Macro: queue_next
- * Function:
- * Returns the entry after an item in the queue.
- * Header:
- * queue_entry_t queue_next(qc)
- * queue_t qc;
- */
-#define queue_next(qc) ((qc)->next)
-
-/*
- * Macro: queue_last
- * Function:
- * Returns the last entry in the queue.
- * Header:
- * queue_entry_t queue_last(q)
- * queue_t q; / * IN * /
- */
-#define queue_last(q) ((q)->prev)
-
-/*
- * Macro: queue_prev
- * Function:
- * Returns the entry before an item in the queue.
- * Header:
- * queue_entry_t queue_prev(qc)
- * queue_t qc;
- */
-#define queue_prev(qc) ((qc)->prev)
-
-/*
- * Macro: queue_end
- * Function:
- * Tests whether a new entry is really the end of
- * the queue.
- * Header:
- * boolean_t queue_end(q, qe)
- * queue_t q;
- * queue_entry_t qe;
- */
-#define queue_end(q, qe) ((q) == (qe))
-
-/*
- * Macro: queue_empty
- * Function:
- * Tests whether a queue is empty.
- * Header:
- * boolean_t queue_empty(q)
- * queue_t q;
- */
-#define queue_empty(q) queue_end((q), queue_first(q))
-
-
-/*----------------------------------------------------------------*/
-/*
- * Macros that operate on generic structures. The queue
- * chain may be at any location within the structure, and there
- * may be more than one chain.
- */
-
-/*
- * Macro: queue_enter
- * Function:
- * Insert a new element at the tail of the queue.
- * Header:
- * void queue_enter(q, elt, type, field)
- * queue_t q;
- * <type> elt;
- * <type> is what's in our queue
- * <field> is the chain field in (*<type>)
- */
-#define queue_enter(head, elt, type, field) \
-{ \
- register queue_entry_t prev; \
- \
- prev = (head)->prev; \
- if ((head) == prev) { \
- (head)->next = (queue_entry_t) (elt); \
- } \
- else { \
- ((type)prev)->field.next = (queue_entry_t)(elt);\
- } \
- (elt)->field.prev = prev; \
- (elt)->field.next = head; \
- (head)->prev = (queue_entry_t) elt; \
-}
-
-/*
- * Macro: queue_enter_first
- * Function:
- * Insert a new element at the head of the queue.
- * Header:
- * void queue_enter_first(q, elt, type, field)
- * queue_t q;
- * <type> elt;
- * <type> is what's in our queue
- * <field> is the chain field in (*<type>)
- */
-#define queue_enter_first(head, elt, type, field) \
-{ \
- register queue_entry_t next; \
- \
- next = (head)->next; \
- if ((head) == next) { \
- (head)->prev = (queue_entry_t) (elt); \
- } \
- else { \
- ((type)next)->field.prev = (queue_entry_t)(elt);\
- } \
- (elt)->field.next = next; \
- (elt)->field.prev = head; \
- (head)->next = (queue_entry_t) elt; \
-}
-
-/*
- * Macro: queue_field [internal use only]
- * Function:
- * Find the queue_chain_t (or queue_t) for the
- * given element (thing) in the given queue (head)
- */
-#define queue_field(head, thing, type, field) \
- (((head) == (thing)) ? (head) : &((type)(thing))->field)
-
-/*
- * Macro: queue_remove
- * Function:
- * Remove an arbitrary item from the queue.
- * Header:
- * void queue_remove(q, qe, type, field)
- * arguments as in queue_enter
- */
-#define queue_remove(head, elt, type, field) \
-{ \
- register queue_entry_t next, prev; \
- \
- next = (elt)->field.next; \
- prev = (elt)->field.prev; \
- \
- if ((head) == next) \
- (head)->prev = prev; \
- else \
- ((type)next)->field.prev = prev; \
- \
- if ((head) == prev) \
- (head)->next = next; \
- else \
- ((type)prev)->field.next = next; \
-}
-
-/*
- * Macro: queue_remove_first
- * Function:
- * Remove and return the entry at the head of
- * the queue.
- * Header:
- * queue_remove_first(head, entry, type, field)
- * entry is returned by reference
- */
-#define queue_remove_first(head, entry, type, field) \
-{ \
- register queue_entry_t next; \
- \
- (entry) = (type) ((head)->next); \
- next = (entry)->field.next; \
- \
- if ((head) == next) \
- (head)->prev = (head); \
- else \
- ((type)(next))->field.prev = (head); \
- (head)->next = next; \
-}
-
-/*
- * Macro: queue_remove_last
- * Function:
- * Remove and return the entry at the tail of
- * the queue.
- * Header:
- * queue_remove_last(head, entry, type, field)
- * entry is returned by reference
- */
-#define queue_remove_last(head, entry, type, field) \
-{ \
- register queue_entry_t prev; \
- \
- (entry) = (type) ((head)->prev); \
- prev = (entry)->field.prev; \
- \
- if ((head) == prev) \
- (head)->next = (head); \
- else \
- ((type)(prev))->field.next = (head); \
- (head)->prev = prev; \
-}
-
-/*
- * Macro: queue_assign
- */
-#define queue_assign(to, from, type, field) \
-{ \
- ((type)((from)->prev))->field.next = (to); \
- ((type)((from)->next))->field.prev = (to); \
- *to = *from; \
-}
-
-/*
- * Macro: queue_iterate
- * Function:
- * iterate over each item in the queue.
- * Generates a 'for' loop, setting elt to
- * each item in turn (by reference).
- * Header:
- * queue_iterate(q, elt, type, field)
- * queue_t q;
- * <type> elt;
- * <type> is what's in our queue
- * <field> is the chain field in (*<type>)
- */
-#define queue_iterate(head, elt, type, field) \
- for ((elt) = (type) queue_first(head); \
- !queue_end((head), (queue_entry_t)(elt)); \
- (elt) = (type) queue_next(&(elt)->field))
-
-
-
-#endif /* _QUEUE_H_ */
diff --git a/serverboot/strfcns.c b/serverboot/strfcns.c
deleted file mode 100644
index cbead7e4..00000000
--- a/serverboot/strfcns.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Character subroutines
- */
-
-#include <stdarg.h>
-
-#define EXPORT_BOOLEAN
-#include <mach/boolean.h>
-
-/*
- * Concatenate a group of strings together into a buffer.
- * Return a pointer to the trailing '\0' character in
- * the result string.
- * The list of strings ends with a '(char *)0'.
- */
-/*VARARGS1*/
-char *
-strbuild(char *dest, ...)
-{
- va_list argptr;
- register char * src;
- register int c;
-
- va_start(argptr, dest);
- while ((src = va_arg(argptr, char *)) != (char *)0) {
-
- while ((c = *src++) != '\0')
- *dest++ = c;
- }
- *dest = '\0';
- va_end(argptr);
- return (dest);
-}
-
-/*
- * Return TRUE if string 2 is a prefix of string 1.
- */
-boolean_t
-strprefix(s1, s2)
- register char *s1, *s2;
-{
- register int c;
-
- while ((c = *s2++) != '\0') {
- if (c != *s1++)
- return (FALSE);
- }
- return (TRUE);
-}
diff --git a/serverboot/wiring.c b/serverboot/wiring.c
deleted file mode 100644
index 585a3075..00000000
--- a/serverboot/wiring.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Package to wire current task's memory.
- */
-#include <mach.h>
-#include <mach_init.h>
-#include <mach/machine/vm_param.h>
-
-mach_port_t this_task; /* our task */
-mach_port_t priv_host_port = MACH_PORT_NULL;
- /* the privileged host port */
-
-void
-wire_setup(host_priv)
- mach_port_t host_priv;
-{
- priv_host_port = host_priv;
- this_task = mach_task_self();
-}
-
-void
-wire_memory(start, size, prot)
- vm_address_t start;
- vm_size_t size;
- vm_prot_t prot;
-{
- kern_return_t kr;
-
- if (priv_host_port == MACH_PORT_NULL)
- return;
-
- kr = vm_wire(priv_host_port,
- this_task,
- start, size, prot);
- if (kr != KERN_SUCCESS)
- panic("mem_wire: %d", kr);
-}
-
-void
-wire_thread()
-{
- kern_return_t kr;
-
- if (priv_host_port == MACH_PORT_NULL)
- return;
-
- kr = thread_wire(priv_host_port,
- mach_thread_self(),
- TRUE);
- if (kr != KERN_SUCCESS)
- panic("wire_thread: %d", kr);
-}
-
-void
-wire_all_memory()
-{
- register kern_return_t kr;
- vm_offset_t address;
- vm_size_t size;
- vm_prot_t protection;
- vm_prot_t max_protection;
- vm_inherit_t inheritance;
- boolean_t is_shared;
- memory_object_name_t object;
- vm_offset_t offset;
-
- if (priv_host_port == MACH_PORT_NULL)
- return;
-
- /* iterate thru all regions, wiring */
- address = 0;
- while (
- (kr = vm_region(this_task, &address,
- &size,
- &protection,
- &max_protection,
- &inheritance,
- &is_shared,
- &object,
- &offset))
- == KERN_SUCCESS)
- {
- if (MACH_PORT_VALID(object))
- (void) mach_port_deallocate(this_task, object);
- if (protection != VM_PROT_NONE)
- {
- /* The VM system cannot cope with a COW fault on another
- unrelated virtual copy happening later when we have
- wired down the original page. So we must touch all our
- pages before wiring to make sure that only we will ever
- use them. */
- void *page;
- if (!(protection & VM_PROT_WRITE))
- {
- kr = vm_protect(this_task, address, size,
- 0, max_protection);
- }
- for (page = (void *) address;
- page < (void *) (address + size);
- page += vm_page_size)
- *(volatile int *) page = *(int *) page;
-
- wire_memory(address, size, protection);
-
- if (!(protection & VM_PROT_WRITE))
- {
- kr = vm_protect(this_task, address, size,
- 0, protection);
- }
- }
- address += size;
- }
-}
-
-/*
- * Alias for vm_allocate to return wired memory.
- */
-kern_return_t
-vm_allocate(task, address, size, anywhere)
- task_t task;
- vm_address_t *address;
- vm_size_t size;
- boolean_t anywhere;
-{
- kern_return_t kr;
-
- if (anywhere)
- *address = VM_MIN_ADDRESS;
- kr = vm_map(task,
- address, size, (vm_offset_t) 0, anywhere,
- MEMORY_OBJECT_NULL, (vm_offset_t)0, FALSE,
- VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
- if (kr != KERN_SUCCESS)
- return kr;
-
- if (task == this_task)
- (void) vm_wire(priv_host_port, task, *address, size,
- VM_PROT_DEFAULT);
- return KERN_SUCCESS;
-}
-
-/* Other versions of this function in libc... */
-kern_return_t
-__vm_allocate (task, address, size, anywhere)
- task_t task;
- vm_address_t *address;
- vm_size_t size;
- boolean_t anywhere;
-{
- return vm_allocate (task, address, size, anywhere);
-}
diff --git a/serverboot/wiring.h b/serverboot/wiring.h
deleted file mode 100644
index b5f8e53f..00000000
--- a/serverboot/wiring.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon the
- * rights to redistribute these changes.
- */
-/*
- * Package to wire current task's memory.
- */
-#include <mach.h>
-#include <mach_init.h>
-
-extern void wire_setup(/* mach_port_t host_priv */);
-extern void wire_memory(/* vm_address_t, vm_size_t, vm_prot_t */);
-extern void wire_thread();
-extern void wire_all_memory();