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
88
ChangeLog
88
ChangeLog
|
@ -1,3 +1,91 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2003-01-03 Yoshinori K. Okuji <okuji@enbug.org>
|
2003-01-03 Yoshinori K. Okuji <okuji@enbug.org>
|
||||||
|
|
||||||
* util/i386/pc/pupa-setup.c (setup): Define the internal
|
* util/i386/pc/pupa-setup.c (setup): Define the internal
|
||||||
|
|
4
NEWS
4
NEWS
|
@ -10,6 +10,10 @@ New in 0.7:
|
||||||
* New utility, ``pupa-setup''. This sets up PUPA to make it bootable
|
* New utility, ``pupa-setup''. This sets up PUPA to make it bootable
|
||||||
from a real disk.
|
from a real disk.
|
||||||
|
|
||||||
|
* New commands, "prefix", "insmod", "rmmod" and "lsmod" are added into
|
||||||
|
the rescue mode to manipulate PUPA modules.
|
||||||
|
|
||||||
|
|
||||||
New in 0.6 - 2002-12-27, Yoshinori K. Okuji:
|
New in 0.6 - 2002-12-27, Yoshinori K. Okuji:
|
||||||
|
|
||||||
* The chainloader and the FAT filesystem are modularized.
|
* The chainloader and the FAT filesystem are modularized.
|
||||||
|
|
3
configure
vendored
3
configure
vendored
|
@ -2069,7 +2069,8 @@ echo "$as_me: error: GCC is required" >&2;}
|
||||||
|
|
||||||
if test "x$default_CFLAGS" = xyes; then
|
if test "x$default_CFLAGS" = xyes; then
|
||||||
# debug flags.
|
# debug flags.
|
||||||
tmp_CFLAGS="-Wall -W -g"
|
tmp_CFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \
|
||||||
|
-Wundef -Wstrict-prototypes -g"
|
||||||
|
|
||||||
# optimization flags.
|
# optimization flags.
|
||||||
echo "$as_me:$LINENO: checking whether optimization for size works" >&5
|
echo "$as_me:$LINENO: checking whether optimization for size works" >&5
|
||||||
|
|
|
@ -45,7 +45,8 @@ test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required])
|
||||||
|
|
||||||
if test "x$default_CFLAGS" = xyes; then
|
if test "x$default_CFLAGS" = xyes; then
|
||||||
# debug flags.
|
# debug flags.
|
||||||
tmp_CFLAGS="-Wall -W -g"
|
tmp_CFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \
|
||||||
|
-Wundef -Wstrict-prototypes -g"
|
||||||
|
|
||||||
# optimization flags.
|
# optimization flags.
|
||||||
AC_CACHE_CHECK([whether optimization for size works], size_flag, [
|
AC_CACHE_CHECK([whether optimization for size works], size_flag, [
|
||||||
|
|
63
fs/fat.c
63
fs/fat.c
|
@ -126,6 +126,10 @@ struct pupa_fat_data
|
||||||
pupa_uint32_t cur_cluster;
|
pupa_uint32_t cur_cluster;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef PUPA_UTIL
|
||||||
|
static pupa_dl_t my_mod;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
log2 (unsigned x)
|
log2 (unsigned x)
|
||||||
{
|
{
|
||||||
|
@ -675,13 +679,17 @@ static pupa_err_t
|
||||||
pupa_fat_dir (pupa_device_t device, const char *path,
|
pupa_fat_dir (pupa_device_t device, const char *path,
|
||||||
int (*hook) (const char *filename, int dir))
|
int (*hook) (const char *filename, int dir))
|
||||||
{
|
{
|
||||||
struct pupa_fat_data *data;
|
struct pupa_fat_data *data = 0;
|
||||||
pupa_disk_t disk = device->disk;
|
pupa_disk_t disk = device->disk;
|
||||||
char *p = (char *) path;
|
char *p = (char *) path;
|
||||||
|
|
||||||
|
#ifndef PUPA_UTIL
|
||||||
|
pupa_dl_ref (my_mod);
|
||||||
|
#endif
|
||||||
|
|
||||||
data = pupa_fat_mount (disk);
|
data = pupa_fat_mount (disk);
|
||||||
if (! data)
|
if (! data)
|
||||||
return pupa_errno;
|
goto fail;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -689,19 +697,30 @@ pupa_fat_dir (pupa_device_t device, const char *path,
|
||||||
}
|
}
|
||||||
while (p && pupa_errno == PUPA_ERR_NONE);
|
while (p && pupa_errno == PUPA_ERR_NONE);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
|
||||||
pupa_free (data);
|
pupa_free (data);
|
||||||
|
|
||||||
|
#ifndef PUPA_UTIL
|
||||||
|
pupa_dl_unref (my_mod);
|
||||||
|
#endif
|
||||||
|
|
||||||
return pupa_errno;
|
return pupa_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pupa_err_t
|
static pupa_err_t
|
||||||
pupa_fat_open (pupa_file_t file, const char *name)
|
pupa_fat_open (pupa_file_t file, const char *name)
|
||||||
{
|
{
|
||||||
struct pupa_fat_data *data;
|
struct pupa_fat_data *data = 0;
|
||||||
char *p = (char *) name;
|
char *p = (char *) name;
|
||||||
|
|
||||||
|
#ifndef PUPA_UTIL
|
||||||
|
pupa_dl_ref (my_mod);
|
||||||
|
#endif
|
||||||
|
|
||||||
data = pupa_fat_mount (file->device->disk);
|
data = pupa_fat_mount (file->device->disk);
|
||||||
if (! data)
|
if (! data)
|
||||||
return pupa_errno;
|
goto fail;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -723,7 +742,13 @@ pupa_fat_open (pupa_file_t file, const char *name)
|
||||||
return PUPA_ERR_NONE;
|
return PUPA_ERR_NONE;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
pupa_free (data);
|
pupa_free (data);
|
||||||
|
|
||||||
|
#ifndef PUPA_UTIL
|
||||||
|
pupa_dl_unref (my_mod);
|
||||||
|
#endif
|
||||||
|
|
||||||
return pupa_errno;
|
return pupa_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,6 +763,11 @@ static pupa_err_t
|
||||||
pupa_fat_close (pupa_file_t file)
|
pupa_fat_close (pupa_file_t file)
|
||||||
{
|
{
|
||||||
pupa_free (file->data);
|
pupa_free (file->data);
|
||||||
|
|
||||||
|
#ifndef PUPA_UTIL
|
||||||
|
pupa_dl_unref (my_mod);
|
||||||
|
#endif
|
||||||
|
|
||||||
return pupa_errno;
|
return pupa_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,19 +782,26 @@ static struct pupa_fs pupa_fat_fs =
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef PUPA_UTIL
|
#ifdef PUPA_UTIL
|
||||||
void pupa_fat_init (void)
|
void
|
||||||
#else
|
pupa_fat_init (void)
|
||||||
PUPA_MOD_INIT
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
pupa_fs_register (&pupa_fat_fs);
|
pupa_fs_register (&pupa_fat_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PUPA_UTIL
|
void
|
||||||
void pupa_fat_fini (void)
|
pupa_fat_fini (void)
|
||||||
#else
|
|
||||||
PUPA_MOD_FINI
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
pupa_fs_unregister (&pupa_fat_fs);
|
pupa_fs_unregister (&pupa_fat_fs);
|
||||||
}
|
}
|
||||||
|
#else /* ! PUPA_UTIL */
|
||||||
|
PUPA_MOD_INIT
|
||||||
|
{
|
||||||
|
pupa_fs_register (&pupa_fat_fs);
|
||||||
|
my_mod = mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
PUPA_MOD_FINI
|
||||||
|
{
|
||||||
|
pupa_fs_unregister (&pupa_fat_fs);
|
||||||
|
}
|
||||||
|
#endif /* ! PUPA_UTIL */
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
#include <pupa/types.h>
|
#include <pupa/types.h>
|
||||||
|
|
||||||
#define PUPA_MOD_INIT \
|
#define PUPA_MOD_INIT \
|
||||||
static void pupa_mod_init (void) __attribute__ ((unused)); \
|
static void pupa_mod_init (pupa_dl_t mod) __attribute__ ((unused)); \
|
||||||
static void \
|
static void \
|
||||||
pupa_mod_init (void)
|
pupa_mod_init (pupa_dl_t mod)
|
||||||
|
|
||||||
#define PUPA_MOD_FINI \
|
#define PUPA_MOD_FINI \
|
||||||
static void pupa_mod_fini (void) __attribute__ ((unused)); \
|
static void pupa_mod_fini (void) __attribute__ ((unused)); \
|
||||||
|
@ -65,7 +65,7 @@ struct pupa_dl
|
||||||
int ref_count;
|
int ref_count;
|
||||||
pupa_dl_dep_t dep;
|
pupa_dl_dep_t dep;
|
||||||
pupa_dl_segment_t segment;
|
pupa_dl_segment_t segment;
|
||||||
void (*init) (void);
|
void (*init) (struct pupa_dl *mod);
|
||||||
void (*fini) (void);
|
void (*fini) (void);
|
||||||
};
|
};
|
||||||
typedef struct pupa_dl *pupa_dl_t;
|
typedef struct pupa_dl *pupa_dl_t;
|
||||||
|
@ -73,12 +73,18 @@ typedef struct pupa_dl *pupa_dl_t;
|
||||||
pupa_dl_t EXPORT_FUNC(pupa_dl_load_file) (const char *filename);
|
pupa_dl_t EXPORT_FUNC(pupa_dl_load_file) (const char *filename);
|
||||||
pupa_dl_t EXPORT_FUNC(pupa_dl_load) (const char *name);
|
pupa_dl_t EXPORT_FUNC(pupa_dl_load) (const char *name);
|
||||||
pupa_dl_t pupa_dl_load_core (void *addr, pupa_size_t size);
|
pupa_dl_t pupa_dl_load_core (void *addr, pupa_size_t size);
|
||||||
void EXPORT_FUNC(pupa_dl_unload) (pupa_dl_t mod);
|
int EXPORT_FUNC(pupa_dl_unload) (pupa_dl_t mod);
|
||||||
|
void pupa_dl_unload_unneeded (void);
|
||||||
|
void pupa_dl_unload_all (void);
|
||||||
|
int EXPORT_FUNC(pupa_dl_ref) (pupa_dl_t mod);
|
||||||
|
int EXPORT_FUNC(pupa_dl_unref) (pupa_dl_t mod);
|
||||||
|
void EXPORT_FUNC(pupa_dl_iterate) (int (*hook) (pupa_dl_t mod));
|
||||||
pupa_dl_t EXPORT_FUNC(pupa_dl_get) (const char *name);
|
pupa_dl_t EXPORT_FUNC(pupa_dl_get) (const char *name);
|
||||||
pupa_err_t EXPORT_FUNC(pupa_dl_register_symbol) (const char *name, void *addr,
|
pupa_err_t EXPORT_FUNC(pupa_dl_register_symbol) (const char *name, void *addr,
|
||||||
pupa_dl_t mod);
|
pupa_dl_t mod);
|
||||||
void *EXPORT_FUNC(pupa_dl_resolve_symbol) (const char *name);
|
void *EXPORT_FUNC(pupa_dl_resolve_symbol) (const char *name);
|
||||||
void pupa_dl_init (const char *dir);
|
void pupa_dl_set_prefix (const char *dir);
|
||||||
|
const char *pupa_dl_get_prefix (void);
|
||||||
|
|
||||||
int pupa_arch_dl_check_header (void *ehdr, pupa_size_t size);
|
int pupa_arch_dl_check_header (void *ehdr, pupa_size_t size);
|
||||||
pupa_err_t pupa_arch_dl_relocate_symbols (pupa_dl_t mod, void *ehdr);
|
pupa_err_t pupa_arch_dl_relocate_symbols (pupa_dl_t mod, void *ehdr);
|
||||||
|
|
|
@ -20,10 +20,34 @@
|
||||||
#ifndef KERNEL_MACHINE_HEADER
|
#ifndef KERNEL_MACHINE_HEADER
|
||||||
#define KERNEL_MACHINE_HEADER 1
|
#define KERNEL_MACHINE_HEADER 1
|
||||||
|
|
||||||
|
#include <pupa/types.h>
|
||||||
|
|
||||||
/* The offset of PUPA_TOTAL_MODULE_SIZE. */
|
/* The offset of PUPA_TOTAL_MODULE_SIZE. */
|
||||||
#define PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8
|
#define PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8
|
||||||
|
|
||||||
/* The offset of PUPA_KERNEL_IMAGE_SIZE. */
|
/* The offset of PUPA_KERNEL_IMAGE_SIZE. */
|
||||||
#define PUPA_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc
|
#define PUPA_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc
|
||||||
|
|
||||||
|
/* The offset of PUPA_INSTALL_DOS_PART. */
|
||||||
|
#define PUPA_KERNEL_MACHINE_INSTALL_DOS_PART 0x10
|
||||||
|
|
||||||
|
/* The offset of PUPA_INSTALL_BSD_PART. */
|
||||||
|
#define PUPA_KERNEL_MACHINE_INSTALL_BSD_PART 0x14
|
||||||
|
|
||||||
|
/* The offset of PUPA_PREFIX. */
|
||||||
|
#define PUPA_KERNEL_MACHINE_PREFIX 0x18
|
||||||
|
|
||||||
|
/* The DOS partition number of the installed partition. */
|
||||||
|
extern pupa_int32_t pupa_install_dos_part;
|
||||||
|
|
||||||
|
/* The BSD partition number of the installed partition. */
|
||||||
|
extern pupa_int32_t pupa_install_bsd_part;
|
||||||
|
|
||||||
|
/* The prefix which points to the directory where PUPA modules and its
|
||||||
|
configuration file are located. */
|
||||||
|
extern char pupa_prefix[];
|
||||||
|
|
||||||
|
/* The boot BIOS drive number. */
|
||||||
|
extern pupa_int32_t pupa_boot_drive;
|
||||||
|
|
||||||
#endif /* ! KERNEL_MACHINE_HEADER */
|
#endif /* ! KERNEL_MACHINE_HEADER */
|
||||||
|
|
|
@ -25,7 +25,11 @@
|
||||||
#include <pupa/types.h>
|
#include <pupa/types.h>
|
||||||
#include <pupa/symbol.h>
|
#include <pupa/symbol.h>
|
||||||
|
|
||||||
void *EXPORT_FUNC(pupa_memcpy) (void *dest, const void *src, pupa_size_t n);
|
/* XXX: If pupa_memmove is too slow, we must implement pupa_memcpy. */
|
||||||
|
#define pupa_memcpy(d,s,n) pupa_memmove ((d), (s), (n))
|
||||||
|
|
||||||
|
void *EXPORT_FUNC(pupa_memmove) (void *dest, const void *src, pupa_size_t n);
|
||||||
|
char *EXPORT_FUNC(pupa_strcpy) (char *dest, const char *src);
|
||||||
int EXPORT_FUNC(pupa_memcmp) (const void *s1, const void *s2, pupa_size_t n);
|
int EXPORT_FUNC(pupa_memcmp) (const void *s1, const void *s2, pupa_size_t n);
|
||||||
int EXPORT_FUNC(pupa_strcmp) (const char *s1, const char *s2);
|
int EXPORT_FUNC(pupa_strcmp) (const char *s1, const char *s2);
|
||||||
char *EXPORT_FUNC(pupa_strchr) (const char *s, int c);
|
char *EXPORT_FUNC(pupa_strchr) (const char *s, int c);
|
||||||
|
|
|
@ -69,7 +69,7 @@ typedef unsigned long long pupa_uint64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Misc types. */
|
/* Misc types. */
|
||||||
#if PUPA_HOST_SIZE_OF_VOID_P == 8
|
#if PUPA_HOST_SIZEOF_VOID_P == 8
|
||||||
typedef pupa_uint64_t pupa_addr_t;
|
typedef pupa_uint64_t pupa_addr_t;
|
||||||
typedef pupa_uint64_t pupa_off_t;
|
typedef pupa_uint64_t pupa_off_t;
|
||||||
typedef pupa_uint64_t pupa_size_t;
|
typedef pupa_uint64_t pupa_size_t;
|
||||||
|
|
94
kern/dl.c
94
kern/dl.c
|
@ -109,6 +109,16 @@ pupa_dl_get (const char *name)
|
||||||
return 0;
|
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
|
struct pupa_symbol
|
||||||
|
@ -345,9 +355,9 @@ pupa_dl_resolve_symbols (pupa_dl_t mod, Elf_Ehdr *e)
|
||||||
return pupa_errno;
|
return pupa_errno;
|
||||||
|
|
||||||
if (pupa_strcmp (name, "pupa_mod_init") == 0)
|
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)
|
else if (pupa_strcmp (name, "pupa_mod_fini") == 0)
|
||||||
mod->fini = (void (*) ()) sym->st_value;
|
mod->fini = (void (*) (void)) sym->st_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STT_SECTION:
|
case STT_SECTION:
|
||||||
|
@ -372,7 +382,7 @@ static void
|
||||||
pupa_dl_call_init (pupa_dl_t mod)
|
pupa_dl_call_init (pupa_dl_t mod)
|
||||||
{
|
{
|
||||||
if (mod->init)
|
if (mod->init)
|
||||||
(mod->init) ();
|
(mod->init) (mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pupa_err_t
|
static pupa_err_t
|
||||||
|
@ -429,6 +439,8 @@ pupa_dl_resolve_dependencies (pupa_dl_t mod, Elf_Ehdr *e)
|
||||||
if (! m)
|
if (! m)
|
||||||
return pupa_errno;
|
return pupa_errno;
|
||||||
|
|
||||||
|
pupa_dl_ref (m);
|
||||||
|
|
||||||
dep = (pupa_dl_dep_t) pupa_malloc (sizeof (*dep));
|
dep = (pupa_dl_dep_t) pupa_malloc (sizeof (*dep));
|
||||||
if (! dep)
|
if (! dep)
|
||||||
return pupa_errno;
|
return pupa_errno;
|
||||||
|
@ -444,6 +456,24 @@ pupa_dl_resolve_dependencies (pupa_dl_t mod, Elf_Ehdr *e)
|
||||||
return PUPA_ERR_NONE;
|
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. */
|
/* Load a module from core memory. */
|
||||||
pupa_dl_t
|
pupa_dl_t
|
||||||
pupa_dl_load_core (void *addr, pupa_size_t size)
|
pupa_dl_load_core (void *addr, pupa_size_t size)
|
||||||
|
@ -513,6 +543,7 @@ pupa_dl_load_file (const char *filename)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
mod = pupa_dl_load_core (core, size);
|
mod = pupa_dl_load_core (core, size);
|
||||||
|
mod->ref_count = 0;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
pupa_file_close (file);
|
pupa_file_close (file);
|
||||||
|
@ -532,10 +563,7 @@ pupa_dl_load (const char *name)
|
||||||
|
|
||||||
mod = pupa_dl_get (name);
|
mod = pupa_dl_get (name);
|
||||||
if (mod)
|
if (mod)
|
||||||
{
|
|
||||||
mod->ref_count++;
|
|
||||||
return mod;
|
return mod;
|
||||||
}
|
|
||||||
|
|
||||||
if (! pupa_dl_dir)
|
if (! pupa_dl_dir)
|
||||||
pupa_fatal ("module dir is not initialized yet");
|
pupa_fatal ("module dir is not initialized yet");
|
||||||
|
@ -559,14 +587,14 @@ pupa_dl_load (const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unload the module MOD. */
|
/* Unload the module MOD. */
|
||||||
void
|
int
|
||||||
pupa_dl_unload (pupa_dl_t mod)
|
pupa_dl_unload (pupa_dl_t mod)
|
||||||
{
|
{
|
||||||
pupa_dl_dep_t dep, depn;
|
pupa_dl_dep_t dep, depn;
|
||||||
pupa_dl_segment_t seg, segn;
|
pupa_dl_segment_t seg, segn;
|
||||||
|
|
||||||
if (--mod->ref_count > 0)
|
if (mod->ref_count > 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (mod->fini)
|
if (mod->fini)
|
||||||
(mod->fini) ();
|
(mod->fini) ();
|
||||||
|
@ -577,7 +605,7 @@ pupa_dl_unload (pupa_dl_t mod)
|
||||||
for (dep = mod->dep; dep; dep = depn)
|
for (dep = mod->dep; dep; dep = depn)
|
||||||
{
|
{
|
||||||
depn = dep->next;
|
depn = dep->next;
|
||||||
pupa_dl_unload (dep->mod);
|
pupa_dl_unref (dep->mod);
|
||||||
pupa_free (dep);
|
pupa_free (dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,10 +618,54 @@ pupa_dl_unload (pupa_dl_t mod)
|
||||||
|
|
||||||
pupa_free (mod->name);
|
pupa_free (mod->name);
|
||||||
pupa_free (mod);
|
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
|
void
|
||||||
pupa_dl_init (const char *dir)
|
pupa_dl_set_prefix (const char *dir)
|
||||||
{
|
{
|
||||||
pupa_dl_dir = (char *) dir;
|
pupa_dl_dir = (char *) dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
pupa_dl_get_prefix (void)
|
||||||
|
{
|
||||||
|
return pupa_dl_dir;
|
||||||
|
}
|
||||||
|
|
|
@ -23,8 +23,33 @@
|
||||||
#include <pupa/machine/memory.h>
|
#include <pupa/machine/memory.h>
|
||||||
#include <pupa/machine/console.h>
|
#include <pupa/machine/console.h>
|
||||||
#include <pupa/machine/biosdisk.h>
|
#include <pupa/machine/biosdisk.h>
|
||||||
|
#include <pupa/machine/kernel.h>
|
||||||
#include <pupa/types.h>
|
#include <pupa/types.h>
|
||||||
#include <pupa/err.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
|
void
|
||||||
pupa_machine_init (void)
|
pupa_machine_init (void)
|
||||||
|
@ -112,4 +137,7 @@ pupa_machine_init (void)
|
||||||
|
|
||||||
/* The memory system was initialized, thus register built-in devices. */
|
/* The memory system was initialized, thus register built-in devices. */
|
||||||
pupa_biosdisk_init ();
|
pupa_biosdisk_init ();
|
||||||
|
|
||||||
|
/* Initialize the prefix. */
|
||||||
|
pupa_dl_set_prefix (make_install_device ());
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,18 +87,18 @@ VARIABLE(pupa_total_module_size)
|
||||||
.long 0
|
.long 0
|
||||||
VARIABLE(pupa_kernel_image_size)
|
VARIABLE(pupa_kernel_image_size)
|
||||||
.long 0
|
.long 0
|
||||||
VARIABLE(install_partition)
|
VARIABLE(pupa_install_dos_part)
|
||||||
.long 0xFFFFFF
|
.long 0xFFFFFFFF
|
||||||
VARIABLE(version_string)
|
VARIABLE(pupa_install_bsd_part)
|
||||||
.string PACKAGE_VERSION
|
.long 0xFFFFFFFF
|
||||||
VARIABLE(config_file)
|
VARIABLE(pupa_prefix)
|
||||||
.string "/boot/pupa/puparc"
|
.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... */
|
/* the real mode code continues... */
|
||||||
codestart:
|
codestart:
|
||||||
|
@ -261,13 +261,16 @@ FUNCTION(pupa_halt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FUNCTION(pupa_chainloader_real_boot)
|
FUNCTION(pupa_chainloader_real_boot)
|
||||||
/* no need to save anything */
|
pushl %edx
|
||||||
|
pushl %eax
|
||||||
|
|
||||||
/* ESI must point to a partition table entry */
|
call EXT_C(pupa_dl_unload_all)
|
||||||
movl %edx, %esi
|
|
||||||
|
|
||||||
/* set up to pass boot drive */
|
/* 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 */
|
/* Turn off Gate A20 */
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
|
|
52
kern/misc.c
52
kern/misc.c
|
@ -26,17 +26,53 @@
|
||||||
#include <pupa/term.h>
|
#include <pupa/term.h>
|
||||||
|
|
||||||
void *
|
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 *d = (char *) dest;
|
||||||
char *s = (char *) src;
|
const char *s = (const char *) src;
|
||||||
|
|
||||||
|
if (d < s)
|
||||||
while (n--)
|
while (n--)
|
||||||
*d++ = *s++;
|
*d++ = *s++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d += n;
|
||||||
|
s += n;
|
||||||
|
|
||||||
|
while (n--)
|
||||||
|
*--d = *--s;
|
||||||
|
}
|
||||||
|
|
||||||
return dest;
|
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
|
int
|
||||||
pupa_printf (const char *fmt, ...)
|
pupa_printf (const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +273,7 @@ pupa_memset (void *s, int c, pupa_size_t n)
|
||||||
pupa_size_t
|
pupa_size_t
|
||||||
pupa_strlen (const char *s)
|
pupa_strlen (const char *s)
|
||||||
{
|
{
|
||||||
char *p = (char *) s;
|
const char *p = s;
|
||||||
|
|
||||||
while (*p)
|
while (*p)
|
||||||
p++;
|
p++;
|
||||||
|
@ -262,7 +298,7 @@ pupa_reverse (char *str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
static char *
|
||||||
pupa_itoa (char *str, int c, unsigned n)
|
pupa_itoa (char *str, int c, unsigned n)
|
||||||
{
|
{
|
||||||
unsigned base = (c == 'x') ? 16 : 10;
|
unsigned base = (c == 'x') ? 16 : 10;
|
||||||
|
@ -292,15 +328,15 @@ pupa_vsprintf (char *str, const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
auto void write_char (char c);
|
auto void write_char (char ch);
|
||||||
auto void write_str (const char *s);
|
auto void write_str (const char *s);
|
||||||
|
|
||||||
void write_char (char c)
|
void write_char (char ch)
|
||||||
{
|
{
|
||||||
if (str)
|
if (str)
|
||||||
*str++ = c;
|
*str++ = ch;
|
||||||
else
|
else
|
||||||
pupa_putchar (c);
|
pupa_putchar (ch);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
19
kern/mm.c
19
kern/mm.c
|
@ -195,7 +195,7 @@ pupa_memalign (pupa_size_t align, pupa_size_t size)
|
||||||
{
|
{
|
||||||
pupa_mm_region_t r;
|
pupa_mm_region_t r;
|
||||||
pupa_size_t n = ((size + PUPA_MM_ALIGN - 1) >> PUPA_MM_ALIGN_LOG2) + 1;
|
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);
|
align = (align >> PUPA_MM_ALIGN_LOG2);
|
||||||
if (align == 0)
|
if (align == 0)
|
||||||
|
@ -212,12 +212,23 @@ pupa_memalign (pupa_size_t align, pupa_size_t size)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If failed, invalidate disk caches to increase free memory. */
|
/* If failed, increase free memory somehow. */
|
||||||
if (first)
|
switch (count)
|
||||||
{
|
{
|
||||||
|
case 0:
|
||||||
|
/* Invalidate disk caches. */
|
||||||
pupa_disk_cache_invalidate_all ();
|
pupa_disk_cache_invalidate_all ();
|
||||||
first = 0;
|
count++;
|
||||||
goto again;
|
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");
|
pupa_error (PUPA_ERR_OUT_OF_MEMORY, "out of memory");
|
||||||
|
|
116
kern/rescue.c
116
kern/rescue.c
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pupa/kernel.h>
|
#include <pupa/kernel.h>
|
||||||
|
#include <pupa/rescue.h>
|
||||||
#include <pupa/term.h>
|
#include <pupa/term.h>
|
||||||
#include <pupa/misc.h>
|
#include <pupa/misc.h>
|
||||||
#include <pupa/disk.h>
|
#include <pupa/disk.h>
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include <pupa/mm.h>
|
#include <pupa/mm.h>
|
||||||
#include <pupa/err.h>
|
#include <pupa/err.h>
|
||||||
#include <pupa/loader.h>
|
#include <pupa/loader.h>
|
||||||
|
#include <pupa/dl.h>
|
||||||
#include <pupa/machine/partition.h>
|
#include <pupa/machine/partition.h>
|
||||||
|
|
||||||
#define PUPA_RESCUE_BUF_SIZE 256
|
#define PUPA_RESCUE_BUF_SIZE 256
|
||||||
|
@ -40,7 +42,7 @@ struct pupa_rescue_command
|
||||||
};
|
};
|
||||||
typedef struct pupa_rescue_command *pupa_rescue_command_t;
|
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;
|
static pupa_rescue_command_t pupa_rescue_command_list;
|
||||||
|
|
||||||
|
@ -85,7 +87,7 @@ pupa_rescue_get_command_line (const char *prompt)
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
pupa_printf (prompt);
|
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')
|
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)
|
if (pos < PUPA_RESCUE_BUF_SIZE - 1)
|
||||||
{
|
{
|
||||||
buf[pos++] = c;
|
linebuf[pos++] = c;
|
||||||
pupa_putchar (c);
|
pupa_putchar (c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +103,7 @@ pupa_rescue_get_command_line (const char *prompt)
|
||||||
{
|
{
|
||||||
if (pos > 0)
|
if (pos > 0)
|
||||||
{
|
{
|
||||||
buf[--pos] = 0;
|
linebuf[--pos] = 0;
|
||||||
pupa_putchar (c);
|
pupa_putchar (c);
|
||||||
pupa_putchar (' ');
|
pupa_putchar (' ');
|
||||||
pupa_putchar (c);
|
pupa_putchar (c);
|
||||||
|
@ -475,6 +477,7 @@ pupa_rescue_cmd_testload (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* dump ADDRESS [SIZE] */
|
||||||
static void
|
static void
|
||||||
pupa_rescue_cmd_dump (int argc, char *argv[])
|
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. */
|
/* Enter the rescue mode. */
|
||||||
void
|
void
|
||||||
pupa_enter_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,
|
pupa_rescue_register_command ("module", pupa_rescue_cmd_module,
|
||||||
"load an OS module");
|
"load an OS module");
|
||||||
pupa_rescue_register_command ("root", pupa_rescue_cmd_root,
|
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,
|
pupa_rescue_register_command ("dump", pupa_rescue_cmd_dump,
|
||||||
"dump memory");
|
"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)
|
while (1)
|
||||||
{
|
{
|
||||||
char *line = buf;
|
char *line = linebuf;
|
||||||
char *name;
|
char *name;
|
||||||
int n;
|
int n;
|
||||||
pupa_rescue_command_t cmd;
|
pupa_rescue_command_t cmd;
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
/* Allocate space statically, because this is very small anyway. */
|
/* Allocate space statically, because this is very small anyway. */
|
||||||
static char pupa_chainloader_boot_sector[PUPA_DISK_SECTOR_SIZE];
|
static char pupa_chainloader_boot_sector[PUPA_DISK_SECTOR_SIZE];
|
||||||
|
|
||||||
|
static pupa_dl_t my_mod;
|
||||||
|
|
||||||
static pupa_err_t
|
static pupa_err_t
|
||||||
pupa_chainloader_boot (void)
|
pupa_chainloader_boot (void)
|
||||||
{
|
{
|
||||||
|
@ -75,13 +77,21 @@ pupa_chainloader_boot (void)
|
||||||
return PUPA_ERR_NONE;
|
return PUPA_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pupa_err_t
|
||||||
|
pupa_chainloader_unload (void)
|
||||||
|
{
|
||||||
|
pupa_dl_unref (my_mod);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pupa_rescue_cmd_chainloader (int argc, char *argv[])
|
pupa_rescue_cmd_chainloader (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
pupa_file_t file;
|
pupa_file_t file = 0;
|
||||||
pupa_uint16_t signature;
|
pupa_uint16_t signature;
|
||||||
int force = 0;
|
int force = 0;
|
||||||
|
|
||||||
|
pupa_dl_ref (my_mod);
|
||||||
|
|
||||||
if (argc > 0 && pupa_strcmp (argv[0], "--force") == 0)
|
if (argc > 0 && pupa_strcmp (argv[0], "--force") == 0)
|
||||||
{
|
{
|
||||||
force = 1;
|
force = 1;
|
||||||
|
@ -92,12 +102,12 @@ pupa_rescue_cmd_chainloader (int argc, char *argv[])
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
{
|
{
|
||||||
pupa_error (PUPA_ERR_BAD_ARGUMENT, "no file specified");
|
pupa_error (PUPA_ERR_BAD_ARGUMENT, "no file specified");
|
||||||
return;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = pupa_file_open (argv[0]);
|
file = pupa_file_open (argv[0]);
|
||||||
if (! file)
|
if (! file)
|
||||||
return;
|
goto fail;
|
||||||
|
|
||||||
/* Read the first block. */
|
/* Read the first block. */
|
||||||
if (pupa_file_read (file, pupa_chainloader_boot_sector,
|
if (pupa_file_read (file, pupa_chainloader_boot_sector,
|
||||||
|
@ -106,20 +116,28 @@ pupa_rescue_cmd_chainloader (int argc, char *argv[])
|
||||||
if (pupa_errno == PUPA_ERR_NONE)
|
if (pupa_errno == PUPA_ERR_NONE)
|
||||||
pupa_error (PUPA_ERR_BAD_OS, "too small");
|
pupa_error (PUPA_ERR_BAD_OS, "too small");
|
||||||
|
|
||||||
pupa_file_close (file);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the signature. */
|
/* Check the signature. */
|
||||||
signature = *((pupa_uint16_t *) (pupa_chainloader_boot_sector
|
signature = *((pupa_uint16_t *) (pupa_chainloader_boot_sector
|
||||||
+ PUPA_DISK_SECTOR_SIZE - 2));
|
+ PUPA_DISK_SECTOR_SIZE - 2));
|
||||||
if (signature != pupa_le_to_cpu16 (0xaa55) && ! force)
|
if (signature != pupa_le_to_cpu16 (0xaa55) && ! force)
|
||||||
|
{
|
||||||
pupa_error (PUPA_ERR_BAD_OS, "invalid signature");
|
pupa_error (PUPA_ERR_BAD_OS, "invalid signature");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
pupa_file_close (file);
|
pupa_file_close (file);
|
||||||
|
pupa_loader_set (0, pupa_chainloader_boot, pupa_chainloader_unload);
|
||||||
|
return;
|
||||||
|
|
||||||
if (pupa_errno == PUPA_ERR_NONE)
|
fail:
|
||||||
pupa_loader_set (0, pupa_chainloader_boot, 0);
|
|
||||||
|
if (file)
|
||||||
|
pupa_file_close (file);
|
||||||
|
|
||||||
|
pupa_dl_unref (my_mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char loader_name[] = "chainloader";
|
static const char loader_name[] = "chainloader";
|
||||||
|
@ -129,6 +147,7 @@ PUPA_MOD_INIT
|
||||||
pupa_rescue_register_command (loader_name,
|
pupa_rescue_register_command (loader_name,
|
||||||
pupa_rescue_cmd_chainloader,
|
pupa_rescue_cmd_chainloader,
|
||||||
"load another boot loader");
|
"load another boot loader");
|
||||||
|
my_mod = mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUPA_MOD_FINI
|
PUPA_MOD_FINI
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <pupa/machine/partition.h>
|
#include <pupa/machine/partition.h>
|
||||||
#include <pupa/machine/util/biosdisk.h>
|
#include <pupa/machine/util/biosdisk.h>
|
||||||
#include <pupa/machine/boot.h>
|
#include <pupa/machine/boot.h>
|
||||||
|
#include <pupa/machine/kernel.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -74,6 +75,8 @@ setup (const char *prefix, const char *dir,
|
||||||
pupa_uint8_t *boot_drive;
|
pupa_uint8_t *boot_drive;
|
||||||
pupa_uint32_t *kernel_sector;
|
pupa_uint32_t *kernel_sector;
|
||||||
struct boot_blocklist *first_block, *block;
|
struct boot_blocklist *first_block, *block;
|
||||||
|
pupa_int32_t *install_dos_part, *install_bsd_part;
|
||||||
|
char *install_prefix;
|
||||||
char *tmp_img;
|
char *tmp_img;
|
||||||
int i;
|
int i;
|
||||||
unsigned long first_sector;
|
unsigned long first_sector;
|
||||||
|
@ -173,6 +176,13 @@ setup (const char *prefix, const char *dir,
|
||||||
+ PUPA_DISK_SECTOR_SIZE
|
+ PUPA_DISK_SECTOR_SIZE
|
||||||
- sizeof (*block));
|
- sizeof (*block));
|
||||||
|
|
||||||
|
install_dos_part = (pupa_int32_t *) (core_img + PUPA_DISK_SECTOR_SIZE
|
||||||
|
+ PUPA_KERNEL_MACHINE_INSTALL_DOS_PART);
|
||||||
|
install_bsd_part = (pupa_int32_t *) (core_img + PUPA_DISK_SECTOR_SIZE
|
||||||
|
+ PUPA_KERNEL_MACHINE_INSTALL_BSD_PART);
|
||||||
|
install_prefix = (core_img + PUPA_DISK_SECTOR_SIZE
|
||||||
|
+ PUPA_KERNEL_MACHINE_PREFIX);
|
||||||
|
|
||||||
/* Open the root device and the destination device. */
|
/* Open the root device and the destination device. */
|
||||||
root_dev = pupa_device_open (root);
|
root_dev = pupa_device_open (root);
|
||||||
if (! root_dev)
|
if (! root_dev)
|
||||||
|
@ -228,6 +238,19 @@ setup (const char *prefix, const char *dir,
|
||||||
block->len = 0;
|
block->len = 0;
|
||||||
block->segment = 0;
|
block->segment = 0;
|
||||||
|
|
||||||
|
/* Embed information about the installed location. */
|
||||||
|
if (root_dev->disk->partition)
|
||||||
|
{
|
||||||
|
*install_dos_part
|
||||||
|
= pupa_cpu_to_le32 (root_dev->disk->partition->dos_part);
|
||||||
|
*install_bsd_part
|
||||||
|
= pupa_cpu_to_le32 (root_dev->disk->partition->bsd_part);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*install_dos_part = *install_bsd_part = pupa_cpu_to_le32 (-1);
|
||||||
|
|
||||||
|
strcpy (install_prefix, prefix);
|
||||||
|
|
||||||
/* Write the core image onto the disk. */
|
/* Write the core image onto the disk. */
|
||||||
if (pupa_disk_write (dest_dev->disk, 1, 0, core_size, core_img))
|
if (pupa_disk_write (dest_dev->disk, 1, 0, core_size, core_img))
|
||||||
pupa_util_error ("%s", pupa_errmsg);
|
pupa_util_error ("%s", pupa_errmsg);
|
||||||
|
@ -363,14 +386,27 @@ setup (const char *prefix, const char *dir,
|
||||||
else
|
else
|
||||||
*boot_drive = 0xFF;
|
*boot_drive = 0xFF;
|
||||||
|
|
||||||
/* Write the first sector of the core image onto the disk. */
|
/* Embed information about the installed location. */
|
||||||
|
if (root_dev->disk->partition)
|
||||||
|
{
|
||||||
|
*install_dos_part
|
||||||
|
= pupa_cpu_to_le32 (root_dev->disk->partition->dos_part);
|
||||||
|
*install_bsd_part
|
||||||
|
= pupa_cpu_to_le32 (root_dev->disk->partition->bsd_part);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*install_dos_part = *install_bsd_part = pupa_cpu_to_le32 (-1);
|
||||||
|
|
||||||
|
strcpy (install_prefix, prefix);
|
||||||
|
|
||||||
|
/* Write the first two sectors of the core image onto the disk. */
|
||||||
core_path = pupa_util_get_path (dir, core_file);
|
core_path = pupa_util_get_path (dir, core_file);
|
||||||
pupa_util_info ("opening the core image `%s'", core_path);
|
pupa_util_info ("opening the core image `%s'", core_path);
|
||||||
fp = fopen (core_path, "r+b");
|
fp = fopen (core_path, "r+b");
|
||||||
if (! fp)
|
if (! fp)
|
||||||
pupa_util_error ("Cannot open `%s'", core_path);
|
pupa_util_error ("Cannot open `%s'", core_path);
|
||||||
|
|
||||||
pupa_util_write_image (core_img, PUPA_DISK_SECTOR_SIZE, fp);
|
pupa_util_write_image (core_img, PUPA_DISK_SECTOR_SIZE * 2, fp);
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
free (core_path);
|
free (core_path);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue