diff options
author | neal <neal> | 2008-02-11 16:16:20 +0000 |
---|---|---|
committer | neal <neal> | 2008-02-11 16:16:20 +0000 |
commit | 17ff98d116f5ca83a24d23b7a2e7ac3c54f3b4ae (patch) | |
tree | f0d680358d7275e38e9dde935e3472fda8af9bc1 /hieronymus/hieronymus.c | |
parent | a778792e357f2c8ee711139f19c9af59055f8154 (diff) |
hieronymus/
2008-02-11 Neal H. Walfield <neal@gnu.org>
* ChangeLog: New file.
* Makefile.am: Likewise.
* module.S: Likewise.
* hieronymus.c: Likewise.
/
2008-02-11 Neal H. Walfield <neal@gnu.org>
* configure.ac: Generate hieronymus/Makefile.
* Makefile.am (SUBDIRS): Add hieronymus.
* README: Update boot instructions.
Diffstat (limited to 'hieronymus/hieronymus.c')
-rw-r--r-- | hieronymus/hieronymus.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/hieronymus/hieronymus.c b/hieronymus/hieronymus.c new file mode 100644 index 0000000..7991bfa --- /dev/null +++ b/hieronymus/hieronymus.c @@ -0,0 +1,155 @@ +/* hieronymus.c - initrd implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + 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 3 of the + License, or (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <hurd/activity.h> +#include <hurd/folio.h> +#include <hurd/storage.h> +#include <hurd/capalloc.h> +#include <hurd/thread.h> +#include <hurd/as.h> +#include <hurd/rm.h> +#include <hurd/ihash.h> +#include <process-spawn.h> + +#include <stdio.h> +#include <string.h> + +#define STRINGIFY_(id) #id +#define STRINGIFY(id) STRINGIFY_(id) + +struct module +{ + const char *name; + int priority; + int share; + const char *commandline; + char *start; + char *end; +}; + +#include "modules.h" + +/* Initialized by the machine-specific startup-code. */ +extern struct hurd_startup_data *__hurd_startup_data; + +#define root_activity __hurd_startup_data->activity + +/* Allocate a new activity out of our storage. */ +static struct storage +activity_alloc (struct activity_policy policy) +{ + struct storage storage + = storage_alloc (root_activity, cap_activity_control, STORAGE_LONG_LIVED, + ADDR_VOID); + if (! storage.cap) + panic ("Failed to allocate storage."); + + struct activity_policy out; + error_t err = rm_activity_policy (storage.addr, + ACTIVITY_POLICY_STORAGE_SET + | ACTIVITY_POLICY_CHILD_REL_SET, + policy, &out); + if (err) + panic ("Failed to set policy on activity"); + + return storage; +} + +int +main (int argc, char *argv[]) +{ + extern int output_debug; + output_debug = 3; + + // extern int __pthread_lock_trace; + // __pthread_lock_trace = 0; + + int count = sizeof (modules) / sizeof (modules[0]); + + struct storage activities[count]; + addr_t thread[count]; + + /* Load modules. */ + int i; + for (i = 0; i < count; i ++) + { + activities[i] = activity_alloc (ACTIVITY_POLICY_VOID); + + const char *argv[] = { modules[i].name, modules[i].commandline, NULL }; + const char *env[] = { NULL }; + thread[i] = process_spawn (activities[i].addr, + modules[i].start, modules[i].end, + argv, env, false); + + debug (0, ""); + + /* Free the memory used by the module's binary. */ + /* XXX: This doesn't free folios or note pages that may be + partially freed. The latter is important because a page may + be used by two modules and after the second module is loaded, + it could be freed. */ + int count = 0; + int j; + for (j = 0; j < __hurd_startup_data->desc_count; j ++) + { + struct hurd_object_desc *desc = &__hurd_startup_data->descs[j]; + + if ((desc->type == cap_page || desc->type == cap_rpage) + && ! ADDR_IS_VOID (desc->storage) + && addr_depth (desc->object) == ADDR_BITS - PAGESIZE_LOG2 + && (uintptr_t) modules[i].start <= addr_prefix (desc->object) + && (addr_prefix (desc->object) + PAGESIZE - 1 + <= (uintptr_t) modules[i].end)) + { + debug (5, "Freeing " ADDR_FMT "(" ADDR_FMT "), a %s", + ADDR_PRINTF (desc->object), ADDR_PRINTF (desc->storage), + cap_type_string (desc->type)); + count ++; + storage_free (desc->storage, true); + } + } + debug (0, "Freed %d pages", count); + + thread_start (thread[i]); + } + + /* Wait for all activities to die. */ + for (i = 0; i < count; i ++) + { + uintptr_t rt = -1; + rm_thread_wait_object_destroyed (root_activity, + thread[i], &rt); + + addr_t folio = addr_chop (activities[i].addr, FOLIO_OBJECTS_LOG2); + int index = addr_extract (activities[i].addr, FOLIO_OBJECTS_LOG2); + + error_t err; + err = rm_folio_object_alloc (ADDR_VOID, folio, index, + cap_void, OBJECT_POLICY_VOID, + (uintptr_t) rt, + ADDR_VOID, ADDR_VOID); + if (err) + debug (0, "deallocating object: %d", err); + + debug (0, "%s exited with %d", modules[i].name, (int) rt); + } + + return 0; +} |