]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2003-01-06 Yoshinori K. Okuji <okuji@enbug.org>
authorokuji <okuji@localhost>
Mon, 6 Jan 2003 00:01:35 +0000 (00:01 +0000)
committerokuji <okuji@localhost>
Mon, 6 Jan 2003 00:01:35 +0000 (00:01 +0000)
* 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.

17 files changed:
ChangeLog
NEWS
configure
configure.ac
fs/fat.c
include/grub/dl.h
include/grub/i386/pc/kernel.h
include/grub/misc.h
include/grub/types.h
kern/dl.c
kern/i386/pc/init.c
kern/i386/pc/startup.S
kern/misc.c
kern/mm.c
kern/rescue.c
loader/i386/pc/chainloader.c
util/i386/pc/grub-setup.c

index 2b4e8264f952a80f62eba2d1b6b76d9ced0ce9d0..dd835ed2ebb8f4a387d90d386aa10c0f12d4ca01 100644 (file)
--- a/ChangeLog
+++ b/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>
 
        * util/i386/pc/pupa-setup.c (setup): Define the internal
diff --git a/NEWS b/NEWS
index 3944a66f0bb0fd40b71fb60439dcfb3632973970..ad72cbd42cfb62049d7ea289ce5429b498d4064a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ New in 0.7:
 * New utility, ``pupa-setup''. This sets up PUPA to make it bootable
   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:
 
 * The chainloader and the FAT filesystem are modularized.
index 9c619bbc815718a9150a7d2188576dc91c627e9b..51c69c0fd5acd70be5e858189b8fc9116caf6a93 100644 (file)
--- a/configure
+++ b/configure
@@ -2069,7 +2069,8 @@ echo "$as_me: error: GCC is required" >&2;}
 
 if test "x$default_CFLAGS" = xyes; then
   # debug flags.
-  tmp_CFLAGS="-Wall -W -g"
+  tmp_CFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \
+               -Wundef -Wstrict-prototypes -g"
 
   # optimization flags.
   echo "$as_me:$LINENO: checking whether optimization for size works" >&5
index 6e63db47c9e574b292c61ef4ae135323a95eadc1..c26fe4e940540d33dba65f2e166e264cff1cf6a0 100644 (file)
@@ -45,7 +45,8 @@ test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required])
 
 if test "x$default_CFLAGS" = xyes; then
   # debug flags.
