mirror of
http://cgit.git.savannah.gnu.org/git/grub.git
synced 2026-04-28 14:33:34 +00:00
Compare commits
16 Commits
arm_corebo
...
phcoder/sc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3635094bf4 | ||
|
|
aeebec13ab | ||
|
|
3863ea6088 | ||
|
|
0290aa8596 | ||
|
|
09f5da1df6 | ||
|
|
002ba123eb | ||
|
|
a7831929d3 | ||
|
|
2cbee7340c | ||
|
|
850da8e056 | ||
|
|
f9fa053b69 | ||
|
|
2f1fd54c38 | ||
|
|
df056a2788 | ||
|
|
1d83f4d467 | ||
|
|
b2b8ed7032 | ||
|
|
4b03082fa9 | ||
|
|
d5edef1a77 |
@@ -119,6 +119,7 @@ library = {
|
||||
common = grub-core/fs/sfs.c;
|
||||
common = grub-core/fs/squash4.c;
|
||||
common = grub-core/fs/tar.c;
|
||||
common = grub-core/fs/greffs.c;
|
||||
common = grub-core/fs/udf.c;
|
||||
common = grub-core/fs/ufs2.c;
|
||||
common = grub-core/fs/ufs.c;
|
||||
|
||||
74
acinclude.m4
74
acinclude.m4
@@ -210,80 +210,6 @@ fi
|
||||
])
|
||||
|
||||
|
||||
dnl Mass confusion!
|
||||
dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit
|
||||
dnl instructions, but implicitly insert addr32 and data32 bytes so
|
||||
dnl that the code works in real mode''.
|
||||
dnl
|
||||
dnl Newer versions of GAS interpret `.code16' to mean ``generate 16-bit
|
||||
dnl instructions,'' which seems right. This requires the programmer
|
||||
dnl to explicitly insert addr32 and data32 instructions when they want
|
||||
dnl them.
|
||||
dnl
|
||||
dnl We only support the newer versions, because the old versions cause
|
||||
dnl major pain, by requiring manual assembly to get 16-bit instructions into
|
||||
dnl asm files.
|
||||
AC_DEFUN([grub_I386_ASM_ADDR32],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([grub_I386_ASM_PREFIX_REQUIREMENT])
|
||||
AC_MSG_CHECKING([for .code16 addr32 assembler support])
|
||||
AC_CACHE_VAL(grub_cv_i386_asm_addr32,
|
||||
[cat > conftest.s.in <<\EOF
|
||||
.code16
|
||||
l1: @ADDR32@ movb %al, l1
|
||||
EOF
|
||||
|
||||
if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then
|
||||
sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s
|
||||
else
|
||||
sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s
|
||||
fi
|
||||
|
||||
if AC_TRY_COMMAND([${CC-cc} ${TARGET_CCASFLAGS} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
|
||||
grub_cv_i386_asm_addr32=yes
|
||||
else
|
||||
grub_cv_i386_asm_addr32=no
|
||||
fi
|
||||
|
||||
rm -f conftest*])
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_i386_asm_addr32])])
|
||||
|
||||
dnl Later versions of GAS requires that addr32 and data32 prefixes
|
||||
dnl appear in the same lines as the instructions they modify, while
|
||||
dnl earlier versions requires that they appear in separate lines.
|
||||
AC_DEFUN([grub_I386_ASM_PREFIX_REQUIREMENT],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(dnl
|
||||
[whether addr32 must be in the same line as the instruction])
|
||||
AC_CACHE_VAL(grub_cv_i386_asm_prefix_requirement,
|
||||
[cat > conftest.s <<\EOF
|
||||
.code16
|
||||
l1: addr32 movb %al, l1
|
||||
EOF
|
||||
|
||||
if AC_TRY_COMMAND([${CC-cc} ${TARGET_CCASFLAGS} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
|
||||
grub_cv_i386_asm_prefix_requirement=yes
|
||||
else
|
||||
grub_cv_i386_asm_prefix_requirement=no
|
||||
fi
|
||||
|
||||
rm -f conftest*])
|
||||
|
||||
if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then
|
||||
grub_tmp_addr32="addr32"
|
||||
grub_tmp_data32="data32"
|
||||
else
|
||||
grub_tmp_addr32="addr32;"
|
||||
grub_tmp_data32="data32;"
|
||||
fi
|
||||
|
||||
ADDR32=$grub_tmp_addr32
|
||||
DATA32=$grub_tmp_data32
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_i386_asm_prefix_requirement])])
|
||||
|
||||
|
||||
dnl Check what symbol is defined as a bss start symbol.
|
||||
dnl Written by Michael Hohmoth and Yoshinori K. Okuji.
|
||||
AC_DEFUN([grub_CHECK_BSS_START_SYMBOL],
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
#define HAVE_FONT_SOURCE @HAVE_FONT_SOURCE@
|
||||
/* Define if C symbols get an underscore after compilation. */
|
||||
#define HAVE_ASM_USCORE @HAVE_ASM_USCORE@
|
||||
/* Define it to \"addr32\" or \"addr32;\" to make GAS happy. */
|
||||
#define ADDR32 @ADDR32@
|
||||
/* Define it to \"data32\" or \"data32;\" to make GAS happy. */
|
||||
#define DATA32 @DATA32@
|
||||
/* Define it to one of __bss_start, edata and _edata. */
|
||||
#define BSS_START_SYMBOL @BSS_START_SYMBOL@
|
||||
/* Define it to either end or _end. */
|
||||
|
||||
29
configure.ac
29
configure.ac
@@ -538,12 +538,33 @@ AC_COMPILE_IFELSE(
|
||||
# on arm clang doesn't support .arch directive
|
||||
# on mips clang doesn't support privilegied instructions, doubleword store/load
|
||||
# and crashes with hand-written assembly
|
||||
if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xi386 \
|
||||
|| test "x$target_cpu" = xx86_64 || test "x$target_cpu" = xarm \
|
||||
if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xarm \
|
||||
|| test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ); then
|
||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as"
|
||||
fi
|
||||
|
||||
if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xi386 \
|
||||
|| test "x$target_cpu" = xx86_64 ); then
|
||||
AC_CACHE_CHECK([if clang can handle .code16], [grub_cv_cc_target_clang_code16]
|
||||
[
|
||||
CFLAGS="$TARGET_CCASFLAGS"
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([], [[
|
||||
asm volatile (".code16\n"
|
||||
"xorw %ax, %ax\n"
|
||||
#ifdef __x86_64__
|
||||
".code64\n"
|
||||
#else
|
||||
".code32\n"
|
||||
#endif
|
||||
);
|
||||
]])],
|
||||
[grub_cv_cc_target_clang_code16=yes], [grub_cv_cc_target_clang_code16=no])])
|
||||
if test x$grub_cv_cc_target_clang_code16 = xno ; then
|
||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$grub_cv_cc_target_clang" = xyes && test "x$target_cpu" = xpowerpc; then
|
||||
AC_CACHE_CHECK([if clang can handle ame instruction], [grub_cv_cc_target_clang_ame]
|
||||
[
|
||||
@@ -1046,8 +1067,6 @@ if test "x$target_cpu" = xi386; then
|
||||
grub_CHECK_END_SYMBOL
|
||||
fi
|
||||
CFLAGS="$TARGET_CFLAGS"
|
||||
grub_I386_ASM_PREFIX_REQUIREMENT
|
||||
grub_I386_ASM_ADDR32
|
||||
fi
|
||||
|
||||
grub_PROG_NM_WORKS
|
||||
@@ -1568,8 +1587,6 @@ AS_IF([test x$target_cpu = xi386 -a x$platform = xqemu],
|
||||
[AC_SUBST([GRUB_BOOT_MACHINE_LINK_ADDR], 0xffe00)])
|
||||
|
||||
AC_SUBST(HAVE_ASM_USCORE)
|
||||
AC_SUBST(ADDR32)
|
||||
AC_SUBST(DATA32)
|
||||
AC_SUBST(BSS_START_SYMBOL)
|
||||
AC_SUBST(END_SYMBOL)
|
||||
AC_SUBST(PACKAGE)
|
||||
|
||||
@@ -1399,6 +1399,11 @@ module = {
|
||||
common = fs/tar.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = greffs;
|
||||
common = fs/greffs.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = udf;
|
||||
common = fs/udf.c;
|
||||
|
||||
@@ -165,8 +165,8 @@ start:
|
||||
* this area.
|
||||
*/
|
||||
|
||||
. = _start + GRUB_BOOT_MACHINE_BPB_START
|
||||
. = _start + 4
|
||||
.org GRUB_BOOT_MACHINE_BPB_START
|
||||
.org 4
|
||||
#endif
|
||||
#ifdef HYBRID_BOOT
|
||||
floppy
|
||||
@@ -174,7 +174,7 @@ start:
|
||||
scratch
|
||||
#endif
|
||||
|
||||
. = _start + GRUB_BOOT_MACHINE_BPB_END
|
||||
.org GRUB_BOOT_MACHINE_BPB_END
|
||||
/*
|
||||
* End of BIOS parameter block.
|
||||
*/
|
||||
@@ -183,14 +183,14 @@ kernel_address:
|
||||
.word GRUB_BOOT_MACHINE_KERNEL_ADDR
|
||||
|
||||
#ifndef HYBRID_BOOT
|
||||
. = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR
|
||||
.org GRUB_BOOT_MACHINE_KERNEL_SECTOR
|
||||
kernel_sector:
|
||||
.long 1
|
||||
kernel_sector_high:
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
. = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE
|
||||
.org GRUB_BOOT_MACHINE_BOOT_DRIVE
|
||||
boot_drive:
|
||||
.byte 0xff /* the disk to load kernel from */
|
||||
/* 0xff means use the boot drive */
|
||||
@@ -208,7 +208,7 @@ LOCAL(after_BPB):
|
||||
* possible boot drive. If GRUB is installed into a floppy,
|
||||
* this does nothing (only jump).
|
||||
*/
|
||||
. = _start + GRUB_BOOT_MACHINE_DRIVE_CHECK
|
||||
.org GRUB_BOOT_MACHINE_DRIVE_CHECK
|
||||
boot_drive_check:
|
||||
jmp 3f /* grub-setup may overwrite this jump */
|
||||
testb $0x80, %dl
|
||||
@@ -511,13 +511,13 @@ LOCAL(message):
|
||||
*/
|
||||
|
||||
#ifdef HYBRID_BOOT
|
||||
. = _start + 0x1b0
|
||||
.org 0x1b0
|
||||
kernel_sector:
|
||||
.long 1
|
||||
kernel_sector_high:
|
||||
.long 0
|
||||
#endif
|
||||
. = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
|
||||
.org GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
|
||||
nt_magic:
|
||||
.long 0
|
||||
.word 0
|
||||
@@ -528,7 +528,7 @@ nt_magic:
|
||||
* sneaky, huh?
|
||||
*/
|
||||
|
||||
. = _start + GRUB_BOOT_MACHINE_PART_START
|
||||
.org GRUB_BOOT_MACHINE_PART_START
|
||||
|
||||
#ifndef HYBRID_BOOT
|
||||
floppy
|
||||
@@ -536,7 +536,7 @@ nt_magic:
|
||||
scratch
|
||||
#endif
|
||||
|
||||
. = _start + GRUB_BOOT_MACHINE_PART_END
|
||||
.org GRUB_BOOT_MACHINE_PART_END
|
||||
|
||||
/* the last 2 bytes in the sector 0 contain the signature */
|
||||
.word GRUB_BOOT_MACHINE_SIGNATURE
|
||||
|
||||
@@ -43,7 +43,7 @@ _start:
|
||||
LOCAL(next):
|
||||
jmp 1f
|
||||
|
||||
. = start + 8
|
||||
.org 8
|
||||
|
||||
bi_pvd:
|
||||
.long 0 /* LBA of primary volume descriptor. */
|
||||
@@ -168,6 +168,6 @@ err_noboot_msg:
|
||||
err_cdfail_msg:
|
||||
.ascii "cdrom read fails\0"
|
||||
|
||||
. = start + 0x7FF
|
||||
.org 0x7FF
|
||||
|
||||
.byte 0
|
||||
|
||||
@@ -362,7 +362,7 @@ LOCAL(message):
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
. = _start + 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE
|
||||
.org 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE
|
||||
LOCAL(firstlist): /* this label has to be before the first list entry!!! */
|
||||
/* fill the first data listing with the default */
|
||||
blocklist_default_start:
|
||||
|
||||
@@ -41,7 +41,7 @@ data_start:
|
||||
xorl %ebp, %ebp
|
||||
jmp LOCAL(linux_next)
|
||||
|
||||
. = data_start + 0x1F1
|
||||
.org 0x1F1
|
||||
|
||||
setup_sects:
|
||||
.byte CODE_SECTORS
|
||||
@@ -292,4 +292,4 @@ LOCAL(fail):
|
||||
err_int15_msg:
|
||||
.ascii "move memory fails\0"
|
||||
|
||||
. = _start + CODE_SECTORS * 512
|
||||
.org (CODE_SECTORS + 1) * 512
|
||||
|
||||
@@ -38,5 +38,5 @@ start:
|
||||
/* This region is a junk. Do you say that this is wasteful?
|
||||
But I like that the memory layout of the body is consistent
|
||||
among different kernels rather than scamping just for 1.5KB. */
|
||||
. = _start + 0x8200 - 0x7C00 - 0x200 - 1
|
||||
.org 0x8200 - 0x7C00 - 0x200 - 1
|
||||
.byte 0
|
||||
|
||||
@@ -50,23 +50,23 @@ LOCAL (base):
|
||||
* This is a special data area.
|
||||
*/
|
||||
|
||||
. = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
|
||||
.org GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
|
||||
LOCAL(compressed_size):
|
||||
.long 0
|
||||
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
|
||||
.org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
|
||||
LOCAL(uncompressed_size):
|
||||
.long 0
|
||||
|
||||
. = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
|
||||
.org GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
|
||||
reed_solomon_redundancy:
|
||||
.long 0
|
||||
. = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH
|
||||
.org GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH
|
||||
.short (LOCAL(reed_solomon_part) - _start)
|
||||
|
||||
/*
|
||||
* This is the area for all of the special variables.
|
||||
*/
|
||||
. = _start + GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE
|
||||
.org GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE
|
||||
LOCAL(boot_dev):
|
||||
.byte 0xFF, 0xFF, 0xFF
|
||||
LOCAL(boot_drive):
|
||||
@@ -89,13 +89,13 @@ LOCAL (codestart):
|
||||
sti /* we're safe again */
|
||||
|
||||
/* save the boot drive */
|
||||
ADDR32 movb %dl, LOCAL(boot_drive)
|
||||
movb %dl, LOCAL(boot_drive)
|
||||
|
||||
/* reset disk system (%ah = 0) */
|
||||
int $0x13
|
||||
|
||||
/* transition to protected mode */
|
||||
DATA32 call real_to_prot
|
||||
calll real_to_prot
|
||||
|
||||
/* The ".code32" directive takes GAS out of 16-bit mode. */
|
||||
.code32
|
||||
@@ -149,7 +149,7 @@ gate_a20_try_bios:
|
||||
movw $0x2401, %ax
|
||||
int $0x15
|
||||
|
||||
DATA32 call real_to_prot
|
||||
calll real_to_prot
|
||||
.code32
|
||||
|
||||
popl %ebp
|
||||
|
||||
@@ -31,7 +31,7 @@ _start:
|
||||
|
||||
jmp 1f
|
||||
|
||||
. = _start + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR
|
||||
.org GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR
|
||||
VARIABLE(grub_core_entry_addr)
|
||||
.long 0
|
||||
1:
|
||||
@@ -48,7 +48,7 @@ VARIABLE(grub_core_entry_addr)
|
||||
/* Transition to protected mode. We use pushl to force generation
|
||||
of a flat return address. */
|
||||
pushl $1f
|
||||
DATA32 jmp real_to_prot
|
||||
jmpl real_to_prot
|
||||
.code32
|
||||
/* Ensure A20 is enabled. We're in qemu, so control port A works
|
||||
and there is no need to wait since there is no real logic, it's
|
||||
@@ -66,9 +66,9 @@ VARIABLE(grub_core_entry_addr)
|
||||
/* Intel, in its infinite wisdom, decided to put the i8086 entry point
|
||||
*right here* and this is why we need this kludge. */
|
||||
|
||||
. = GRUB_BOOT_MACHINE_SIZE - 16
|
||||
.org GRUB_BOOT_MACHINE_SIZE - 16
|
||||
|
||||
.code16
|
||||
|
||||
jmp _start
|
||||
. = GRUB_BOOT_MACHINE_SIZE
|
||||
.org GRUB_BOOT_MACHINE_SIZE
|
||||
|
||||
@@ -162,7 +162,7 @@ retry_cs5536:
|
||||
|
||||
b continue
|
||||
|
||||
. = start + GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START
|
||||
.org GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START
|
||||
tlb_refill:
|
||||
mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
|
||||
mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR
|
||||
@@ -196,13 +196,13 @@ tlb_refill:
|
||||
b fatal
|
||||
addiu $a0, $a0, %lo(unhandled_tlb_refill)
|
||||
|
||||
. = start + GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START
|
||||
.org GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START
|
||||
cache_error:
|
||||
lui $a0, %hi(unhandled_cache_error)
|
||||
b fatal
|
||||
addiu $a0, $a0, %lo(unhandled_cache_error)
|
||||
|
||||
. = start + GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START
|
||||
.org GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START
|
||||
other_exception:
|
||||
mfc0 $s0, GRUB_CPU_LOONGSON_COP0_CAUSE
|
||||
mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
|
||||
|
||||
@@ -39,13 +39,13 @@ start:
|
||||
bal codestart
|
||||
nop
|
||||
base:
|
||||
. = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
|
||||
.org GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
|
||||
compressed_size:
|
||||
.long 0
|
||||
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
|
||||
.org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
|
||||
uncompressed_size:
|
||||
.long 0
|
||||
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR
|
||||
.org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR
|
||||
uncompressed_addr:
|
||||
.long 0
|
||||
codestart:
|
||||
|
||||
@@ -41,9 +41,9 @@ pic_base:
|
||||
* After loading in that block we will execute it by jumping to the
|
||||
* load address plus the size of the prepended A.OUT header (32 bytes).
|
||||
*/
|
||||
. = _start + GRUB_BOOT_MACHINE_BOOT_DEVPATH
|
||||
.org GRUB_BOOT_MACHINE_BOOT_DEVPATH
|
||||
boot_path:
|
||||
. = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE
|
||||
.org GRUB_BOOT_MACHINE_KERNEL_BYTE
|
||||
boot_path_end:
|
||||
kernel_byte: .xword (2 << 9)
|
||||
kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
|
||||
@@ -52,7 +52,7 @@ kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
|
||||
#define boot_path_end (_start + 1024)
|
||||
#include <grub/offsets.h>
|
||||
|
||||
. = _start + 8
|
||||
.org 8
|
||||
kernel_byte: .xword (2 << 9)
|
||||
kernel_size: .word 512
|
||||
kernel_address: .word GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS
|
||||
@@ -224,7 +224,7 @@ bootpath_known:
|
||||
#else
|
||||
nop
|
||||
#endif
|
||||
. = _start + GRUB_BOOT_MACHINE_CODE_END
|
||||
.org GRUB_BOOT_MACHINE_CODE_END
|
||||
|
||||
/* the last 4 bytes in the sector 0 contain the signature */
|
||||
.word GRUB_BOOT_MACHINE_SIGNATURE
|
||||
|
||||
@@ -136,7 +136,7 @@ lastlist:
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
. = _start + (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE)
|
||||
.org (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE)
|
||||
blocklist_default_start:
|
||||
.word 0
|
||||
.word 2
|
||||
|
||||
@@ -333,6 +333,21 @@ name_devices (struct grub_efidisk_data *devices)
|
||||
if (! dp)
|
||||
continue;
|
||||
|
||||
/* Ghosts proudly presented by Apple. */
|
||||
if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
|
||||
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (dp)
|
||||
== GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE)
|
||||
{
|
||||
grub_efi_vendor_device_path_t *vendor = (grub_efi_vendor_device_path_t *) dp;
|
||||
const struct grub_efi_guid apple = GRUB_EFI_VENDOR_APPLE_GUID;
|
||||
|
||||
if (vendor->header.length == sizeof (*vendor)
|
||||
&& grub_memcmp (&vendor->vendor_guid, &apple,
|
||||
sizeof (vendor->vendor_guid)) == 0
|
||||
&& find_parent_device (devices, d))
|
||||
continue;
|
||||
}
|
||||
|
||||
m = d->block_io->media;
|
||||
if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_ACPI_DEVICE_PATH_TYPE
|
||||
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (dp)
|
||||
@@ -654,6 +669,7 @@ grub_efidisk_get_device_handle (grub_disk_t disk)
|
||||
|
||||
case 'h':
|
||||
/* If this is the whole disk, just return its own data. */
|
||||
grub_printf ("parent handle = %p\n", d->handle);
|
||||
if (! disk->partition)
|
||||
return d->handle;
|
||||
|
||||
@@ -664,13 +680,24 @@ grub_efidisk_get_device_handle (grub_disk_t disk)
|
||||
struct grub_efidisk_data *c;
|
||||
|
||||
devices = make_devices ();
|
||||
FOR_CHILDREN (c, devices)
|
||||
grub_efi_print_device_path (d->device_path);
|
||||
for (c = devices; c; c = c->next)
|
||||
{
|
||||
grub_efi_hard_drive_device_path_t *hd;
|
||||
|
||||
hd = (grub_efi_hard_drive_device_path_t *) c->last_device_path;
|
||||
|
||||
if ((GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path)
|
||||
grub_efi_print_device_path (c->device_path);
|
||||
grub_printf ("part %d = %x, %x, %x, %x, %x, %x\n",
|
||||
is_child (c, d),
|
||||
(int) GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path),
|
||||
(int) GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path),
|
||||
(int) hd->partition_start, (int) hd->partition_size,
|
||||
(int) grub_partition_get_start (disk->partition),
|
||||
(int) grub_partition_get_len (disk->partition));
|
||||
|
||||
if (is_child (c, d)
|
||||
&& (GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path)
|
||||
== GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
|
||||
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path)
|
||||
== GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)
|
||||
|
||||
314
grub-core/fs/greffs.c
Normal file
314
grub-core/fs/greffs.c
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/misc.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/archelp.h>
|
||||
|
||||
#include <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/greffs.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
struct grub_greffs_data
|
||||
{
|
||||
grub_uint32_t dofs;
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
get_string (grub_disk_t disk,
|
||||
const struct grub_greffs_header *head,
|
||||
grub_uint32_t fn,
|
||||
char **buf, grub_size_t *size)
|
||||
{
|
||||
grub_uint32_t desc[2];
|
||||
grub_size_t read_size;
|
||||
|
||||
if (grub_disk_read (disk, 0,
|
||||
grub_cpu_to_le32 (head->string_ptrs_offset)
|
||||
+ fn * sizeof (desc[0]), sizeof (desc), &desc))
|
||||
return grub_errno;
|
||||
read_size = desc[1] - desc[0];
|
||||
if (*size < read_size + 1)
|
||||
{
|
||||
grub_free (*buf);
|
||||
*size = (read_size + 4) * 2;
|
||||
*buf = grub_malloc (*size);
|
||||
if (!*buf)
|
||||
{
|
||||
*size = 0;
|
||||
return grub_errno;
|
||||
}
|
||||
}
|
||||
if (grub_disk_read (disk, 0, desc[0], read_size, *buf))
|
||||
return grub_errno;
|
||||
(*buf)[read_size] = '\0';
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
find_file (grub_disk_t disk,
|
||||
struct grub_greffs_header *head,
|
||||
const char *name_in, grub_uint32_t *f, int exact)
|
||||
{
|
||||
grub_uint32_t num_files, cur_file = 0;
|
||||
int i;
|
||||
char *buf = NULL;
|
||||
grub_size_t buf_size = 0;
|
||||
grub_err_t err;
|
||||
|
||||
num_files = grub_le_to_cpu32 (head->nfiles);
|
||||
|
||||
for (i = 31; i >= 0; i--)
|
||||
{
|
||||
int cmp;
|
||||
if ((cur_file | (1 << i)) > num_files)
|
||||
continue;
|
||||
err = get_string (disk, head, (cur_file | (1 << i)) - 1, &buf, &buf_size);
|
||||
if (err)
|
||||
{
|
||||
grub_free (buf);
|
||||
return err;
|
||||
}
|
||||
cmp = grub_strcmp (buf, name_in);
|
||||
if (cmp <= 0)
|
||||
cur_file |= (1 << i);
|
||||
if (cmp == 0)
|
||||
{
|
||||
grub_free (buf);
|
||||
*f = cur_file - 1;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
grub_free (buf);
|
||||
if (!exact)
|
||||
{
|
||||
*f = cur_file;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
|
||||
name_in);
|
||||
}
|
||||
|
||||
static char *
|
||||
canonicalize (const char *name_in, int make_dir)
|
||||
{
|
||||
const char *iptr;
|
||||
char *out, *optr;
|
||||
out = grub_malloc (grub_strlen (name_in) + 2);
|
||||
if (!out)
|
||||
return NULL;
|
||||
for (iptr = name_in, optr = out; *iptr; )
|
||||
{
|
||||
while (*iptr == '/')
|
||||
iptr++;
|
||||
if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0))
|
||||
{
|
||||
iptr += 2;
|
||||
continue;
|
||||
}
|
||||
if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0))
|
||||
{
|
||||
iptr += 3;
|
||||
if (optr == out)
|
||||
continue;
|
||||
for (optr -= 2; optr >= out && *optr != '/'; optr--);
|
||||
optr++;
|
||||
continue;
|
||||
}
|
||||
while (*iptr && *iptr != '/')
|
||||
*optr++ = *iptr++;
|
||||
if (*iptr)
|
||||
*optr++ = *iptr++;
|
||||
else if (make_dir && optr != out)
|
||||
*optr++ = '/';
|
||||
}
|
||||
*optr = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_greffs_dir (grub_device_t device, const char *path_in,
|
||||
grub_fs_dir_hook_t hook, void *hook_data)
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_uint32_t cur_file, num_files;
|
||||
char *buf = 0;
|
||||
grub_size_t buf_size = 0;
|
||||
char *can;
|
||||
grub_size_t len;
|
||||
struct grub_greffs_header head;
|
||||
|
||||
if (grub_disk_read (device->disk, 0, 0, sizeof (head), &head))
|
||||
return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
|
||||
|
||||
if (grub_memcmp (head.magic, GRUB_GREFFS_MAGIC, sizeof (head.magic)) != 0)
|
||||
return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
|
||||
|
||||
can = canonicalize (path_in, 1);
|
||||
if (!can)
|
||||
return grub_errno;
|
||||
|
||||
if (can[0] == '\0')
|
||||
cur_file = 0;
|
||||
else
|
||||
{
|
||||
err = find_file (device->disk, &head, can, &cur_file, 0);
|
||||
if (err)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
num_files = grub_le_to_cpu32 (head.nfiles);
|
||||
|
||||
len = grub_strlen (can);
|
||||
|
||||
while (cur_file < num_files)
|
||||
{
|
||||
char *p, *n;
|
||||
struct grub_dirhook_info info;
|
||||
|
||||
err = get_string (device->disk, &head, cur_file, &buf, &buf_size);
|
||||
if (err)
|
||||
goto fail;
|
||||
if (grub_memcmp (can, buf, len) != 0)
|
||||
break;
|
||||
grub_memset (&info, 0, sizeof (info));
|
||||
|
||||
n = buf + len;
|
||||
while (*n == '/')
|
||||
n++;
|
||||
|
||||
p = grub_strchr (n, '/');
|
||||
if (p)
|
||||
*p = 0;
|
||||
info.dir = (p != NULL);
|
||||
if (hook (n, &info, hook_data))
|
||||
goto fail;
|
||||
if (!p)
|
||||
cur_file++;
|
||||
else
|
||||
{
|
||||
*p = '/' + 1;
|
||||
p[1] = '\0';
|
||||
err = find_file (device->disk, &head, buf, &cur_file, 0);
|
||||
if (err)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
grub_free (buf);
|
||||
grub_free (can);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
|
||||
static grub_err_t
|
||||
grub_greffs_open (grub_file_t file, const char *name_in)
|
||||
{
|
||||
struct grub_greffs_header head;
|
||||
struct grub_greffs_data *data;
|
||||
struct grub_greffs_inode inode;
|
||||
grub_err_t err;
|
||||
grub_uint32_t cur_file;
|
||||
char *can;
|
||||
|
||||
if (grub_disk_read (file->device->disk, 0, 0, sizeof (head), &head))
|
||||
return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
|
||||
|
||||
if (grub_memcmp (head.magic, GRUB_GREFFS_MAGIC, sizeof (head.magic)) != 0)
|
||||
return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
|
||||
|
||||
can = canonicalize (name_in, 0);
|
||||
if (!can)
|
||||
return grub_errno;
|
||||
|
||||
err = find_file (file->device->disk, &head, can, &cur_file, 1);
|
||||
grub_free (can);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
data = grub_malloc (sizeof (*data));
|
||||
if (!data)
|
||||
return grub_errno;
|
||||
if (grub_disk_read (file->device->disk,
|
||||
0, grub_le_to_cpu32 (head.inodes_offset)
|
||||
+ sizeof (inode) * cur_file, sizeof (inode), &inode))
|
||||
return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
|
||||
|
||||
data->dofs = grub_cpu_to_le32 (inode.start);
|
||||
file->size = grub_cpu_to_le32 (inode.size);
|
||||
|
||||
file->data = data;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_ssize_t
|
||||
grub_greffs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||
{
|
||||
struct grub_greffs_data *data;
|
||||
grub_ssize_t ret;
|
||||
|
||||
data = file->data;
|
||||
|
||||
file->device->disk->read_hook = file->read_hook;
|
||||
file->device->disk->read_hook_data = file->read_hook_data;
|
||||
ret = (grub_disk_read (file->device->disk, 0, data->dofs + file->offset,
|
||||
len, buf)) ? -1 : (grub_ssize_t) len;
|
||||
file->device->disk->read_hook = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_greffs_close (grub_file_t file)
|
||||
{
|
||||
struct grub_greffs_data *data;
|
||||
|
||||
data = file->data;
|
||||
grub_free (data);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static struct grub_fs grub_greffs_fs = {
|
||||
.name = "greffs",
|
||||
.dir = grub_greffs_dir,
|
||||
.open = grub_greffs_open,
|
||||
.read = grub_greffs_read,
|
||||
.close = grub_greffs_close,
|
||||
#ifdef GRUB_UTIL
|
||||
.reserved_first_sector = 0,
|
||||
.blocklist_install = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT (greffs)
|
||||
{
|
||||
grub_fs_register (&grub_greffs_fs);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (greffs)
|
||||
{
|
||||
grub_fs_unregister (&grub_greffs_fs);
|
||||
}
|
||||
@@ -51,7 +51,7 @@ FUNCTION(_start)
|
||||
b codestart
|
||||
|
||||
@ Size of final image integrated module blob - set by grub-mkimage
|
||||
.org _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||
.org GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||
VARIABLE(grub_total_module_size)
|
||||
.long 0
|
||||
|
||||
|
||||
@@ -385,6 +385,34 @@ grub_efi_get_device_path (grub_efi_handle_t handle)
|
||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
|
||||
{
|
||||
grub_uint32_t vendor_data_len = vendor->header.length - sizeof (*vendor);
|
||||
grub_printf ("/%sVendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)[%x: ",
|
||||
type,
|
||||
(unsigned) vendor->vendor_guid.data1,
|
||||
(unsigned) vendor->vendor_guid.data2,
|
||||
(unsigned) vendor->vendor_guid.data3,
|
||||
(unsigned) vendor->vendor_guid.data4[0],
|
||||
(unsigned) vendor->vendor_guid.data4[1],
|
||||
(unsigned) vendor->vendor_guid.data4[2],
|
||||
(unsigned) vendor->vendor_guid.data4[3],
|
||||
(unsigned) vendor->vendor_guid.data4[4],
|
||||
(unsigned) vendor->vendor_guid.data4[5],
|
||||
(unsigned) vendor->vendor_guid.data4[6],
|
||||
(unsigned) vendor->vendor_guid.data4[7],
|
||||
vendor_data_len);
|
||||
if (vendor->header.length > sizeof (*vendor))
|
||||
{
|
||||
grub_uint32_t i;
|
||||
for (i = 0; i < vendor_data_len; i++)
|
||||
grub_printf ("%02x ", vendor->vendor_defined_data[i]);
|
||||
}
|
||||
grub_printf ("]");
|
||||
}
|
||||
|
||||
|
||||
/* Print the chain of Device Path nodes. This is mainly for debugging. */
|
||||
void
|
||||
grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||
@@ -444,21 +472,8 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE:
|
||||
{
|
||||
grub_efi_vendor_device_path_t *vendor = (grub_efi_vendor_device_path_t *) dp;
|
||||
grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
|
||||
(unsigned) vendor->vendor_guid.data1,
|
||||
(unsigned) vendor->vendor_guid.data2,
|
||||
(unsigned) vendor->vendor_guid.data3,
|
||||
(unsigned) vendor->vendor_guid.data4[0],
|
||||
(unsigned) vendor->vendor_guid.data4[1],
|
||||
(unsigned) vendor->vendor_guid.data4[2],
|
||||
(unsigned) vendor->vendor_guid.data4[3],
|
||||
(unsigned) vendor->vendor_guid.data4[4],
|
||||
(unsigned) vendor->vendor_guid.data4[5],
|
||||
(unsigned) vendor->vendor_guid.data4[6],
|
||||
(unsigned) vendor->vendor_guid.data4[7]);
|
||||
}
|
||||
dump_vendor_path ("Hardware",
|
||||
(grub_efi_vendor_device_path_t *) dp);
|
||||
break;
|
||||
case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE:
|
||||
{
|
||||
@@ -663,22 +678,8 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE:
|
||||
{
|
||||
grub_efi_vendor_messaging_device_path_t *vendor
|
||||
= (grub_efi_vendor_messaging_device_path_t *) dp;
|
||||
grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
|
||||
(unsigned) vendor->vendor_guid.data1,
|
||||
(unsigned) vendor->vendor_guid.data2,
|
||||
(unsigned) vendor->vendor_guid.data3,
|
||||
(unsigned) vendor->vendor_guid.data4[0],
|
||||
(unsigned) vendor->vendor_guid.data4[1],
|
||||
(unsigned) vendor->vendor_guid.data4[2],
|
||||
(unsigned) vendor->vendor_guid.data4[3],
|
||||
(unsigned) vendor->vendor_guid.data4[4],
|
||||
(unsigned) vendor->vendor_guid.data4[5],
|
||||
(unsigned) vendor->vendor_guid.data4[6],
|
||||
(unsigned) vendor->vendor_guid.data4[7]);
|
||||
}
|
||||
dump_vendor_path ("Messaging",
|
||||
(grub_efi_vendor_device_path_t *) dp);
|
||||
break;
|
||||
default:
|
||||
grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype);
|
||||
@@ -719,22 +720,8 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE:
|
||||
{
|
||||
grub_efi_vendor_device_path_t *vendor = (grub_efi_vendor_device_path_t *) dp;
|
||||
|
||||
grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
|
||||
(unsigned) vendor->vendor_guid.data1,
|
||||
(unsigned) vendor->vendor_guid.data2,
|
||||
(unsigned) vendor->vendor_guid.data3,
|
||||
(unsigned) vendor->vendor_guid.data4[0],
|
||||
(unsigned) vendor->vendor_guid.data4[1],
|
||||
(unsigned) vendor->vendor_guid.data4[2],
|
||||
(unsigned) vendor->vendor_guid.data4[3],
|
||||
(unsigned) vendor->vendor_guid.data4[4],
|
||||
(unsigned) vendor->vendor_guid.data4[5],
|
||||
(unsigned) vendor->vendor_guid.data4[6],
|
||||
(unsigned) vendor->vendor_guid.data4[7]);
|
||||
}
|
||||
dump_vendor_path ("Media",
|
||||
(grub_efi_vendor_device_path_t *) dp);
|
||||
break;
|
||||
case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
|
||||
{
|
||||
|
||||
@@ -67,6 +67,8 @@ grub_file_open (const char *name)
|
||||
const char *file_name;
|
||||
grub_file_filter_id_t filter;
|
||||
|
||||
grub_boot_time ("Opening '%s'", name);
|
||||
|
||||
device_name = grub_file_get_device_name (name);
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
|
||||
@@ -135,7 +135,7 @@ LOCAL(prot_to_real_addr):
|
||||
|
||||
.macro REAL_TO_PROT
|
||||
movl LOCAL(real_to_prot_addr), %eax
|
||||
DATA32 call *%ax
|
||||
calll *%eax
|
||||
.endm
|
||||
|
||||
/*
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
_start:
|
||||
jmp codestart
|
||||
|
||||
. = _start + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR
|
||||
.org GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR
|
||||
VARIABLE(grub_core_entry_addr)
|
||||
.long 0
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ protstack:
|
||||
.endm
|
||||
|
||||
.macro REAL_TO_PROT
|
||||
DATA32 call real_to_prot
|
||||
calll real_to_prot
|
||||
.endm
|
||||
|
||||
/*
|
||||
@@ -137,7 +137,7 @@ real_to_prot:
|
||||
/* load the GDT register */
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
DATA32 ADDR32 lgdt gdtdesc
|
||||
lgdtl gdtdesc
|
||||
|
||||
/* turn on protected mode */
|
||||
movl %cr0, %eax
|
||||
@@ -145,7 +145,7 @@ real_to_prot:
|
||||
movl %eax, %cr0
|
||||
|
||||
/* jump to relocation, flush prefetch queue, and reload %cs */
|
||||
DATA32 ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
|
||||
ljmpl $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
|
||||
|
||||
.code32
|
||||
protcseg:
|
||||
@@ -237,7 +237,7 @@ tmpcseg:
|
||||
movl %eax, %cr0
|
||||
|
||||
/* flush prefetch queue, reload %cs */
|
||||
DATA32 ljmp $0, $realcseg
|
||||
ljmpl $0, $realcseg
|
||||
|
||||
realcseg:
|
||||
/* we are in real mode now
|
||||
@@ -258,6 +258,6 @@ realcseg:
|
||||
#endif
|
||||
|
||||
/* return on new stack! */
|
||||
DATA32 ret
|
||||
retl
|
||||
|
||||
.code32
|
||||
|
||||
@@ -36,7 +36,7 @@ start:
|
||||
bal cont
|
||||
nop
|
||||
|
||||
. = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||
.org GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||
VARIABLE(grub_total_modules_size)
|
||||
.long 0
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ _start:
|
||||
ba codestart
|
||||
mov %o4, %o0
|
||||
|
||||
. = EXT_C(_start) + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||
.org GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||
|
||||
VARIABLE(grub_total_module_size)
|
||||
.word 0
|
||||
|
||||
@@ -89,8 +89,7 @@ struct piwg_full_device_path
|
||||
.subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, \
|
||||
.length = sizeof (struct grub_efi_piwg_device_path) \
|
||||
}, \
|
||||
.guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, \
|
||||
0x01, 0xAE, 0xF2, 0xB7}} \
|
||||
.guid = GRUB_EFI_VENDOR_APPLE_GUID \
|
||||
}, \
|
||||
.end = \
|
||||
{ \
|
||||
|
||||
@@ -249,7 +249,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
if (! dp)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
|
||||
grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device (%p, %p)",
|
||||
dev_handle, dp);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ grub_have_font_source=@HAVE_FONT_SOURCE@
|
||||
|
||||
# Autodetected config
|
||||
grub_have_asm_uscore=@HAVE_ASM_USCORE@
|
||||
grub_i8086_addr32="@ADDR32@"
|
||||
grub_i8086_data32="@DATA32@"
|
||||
grub_bss_start_symbol="@BSS_START_SYMBOL@"
|
||||
grub_end_symbol="@END_SYMBOL@"
|
||||
|
||||
|
||||
@@ -230,12 +230,18 @@ read_lists (const char *val)
|
||||
{
|
||||
if (! grub_no_modules)
|
||||
{
|
||||
grub_boot_time ("Reading commands");
|
||||
read_command_list (val);
|
||||
grub_boot_time ("Reading filesystems");
|
||||
read_fs_list (val);
|
||||
grub_boot_time ("Reading crypto");
|
||||
read_crypto_list (val);
|
||||
grub_boot_time ("Reading terminal");
|
||||
read_terminal_list (val);
|
||||
}
|
||||
grub_boot_time ("Reading gettext");
|
||||
grub_gettext_reread_prefix (val);
|
||||
grub_boot_time ("Lists reread");
|
||||
}
|
||||
|
||||
static char *
|
||||
|
||||
@@ -198,124 +198,17 @@ char *
|
||||
grub_util_devmapper_part_to_disk (struct stat *st,
|
||||
int *is_part, const char *path)
|
||||
{
|
||||
struct dm_tree *tree;
|
||||
uint32_t maj, min;
|
||||
struct dm_tree_node *node = NULL, *child;
|
||||
void *handle;
|
||||
const char *node_uuid, *mapper_name = NULL, *child_uuid, *child_name;
|
||||
int major, minor;
|
||||
|
||||
tree = dm_tree_create ();
|
||||
if (! tree)
|
||||
if (grub_util_get_dm_node_linear_info (st->st_rdev,
|
||||
&major, &minor, 0))
|
||||
{
|
||||
grub_util_info ("dm_tree_create failed");
|
||||
goto devmapper_out;
|
||||
*is_part = 1;
|
||||
return grub_find_device ("/dev",
|
||||
(major << 8) | minor);
|
||||
}
|
||||
|
||||
maj = major (st->st_rdev);
|
||||
min = minor (st->st_rdev);
|
||||
if (! dm_tree_add_dev (tree, maj, min))
|
||||
{
|
||||
grub_util_info ("dm_tree_add_dev failed");
|
||||
goto devmapper_out;
|
||||
}
|
||||
|
||||
node = dm_tree_find_node (tree, maj, min);
|
||||
if (! node)
|
||||
{
|
||||
grub_util_info ("dm_tree_find_node failed");
|
||||
goto devmapper_out;
|
||||
}
|
||||
reiterate:
|
||||
node_uuid = dm_tree_node_get_uuid (node);
|
||||
if (! node_uuid)
|
||||
{
|
||||
grub_util_info ("%s has no DM uuid", path);
|
||||
goto devmapper_out;
|
||||
}
|
||||
if (strncmp (node_uuid, "LVM-", 4) == 0)
|
||||
{
|
||||
grub_util_info ("%s is an LVM", path);
|
||||
goto devmapper_out;
|
||||
}
|
||||
if (strncmp (node_uuid, "mpath-", 6) == 0)
|
||||
{
|
||||
/* Multipath partitions have partN-mpath-* UUIDs, and are
|
||||
linear mappings so are handled by
|
||||
grub_util_get_dm_node_linear_info. Multipath disks are not
|
||||
linear mappings and must be handled specially. */
|
||||
grub_util_info ("%s is a multipath disk", path);
|
||||
goto devmapper_out;
|
||||
}
|
||||
if (strncmp (node_uuid, "DMRAID-", 7) != 0)
|
||||
{
|
||||
int major, minor;
|
||||
const char *node_name;
|
||||
grub_util_info ("%s is not DM-RAID", path);
|
||||
|
||||
if ((node_name = dm_tree_node_get_name (node))
|
||||
&& grub_util_get_dm_node_linear_info (node_name,
|
||||
&major, &minor, 0))
|
||||
{
|
||||
*is_part = 1;
|
||||
if (tree)
|
||||
dm_tree_free (tree);
|
||||
char *ret = grub_find_device ("/dev",
|
||||
(major << 8) | minor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
goto devmapper_out;
|
||||
}
|
||||
|
||||
handle = NULL;
|
||||
/* Counter-intuitively, device-mapper refers to the disk-like
|
||||
device containing a DM-RAID partition device as a "child" of
|
||||
the partition device. */
|
||||
child = dm_tree_next_child (&handle, node, 0);
|
||||
if (! child)
|
||||
{
|
||||
grub_util_info ("%s has no DM children", path);
|
||||
goto devmapper_out;
|
||||
}
|
||||
child_uuid = dm_tree_node_get_uuid (child);
|
||||
if (! child_uuid)
|
||||
{
|
||||
grub_util_info ("%s child has no DM uuid", path);
|
||||
goto devmapper_out;
|
||||
}
|
||||
else if (strncmp (child_uuid, "DMRAID-", 7) != 0)
|
||||
{
|
||||
grub_util_info ("%s child is not DM-RAID", path);
|
||||
goto devmapper_out;
|
||||
}
|
||||
child_name = dm_tree_node_get_name (child);
|
||||
if (! child_name)
|
||||
{
|
||||
grub_util_info ("%s child has no DM name", path);
|
||||
goto devmapper_out;
|
||||
}
|
||||
mapper_name = child_name;
|
||||
*is_part = 1;
|
||||
node = child;
|
||||
goto reiterate;
|
||||
|
||||
devmapper_out:
|
||||
if (! mapper_name && node)
|
||||
{
|
||||
/* This is a DM-RAID disk, not a partition. */
|
||||
mapper_name = dm_tree_node_get_name (node);
|
||||
if (! mapper_name)
|
||||
grub_util_info ("%s has no DM name", path);
|
||||
}
|
||||
char *ret;
|
||||
if (mapper_name)
|
||||
ret = xasprintf ("/dev/mapper/%s", mapper_name);
|
||||
else
|
||||
ret = NULL;
|
||||
|
||||
if (tree)
|
||||
dm_tree_free (tree);
|
||||
return ret;
|
||||
*is_part = 0;
|
||||
return xstrdup (path);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -83,7 +83,7 @@ grub_util_device_is_mapped (const char *dev)
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_get_dm_node_linear_info (const char *dev,
|
||||
grub_util_get_dm_node_linear_info (dev_t dev,
|
||||
int *maj, int *min,
|
||||
grub_disk_addr_t *st)
|
||||
{
|
||||
@@ -97,14 +97,16 @@ grub_util_get_dm_node_linear_info (const char *dev,
|
||||
grub_disk_addr_t partstart = 0;
|
||||
const char *node_uuid;
|
||||
|
||||
major = major (dev);
|
||||
minor = minor (dev);
|
||||
|
||||
while (1)
|
||||
{
|
||||
dmt = dm_task_create(DM_DEVICE_TABLE);
|
||||
if (!dmt)
|
||||
break;
|
||||
|
||||
if (! (first ? dm_task_set_name (dmt, dev)
|
||||
: dm_task_set_major_minor (dmt, major, minor, 0)))
|
||||
if (! (dm_task_set_major_minor (dmt, major, minor, 0)))
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
break;
|
||||
@@ -117,8 +119,7 @@ grub_util_get_dm_node_linear_info (const char *dev,
|
||||
}
|
||||
node_uuid = dm_task_get_uuid (dmt);
|
||||
if (node_uuid && (strncmp (node_uuid, "LVM-", 4) == 0
|
||||
|| strncmp (node_uuid, "mpath-", 6) == 0
|
||||
|| strncmp (node_uuid, "DMRAID-", 7) == 0))
|
||||
|| strncmp (node_uuid, "mpath-", 6) == 0))
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
break;
|
||||
@@ -190,7 +191,7 @@ grub_util_device_is_mapped (const char *dev __attribute__ ((unused)))
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_get_dm_node_linear_info (const char *dev __attribute__ ((unused)),
|
||||
grub_util_get_dm_node_linear_info (dev_t dev __attribute__ ((unused)),
|
||||
int *maj __attribute__ ((unused)),
|
||||
int *min __attribute__ ((unused)),
|
||||
grub_disk_addr_t *st __attribute__ ((unused)))
|
||||
|
||||
@@ -288,6 +288,7 @@ grub_hostdisk_linux_find_partition (char *dev, grub_disk_addr_t sector)
|
||||
{
|
||||
grub_util_fd_t fd;
|
||||
grub_disk_addr_t start;
|
||||
struct stat st;
|
||||
|
||||
sprintf (p, format, i);
|
||||
|
||||
@@ -300,14 +301,16 @@ grub_hostdisk_linux_find_partition (char *dev, grub_disk_addr_t sector)
|
||||
return 0;
|
||||
}
|
||||
missing = 0;
|
||||
close (fd);
|
||||
|
||||
if (!grub_util_device_is_mapped (real_dev)
|
||||
|| !grub_util_get_dm_node_linear_info (real_dev, 0, 0, &start))
|
||||
if (fstat (fd, &st) < 0
|
||||
|| !grub_util_device_is_mapped_stat (&st)
|
||||
|| !grub_util_get_dm_node_linear_info (st.st_rdev, 0, 0, &start))
|
||||
start = grub_util_find_partition_start_os (real_dev);
|
||||
/* We don't care about errors here. */
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
close (fd);
|
||||
|
||||
if (start == sector)
|
||||
{
|
||||
struct linux_partition_cache *new_cache_item;
|
||||
|
||||
@@ -46,5 +46,5 @@ message:
|
||||
.ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n"
|
||||
.byte 0
|
||||
|
||||
. = base + 510
|
||||
.org 510
|
||||
.short 0xaa55
|
||||
@@ -280,6 +280,12 @@
|
||||
{ 0xb1b621d5, 0xf19c, 0x41a5, \
|
||||
{ 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
|
||||
}
|
||||
|
||||
#define GRUB_EFI_VENDOR_APPLE_GUID \
|
||||
{ 0x2B0585EB, 0xD8B8, 0x49A9, \
|
||||
{ 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
|
||||
}
|
||||
|
||||
struct grub_efi_sal_system_table
|
||||
{
|
||||
grub_uint32_t signature;
|
||||
@@ -815,14 +821,6 @@ typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t;
|
||||
|
||||
#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10
|
||||
|
||||
struct grub_efi_vendor_messaging_device_path
|
||||
{
|
||||
grub_efi_device_path_t header;
|
||||
grub_efi_packed_guid_t vendor_guid;
|
||||
grub_efi_uint8_t vendor_defined_data[0];
|
||||
} GRUB_PACKED;
|
||||
typedef struct grub_efi_vendor_messaging_device_path grub_efi_vendor_messaging_device_path_t;
|
||||
|
||||
/* Media Device Path. */
|
||||
#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE 4
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ char *
|
||||
grub_util_get_os_disk (const char *os_dev);
|
||||
|
||||
int
|
||||
grub_util_get_dm_node_linear_info (const char *dev,
|
||||
grub_util_get_dm_node_linear_info (dev_t dev,
|
||||
int *maj, int *min,
|
||||
grub_disk_addr_t *st);
|
||||
|
||||
|
||||
55
include/grub/greffs.h
Normal file
55
include/grub/greffs.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_GREFFS_HEADER
|
||||
#define GRUB_GREFFS_HEADER 1
|
||||
|
||||
#include <grub/types.h>
|
||||
|
||||
/*
|
||||
Layout:
|
||||
header
|
||||
grub_uint32_t[] pointers to names
|
||||
inodes
|
||||
names
|
||||
contents.
|
||||
Everything is little-endian.
|
||||
*/
|
||||
|
||||
struct grub_greffs_header
|
||||
{
|
||||
char magic[4];
|
||||
#define GRUB_GREFFS_MAGIC "gref"
|
||||
grub_uint32_t nfiles;
|
||||
/* must be divisible by 4. */
|
||||
grub_uint32_t inodes_offset;
|
||||
/* must be divisible by 4. */
|
||||
grub_uint32_t string_ptrs_offset;
|
||||
};
|
||||
|
||||
struct grub_greffs_inode
|
||||
{
|
||||
grub_uint32_t start;
|
||||
grub_uint32_t size;
|
||||
grub_uint32_t mtime;
|
||||
/* Currently always 0. If we ever need symlinks,
|
||||
it could be added. */
|
||||
grub_uint32_t type;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -77,10 +77,15 @@
|
||||
grub_disk_addr_t
|
||||
grub_util_find_partition_start (const char *dev)
|
||||
{
|
||||
#if GRUB_UTIL_FD_STAT_IS_FUNCTIONAL
|
||||
struct stat st;
|
||||
grub_disk_addr_t partition_start;
|
||||
if (grub_util_device_is_mapped (dev)
|
||||
&& grub_util_get_dm_node_linear_info (dev, 0, 0, &partition_start))
|
||||
|
||||
if (stat (dev, &st) >= 0
|
||||
&& grub_util_device_is_mapped_stat (&st)
|
||||
&& grub_util_get_dm_node_linear_info (st.st_rdev, 0, 0, &partition_start))
|
||||
return partition_start;
|
||||
#endif
|
||||
|
||||
return grub_util_find_partition_start_os (dev);
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ for i in "${grub_mkconfig_dir}"/* ; do
|
||||
echo "### BEGIN $i ($platform) ###"
|
||||
case x$platform in
|
||||
xx86)
|
||||
echo "if [ x\"\$grub_platform\" != xxen \\( x\"\$grub_cpu\" = xi386 -o x\"\$grub_cpu\" = xx86_64 -o x\"\$grub_platform\" = x \\) ]; then" ;;
|
||||
echo "if [ x\"\$grub_platform\" != xxen -a \\( x\"\$grub_cpu\" = xi386 -o x\"\$grub_cpu\" = xx86_64 -o x\"\$grub_platform\" = x \\) ]; then" ;;
|
||||
xi386-xen-pae)
|
||||
echo "if [ x\"\$grub_cpu-\$grub_platform\" = xi386-xen -o x\"\$grub_cpu-\$grub_platform\" = x- ]; then" ;;
|
||||
xx86_64-xen)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <grub/util/install.h>
|
||||
#include <grub/util/misc.h>
|
||||
#include <grub/emu/config.h>
|
||||
#include <grub/greffs.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -34,7 +35,6 @@ static char *output_image;
|
||||
static char **files;
|
||||
static int nfiles;
|
||||
const struct grub_install_image_target_desc *format;
|
||||
static FILE *memdisk;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -116,91 +116,56 @@ struct argp argp = {
|
||||
NULL, help_filter, NULL
|
||||
};
|
||||
|
||||
/* tar support */
|
||||
#define MAGIC "ustar"
|
||||
struct head
|
||||
struct file_desc
|
||||
{
|
||||
char name[100];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char chksum[8];
|
||||
char typeflag;
|
||||
char linkname[100];
|
||||
char magic[6];
|
||||
char version[2];
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char prefix[155];
|
||||
char pad[12];
|
||||
} GRUB_PACKED;
|
||||
char *name;
|
||||
char *source;
|
||||
grub_size_t size;
|
||||
grub_size_t mtime;
|
||||
};
|
||||
static struct file_desc *file_descs;
|
||||
static size_t n_file_descs, alloc_file_descs;
|
||||
|
||||
static void
|
||||
write_zeros (unsigned rsz)
|
||||
static inline void
|
||||
canonicalize (char *name)
|
||||
{
|
||||
char buf[512];
|
||||
|
||||
memset (buf, 0, 512);
|
||||
fwrite (buf, 1, rsz, memdisk);
|
||||
}
|
||||
|
||||
static void
|
||||
write_pad (unsigned sz)
|
||||
{
|
||||
write_zeros ((~sz + 1) & 511);
|
||||
}
|
||||
|
||||
static void
|
||||
set_tar_value (char *field, grub_uint32_t val,
|
||||
unsigned len)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < len - 1; i++)
|
||||
field[len - 2 - i] = '0' + ((val >> (3 * i)) & 7);
|
||||
}
|
||||
|
||||
static void
|
||||
compute_checksum (struct head *hd)
|
||||
{
|
||||
unsigned int chk = 0;
|
||||
unsigned char *ptr;
|
||||
memset (hd->chksum, ' ', 8);
|
||||
for (ptr = (unsigned char *) hd; ptr < (unsigned char *) (hd + 1); ptr++)
|
||||
chk += *ptr;
|
||||
set_tar_value (hd->chksum, chk, 8);
|
||||
char *iptr, *optr;
|
||||
for (iptr = name, optr = name; *iptr; )
|
||||
{
|
||||
while (*iptr == '/')
|
||||
iptr++;
|
||||
if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0))
|
||||
{
|
||||
iptr += 2;
|
||||
continue;
|
||||
}
|
||||
if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0))
|
||||
{
|
||||
iptr += 3;
|
||||
if (optr == name)
|
||||
continue;
|
||||
for (optr -= 2; optr >= name && *optr != '/'; optr--);
|
||||
optr++;
|
||||
continue;
|
||||
}
|
||||
while (*iptr && *iptr != '/')
|
||||
*optr++ = *iptr++;
|
||||
if (*iptr)
|
||||
*optr++ = *iptr++;
|
||||
}
|
||||
*optr = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
add_tar_file (const char *from,
|
||||
const char *to)
|
||||
{
|
||||
char *tcn;
|
||||
const char *iptr;
|
||||
char *optr;
|
||||
struct head hd;
|
||||
grub_util_fd_t in;
|
||||
ssize_t r;
|
||||
grub_uint32_t mtime = 0;
|
||||
grub_uint32_t size;
|
||||
|
||||
COMPILE_TIME_ASSERT (sizeof (hd) == 512);
|
||||
size_t idx;
|
||||
|
||||
if (grub_util_is_special_file (from))
|
||||
return;
|
||||
|
||||
mtime = grub_util_get_mtime (from);
|
||||
|
||||
optr = tcn = xmalloc (strlen (to) + 1);
|
||||
for (iptr = to; *iptr == '/'; iptr++);
|
||||
for (; *iptr; iptr++)
|
||||
if (!(iptr[0] == '/' && iptr[1] == '/'))
|
||||
*optr++ = *iptr;
|
||||
*optr = '\0';
|
||||
|
||||
if (grub_util_is_directory (from))
|
||||
{
|
||||
grub_util_fd_dir_t d;
|
||||
@@ -221,69 +186,138 @@ add_tar_file (const char *from,
|
||||
free (fp);
|
||||
}
|
||||
grub_util_fd_closedir (d);
|
||||
free (tcn);
|
||||
return;
|
||||
}
|
||||
|
||||
if (optr - tcn > 99)
|
||||
idx = n_file_descs++;
|
||||
if (idx >= alloc_file_descs)
|
||||
{
|
||||
memset (&hd, 0, sizeof (hd));
|
||||
memcpy (hd.name, tcn, 99);
|
||||
memcpy (hd.mode, "0000600", 7);
|
||||
memcpy (hd.uid, "0001750", 7);
|
||||
memcpy (hd.gid, "0001750", 7);
|
||||
|
||||
set_tar_value (hd.size, optr - tcn, 12);
|
||||
set_tar_value (hd.mtime, mtime, 12);
|
||||
hd.typeflag = 'L';
|
||||
memcpy (hd.magic, "ustar ", 7);
|
||||
memcpy (hd.uname, "grub", 4);
|
||||
memcpy (hd.gname, "grub", 4);
|
||||
|
||||
compute_checksum (&hd);
|
||||
|
||||
fwrite (&hd, 1, sizeof (hd), memdisk);
|
||||
fwrite (tcn, 1, optr - tcn, memdisk);
|
||||
|
||||
write_pad (optr - tcn);
|
||||
alloc_file_descs = 2 * n_file_descs;
|
||||
file_descs = xrealloc (file_descs, alloc_file_descs
|
||||
* sizeof (file_descs[0]));
|
||||
}
|
||||
|
||||
in = grub_util_fd_open (from, GRUB_UTIL_FD_O_RDONLY);
|
||||
if (!GRUB_UTIL_FD_IS_VALID (in))
|
||||
grub_util_error (_("cannot open `%s': %s"), from, grub_util_fd_strerror ());
|
||||
|
||||
file_descs[idx].name = xstrdup (to);
|
||||
file_descs[idx].source = xstrdup (from);
|
||||
canonicalize (file_descs[idx].name);
|
||||
file_descs[idx].mtime = grub_util_get_mtime (from);
|
||||
file_descs[idx].size = grub_util_get_fd_size (in, from, NULL);
|
||||
|
||||
grub_util_fd_close (in);
|
||||
}
|
||||
|
||||
static int
|
||||
filecmp (const void *p1, const void *p2)
|
||||
{
|
||||
const struct file_desc *a = p1, *b = p2;
|
||||
|
||||
/* Don't use strcmp, it's buggy on some systems. */
|
||||
return grub_strcmp (a->name, b->name);
|
||||
}
|
||||
|
||||
static void
|
||||
write_memdisk (char *memdisk_img)
|
||||
{
|
||||
FILE *memdisk;
|
||||
struct grub_greffs_header head;
|
||||
struct grub_greffs_inode inode;
|
||||
size_t total_strlen = 0, i;
|
||||
size_t name_pad = 0;
|
||||
grub_uint32_t file_offset;
|
||||
|
||||
qsort (file_descs, n_file_descs, sizeof (file_descs[0]), filecmp);
|
||||
|
||||
for (i = 0; i < n_file_descs; i++)
|
||||
total_strlen += grub_strlen (file_descs[i].name);
|
||||
name_pad = ALIGN_UP (total_strlen, 4) - total_strlen;
|
||||
total_strlen += name_pad;
|
||||
|
||||
grub_memcpy (head.magic, GRUB_GREFFS_MAGIC, sizeof (head.magic));
|
||||
head.nfiles = grub_cpu_to_le32 (n_file_descs);
|
||||
head.inodes_offset = grub_cpu_to_le32 (sizeof (head)
|
||||
+ sizeof (grub_uint32_t)
|
||||
* (n_file_descs + 1));
|
||||
head.string_ptrs_offset = grub_cpu_to_le32 (sizeof (head));
|
||||
|
||||
memdisk = grub_util_fopen (memdisk_img, "wb");
|
||||
if (!memdisk)
|
||||
grub_util_error (_("Can't create file: %s"), strerror (errno));
|
||||
|
||||
fwrite (&head, 1, sizeof (head), memdisk);
|
||||
|
||||
grub_uint32_t curname = sizeof (head) + sizeof (grub_uint32_t)
|
||||
* (n_file_descs + 1) + sizeof (inode) * n_file_descs;
|
||||
for (i = 0; i <= n_file_descs; i++)
|
||||
{
|
||||
grub_uint32_t curname_le = grub_cpu_to_le32 (curname);
|
||||
fwrite (&curname_le, 1, sizeof (curname_le), memdisk);
|
||||
if (i != n_file_descs)
|
||||
curname += grub_strlen (file_descs[i].name);
|
||||
}
|
||||
|
||||
file_offset = sizeof (head) + sizeof (grub_uint32_t)
|
||||
* (n_file_descs + 1) + sizeof (inode) * n_file_descs + total_strlen;
|
||||
for (i = 0; i < n_file_descs; i++)
|
||||
{
|
||||
inode.start = grub_cpu_to_le32 (file_offset);
|
||||
inode.size = grub_cpu_to_le32 (file_descs[i].size);
|
||||
inode.mtime = grub_cpu_to_le32 (file_descs[i].mtime);
|
||||
inode.type = 0;
|
||||
fwrite (&inode, 1, sizeof (inode), memdisk);
|
||||
file_offset += file_descs[i].size;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_file_descs; i++)
|
||||
fwrite (file_descs[i].name, 1, grub_strlen (file_descs[i].name), memdisk);
|
||||
|
||||
if (!grub_install_copy_buffer)
|
||||
grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
|
||||
|
||||
size = grub_util_get_fd_size (in, from, NULL);
|
||||
grub_memset (grub_install_copy_buffer, 0, 4);
|
||||
fwrite (grub_install_copy_buffer, 1, name_pad, memdisk);
|
||||
|
||||
memset (&hd, 0, sizeof (hd));
|
||||
memcpy (hd.name, tcn, optr - tcn < 99 ? optr - tcn : 99);
|
||||
memcpy (hd.mode, "0000600", 7);
|
||||
memcpy (hd.uid, "0001750", 7);
|
||||
memcpy (hd.gid, "0001750", 7);
|
||||
|
||||
set_tar_value (hd.size, size, 12);
|
||||
set_tar_value (hd.mtime, mtime, 12);
|
||||
hd.typeflag = '0';
|
||||
memcpy (hd.magic, "ustar ", 7);
|
||||
memcpy (hd.uname, "grub", 4);
|
||||
memcpy (hd.gname, "grub", 4);
|
||||
|
||||
compute_checksum (&hd);
|
||||
|
||||
fwrite (&hd, 1, sizeof (hd), memdisk);
|
||||
|
||||
while (1)
|
||||
for (i = 0; i < n_file_descs; i++)
|
||||
{
|
||||
r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE);
|
||||
if (r <= 0)
|
||||
break;
|
||||
fwrite (grub_install_copy_buffer, 1, r, memdisk);
|
||||
}
|
||||
grub_util_fd_close (in);
|
||||
grub_util_fd_t in;
|
||||
size_t remaining = file_descs[i].size;
|
||||
in = grub_util_fd_open (file_descs[i].source, GRUB_UTIL_FD_O_RDONLY);
|
||||
if (!GRUB_UTIL_FD_IS_VALID (in))
|
||||
grub_util_error (_("cannot open `%s': %s"),
|
||||
file_descs[i].source, grub_util_fd_strerror ());
|
||||
|
||||
while (remaining)
|
||||
{
|
||||
size_t toread = remaining;
|
||||
ssize_t r;
|
||||
if (remaining > GRUB_INSTALL_COPY_BUFFER_SIZE)
|
||||
toread = GRUB_INSTALL_COPY_BUFFER_SIZE;
|
||||
r = grub_util_fd_read (in, grub_install_copy_buffer, toread);
|
||||
if (r <= 0)
|
||||
break;
|
||||
fwrite (grub_install_copy_buffer, 1, r, memdisk);
|
||||
if (r >= remaining)
|
||||
remaining = 0;
|
||||
else
|
||||
remaining -= r;
|
||||
}
|
||||
grub_util_fd_close (in);
|
||||
|
||||
write_pad (size);
|
||||
grub_memset (grub_install_copy_buffer, 0, GRUB_INSTALL_COPY_BUFFER_SIZE);
|
||||
while (remaining)
|
||||
{
|
||||
size_t toread = remaining;
|
||||
if (remaining > GRUB_INSTALL_COPY_BUFFER_SIZE)
|
||||
toread = GRUB_INSTALL_COPY_BUFFER_SIZE;
|
||||
fwrite (grub_install_copy_buffer, 1, toread, memdisk);
|
||||
remaining -= toread;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (memdisk);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -319,8 +353,6 @@ main (int argc, char *argv[])
|
||||
|
||||
char *memdisk_img = grub_util_make_temporary_file ();
|
||||
|
||||
memdisk = grub_util_fopen (memdisk_img, "wb");
|
||||
|
||||
add_tar_file (memdisk_dir, "");
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
@@ -341,14 +373,12 @@ main (int argc, char *argv[])
|
||||
to++;
|
||||
add_tar_file (from, to);
|
||||
}
|
||||
write_zeros (512);
|
||||
|
||||
fclose (memdisk);
|
||||
|
||||
write_memdisk (memdisk_img);
|
||||
grub_util_unlink_recursive (memdisk_dir);
|
||||
|
||||
grub_install_push_module ("memdisk");
|
||||
grub_install_push_module ("tar");
|
||||
grub_install_push_module ("greffs");
|
||||
|
||||
grub_install_make_image_wrap (grub_install_source_directory,
|
||||
"(memdisk)/boot/grub", output_image,
|
||||
@@ -356,5 +386,6 @@ main (int argc, char *argv[])
|
||||
grub_util_get_target_name (format), 0);
|
||||
|
||||
grub_util_unlink (memdisk_img);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user