2007-02-21 Hollis Blanchard <hollis@penguinppc.org>

* conf/powerpc-ieee1275.rmk (kernel_elf_LDFLAGS): Link at 64KB.
	* kern/powerpc/ieee1275/init.c (_end): Add declaration.
	(_start): Likewise.
	(grub_arch_modules_addr): Return address after `_end'.
	* util/powerpc/ieee1275/grub-mkimage.c: Include grub/misc.h.
	(load_modules): Use new parameter as `p_paddr' and `p_vaddr'.
	(add_segments): Calculate `_end' from phdr size and location.
	(ALIGN_UP): Moved to ...
	* include/grub/misc.h: here.
	* include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MOD_ALIGN):
	New macro.
	(GRUB_IEEE1275_MODULE_BASE): Removed.
This commit is contained in:
hollisb 2007-02-21 23:22:20 +00:00
parent fd7d8ebae4
commit a0cbb02386
7 changed files with 48 additions and 13 deletions

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,2005,2006 Free Software Foundation, Inc.
* Copyright (C) 2004,2005,2006,2007 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
@ -27,13 +27,12 @@
#include <stdlib.h>
#include <string.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/util/misc.h>
#include <grub/util/resolve.h>
#include <grub/kernel.h>
#include <grub/machine/kernel.h>
#define ALIGN_UP(addr, align) ((long)((char *)addr + align - 1) & ~(align - 1))
#define GRUB_IEEE1275_NOTE_NAME "PowerPC"
#define GRUB_IEEE1275_NOTE_TYPE 0x1275
@ -98,7 +97,8 @@ load_note (Elf32_Phdr *phdr, FILE *out)
}
void
load_modules (Elf32_Phdr *phdr, const char *dir, char *mods[], FILE *out)
load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir,
char *mods[], FILE *out)
{
char *module_img;
struct grub_util_path_list *path_list;
@ -152,8 +152,8 @@ load_modules (Elf32_Phdr *phdr, const char *dir, char *mods[], FILE *out)
phdr->p_type = grub_cpu_to_be32 (PT_LOAD);
phdr->p_flags = grub_cpu_to_be32 (PF_R | PF_W | PF_X);
phdr->p_align = grub_cpu_to_be32 (sizeof (long));
phdr->p_vaddr = grub_cpu_to_be32 (GRUB_IEEE1275_MODULE_BASE);
phdr->p_paddr = grub_cpu_to_be32 (GRUB_IEEE1275_MODULE_BASE);
phdr->p_vaddr = grub_cpu_to_be32 (modbase);
phdr->p_paddr = grub_cpu_to_be32 (modbase);
phdr->p_filesz = grub_cpu_to_be32 (total_module_size);
phdr->p_memsz = grub_cpu_to_be32 (total_module_size);
}
@ -166,6 +166,7 @@ add_segments (char *dir, FILE *out, int chrp, char *mods[])
Elf32_Phdr *phdr;
FILE *in;
char *kernel_path;
grub_addr_t grub_end = 0;
off_t phdroff;
int i;
@ -183,6 +184,7 @@ add_segments (char *dir, FILE *out, int chrp, char *mods[])
for (i = 0; i < grub_be_to_cpu16 (ehdr.e_phnum); i++)
{
char *segment_img;
grub_size_t segment_end;
phdr = phdrs + i;
@ -194,6 +196,13 @@ add_segments (char *dir, FILE *out, int chrp, char *mods[])
grub_util_info ("copying segment %d, type %d", i,
grub_be_to_cpu32 (phdr->p_type));
/* Locate _end. */
segment_end = grub_be_to_cpu32 (phdr->p_paddr)
+ grub_be_to_cpu32 (phdr->p_memsz);
grub_util_info ("segment %u end 0x%lx", i, segment_end);
if (segment_end > grub_end)
grub_end = segment_end;
/* Read segment data and write it to new file. */
segment_img = xmalloc (grub_be_to_cpu32 (phdr->p_filesz));
@ -207,6 +216,11 @@ add_segments (char *dir, FILE *out, int chrp, char *mods[])
if (mods[0] != NULL)
{
grub_addr_t modbase;
/* Place modules just after grub segment. */
modbase = ALIGN_UP(grub_end, GRUB_IEEE1275_MOD_ALIGN);
/* Construct new segment header for modules. */
phdr = phdrs + grub_be_to_cpu16 (ehdr.e_phnum);
ehdr.e_phnum = grub_cpu_to_be16 (grub_be_to_cpu16 (ehdr.e_phnum) + 1);
@ -215,7 +229,7 @@ add_segments (char *dir, FILE *out, int chrp, char *mods[])
phdr->p_offset = grub_cpu_to_be32 (ALIGN_UP (grub_util_get_fp_size (out),
sizeof (long)));
load_modules (phdr, dir, mods, out);
load_modules (modbase, phdr, dir, mods, out);
}
if (chrp)