-  tmp_CFLAGS="-Wall -W -g"
+  tmp_CFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \
+               -Wundef -Wstrict-prototypes -g"
 
   # optimization flags.
   AC_CACHE_CHECK([whether optimization for size works], size_flag, [
index 045c04b6c0be3e8d586891a3c00ee62b4ffb12b8..49b89f5b504ed484860ea171a74b202f060010e9 100644 (file)
--- a/fs/fat.c
+++ b/fs/fat.c
@@ -126,6 +126,10 @@ struct pupa_fat_data
   pupa_uint32_t cur_cluster;
 };
 
+#ifndef PUPA_UTIL
+static pupa_dl_t my_mod;
+#endif
+
 static int
 log2 (unsigned x)
 {
@@ -675,13 +679,17 @@ static pupa_err_t
 pupa_fat_dir (pupa_device_t device, const char *path,
              int (*hook) (const char *filename, int dir))
 {
-  struct pupa_fat_data *data;
+  struct pupa_fat_data *data = 0;
   pupa_disk_t disk = device->disk;
   char *p = (char *) path;
+
+#ifndef PUPA_UTIL
+  pupa_dl_ref (my_mod);
+#endif
   
   data = pupa_fat_mount (disk);
   if (! data)
-    return pupa_errno;
+    goto fail;
 
   do
     {
@@ -689,19 +697,30 @@ pupa_fat_dir (pupa_device_t device, const char *path,
     }
   while (p && pupa_errno == PUPA_ERR_NONE);
 
+ fail:
+  
   pupa_free (data);
+  
+#ifndef PUPA_UTIL
+  pupa_dl_unref (my_mod);
+#endif
+  
   return pupa_errno;
 }
 
 static pupa_err_t
 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;
+
+#ifndef PUPA_UTIL
+  pupa_dl_ref (my_mod);
+#endif
   
   data = pupa_fat_mount (file->device->disk);
   if (! data)
-    return pupa_errno;
+    goto fail;
 
   do
     {
@@ -723,7 +742,13 @@ pupa_fat_open (pupa_file_t file, const char *name)
   return PUPA_ERR_NONE;
 
  fail:
+  
   pupa_free (data);
+  
+#ifndef PUPA_UTIL
+  pupa_dl_unref (my_mod);
+#endif
+  
   return pupa_errno;
 }
 
@@ -738,6 +763,11 @@ static pupa_err_t
 pupa_fat_close (pupa_file_t file)
 {
   pupa_free (file->data);
+  
+#ifndef PUPA_UTIL
+  pupa_dl_unref (my_mod);
+#endif
+  
   return pupa_errno;
 }
 
@@ -752,19 +782,26 @@ static struct pupa_fs pupa_fat_fs =
   };
 
 #ifdef PUPA_UTIL
-void pupa_fat_init (void)
-#else
+void
+pupa_fat_init (void)
+{
+  pupa_fs_register (&pupa_fat_fs);
+}
+
+void
+pupa_fat_fini (void)
+{
+  pupa_fs_unregister (&pupa_fat_fs);
+}
+#else /* ! PUPA_UTIL */
 PUPA_MOD_INIT
-#endif
 {
   pupa_fs_register (&pupa_fat_fs);
+  my_mod = mod;
 }
 
-#ifdef PUPA_UTIL
-void pupa_fat_fini (void)
-#else
 PUPA_MOD_FINI
-#endif
 {
   pupa_fs_unregister (&pupa_fat_fs);
 }
+#endif /* ! PUPA_UTIL */
index 2763497ed68dd1ab283df91dab65a0aac1076e32..9541601803588458190af5d9a22b7d0a2a8627fe 100644 (file)
@@ -26,9 +26,9 @@
 #include <pupa/types.h>
 
 #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 \
-pupa_mod_init (void)
+pupa_mod_init (pupa_dl_t mod)
 
 #define PUPA_MOD_FINI  \
 static void pupa_mod_fini (void) __attribute__ ((unused)); \
@@ -65,7 +65,7 @@ struct pupa_dl
   int ref_count;
   pupa_dl_dep_t dep;
   pupa_dl_segment_t segment;
-  void (*init) (void);
+  void (*init) (struct pupa_dl *mod);
   void (*fini) (void);
 };
 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) (const char *name);
 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_err_t EXPORT_FUNC(pupa_dl_register_symbol) (const char *name, void *addr,
                                            pupa_dl_t mod);
 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);
 pupa_err_t pupa_arch_dl_relocate_symbols (pupa_dl_t mod, void *ehdr);
index d6928d3c718edff7688253f491025dbf601626e2..e7a785a051628d055f4919cc40c63f6000ec719e 100644 (file)
 #ifndef KERNEL_MACHINE_HEADER
 #define KERNEL_MACHINE_HEADER  1
 
+#include <pupa/types.h>
+
 /* The offset of PUPA_TOTAL_MODULE_SIZE.  */
 #define PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE  0x8
 
 /* The offset of PUPA_KERNEL_IMAGE_SIZE.  */
 #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 */
index fa28322452dbfd5ce1ede8cdd9ecb1f1fdf2a52c..a5c6835b80e5c04793020e8f2a6140de30369907 100644 (file)
 #include <pupa/types.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_strcmp) (const char *s1, const char *s2);
 char *EXPORT_FUNC(pupa_strchr) (const char *s, int c);
index 0dda38486777e981c596ad19b2fb0728edab92e1..b2d4482d0ceafdfe1a08631aeb530c92a934a0d8 100644 (file)
@@ -69,7 +69,7 @@ typedef unsigned long long    pupa_uint64_t;
 #endif
 
 /* 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_off_t;
 typedef pupa_uint64_t  pupa_size_t;
index c22c98403e932ca590beb086160a4ebf0ffca931..8bf0cdebaaffae4c3166e94a5ec32ba666f498ec 100644 (file)
--- a/kern/dl.c
+++ b/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;
+}
+
 \f
 
 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_init (const char *dir)
+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_set_prefix (const char *dir)
 {
   pupa_dl_dir = (char *) dir;
 }
+
+const char *
+pupa_dl_get_prefix (void)
+{
+  return pupa_dl_dir;
+}
index 012ec99a44bdb356c564039c46f2512883412704..604cc29b2c0bc33b84ad86c3acd819bb1318bfe6 100644 (file)
 #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 ());
 }
index 0fdc656812ba979cca835b59bcd4463d23404ae3..a1f12cf23e37665d8828a4523b522a89473114c0 100644 (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
index 3ddd3aadadcffae16fe8c89f67ca76ce6278b2ea..b765948f55969d04010b46819ad0c1fe89a66368 100644 (file)
 #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++;
     }
index 9b888b62b331bec21172ede4c2240c1ab0190f23..5f8e6c9fe9d6880fd882f4d0d5f695a32ae9a557 100644 (file)
--- a/kern/mm.c
+++ b/kern/mm.c
@@ -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;
 }
index 29aecb8a71527c96986383d7ad993607a6a92326..abec3503401528efa7f446e7d78c1efe5249fff9 100644 (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;
index 911f795d9f6c113a2a2b997def0aa26df4ff5f4c..cfcc88dbb88ea746d77e8709471fd60442f3f355 100644 (file)
@@ -35,6 +35,8 @@
 /* Allocate space statically, because this is very small anyway.  */
 static char pupa_chainloader_boot_sector[PUPA_DISK_SECTOR_SIZE];
 
