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.
This commit is contained in:
okuji 2003-01-31 03:26:56 +00:00
parent ce5bf700ca
commit 1f5ab4280a
18 changed files with 931 additions and 298 deletions

View File

@ -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.

View File

@ -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.

6
NEWS
View File

@ -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:

4
THANKS
View File

@ -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.

View 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 $@ $<

View 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 \

View 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

146
configure vendored
View File

@ -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"

View 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"

View File

@ -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]

View 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
@ -20,22 +20,30 @@
#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 */

View 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 */

View 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)

323
kern/i386/pc/lzo1x.S Normal file
View File

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

View 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 */

View File

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

View 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
@ -35,14 +35,49 @@
#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;

View 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)
{