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:
okuji 2003-01-06 00:01:35 +00:00
parent 012d7999fe
commit a5ffe96617
17 changed files with 553 additions and 79 deletions

View file

@ -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;
}

View file

@ -23,8 +23,33 @@
#include <pupa/machine/memory.h>
#include <pupa/machine/console.h>
#include <pupa/machine/biosdisk.h>
#include <pupa/machine/kernel.h>
#include <pupa/types.h>
#include <pupa/err.h>
#include <pupa/dl.h>
#include <pupa/misc.h>
static char *
make_install_device (void)
{
/* XXX: This should be enough. */
char dev[100];
pupa_sprintf (dev, "(%cd%u",
(pupa_boot_drive & 0x80) ? 'h' : 'f',
pupa_boot_drive & 0x7f);
if (pupa_install_dos_part >= 0)
pupa_sprintf (dev + pupa_strlen (dev), ",%u", pupa_install_dos_part);
if (pupa_install_bsd_part >= 0)
pupa_sprintf (dev + pupa_strlen (dev), ",%c", pupa_install_bsd_part + 'a');
pupa_sprintf (dev + pupa_strlen (dev), ")%s", pupa_prefix);
pupa_strcpy (pupa_prefix, dev);
return pupa_prefix;
}
void
pupa_machine_init (void)
@ -112,4 +137,7 @@ pupa_machine_init (void)
/* The memory system was initialized, thus register built-in devices. */
pupa_biosdisk_init ();
/* Initialize the prefix. */
pupa_dl_set_prefix (make_install_device ());
}

View file

@ -87,18 +87,18 @@ VARIABLE(pupa_total_module_size)
.long 0
VARIABLE(pupa_kernel_image_size)
.long 0
VARIABLE(install_partition)
.long 0xFFFFFF
VARIABLE(version_string)
.string PACKAGE_VERSION
VARIABLE(config_file)
.string "/boot/pupa/puparc"
VARIABLE(pupa_install_dos_part)
.long 0xFFFFFFFF
VARIABLE(pupa_install_bsd_part)
.long 0xFFFFFFFF
VARIABLE(pupa_prefix)
.string "/boot/pupa"
/*
* Leave some breathing room for the config file name.
* Leave some breathing room for the prefix.
*/
. = EXT_C(start) + 0x70
. = EXT_C(start) + 0x50
/* the real mode code continues... */
codestart:
@ -261,13 +261,16 @@ FUNCTION(pupa_halt)
*/
FUNCTION(pupa_chainloader_real_boot)
/* no need to save anything */
pushl %edx
pushl %eax
/* ESI must point to a partition table entry */
movl %edx, %esi
call EXT_C(pupa_dl_unload_all)
/* set up to pass boot drive */
movl %eax, %edx
popl %edx
/* ESI must point to a partition table entry */
popl %esi
/* Turn off Gate A20 */
xorl %eax, %eax

View file

@ -26,17 +26,53 @@
#include <pupa/term.h>
void *
pupa_memcpy (void *dest, const void *src, pupa_size_t n)
pupa_memmove (void *dest, const void *src, pupa_size_t n)
{
char *d = (char *) dest;
char *s = (char *) src;
while (n--)
*d++ = *s++;
const char *s = (const char *) src;
if (d < s)
while (n--)
*d++ = *s++;
else
{
d += n;
s += n;
while (n--)
*--d = *--s;
}
return dest;
}
char *
pupa_strcpy (char *dest, const char *src)
{
char *p = dest;
while ((*p++ = *src++) != '\0')
;
return dest;
}
#if 0
char *
pupa_strcat (char *dest, const char *src)
{
char *p = dest;
while (*p)
p++;
while ((*p++ = *src++) != '\0')
;
return dest;
}
#endif
int
pupa_printf (const char *fmt, ...)
{
@ -237,7 +273,7 @@ pupa_memset (void *s, int c, pupa_size_t n)
pupa_size_t
pupa_strlen (const char *s)
{
char *p = (char *) s;
const char *p = s;
while (*p)
p++;
@ -262,7 +298,7 @@ pupa_reverse (char *str)
}
}
char *
static char *
pupa_itoa (char *str, int c, unsigned n)
{
unsigned base = (c == 'x') ? 16 : 10;
@ -292,15 +328,15 @@ pupa_vsprintf (char *str, const char *fmt, va_list args)
{
char c;
int count = 0;
auto void write_char (char c);
auto void write_char (char ch);
auto void write_str (const char *s);
void write_char (char c)
void write_char (char ch)
{
if (str)
*str++ = c;
*str++ = ch;
else
pupa_putchar (c);
pupa_putchar (ch);
count++;
}

View file

@ -195,7 +195,7 @@ pupa_memalign (pupa_size_t align, pupa_size_t size)
{
pupa_mm_region_t r;
pupa_size_t n = ((size + PUPA_MM_ALIGN - 1) >> PUPA_MM_ALIGN_LOG2) + 1;
int first = 1;
int count = 0;
align = (align >> PUPA_MM_ALIGN_LOG2);
if (align == 0)
@ -212,14 +212,25 @@ pupa_memalign (pupa_size_t align, pupa_size_t size)
return p;
}
/* If failed, invalidate disk caches to increase free memory. */
if (first)
/* If failed, increase free memory somehow. */
switch (count)
{
case 0:
/* Invalidate disk caches. */
pupa_disk_cache_invalidate_all ();
first = 0;
count++;
goto again;
case 1:
/* Unload unneeded modules. */
pupa_dl_unload_unneeded ();
count++;
goto again;
}
default:
break;
}
pupa_error (PUPA_ERR_OUT_OF_MEMORY, "out of memory");
return 0;
}