+static pupa_dl_t my_mod;
+
 static pupa_err_t
 pupa_chainloader_boot (void)
 {
@@ -75,13 +77,21 @@ pupa_chainloader_boot (void)
   return PUPA_ERR_NONE;
 }
 
+static pupa_err_t
+pupa_chainloader_unload (void)
+{
+  pupa_dl_unref (my_mod);
+}
+
 static void
 pupa_rescue_cmd_chainloader (int argc, char *argv[])
 {
-  pupa_file_t file;
+  pupa_file_t file = 0;
   pupa_uint16_t signature;
   int force = 0;
 
+  pupa_dl_ref (my_mod);
+  
   if (argc > 0 && pupa_strcmp (argv[0], "--force") == 0)
     {
       force = 1;
@@ -92,12 +102,12 @@ pupa_rescue_cmd_chainloader (int argc, char *argv[])
   if (argc == 0)
     {
       pupa_error (PUPA_ERR_BAD_ARGUMENT, "no file specified");
-      return;
+      goto fail;
     }
 
   file = pupa_file_open (argv[0]);
   if (! file)
-    return;
+    goto fail;
 
   /* Read the first block.  */
   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)
        pupa_error (PUPA_ERR_BAD_OS, "too small");
 
-      pupa_file_close (file);
-      return;
+      goto fail;
     }
 
   /* Check the signature.  */
   signature = *((pupa_uint16_t *) (pupa_chainloader_boot_sector
                                   + PUPA_DISK_SECTOR_SIZE - 2));
   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_loader_set (0, pupa_chainloader_boot, pupa_chainloader_unload);
+  return;
+  
+ fail:
 
-  if (pupa_errno == PUPA_ERR_NONE)
-    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";
@@ -129,6 +147,7 @@ PUPA_MOD_INIT
   pupa_rescue_register_command (loader_name,
                                pupa_rescue_cmd_chainloader,
                                "load another boot loader");
+  my_mod = mod;
 }
 
 PUPA_MOD_FINI
index b4b123c44aea050d2662d2890c9b6be5e521e295..cada26e0f6ae8482fff611429e0712e0d3288c23 100644 (file)
@@ -29,6 +29,7 @@
 #include <pupa/machine/partition.h>
 #include <pupa/machine/util/biosdisk.h>
 #include <pupa/machine/boot.h>
+#include <pupa/machine/kernel.h>
 
 #include <stdio.h>
 #include <unistd.h>
@@ -74,6 +75,8 @@ setup (const char *prefix, const char *dir,
   pupa_uint8_t *boot_drive;
   pupa_uint32_t *kernel_sector;
   struct boot_blocklist *first_block, *block;
+  pupa_int32_t *install_dos_part, *install_bsd_part;
+  char *install_prefix;
   char *tmp_img;
   int i;
   unsigned long first_sector;
@@ -172,7 +175,14 @@ setup (const char *prefix, const char *dir,
   first_block = (struct boot_blocklist *) (core_img
                                           + PUPA_DISK_SECTOR_SIZE
                                           - 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.  */
   root_dev = pupa_device_open (root);
   if (! root_dev)
@@ -227,6 +237,19 @@ setup (const char *prefix, const char *dir,
          block->start = 0;
          block->len = 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.  */
          if (pupa_disk_write (dest_dev->disk, 1, 0, core_size, core_img))
@@ -363,14 +386,27 @@ setup (const char *prefix, const char *dir,
   else
     *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);
   pupa_util_info ("opening the core image `%s'", core_path);
   fp = fopen (core_path, "r+b");
   if (! fp)
     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);
   free (core_path);