2003-01-06 Yoshinori K. Okuji <okuji@enbug.org>
* util/i386/pc/pupa-setup.c: Include pupa/machine/kernel.h. (setup): Configure the installed partition information and the dl prefix. * loader/i386/pc/chainloader.c (my_mod): New variable. (pupa_chainloader_unload): New function. (pupa_rescue_cmd_chainloader): Refer itself. (PUPA_MOD_INIT): Save its own module in MY_MOD. * kern/i386/pc/startup.S (install_partition): Removed. (version_string): Likewise. (config_file): Likewise. (pupa_install_dos_part): New variable. (pupa_install_bsd_part): Likewise. (pupa_prefix): Likewise. (pupa_chainloader_real_boot): Call pupa_dl_unload_all. * kern/i386/pc/init.c: Include pupa/machine/kernel.h, pupa/dl.h and pupa/misc.h. (make_install_device): New function. (pupa_machine_init): Set the dl prefix. * kern/rescue.c: Include pupa/rescue.h and pupa/dl.h. (buf): Renamed to ... (linebuf): ... this. (pupa_rescue_cmd_prefix): New function. (pupa_rescue_cmd_insmod): Likewise. (pupa_rescue_cmd_rmmod): Likewise. (pupa_rescue_cmd_lsmod): Likewise. (pupa_enter_rescue_mode): Register new commands: prefix, insmod, rmmod and lsmod. * kern/mm.c (pupa_memalign): If failed even after invalidating disk caches, unload unneeded modules and retry. * kern/misc.c (pupa_memmove): New function. (pupa_memcpy): Removed. (pupa_strcpy): New function. (pupa_itoa): Made static. * kern/dl.c (pupa_dl_iterate): New function. (pupa_dl_ref): Likewise. (pupa_dl_unref): Likewise. (pupa_dl_unload): Return if succeeded or not. (pupa_dl_unload_unneeded): New function. (pupa_dl_unload_all): Likewise. (pupa_dl_init): Renamed to ... (pupa_dl_set_prefix): ... this. (pupa_dl_get_prefix): New function. * include/pupa/i386/pc/kernel.h: Include pupa/types.h. (PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): New macro. (PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise. (PUPA_KERNEL_MACHINE_PREFIX): Likewise. (pupa_install_dos_part): Declared. (pupa_install_bsd_part): Likewise. (pupa_prefix): Likewise. (pupa_boot_drive): Likewise. * include/pupa/types.h: Fix a typo. * include/pupa/misc.h (pupa_memcpy): New macro. Just an alias to pupa_memmove. (pupa_memmove): Declared. (pupa_strcpy): Likewise. * include/pupa/dl.h (PUPA_MOD_INIT): Change the prototype. Now pupa_mod_init takes one argument, its own module. (pupa_dl_unload_unneeded): Declared. (pupa_dl_unload_all): Likewise. (pupa_dl_ref): Likewise. (pupa_dl_unref): Likewise. (pupa_dl_iterate): Likewise. (pupa_dl_init): Renamed to ... (pupa_dl_set_prefix): ... this. (pupa_dl_get_prefix): Declared. * fs/fat.c [!PUPA_UTIL] (my_mod): New variable. (pupa_fat_dir) [!PUPA_UTIL]: Prevent the fat module from being unloaded. (pupa_fat_open) [!PUPA_UTIL]: Refer itself if succeeded. (pupa_fat_close) [!PUPA_UTIL]: Unrefer itself. * configure.ac (tmp_CFLAGS): Added -Wshadow, -Wpointer-arith, -Wmissing-prototypes, -Wundef and -Wstrict-prototypes.
This commit is contained in:
parent
012d7999fe
commit
a5ffe96617
17 changed files with 553 additions and 79 deletions
96
kern/dl.c
96
kern/dl.c
|
@ -109,6 +109,16 @@ pupa_dl_get (const char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pupa_dl_iterate (int (*hook) (pupa_dl_t mod))
|
||||
{
|
||||
pupa_dl_list_t l;
|
||||
|
||||
for (l = pupa_dl_head; l; l = l->next)
|
||||
if (hook (l->mod))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct pupa_symbol
|
||||
|
@ -345,9 +355,9 @@ pupa_dl_resolve_symbols (pupa_dl_t mod, Elf_Ehdr *e)
|
|||
return pupa_errno;
|
||||
|
||||
if (pupa_strcmp (name, "pupa_mod_init") == 0)
|
||||
mod->init = (void (*) ()) sym->st_value;
|
||||
mod->init = (void (*) (pupa_dl_t)) sym->st_value;
|
||||
else if (pupa_strcmp (name, "pupa_mod_fini") == 0)
|
||||
mod->fini = (void (*) ()) sym->st_value;
|
||||
mod->fini = (void (*) (void)) sym->st_value;
|
||||
break;
|
||||
|
||||
case STT_SECTION:
|
||||
|
@ -372,7 +382,7 @@ static void
|
|||
pupa_dl_call_init (pupa_dl_t mod)
|
||||
{
|
||||
if (mod->init)
|
||||
(mod->init) ();
|
||||
(mod->init) (mod);
|
||||
}
|
||||
|
||||
static pupa_err_t
|
||||
|
@ -428,6 +438,8 @@ pupa_dl_resolve_dependencies (pupa_dl_t mod, Elf_Ehdr *e)
|
|||
m = pupa_dl_load (name);
|
||||
if (! m)
|
||||
return pupa_errno;
|
||||
|
||||
pupa_dl_ref (m);
|
||||
|
||||
dep = (pupa_dl_dep_t) pupa_malloc (sizeof (*dep));
|
||||
if (! dep)
|
||||
|
@ -444,6 +456,24 @@ pupa_dl_resolve_dependencies (pupa_dl_t mod, Elf_Ehdr *e)
|
|||
return PUPA_ERR_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
pupa_dl_ref (pupa_dl_t mod)
|
||||
{
|
||||
return ++mod->ref_count;
|
||||
}
|
||||
|
||||
int
|
||||
pupa_dl_unref (pupa_dl_t mod)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = --mod->ref_count;
|
||||
if (ret <= 0)
|
||||
pupa_dl_unload (mod);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Load a module from core memory. */
|
||||
pupa_dl_t
|
||||
pupa_dl_load_core (void *addr, pupa_size_t size)
|
||||
|
@ -513,6 +543,7 @@ pupa_dl_load_file (const char *filename)
|
|||
goto failed;
|
||||
|
||||
mod = pupa_dl_load_core (core, size);
|
||||
mod->ref_count = 0;
|
||||
|
||||
failed:
|
||||
pupa_file_close (file);
|
||||
|
@ -532,10 +563,7 @@ pupa_dl_load (const char *name)
|
|||
|
||||
mod = pupa_dl_get (name);
|
||||
if (mod)
|
||||
{
|
||||
mod->ref_count++;
|
||||
return mod;
|
||||
}
|
||||
return mod;
|
||||
|
||||
if (! pupa_dl_dir)
|
||||
pupa_fatal ("module dir is not initialized yet");
|
||||
|
@ -559,14 +587,14 @@ pupa_dl_load (const char *name)
|
|||
}
|
||||
|
||||
/* Unload the module MOD. */
|
||||
void
|
||||
int
|
||||
pupa_dl_unload (pupa_dl_t mod)
|
||||
{
|
||||
pupa_dl_dep_t dep, depn;
|
||||
pupa_dl_segment_t seg, segn;
|
||||
|
||||
if (--mod->ref_count > 0)
|
||||
return;
|
||||
if (mod->ref_count > 0)
|
||||
return 0;
|
||||
|
||||
if (mod->fini)
|
||||
(mod->fini) ();
|
||||
|
@ -577,7 +605,7 @@ pupa_dl_unload (pupa_dl_t mod)
|
|||
for (dep = mod->dep; dep; dep = depn)
|
||||
{
|
||||
depn = dep->next;
|
||||
pupa_dl_unload (dep->mod);
|
||||
pupa_dl_unref (dep->mod);
|
||||
pupa_free (dep);
|
||||
}
|
||||
|
||||
|
@ -590,10 +618,54 @@ pupa_dl_unload (pupa_dl_t mod)
|
|||
|
||||
pupa_free (mod->name);
|
||||
pupa_free (mod);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Unload unneeded modules. */
|
||||
void
|
||||
pupa_dl_unload_unneeded (void)
|
||||
{
|
||||
/* Because pupa_dl_remove modifies the list of modules, this
|
||||
implementation is tricky. */
|
||||
pupa_dl_list_t p = pupa_dl_head;
|
||||
|
||||
while (p)
|
||||
{
|
||||
if (pupa_dl_unload (p->mod))
|
||||
{
|
||||
p = pupa_dl_head;
|
||||
continue;
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unload all modules. */
|
||||
void
|
||||
pupa_dl_unload_all (void)
|
||||
{
|
||||
while (pupa_dl_head)
|
||||
{
|
||||
pupa_dl_list_t p;
|
||||
|
||||
pupa_dl_unload_unneeded ();
|
||||
|
||||
/* Force to decrement the ref count. This will purge pre-loaded
|
||||
modules and manually inserted modules. */
|
||||
for (p = pupa_dl_head; p; p = p->next)
|
||||
p->mod->ref_count--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pupa_dl_init (const char *dir)
|
||||
pupa_dl_set_prefix (const char *dir)
|
||||
{
|
||||
pupa_dl_dir = (char *) dir;
|
||||
}
|
||||
|
||||
const char *
|
||||
pupa_dl_get_prefix (void)
|
||||
{
|
||||
return pupa_dl_dir;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue