]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2003-01-31 Yoshinori K. Okuji <okuji@enbug.org>
authorokuji <okuji@localhost>
Fri, 31 Jan 2003 03:26:56 +0000 (03:26 +0000)
committerokuji <okuji@localhost>
Fri, 31 Jan 2003 03:26:56 +0000 (03:26 +0000)
* kern/i386/pc/lzo1x.S: New file.

* util/i386/pc/pupa-mkimage.c: Include lzo1x.h.
(compress_kernel): New variable.
(generate_image): Heavily modified to support compressing a
large part of the core image.

* util/misc.c (pupa_util_read_image): Fix a file descriptor
leak.
(pupa_util_load_image): New function.

* kern/i386/pc/startup.S: Include pupa/machine/kernel.h.
(pupa_compressed_size): New variable.
(codestart): Enable Gate A20 here.
Decompress the compressed part of the core image.
Rearrange the code to put functions and variables which are
required for initialization in the non-compressed part.
Include lzo1x.S.

* kern/i386/pc/init.c (pupa_machine_init): Don't enable Gate A20
here.

* include/pupa/util/misc.h (pupa_util_write_image): Declared.

* include/pupa/i386/pc/kernel.h
(PUPA_KERNEL_MACHINE_COMPRESSED_SIZE): New macro.
(PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): Increased by 4.
(PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise.
(PUPA_KERNEL_MACHINE_PREFIX): Likewise.
(PUPA_KERNEL_MACHINE_RAW_SIZE): New macro.

* conf/i386-pc.rmk (pupa_mkimage_LDFLAGS): New variable.

* genmk.rb (Image#rule): Put LDFLAGS at the end of a line.
(Utility#rule): Likewise.

* configure.ac: Check if LZO is available.

18 files changed:
ChangeLog
INSTALL
NEWS
THANKS
conf/i386-pc.mk
conf/i386-pc.rmk
config.h.in
configure
configure.ac
genmk.rb
include/grub/i386/pc/kernel.h
include/grub/util/misc.h
kern/i386/pc/init.c
kern/i386/pc/lzo1x.S [new file with mode: 0644]
kern/i386/pc/startup.S
kern/mm.c
util/i386/pc/grub-mkimage.c
util/misc.c

index 7a078f7a09767d4839ffa21671589c447c41c6bb..80b8ae35ea7133b3bb7dec41c015605eeb29c7db 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2003-01-31  Yoshinori K. Okuji  <okuji@enbug.org>
+
+       * kern/i386/pc/lzo1x.S: New file.
+       
+       * util/i386/pc/pupa-mkimage.c: Include lzo1x.h.
+       (compress_kernel): New variable.
+       (generate_image): Heavily modified to support compressing a
+       large part of the core image.
+
+       * util/misc.c (pupa_util_read_image): Fix a file descriptor
+       leak.
+       (pupa_util_load_image): New function.
+
+       * kern/i386/pc/startup.S: Include pupa/machine/kernel.h.
+       (pupa_compressed_size): New variable.
+       (codestart): Enable Gate A20 here.
+       Decompress the compressed part of the core image.
+       Rearrange the code to put functions and variables which are
+       required for initialization in the non-compressed part.
+       Include lzo1x.S.
+
+       * kern/i386/pc/init.c (pupa_machine_init): Don't enable Gate A20
+       here.
+
+       * include/pupa/util/misc.h (pupa_util_write_image): Declared.
+
+       * include/pupa/i386/pc/kernel.h 
+       (PUPA_KERNEL_MACHINE_COMPRESSED_SIZE): New macro.
+       (PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): Increased by 4.
+       (PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise.
+       (PUPA_KERNEL_MACHINE_PREFIX): Likewise.
+       (PUPA_KERNEL_MACHINE_RAW_SIZE): New macro.
+
+       * conf/i386-pc.rmk (pupa_mkimage_LDFLAGS): New variable.
+
+       * genmk.rb (Image#rule): Put LDFLAGS at the end of a line.
+       (Utility#rule): Likewise.
+
+       * configure.ac: Check if LZO is available.
+
 2003-01-20  Yoshinori K. Okuji  <okuji@enbug.org>
 
        * include/pupa/normal.h: New file.
diff --git a/INSTALL b/INSTALL
index 228029e42b06b95728dc59a6efce9297184bd172..4f6e79586febbefb4ff9440f625caccfb7e0b213 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -15,6 +15,7 @@ configuring the PUPA.
 * GNU Make
 * GNU binutils 2.9.1.0.23 or later
 * Other standard GNU/Unix tools
+* LZO 1.02 or later
 
 If you'd like to develop PUPA, these below are also required.
 
diff --git a/NEWS b/NEWS
index 974707acc02f2d1d09617261d391f34acb5efecb..1837fdd81bc1183f580f5129748a0ba4ab8e4dac 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,12 @@ New in 0.7:
 
 * Linux support is added. Initrd is not support yet.
 
+* Reduce the size of a core image significantly by compressing a large
+  part of the core image and decompressing itself at boot time. The
+  currently used algorithm is LZO (more precisely, LZO1X-999). So you
+  have to install LZO to build PUPA. See
+  <http://www.oberhumer.com/opensource/lzo/>, for more information.
+
 
 New in 0.6 - 2002-12-27, Yoshinori K. Okuji:
 
diff --git a/THANKS b/THANKS
index 6c0277094904ff59577f25dc91ba20421a063447..3f1b71829b985bdcd334921bddf2d85b8be40e01 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -9,8 +9,8 @@ generally assist in the PUPA maintainership process:
 NIIBE Yutaka <gniibe@m17n.org>
 Tsuneyoshi Yasuo <tuneyoshi@naic.co.jp>
 
-Also, we thank the projects GNU GRUB and GNU Automake. Some code were
-stolen from them.
+Also, we thank the projects GNU GRUB, GNU Automake and LZO. Some code
+were stolen from them.
 
 This project is supported by Information-technology Promotion Agency,
 Japan.
index 25bd00297e1d0264e534240f93ca853d85e902ae..a44441bfd34df3d07b67b17f2343dc37dd122bf6 100644 (file)
@@ -15,7 +15,7 @@ boot.img: boot.exec
        $(OBJCOPY) -O binary -R .note -R .comment $< $@
 
 boot.exec: boot_img-boot_i386_pc_boot.o
-       $(CC) $(LDFLAGS) $(boot_img_LDFLAGS) -o $@ $^
+       $(CC) -o $@ $^ $(LDFLAGS) $(boot_img_LDFLAGS)
 
 boot_img-boot_i386_pc_boot.o: boot/i386/pc/boot.S
        $(CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(boot_img_ASFLAGS) -c -o $@ $<
@@ -37,7 +37,7 @@ diskboot.img: diskboot.exec
        $(OBJCOPY) -O binary -R .note -R .comment $< $@
 
 diskboot.exec: diskboot_img-boot_i386_pc_diskboot.o
-       $(CC) $(LDFLAGS) $(diskboot_img_LDFLAGS) -o $@ $^
+       $(CC) -o $@ $^ $(LDFLAGS) $(diskboot_img_LDFLAGS)
 
 diskboot_img-boot_i386_pc_diskboot.o: boot/i386/pc/diskboot.S
        $(CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(diskboot_img_ASFLAGS) -c -o $@ $<
@@ -65,7 +65,7 @@ kernel.img: kernel.exec
        $(OBJCOPY) -O binary -R .note -R .comment $< $@
 
 kernel.exec: kernel_img-kern_i386_pc_startup.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_loader.o kernel_img-kern_rescue.o kernel_img-kern_term.o kernel_img-kern_i386_dl.o kernel_img-kern_i386_pc_init.o kernel_img-disk_i386_pc_partition.o kernel_img-disk_i386_pc_biosdisk.o kernel_img-term_i386_pc_console.o kernel_img-symlist.o
-       $(CC) $(LDFLAGS) $(kernel_img_LDFLAGS) -o $@ $^
+       $(CC) -o $@ $^ $(LDFLAGS) $(kernel_img_LDFLAGS)
 
 kernel_img-kern_i386_pc_startup.o: kern/i386/pc/startup.S
        $(CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(kernel_img_ASFLAGS) -c -o $@ $<
@@ -249,7 +249,7 @@ CLEANFILES += pupa-mkimage pupa_mkimage-util_i386_pc_pupa_mkimage.o pupa_mkimage
 MOSTLYCLEANFILES += pupa_mkimage-util_i386_pc_pupa_mkimage.d pupa_mkimage-util_misc.d pupa_mkimage-util_resolve.d
 
 pupa-mkimage: pupa_mkimage-util_i386_pc_pupa_mkimage.o pupa_mkimage-util_misc.o pupa_mkimage-util_resolve.o
-       $(BUILD_CC) $(BUILD_LDFLAGS) $(pupa_mkimage_LDFLAGS) -o $@ $^
+       $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(pupa_mkimage_LDFLAGS)
 
 pupa_mkimage-util_i386_pc_pupa_mkimage.o: util/i386/pc/pupa-mkimage.c
        $(BUILD_CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DPUPA_UTIL=1 $(pupa_mkimage_CFLAGS) -c -o $@ $<
@@ -275,6 +275,7 @@ pupa_mkimage-util_resolve.d: util/resolve.c
 
 -include pupa_mkimage-util_resolve.d
 
+pupa_mkimage_LDFLAGS = -llzo
 
 # For pupa-setup.
 pupa_setup_SOURCES = util/i386/pc/pupa-setup.c util/i386/pc/biosdisk.c \
@@ -284,7 +285,7 @@ CLEANFILES += pupa-setup pupa_setup-util_i386_pc_pupa_setup.o pupa_setup-util_i3
 MOSTLYCLEANFILES += pupa_setup-util_i386_pc_pupa_setup.d pupa_setup-util_i386_pc_biosdisk.d pupa_setup-util_misc.d pupa_setup-kern_device.d pupa_setup-kern_disk.d pupa_setup-kern_file.d pupa_setup-kern_fs.d pupa_setup-kern_err.d pupa_setup-kern_misc.d pupa_setup-disk_i386_pc_partition.d pupa_setup-fs_fat.d
 
 pupa-setup: pupa_setup-util_i386_pc_pupa_setup.o pupa_setup-util_i386_pc_biosdisk.o pupa_setup-util_misc.o pupa_setup-kern_device.o pupa_setup-kern_disk.o pupa_setup-kern_file.o pupa_setup-kern_fs.o pupa_setup-kern_err.o pupa_setup-kern_misc.o pupa_setup-disk_i386_pc_partition.o pupa_setup-fs_fat.o
-       $(BUILD_CC) $(BUILD_LDFLAGS) $(pupa_setup_LDFLAGS) -o $@ $^
+       $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(pupa_setup_LDFLAGS)
 
 pupa_setup-util_i386_pc_pupa_setup.o: util/i386/pc/pupa-setup.c
        $(BUILD_CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DPUPA_UTIL=1 $(pupa_setup_CFLAGS) -c -o $@ $<
@@ -381,7 +382,7 @@ CLEANFILES += genmoddep genmoddep-util_genmoddep.o
 MOSTLYCLEANFILES += genmoddep-util_genmoddep.d
 
 genmoddep: genmoddep-util_genmoddep.o
-       $(BUILD_CC) $(BUILD_LDFLAGS) $(genmoddep_LDFLAGS) -o $@ $^
+       $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(genmoddep_LDFLAGS)
 
 genmoddep-util_genmoddep.o: util/genmoddep.c
        $(BUILD_CC) -Iutil -I$(srcdir)/util $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DPUPA_UTIL=1 $(genmoddep_CFLAGS) -c -o $@ $<
index 847f83bead8c1c015d82ef1d260fa9fe21f131b2..f8123ae46f3c8055b4bfe7d888a0d1178603a234 100644 (file)
@@ -50,6 +50,7 @@ noinst_UTILITIES = genmoddep
 # For pupa-mkimage.
 pupa_mkimage_SOURCES = util/i386/pc/pupa-mkimage.c util/misc.c \
        util/resolve.c
+pupa_mkimage_LDFLAGS = -llzo
 
 # For pupa-setup.
 pupa_setup_SOURCES = util/i386/pc/pupa-setup.c util/i386/pc/biosdisk.c \
index 44ab1f71905076f5f59930eb8b71ee63d50791dc..125f5e3bca7770c29d2346e20cf100253f102f37 100644 (file)
@@ -22,6 +22,9 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
+/* Define to 1 if you have the `lzo' library (-llzo). */
+#undef HAVE_LIBLZO
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
index 51c69c0fd5acd70be5e858189b8fc9116caf6a93..c08d80883eb3c69ec4d944b8fb35700da1588bd4 100644 (file)
--- a/configure
+++ b/configure
@@ -3358,6 +3358,8 @@ tmp_CPPFLAGS="$CPPFLAGS"
 CC="$BUILD_CC"
 CFLAGS="$BUILD_CFLAGS"
 CPPFLAGS="$BUILD_CPPFLAGS"
+
+# Identify characteristics of the build architecture.
 echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
 if test "${ac_cv_c_bigendian+set}" = set; then
@@ -4682,6 +4684,150 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+
+# Check LZO.
+
+echo "$as_me:$LINENO: checking for __lzo_init2 in -llzo" >&5
+echo $ECHO_N "checking for __lzo_init2 in -llzo... $ECHO_C" >&6
+if test "${ac_cv_lib_lzo___lzo_init2+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-llzo  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char __lzo_init2 ();
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+__lzo_init2 ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_lzo___lzo_init2=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_lib_lzo___lzo_init2=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_lzo___lzo_init2" >&5
+echo "${ECHO_T}$ac_cv_lib_lzo___lzo_init2" >&6
+if test $ac_cv_lib_lzo___lzo_init2 = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBLZO 1
+_ACEOF
+
+  LIBS="-llzo $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: LZO library version 1.02 or later is required" >&5
+echo "$as_me: error: LZO library version 1.02 or later is required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+echo "$as_me:$LINENO: checking for lzo1x_999_compress" >&5
+echo $ECHO_N "checking for lzo1x_999_compress... $ECHO_C" >&6
+if test "${ac_cv_func_lzo1x_999_compress+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char lzo1x_999_compress (); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char lzo1x_999_compress ();
+char (*f) ();
+
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_lzo1x_999_compress) || defined (__stub___lzo1x_999_compress)
+choke me
+#else
+f = lzo1x_999_compress;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_lzo1x_999_compress=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_func_lzo1x_999_compress=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_lzo1x_999_compress" >&5
+echo "${ECHO_T}$ac_cv_func_lzo1x_999_compress" >&6
+if test $ac_cv_func_lzo1x_999_compress = yes; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: LZO1X-999 must be enabled" >&5
+echo "$as_me: error: LZO1X-999 must be enabled" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
 CC="$tmp_CC"
 CFLAGS="$tmp_CFLAGS"
 CPPFLAGS="$tmp_CPPFLAGS"
index c26fe4e940540d33dba65f2e166e264cff1cf6a0..4045133b2d9415cb796c4d4f19bb31903b043f10 100644 (file)
@@ -1,6 +1,6 @@
 # Process this file with autoconf to produce a configure script.
 
-# Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+# Copyright (C) 2002,2003  Yoshinori K. Okuji <okuji@enbug.org>
 #
 # This configure.ac is free software; the author
 # gives unlimited permission to copy and/or distribute it,
@@ -117,9 +117,18 @@ tmp_CPPFLAGS="$CPPFLAGS"
 CC="$BUILD_CC"
 CFLAGS="$BUILD_CFLAGS"
 CPPFLAGS="$BUILD_CPPFLAGS"
+
+# Identify characteristics of the build architecture.
 AC_C_BIGENDIAN
 AC_CHECK_SIZEOF(void *)
 AC_CHECK_SIZEOF(long)
+
+# Check LZO.
+AC_CHECK_LIB(lzo, __lzo_init2, ,
+            AC_MSG_ERROR([LZO library version 1.02 or later is required]))
+AC_CHECK_FUNC(lzo1x_999_compress, , 
+             [AC_MSG_ERROR([LZO1X-999 must be enabled])])
+
 CC="$tmp_CC"
 CFLAGS="$tmp_CFLAGS"
 CPPFLAGS="$tmp_CPPFLAGS"
index a48aa04bd35c053d88cef7bb6809748e00221334..b7b23dd5797d80dbc51ef7a11a8b69ccbaa7477b 100644 (file)
--- a/genmk.rb
+++ b/genmk.rb
@@ -1,6 +1,6 @@
 #! /usr/bin/ruby -w
 #
-# Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+# Copyright (C) 2002,2003 Yoshinori K. Okuji <okuji@enbug.org>
 #
 # This genmk.rb is free software; the author
 # gives unlimited permission to copy and/or distribute it,
@@ -60,7 +60,7 @@ MOSTLYCLEANFILES += #{deps_str}
        $(OBJCOPY) -O binary -R .note -R .comment $< $@
 
 #{exe}: #{objs_str}
-       $(CC) $(LDFLAGS) $(#{prefix}_LDFLAGS) -o $@ $^
+       $(CC) -o $@ $^ $(LDFLAGS) $(#{prefix}_LDFLAGS)
 
 " + objs.collect_with_index do |obj, i|
       src = sources[i]
@@ -181,7 +181,7 @@ class Utility
 MOSTLYCLEANFILES += #{deps_str}
 
 #{@name}: #{objs_str}
-       $(BUILD_CC) $(BUILD_LDFLAGS) $(#{prefix}_LDFLAGS) -o $@ $^
+       $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(#{prefix}_LDFLAGS)
 
 " + objs.collect_with_index do |obj, i|
       src = sources[i]
index e7a785a051628d055f4919cc40c63f6000ec719e..ee63d6f5cf5fbd90d893388bed7c4e9f22610d2a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
- *  Copyright (C) 2002  Yoshinori K. Okuji <okuji@enbug.org>
+ *  Copyright (C) 2002,2003  Yoshinori K. Okuji <okuji@enbug.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
 #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_COMPRESSED_SIZE.  */
+#define PUPA_KERNEL_MACHINE_COMPRESSED_SIZE    0x10
+
 /* The offset of PUPA_INSTALL_DOS_PART.  */
-#define PUPA_KERNEL_MACHINE_INSTALL_DOS_PART   0x10
+#define PUPA_KERNEL_MACHINE_INSTALL_DOS_PART   0x14
 
 /* The offset of PUPA_INSTALL_BSD_PART.  */
-#define PUPA_KERNEL_MACHINE_INSTALL_BSD_PART   0x14
+#define PUPA_KERNEL_MACHINE_INSTALL_BSD_PART   0x18
 
 /* The offset of PUPA_PREFIX.  */
-#define PUPA_KERNEL_MACHINE_PREFIX             0x18
+#define PUPA_KERNEL_MACHINE_PREFIX             0x1c
+
+/* The size of the first region which won't be compressed.  */
+#define PUPA_KERNEL_MACHINE_RAW_SIZE           0x400
+
+#ifndef ASM_FILE
+
+#include <pupa/types.h>
 
 /* The DOS partition number of the installed partition.  */
 extern pupa_int32_t pupa_install_dos_part;
@@ -50,4 +58,6 @@ extern char pupa_prefix[];
 /* The boot BIOS drive number.  */
 extern pupa_int32_t pupa_boot_drive;
 
+#endif /* ! ASM_FILE */
+
 #endif /* ! KERNEL_MACHINE_HEADER */
index 10d0a47b20b69e464450595b366541b7907c260b..03c01a4c25dd0b8b443425c03eafa7b7b8a9c5e2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
- *  Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *  Copyright (C) 2002,2003  Yoshinori K. Okuji <okuji@enbug.org>
  *
  *  PUPA is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@ char *xstrdup (const char *str);
 char *pupa_util_get_path (const char *dir, const char *file);
 size_t pupa_util_get_image_size (const char *path);
 char *pupa_util_read_image (const char *path);
+void pupa_util_load_image (const char *path, char *buf);
 void pupa_util_write_image (const char *img, size_t size, FILE *out);
 
 #endif /* ! PUPA_UTIL_MISC_HEADER */
index 7e0db5c03d4a5de8e2a4a5023148861854202a31..57c6d3d758a6c11c00272349598accd9953a7d71 100644 (file)
@@ -130,9 +130,11 @@ pupa_machine_init (void)
   /* Sanity check.  */
   if (pupa_lower_mem < PUPA_MEMORY_MACHINE_RESERVED_END)
     pupa_fatal ("too small memory");
-  
+
+#if 0
   /* Turn on Gate A20 to access >1MB.  */
   pupa_gate_a20 (1);
+#endif
 
   /* Add the lower memory into free memory.  */
   if (pupa_lower_mem >= PUPA_MEMORY_MACHINE_RESERVED_END)
diff --git a/kern/i386/pc/lzo1x.S b/kern/i386/pc/lzo1x.S
new file mode 100644 (file)
index 0000000..616d146
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
+ *  Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
+ *  Copyright (C) 2003  Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+       
+/*
+ * This code was stolen from the files enter.sh, leave.sh, lzo1x_d.sh,
+ * lzo1x_f.s and lzo_asm.h in LZO version 1.08, and was heavily modified
+ * to adapt it to PUPA's requirement.
+ *
+ * See <http://www.oberhumer.com/opensource/lzo/>, for more information
+ * about LZO.
+ */
+
+#define INP    4+16(%esp)
+#define INS    8+16(%esp)
+#define OUTP   12+16(%esp)
+#define NN     3
+#define N_3    %ebp
+#define N_255  $255
+#define LODSB  movb (%esi), %al ;  incl %esi
+#define NOTL_3(r)      xorl N_3, r
+#define MOVSL(r1,r2,x) movl (r1), x ; addl $4, r1 ; movl x, (r2) ; addl $4, r2
+#define COPYL_C(r1,r2,x,rc)    9: MOVSL(r1,r2,x) ; decl rc ; jnz 9b
+#define COPYL(r1,r2,x) COPYL_C(r1,r2,x,%ecx)
+       
+lzo1x_decompress:
+       pushl   %ebp
+       pushl   %edi
+       pushl   %esi
+       pushl   %ebx
+
+       cld
+
+       movl    INP, %esi
+       movl    OUTP, %edi
+       movl    $3, %ebp
+
+       
+       xorl    %eax, %eax
+       xorl    %ebx, %ebx      /* high bits 9-32 stay 0 */
+       lodsb
+       cmpb    $17, %al
+       jbe     .L01
+       subb    $17-NN, %al
+       jmp     .LFLR
+
+
+/***********************************************************************
+// literal run
+************************************************************************/
+
+0:     addl    N_255, %eax
+1:     movb    (%esi), %bl
+       incl    %esi
+       orb     %bl, %bl
+       jz      0b
+       leal    18+NN(%eax,%ebx), %eax
+       jmp     3f
+
+
+       .align  8
+.L00:
+       LODSB
+.L01:
+       cmpb    $16, %al
+       jae     .LMATCH
+
+       /* a literal run */
+       orb     %al, %al
+       jz      1b
+       addl    $3+NN, %eax
+3:
+.LFLR:
+       movl    %eax, %ecx
+       NOTL_3(%eax)
+       shrl    $2, %ecx
+       andl    N_3, %eax
+       COPYL(%esi,%edi,%edx)
+       subl    %eax, %esi
+       subl    %eax, %edi
+
+       LODSB
+       cmpb    $16, %al
+       jae     .LMATCH
+
+
+/***********************************************************************
+// R1
+************************************************************************/
+
+       shrl    $2, %eax
+       movb    (%esi), %bl
+       leal    -0x801(%edi), %edx
+       leal    (%eax,%ebx,4), %eax
+       incl    %esi
+       subl    %eax, %edx
+       movl    (%edx), %ecx
+       movl    %ecx, (%edi)
+       addl    N_3, %edi
+       jmp     .LMDONE
+
+
+/***********************************************************************
+// M2
+************************************************************************/
+
+       .align  8
+.LMATCH:
+       cmpb    $64, %al
+       jb      .LM3MATCH
+
+       /* a M2 match */
+       movl    %eax, %ecx
+       shrl    $2, %eax
+       leal    -1(%edi), %edx
+       andl    $7, %eax
+       movb    (%esi), %bl
+       shrl    $5, %ecx
+       leal    (%eax,%ebx,8), %eax
+       incl    %esi
+       subl    %eax, %edx
+
+       addl    $1+3, %ecx
+
+       cmpl    N_3, %eax
+       jae     .LCOPYLONG
+       jmp     .LCOPYBYTE
+
+
+/***********************************************************************
+// M3
+************************************************************************/
+
+0:     addl    N_255, %eax
+1:     movb    (%esi), %bl
+       incl    %esi
+       orb     %bl, %bl
+       jz      0b
+       leal    33+NN(%eax,%ebx), %ecx
+       xorl    %eax, %eax
+       jmp     3f
+
+
+       .align  8
+.LM3MATCH:
+       cmpb    $32, %al
+       jb      .LM4MATCH
+
+       /* a M3 match */
+       andl    $31, %eax
+       jz      1b
+       lea     2+NN(%eax), %ecx
+3:
+       movw    (%esi), %ax
+       leal    -1(%edi), %edx
+       shrl    $2, %eax
+       addl    $2, %esi
+       subl    %eax, %edx
+
+       cmpl    N_3, %eax
+       jb      .LCOPYBYTE
+
+
+/***********************************************************************
+// copy match
+************************************************************************/
+
+       .align  2
+.LCOPYLONG:                     /* copy match using longwords */
+       leal    -3(%edi,%ecx), %eax
+       shrl    $2, %ecx
+       COPYL(%edx,%edi,%ebx)
+       movl    %eax, %edi
+       xorl    %ebx, %ebx
+
+.LMDONE:
+       movb    -2(%esi), %al
+       andl    N_3, %eax
+       jz      .L00
+.LFLR3:
+       movl    (%esi), %edx
+       addl    %eax, %esi
+       movl    %edx, (%edi)
+       addl    %eax, %edi
+
+       LODSB
+       jmp     .LMATCH
+
+
+       .align  8
+.LCOPYBYTE:                     /* copy match using bytes */
+       xchgl   %edx,%esi
+       subl    N_3,%ecx
+
+       rep
+       movsb
+       movl    %edx, %esi
+       jmp     .LMDONE
+
+
+/***********************************************************************
+// M4
+************************************************************************/
+
+0:     addl    N_255, %ecx
+1:     movb    (%esi), %bl
+       incl    %esi
+       orb     %bl, %bl
+       jz      0b
+       leal    9+NN(%ebx,%ecx), %ecx
+       jmp     3f
+
+
+       .align  8
+.LM4MATCH:
+       cmpb    $16, %al
+       jb      .LM1MATCH
+
+       /* a M4 match */
+       movl    %eax, %ecx
+       andl    $8, %eax
+       shll    $13, %eax       /* save in bit 16 */
+       andl    $7, %ecx
+       jz      1b
+       addl    $2+NN, %ecx
+3:
+       movw    (%esi), %ax
+       addl    $2, %esi
+       leal    -0x4000(%edi), %edx
+       shrl    $2, %eax
+       jz      .LEOF
+       subl    %eax, %edx
+       jmp     .LCOPYLONG
+
+
+/***********************************************************************
+// M1
+************************************************************************/
+
+       .align  8
+.LM1MATCH:
+       /* a M1 match */
+       shrl    $2, %eax
+       movb    (%esi), %bl
+       leal    -1(%edi), %edx
+       leal    (%eax,%ebx,4), %eax
+       incl    %esi
+       subl    %eax, %edx
+
+       movb    (%edx), %al     /* we must use this because edx can be edi-1 */
+       movb    %al, (%edi)
+       movb    1(%edx), %bl
+       movb    %bl, 1(%edi)
+       addl    $2, %edi
+       jmp     .LMDONE
+
+
+/***********************************************************************
+//
+************************************************************************/
+
+.LEOF:
+/****  xorl    %eax,%eax          eax=0 from above */
+
+       cmpl    $3+NN, %ecx     /* ecx must be 3/6 */
+       setnz   %al
+
+       /* check compressed size */
+       movl    INP, %edx
+       addl    INS, %edx
+       cmpl    %edx, %esi       /* check compressed size */
+       ja      .L_input_overrun
+       jb      .L_input_not_consumed
+
+.L_leave:
+       negl    %eax
+       jnz     1f
+       
+       subl    OUTP, %edi       /* write back the uncompressed size */
+       movl    %edi, %eax
+
+1:     popl    %ebx
+       popl    %esi
+       popl    %edi
+       popl    %ebp
+       ret
+
+.L_input_not_consumed:
+        movl    $8, %eax         /* LZO_E_INPUT_NOT_CONSUMED */
+        jmp     .L_leave
+
+.L_input_overrun:
+        movl    $4, %eax         /* LZO_E_INPUT_OVERRUN */
+        jmp     .L_leave
+
+#undef INP
+#undef INS
+#undef OUTP
+#undef NN
+#undef NN
+#undef N_3
+#undef N_255
+#undef LODSB
+#undef NOTL_3
+#undef MOVSL
+#undef COPYL_C
+#undef COPYL
index f2cb6e9029f3799c234d942cd95494fb783a1f0d..da3f8668bcbc60fc373239d1fdc79e230ed23a78 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
  *  Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
- *  Copyright (C) 2002  Yoshinori K. Okuji <okuji@enbug.org>
+ *  Copyright (C) 2002,2003  Yoshinori K. Okuji <okuji@enbug.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -50,7 +50,8 @@
 #include <pupa/machine/memory.h>
 #include <pupa/machine/console.h>
 #include <pupa/machine/linux.h>
-       
+#include <pupa/machine/kernel.h>
+               
 #define ABS(x) ((x) - EXT_C(start) + PUPA_BOOT_MACHINE_KERNEL_ADDR + 0x200)
        
        .file   "startup.S"
@@ -88,6 +89,8 @@ VARIABLE(pupa_total_module_size)
        .long   0
 VARIABLE(pupa_kernel_image_size)
        .long   0
+VARIABLE(pupa_compressed_size)
+       .long   0
 VARIABLE(pupa_install_dos_part)
        .long   0xFFFFFFFF
 VARIABLE(pupa_install_bsd_part)
@@ -129,6 +132,25 @@ codestart:
        /* The ".code32" directive takes GAS out of 16-bit mode. */
        .code32
 
+       incl    %eax
+       call    EXT_C(pupa_gate_a20)
+
+       /* decompress the compressed part and put the result at 1MB */
+       movl    $0x100000, %esi
+       movl    $(START_SYMBOL + PUPA_KERNEL_MACHINE_RAW_SIZE), %edi
+
+       pushl   %esi
+       pushl   EXT_C(pupa_compressed_size)
+       pushl   %edi
+       call    lzo1x_decompress
+       addl    $12, %esp
+
+       /* copy back the decompressed part */
+       movl    %eax, %ecx
+       cld
+       rep
+       movsb
+
        /* copy modules before cleaning out the bss */
        movl    EXT_C(pupa_total_module_size), %ecx
        movl    EXT_C(pupa_kernel_image_size), %esi
@@ -148,8 +170,9 @@ codestart:
        /* compute the bss length */
        movl    $END_SYMBOL, %ecx
        subl    %edi, %ecx
-               
+                       
        /* clean out */
+       xorl    %eax, %eax
        cld
        rep
        stosb
@@ -160,6 +183,255 @@ codestart:
        call EXT_C(pupa_main)
 
 
+/*
+ *  This is the area for all of the special variables.
+ */
+
+       .p2align        2       /* force 4-byte alignment */
+
+protstack:
+       .long   PUPA_MEMORY_MACHINE_PROT_STACK
+
+VARIABLE(pupa_boot_drive)
+       .long   0
+
+VARIABLE(pupa_start_addr)
+       .long   START_SYMBOL
+
+VARIABLE(pupa_end_addr)
+       .long   END_SYMBOL
+       
+VARIABLE(pupa_apm_bios_info)
+       .word   0       /* version */
+       .word   0       /* cseg */
+       .long   0       /* offset */
+       .word   0       /* cseg_16 */
+       .word   0       /* dseg_16 */
+       .word   0       /* cseg_len */
+       .word   0       /* cseg_16_len */
+       .word   0       /* dseg_16_len */
+       
+/*
+ * This is the Global Descriptor Table
+ *
+ *  An entry, a "Segment Descriptor", looks like this:
+ *
+ * 31          24         19   16                 7           0
+ * ------------------------------------------------------------
+ * |             | |B| |A|       | |   |1|0|E|W|A|            |
+ * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |
+ * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
+ * ------------------------------------------------------------
+ * |                             |                            |
+ * |        BASE 15..0           |       LIMIT 15..0          |
+ * |                             |                            |
+ * ------------------------------------------------------------
+ *
+ *  Note the ordering of the data items is reversed from the above
+ *  description.
+ */
+
+       .p2align        2       /* force 4-byte alignment */
+gdt:
+       .word   0, 0
+       .byte   0, 0, 0, 0
+
+       /* code segment */
+       .word   0xFFFF, 0
+       .byte   0, 0x9A, 0xCF, 0
+
+       /* data segment */
+       .word   0xFFFF, 0
+       .byte   0, 0x92, 0xCF, 0
+
+       /* 16 bit real mode CS */
+       .word   0xFFFF, 0
+       .byte   0, 0x9E, 0, 0
+
+       /* 16 bit real mode DS */
+       .word   0xFFFF, 0
+       .byte   0, 0x92, 0, 0
+
+
+/* this is the GDT descriptor */
+gdtdesc:
+       .word   0x27                    /* limit */
+       .long   gdt                     /* addr */
+
+       
+/*
+ *  These next two routines, "real_to_prot" and "prot_to_real" are structured
+ *  in a very specific way.  Be very careful when changing them.
+ *
+ *  NOTE:  Use of either one messes up %eax and %ebp.
+ */
+
+real_to_prot:
+       .code16
+       cli
+
+       /* load the GDT register */
+       DATA32  ADDR32  lgdt    gdtdesc
+
+       /* turn on protected mode */
+       movl    %cr0, %eax
+       orl     $PUPA_MEMORY_MACHINE_CR0_PE_ON, %eax
+       movl    %eax, %cr0
+
+       /* jump to relocation, flush prefetch queue, and reload %cs */
+       DATA32  ljmp    $PUPA_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
+
+       .code32
+protcseg:
+       /* reload other segment registers */
+       movw    $PUPA_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+
+       /* put the return address in a known safe location */
+       movl    (%esp), %eax
+       movl    %eax, PUPA_MEMORY_MACHINE_REAL_STACK
+
+       /* get protected mode stack */
+       movl    protstack, %eax
+       movl    %eax, %esp
+       movl    %eax, %ebp
+
+       /* get return address onto the right stack */
+       movl    PUPA_MEMORY_MACHINE_REAL_STACK, %eax
+       movl    %eax, (%esp)
+
+       /* zero %eax */
+       xorl    %eax, %eax
+
+       /* return on the old (or initialized) stack! */
+       ret
+
+
+prot_to_real:
+       /* just in case, set GDT */
+       lgdt    gdtdesc
+
+       /* save the protected mode stack */
+       movl    %esp, %eax
+       movl    %eax, protstack
+
+       /* get the return address */
+       movl    (%esp), %eax
+       movl    %eax, PUPA_MEMORY_MACHINE_REAL_STACK
+
+       /* set up new stack */
+       movl    $PUPA_MEMORY_MACHINE_REAL_STACK, %eax
+       movl    %eax, %esp
+       movl    %eax, %ebp
+
+       /* set up segment limits */
+       movw    $PUPA_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+
+       /* this might be an extra step */
+       /* jump to a 16 bit segment */
+       ljmp    $PUPA_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
+
+tmpcseg:
+       .code16
+
+       /* clear the PE bit of CR0 */
+       movl    %cr0, %eax
+       andl    $(~PUPA_MEMORY_MACHINE_CR0_PE_ON), %eax
+       movl    %eax, %cr0
+
+       /* flush prefetch queue, reload %cs */
+       DATA32  ljmp    $0, $realcseg
+
+realcseg:
+       /* we are in real mode now
+        * set up the real mode segment registers : DS, SS, ES
+        */
+       /* zero %eax */
+       xorl    %eax, %eax
+
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+
+       /* restore interrupts */
+       sti
+
+       /* return on new stack! */
+       DATA32  ret
+
+       .code32
+
+
+/*
+ * pupa_gate_a20(int on)
+ *
+ * Gate address-line 20 for high memory.
+ *
+ * This routine is probably overconservative in what it does, but so what?
+ *
+ * It also eats any keystrokes in the keyboard buffer.  :-(
+ */
+
+FUNCTION(pupa_gate_a20)
+       movl    %eax, %ecx
+
+       call    gloop1
+
+       movb    $0xd1, %al
+       outb    $0x64
+
+gloopint1:
+       inb     $0x64
+       andb    $0x02, %al
+       jnz     gloopint1
+
+       movb    $0xdd, %al
+       testl   %ecx, %ecx
+       jz      gdoit
+
+       orb     $0x02, %al
+gdoit:
+       outb    $0x60
+
+       call    gloop1
+
+       /* output a dummy command (USB keyboard hack) */
+       movb    $0xff, %al
+       outb    $0x64
+       call    gloop1
+       
+       ret
+
+gloop1:
+       inb     $0x64
+       andb    $0x02, %al
+       jnz     gloop1
+
+gloop2:
+       inb     $0x64
+       andb    $0x01, %al
+       jz      gloop2ret
+       inb     $0x60
+       jmp     gloop2
+
+gloop2ret:
+       ret
+
+
+#include "lzo1x.S"
+
+
 /*
  *  This call is special...  it never returns...  in fact it should simply
  *  hang at this point!
@@ -348,120 +620,6 @@ linux_setup_seg:
        .code32
 
                
-/*
- *  These next two routines, "real_to_prot" and "prot_to_real" are structured
- *  in a very specific way.  Be very careful when changing them.
- *
- *  NOTE:  Use of either one messes up %eax and %ebp.
- */
-
-real_to_prot:
-       .code16
-       cli
-
-       /* load the GDT register */
-       DATA32  ADDR32  lgdt    gdtdesc
-
-       /* turn on protected mode */
-       movl    %cr0, %eax
-       orl     $PUPA_MEMORY_MACHINE_CR0_PE_ON, %eax
-       movl    %eax, %cr0
-
-       /* jump to relocation, flush prefetch queue, and reload %cs */
-       DATA32  ljmp    $PUPA_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
-
-       .code32
-protcseg:
-       /* reload other segment registers */
-       movw    $PUPA_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-
-       /* put the return address in a known safe location */
-       movl    (%esp), %eax
-       movl    %eax, PUPA_MEMORY_MACHINE_REAL_STACK
-
-       /* get protected mode stack */
-       movl    protstack, %eax
-       movl    %eax, %esp
-       movl    %eax, %ebp
-
-       /* get return address onto the right stack */
-       movl    PUPA_MEMORY_MACHINE_REAL_STACK, %eax
-       movl    %eax, (%esp)
-
-       /* zero %eax */
-       xorl    %eax, %eax
-
-       /* return on the old (or initialized) stack! */
-       ret
-
-
-prot_to_real:
-       /* just in case, set GDT */
-       lgdt    gdtdesc
-
-       /* save the protected mode stack */
-       movl    %esp, %eax
-       movl    %eax, protstack
-
-       /* get the return address */
-       movl    (%esp), %eax
-       movl    %eax, PUPA_MEMORY_MACHINE_REAL_STACK
-
-       /* set up new stack */
-       movl    $PUPA_MEMORY_MACHINE_REAL_STACK, %eax
-       movl    %eax, %esp
-       movl    %eax, %ebp
-
-       /* set up segment limits */
-       movw    $PUPA_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-
-       /* this might be an extra step */
-       /* jump to a 16 bit segment */
-       ljmp    $PUPA_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
-
-tmpcseg:
-       .code16
-
-       /* clear the PE bit of CR0 */
-       movl    %cr0, %eax
-       andl    $(~PUPA_MEMORY_MACHINE_CR0_PE_ON), %eax
-       movl    %eax, %cr0
-
-       /* flush prefetch queue, reload %cs */
-       DATA32  ljmp    $0, $realcseg
-
-realcseg:
-       /* we are in real mode now
-        * set up the real mode segment registers : DS, SS, ES
-        */
-       /* zero %eax */
-       xorl    %eax, %eax
-
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-
-       /* restore interrupts */
-       sti
-
-       /* return on new stack! */
-       DATA32  ret
-
-       .code32
-
-
 /*
  *   int pupa_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
  *
@@ -931,63 +1089,6 @@ xsmap:
        ret
 
        
-/*
- * pupa_gate_a20(int on)
- *
- * Gate address-line 20 for high memory.
- *
- * This routine is probably overconservative in what it does, but so what?
- *
- * It also eats any keystrokes in the keyboard buffer.  :-(
- */
-
-FUNCTION(pupa_gate_a20)
-       pushl   %eax
-
-       call    gloop1
-
-       movb    $0xd1, %al
-       outb    $0x64
-
-gloopint1:
-       inb     $0x64
-       andb    $0x02, %al
-       jnz     gloopint1
-
-       movb    $0xdd, %al
-       cmpb    $0, 0x8(%esp)
-       jz      gdoit
-
-       orb     $0x02, %al
-gdoit:
-       outb    $0x60
-
-       call    gloop1
-
-       /* output a dummy command (USB keyboard hack) */
-       movb    $0xff, %al
-       outb    $0x64
-       call    gloop1
-       
-       popl    %eax
-       ret
-
-gloop1:
-       inb     $0x64
-       andb    $0x02, %al
-       jnz     gloop1
-
-gloop2:
-       inb     $0x64
-       andb    $0x01, %al
-       jz      gloop2ret
-       inb     $0x60
-       jmp     gloop2
-
-gloop2ret:
-       ret
-
-
 /*
  * void pupa_console_putchar (int c)
  *
@@ -1413,79 +1514,3 @@ FUNCTION(pupa_currticks)
 
        popl    %ebp
        ret
-
-
-/*
- *  This is the area for all of the special variables.
- */
-
-       .p2align        2       /* force 4-byte alignment */
-
-protstack:
-       .long   PUPA_MEMORY_MACHINE_PROT_STACK
-
-VARIABLE(pupa_boot_drive)
-       .long   0
-
-VARIABLE(pupa_start_addr)
-       .long   START_SYMBOL
-
-VARIABLE(pupa_end_addr)
-       .long   END_SYMBOL
-       
-VARIABLE(pupa_apm_bios_info)
-       .word   0       /* version */
-       .word   0       /* cseg */
-       .long   0       /* offset */
-       .word   0       /* cseg_16 */
-       .word   0       /* dseg_16 */
-       .word   0       /* cseg_len */
-       .word   0       /* cseg_16_len */
-       .word   0       /* dseg_16_len */
-       
-/*
- * This is the Global Descriptor Table
- *
- *  An entry, a "Segment Descriptor", looks like this:
- *
- * 31          24         19   16                 7           0
- * ------------------------------------------------------------
- * |             | |B| |A|       | |   |1|0|E|W|A|            |
- * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |
- * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
- * ------------------------------------------------------------
- * |                             |                            |
- * |        BASE 15..0           |       LIMIT 15..0          |
- * |                             |                            |
- * ------------------------------------------------------------
- *
- *  Note the ordering of the data items is reversed from the above
- *  description.
- */
-
-       .p2align        2       /* force 4-byte alignment */
-gdt:
-       .word   0, 0
-       .byte   0, 0, 0, 0
-
-       /* code segment */
-       .word   0xFFFF, 0
-       .byte   0, 0x9A, 0xCF, 0
-
-       /* data segment */
-       .word   0xFFFF, 0
-       .byte   0, 0x92, 0xCF, 0
-
-       /* 16 bit real mode CS */
-       .word   0xFFFF, 0
-       .byte   0, 0x9E, 0, 0
-
-       /* 16 bit real mode DS */
-       .word   0xFFFF, 0
-       .byte   0, 0x92, 0, 0
-
-
-/* this is the GDT descriptor */
-gdtdesc:
-       .word   0x27                    /* limit */
-       .long   gdt                     /* addr */
index 6eba8d3d806629c9b9026fafe83826adb84befbf..ce88f9a89074fe6809e14a3f3af6e052b69fd2fb 100644 (file)
--- a/kern/mm.c
+++ b/kern/mm.c
@@ -135,7 +135,7 @@ static void *
 pupa_real_malloc (pupa_mm_header_t *first, pupa_size_t n, pupa_size_t align)
 {
   pupa_mm_header_t p, q;
-  
+
   if ((*first)->magic == PUPA_MM_ALLOC_MAGIC)
     return 0;
 
index 0713a6647b088d73894a2411676e25fc7d5fe1d4..ea850dc4ee1aedb4b5c01bb1697e09bd8013bcaf 100644 (file)
@@ -1,7 +1,7 @@
 /* pupa-mkimage.c - make a bootable image */
 /*
  *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
- *  Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *  Copyright (C) 2002,2003  Yoshinori K. Okuji <okuji@enbug.org>
  *
  *  PUPA is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
 #define _GNU_SOURCE    1
 #include <getopt.h>
 
+#include <lzo1x.h>
+
+static void
+compress_kernel (char *kernel_img, size_t kernel_size,
+                char **core_img, size_t *core_size)
+{
+  lzo_uint size;
+  char *wrkmem;
+  
+  pupa_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
+  if (kernel_size < PUPA_KERNEL_MACHINE_RAW_SIZE)
+    pupa_util_error ("the core image is too small");
+  
+  if (lzo_init () != LZO_E_OK)
+    pupa_util_error ("cannot initialize LZO");
+
+  *core_img = xmalloc (kernel_size + kernel_size / 64 + 16 + 3);
+  wrkmem = xmalloc (LZO1X_999_MEM_COMPRESS);
+
+  memcpy (*core_img, kernel_img, PUPA_KERNEL_MACHINE_RAW_SIZE);
+  
+  pupa_util_info ("compressing the core image");
+  if (lzo1x_999_compress (kernel_img + PUPA_KERNEL_MACHINE_RAW_SIZE,
+                         kernel_size - PUPA_KERNEL_MACHINE_RAW_SIZE,
+                         *core_img + PUPA_KERNEL_MACHINE_RAW_SIZE,
+                         &size, wrkmem)
+      != LZO_E_OK)
+    pupa_util_error ("cannot compress the kernel image");
+
+  free (wrkmem);
+
+  *core_size = (size_t) size + PUPA_KERNEL_MACHINE_RAW_SIZE;
+}
+
 static void
 generate_image (const char *dir, FILE *out, char *mods[])
 {
   pupa_addr_t module_addr = 0;
-  char *kernel_img, *boot_img;
-  size_t kernel_size, boot_size, total_module_size;
+  char *kernel_img, *boot_img, *core_img;
+  size_t kernel_size, boot_size, total_module_size, core_size;
   char *kernel_path, *boot_path;
   unsigned num;
+  size_t offset;
   struct pupa_util_path_list *path_list, *p, *next;
 
   path_list = pupa_util_resolve_dependencies (dir, "moddep.lst", mods);
@@ -56,9 +91,32 @@ generate_image (const char *dir, FILE *out, char *mods[])
                          + sizeof (struct pupa_module_header));
 
   pupa_util_info ("the total module size is 0x%x", total_module_size);
+
+  kernel_img = xmalloc (kernel_size + total_module_size);
+  pupa_util_load_image (kernel_path, kernel_img);
+  offset = kernel_size;
+  for (p = path_list; p; p = p->next)
+    {
+      struct pupa_module_header *header;
+      size_t mod_size;
+
+      mod_size = pupa_util_get_image_size (p->name);
+      
+      header = (struct pupa_module_header *) (kernel_img + offset);
+      header->offset = pupa_cpu_to_le32 (sizeof (*header));
+      header->size = pupa_cpu_to_le32 (mod_size + sizeof (*header));
+      
+      pupa_util_load_image (p->name, kernel_img + offset + sizeof (*header));
+
+      offset += sizeof (*header) + mod_size;
+    }
+
+  compress_kernel (kernel_img, kernel_size + total_module_size,
+                  &core_img, &core_size);
+
+  pupa_util_info ("the core size is 0x%x", core_size);
   
-  num = ((kernel_size + total_module_size + PUPA_DISK_SECTOR_SIZE - 1)
-        >> PUPA_DISK_SECTOR_BITS);
+  num = ((core_size + PUPA_DISK_SECTOR_SIZE - 1) >> PUPA_DISK_SECTOR_BITS);
   if (num > 0xffff)
     pupa_util_error ("the core image is too big");
 
@@ -78,42 +136,27 @@ generate_image (const char *dir, FILE *out, char *mods[])
   free (boot_img);
   free (boot_path);
   
-  kernel_img = pupa_util_read_image (kernel_path);
   module_addr = (path_list
                 ? (PUPA_BOOT_MACHINE_KERNEL_ADDR + PUPA_DISK_SECTOR_SIZE
                    + kernel_size)
                 : 0);
 
   pupa_util_info ("the first module address is 0x%x", module_addr);
-  *((pupa_uint32_t *) (kernel_img + PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE))
+  *((pupa_uint32_t *) (core_img + PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE))
     = pupa_cpu_to_le32 (total_module_size);
-  *((pupa_uint32_t *) (kernel_img + PUPA_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
+  *((pupa_uint32_t *) (core_img + PUPA_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
     = pupa_cpu_to_le32 (kernel_size);
+  *((pupa_uint32_t *) (core_img + PUPA_KERNEL_MACHINE_COMPRESSED_SIZE))
+    = pupa_cpu_to_le32 (core_size - PUPA_KERNEL_MACHINE_RAW_SIZE);
   
-  pupa_util_write_image (kernel_img, kernel_size, out);
+  pupa_util_write_image (core_img, core_size, out);
   free (kernel_img);
+  free (core_img);
   free (kernel_path);
 
   while (path_list)
     {
-      struct pupa_module_header header;
-      size_t mod_size;
-      char *mod_img;
-      
       next = path_list->next;
-      
-      mod_size = pupa_util_get_image_size (path_list->name);
-
-      header.offset = pupa_cpu_to_le32 (sizeof (header));
-      header.size = pupa_cpu_to_le32 (mod_size + sizeof (header));
-
-      pupa_util_info ("offset=0x%x, size=0x%x", header.offset, header.size);
-      pupa_util_write_image ((char *) &header, sizeof (header), out);
-      
-      mod_img = pupa_util_read_image (path_list->name);
-      pupa_util_write_image (mod_img, mod_size, out);
-      free (mod_img);
-
       free ((void *) path_list->name);
       free (path_list);
       path_list = next;
index 95b10e36e3f0bdc25ab1d8f8e72406ed53aed60a..a8a0b971795c74b9a27211fa00cb7ad3990a34ab 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
- *  Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *  Copyright (C) 2002,2003 Yoshinori K. Okuji <okuji@enbug.org>
  *
  *  PUPA is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -136,9 +136,31 @@ pupa_util_read_image (const char *path)
   if (fread (img, 1, size, fp) != size)
     pupa_util_error ("cannot read %s", path);
 
+  fclose (fp);
+  
   return img;
 }
 
+void
+pupa_util_load_image (const char *path, char *buf)
+{
+  FILE *fp;
+  size_t size;
+  
+  pupa_util_info ("reading %s", path);
+
+  size = pupa_util_get_image_size (path);
+  
+  fp = fopen (path, "rb");
+  if (! fp)
+    pupa_util_error ("cannot open %s", path);
+
+  if (fread (buf, 1, size, fp) != size)
+    pupa_util_error ("cannot read %s", path);
+
+  fclose (fp);
+}
+
 void
 pupa_util_write_image (const char *img, size_t size, FILE *out)
 {