View file

@ -19,6 +19,7 @@
*/
#include <pupa/kernel.h>
#include <pupa/rescue.h>
#include <pupa/term.h>
#include <pupa/misc.h>
#include <pupa/disk.h>
@ -26,6 +27,7 @@
#include <pupa/mm.h>
#include <pupa/err.h>
#include <pupa/loader.h>
#include <pupa/dl.h>
#include <pupa/machine/partition.h>
#define PUPA_RESCUE_BUF_SIZE 256
@ -40,7 +42,7 @@ struct pupa_rescue_command
};
typedef struct pupa_rescue_command *pupa_rescue_command_t;
static char buf[PUPA_RESCUE_BUF_SIZE];
static char linebuf[PUPA_RESCUE_BUF_SIZE];
static pupa_rescue_command_t pupa_rescue_command_list;
@ -85,7 +87,7 @@ pupa_rescue_get_command_line (const char *prompt)
int pos = 0;
pupa_printf (prompt);
pupa_memset (buf, 0, PUPA_RESCUE_BUF_SIZE);
pupa_memset (linebuf, 0, PUPA_RESCUE_BUF_SIZE);
while ((c = PUPA_TERM_ASCII_CHAR (pupa_getkey ())) != '\n' && c != '\r')
{
@ -93,7 +95,7 @@ pupa_rescue_get_command_line (const char *prompt)
{
if (pos < PUPA_RESCUE_BUF_SIZE - 1)
{
buf[pos++] = c;
linebuf[pos++] = c;
pupa_putchar (c);
}
}
@ -101,7 +103,7 @@ pupa_rescue_get_command_line (const char *prompt)
{
if (pos > 0)
{
buf[--pos] = 0;
linebuf[--pos] = 0;
pupa_putchar (c);
pupa_putchar (' ');
pupa_putchar (c);
@ -475,6 +477,7 @@ pupa_rescue_cmd_testload (int argc, char *argv[])
}
#endif
/* dump ADDRESS [SIZE] */
static void
pupa_rescue_cmd_dump (int argc, char *argv[])
{
@ -501,6 +504,99 @@ pupa_rescue_cmd_dump (int argc, char *argv[])
}
}
/* prefix [DIR] */
static void
pupa_rescue_cmd_prefix (int argc, char *argv[])
{
static char prefix[100];
if (argc == 0)
pupa_printf ("%s\n", pupa_dl_get_prefix ());
else
{
if (pupa_strlen (argv[0]) >= sizeof (prefix))
{
pupa_error (PUPA_ERR_BAD_ARGUMENT, "too long prefix");
return;
}
pupa_strcpy (prefix, argv[0]);
pupa_dl_set_prefix (prefix);
}
}
/* insmod MODULE */
static void
pupa_rescue_cmd_insmod (int argc, char *argv[])
{
char *p;
pupa_dl_t mod;
if (argc == 0)
{
pupa_error (PUPA_ERR_BAD_ARGUMENT, "no module specified");
return;
}
p = pupa_strchr (argv[0], '/');
if (! p)
mod = pupa_dl_load (argv[0]);
else
mod = pupa_dl_load_file (argv[0]);
if (mod)
pupa_dl_ref (mod);
}
/* rmmod MODULE */
static void
pupa_rescue_cmd_rmmod (int argc, char *argv[])
{
pupa_dl_t mod;
if (argc == 0)
{
pupa_error (PUPA_ERR_BAD_ARGUMENT, "no module specified");
return;
}
mod = pupa_dl_get (argv[0]);
if (! mod)
{
pupa_error (PUPA_ERR_BAD_ARGUMENT, "no such module");
return;
}
pupa_dl_unref (mod);
}
/* lsmod */
static void
pupa_rescue_cmd_lsmod (int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
auto int print_module (pupa_dl_t mod);
int print_module (pupa_dl_t mod)
{
pupa_dl_dep_t dep;
pupa_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
for (dep = mod->dep; dep; dep = dep->next)
{
if (dep != mod->dep)
pupa_putchar (',');
pupa_printf ("%s", dep->mod->name);
}
pupa_putchar ('\n');
return 0;
}
pupa_printf ("Name\tRef Count\tDependencies\n");
pupa_dl_iterate (print_module);
}
/* Enter the rescue mode. */
void
pupa_enter_rescue_mode (void)
@ -518,13 +614,21 @@ pupa_enter_rescue_mode (void)
pupa_rescue_register_command ("module", pupa_rescue_cmd_module,
"load an OS module");
pupa_rescue_register_command ("root", pupa_rescue_cmd_root,
"set a root device");
"set the root device");
pupa_rescue_register_command ("dump", pupa_rescue_cmd_dump,
"dump memory");
pupa_rescue_register_command ("prefix", pupa_rescue_cmd_prefix,
"set the prefix");
pupa_rescue_register_command ("insmod", pupa_rescue_cmd_insmod,
"insert a module");
pupa_rescue_register_command ("rmmod", pupa_rescue_cmd_rmmod,
"remove a module");
pupa_rescue_register_command ("lsmod", pupa_rescue_cmd_lsmod,
"show loaded modules");
while (1)
{
char *line = buf;
char *line = linebuf;
char *name;
int n;
pupa_rescue_command_t cmd;