Commit 5f12b0bf authored by Anton Blanchard's avatar Anton Blanchard

Add ppc64 support. This includes both pSeries (RS/6000) and

iSeries (AS/400).

There are no changes outside of include/asm-ppc64 and arch/ppc64
in this changeset.
parent 7994321a
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1994 by Linus Torvalds
# Changes for PPC by Gary Thomas
# Rewritten by Cort Dougan and Paul Mackerras
# Adjusted for PPC64 by Tom Gall
#
KERNELLOAD =0xc000000000000000
LINKFLAGS = -T arch/ppc64/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic
CFLAGS := $(CFLAGS) -fsigned-char -msoft-float -pipe \
-Wno-uninitialized -mminimal-toc -fno-builtin
CPP = $(CC) -E $(CFLAGS)
HEAD := arch/ppc64/kernel/head.o
ARCH_SUBDIRS = arch/ppc64/kernel arch/ppc64/mm arch/ppc64/lib
SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS)
ARCHIVES := arch/ppc64/kernel/kernel.o arch/ppc64/mm/mm.o arch/ppc64/lib/lib.o $(ARCHIVES)
CORE_FILES := arch/ppc64/kernel/kernel.o arch/ppc64/mm/mm.o arch/ppc64/lib/lib.o $(CORE_FILES)
ifdef CONFIG_XMON
SUBDIRS += arch/ppc64/xmon
CORE_FILES += arch/ppc64/xmon/x.o
endif
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
ifdef CONFIG_PPC_PSERIES
BOOT_TARGETS = zImage znetboot.initrd zImage.initrd
endif
ifdef CONFIG_PPC_ISERIES
BOOT_TARGETS = vmlinux.sminitrd vmlinux.initrd vmlinux.sm
endif
$(BOOT_TARGETS): vmlinux
@$(MAKEBOOT) $@
znetboot: vmlinux
ifdef CONFIG_SMP
cp -f vmlinux /tftpboot/vmlinux.smp
else
cp -f vmlinux /tftpboot/vmlinux
endif
@$(MAKEBOOT) $@
%_config: arch/ppc64/configs/%_defconfig
rm -f .config arch/ppc64/defconfig
cp -f arch/ppc64/configs/$(@:config=defconfig) arch/ppc64/defconfig
archclean:
rm -f arch/ppc64/kernel/{ppc_defs.h,mk_defs.s,mk_defs_out.c,mk_defs_tpl}
@$(MAKEBOOT) clean
archmrproper:
archdep:
$(MAKEBOOT) fastdep
# Makefile for making ELF bootable images for booting on CHRP
# using Open Firmware.
#
# Geert Uytterhoeven September 1997
#
# Based on coffboot by Paul Mackerras
# Simplified for ppc64 by Todd Inglett
#
# NOTE: this code is built for 32 bit in ELF32 format even though
# it packages a 64 bit kernel. We do this to simplify the
# bootloader and increase compatibility with OpenFirmware.
#
# To this end we need to define BOOTCC, etc, as the tools
# needed to build the 32 bit image. These are normally HOSTCC,
# but may be a third compiler if, for example, you are cross
# compiling from an intel box. Once the 64bit ppc gcc is
# stable it will probably simply be a compiler switch to
# compile for 32bit mode.
# To make it easier to setup a cross compiler,
# CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE
# in the toplevel makefile.
CROSS32_COMPILE =
#CROSS32_COMPILE = /usr/local/ppc/bin/powerpc-linux-
BOOTCC = $(CROSS32_COMPILE)gcc
BOOTCFLAGS = $(HOSTCFLAGS) -I$(HPATH)
BOOTLD = $(CROSS32_COMPILE)ld
BOOTAS = $(CROSS32_COMPILE)as
BOOTAFLAGS = -D__ASSEMBLY__ $(HOSTCFLAGS)
.c.o:
$(BOOTCC) $(BOOTCFLAGS) -c -o $*.o $<
.S.o:
$(BOOTCC) $(BOOTAFLAGS) -traditional -c -o $*.o $<
CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS
LD_ARGS = -Ttext 0x00400000 -e _start
OBJS = crt0.o start.o main.o zlib.o image.o imagesize.o
#LIBS = $(TOPDIR)/lib/lib.a
LIBS =
ifeq ($(CONFIG_SMP),y)
TFTPIMAGE=/tftpboot/zImage.chrp.smp
else
TFTPIMAGE=/tftpboot/zImage.chrp
endif
ifeq ($(CONFIG_PPC_ISERIES),y)
all: vmlinux.sm
else
all: $(TOPDIR)/zImage
endif
znetboot: zImage
cp zImage $(TFTPIMAGE)
ifeq ($(CONFIG_PPC_ISERIES),y)
addSystemMap: addSystemMap.c
$(HOSTCC) $(HOSTCFLAGS) -o addSystemMap addSystemMap.c
vmlinux.sm: $(TOPDIR)/vmlinux addSystemMap
./addSystemMap $(TOPDIR)/System.map $(TOPDIR)/vmlinux vmlinux.sm
addRamDisk: addRamDisk.c
$(HOSTCC) $(HOSTCFLAGS) -o addRamDisk addRamDisk.c
vmlinux.initrd: $(TOPDIR)/vmlinux addRamDisk ramdisk.image.gz $(TOPDIR)/System.map
./addRamDisk ramdisk.image.gz $(TOPDIR)/System.map $(TOPDIR)/vmlinux vmlinux.initrd
vmlinux.sminitrd: vmlinux.sm addRamDisk ramdisk.image.gz $(TOPDIR)/System.map
./addRamDisk ramdisk.image.gz $(TOPDIR)/System.map vmlinux.sm vmlinux.sminitrd
endif
znetboot.initrd: zImage.initrd
cp zImage.initrd $(TFTPIMAGE)
floppy: zImage
mcopy zImage a:zImage
piggyback: piggyback.c
$(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
addnote: addnote.c
$(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c
image.o: piggyback vmlinux.gz
./piggyback image < vmlinux.gz | $(BOOTAS) -o image.o
sysmap.o: piggyback ../../../System.map
./piggyback sysmap < ../../../System.map | $(BOOTAS) -o sysmap.o
initrd.o: ramdisk.image.gz piggyback
./piggyback initrd < ramdisk.image.gz | $(BOOTAS) -o initrd.o
zImage: $(OBJS) no_initrd.o addnote
$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) no_initrd.o $(LIBS)
./addnote $@
zImage.initrd: $(OBJS) initrd.o addnote
$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) initrd.o $(LIBS)
./addnote $@
vmlinux.gz: $(TOPDIR)/vmlinux
$(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
ls -l vmlinux | awk '{printf "/* generated -- do not edit! */\nint uncompressed_size = %d;\n", $$5}' > imagesize.c
$(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | tail -1 | awk '{printf "long vmlinux_end = 0x%s;\n", substr($$1,8)}' >> imagesize.c
gzip -vf9 vmlinux
imagesize.c: vmlinux.gz
clean:
rm -f piggyback note addnote $(OBJS) zImage zImage.initrd vmlinux.gz no_initrd.o imagesize.c addSystemMap vmlinux.sm addRamDisk vmlinux.initrd vmlinux.sminitrd
fastdep:
$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
dep:
$(CPP) $(CPPFLAGS) -M *.S *.c > .depend
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#define ElfHeaderSize (64 * 1024)
#define ElfPages (ElfHeaderSize / 4096)
#define KERNELBASE (0xc000000000000000)
void get4k(FILE *file, char *buf )
{
unsigned j;
unsigned num = fread(buf, 1, 4096, file);
for ( j=num; j<4096; ++j )
buf[j] = 0;
}
void put4k(FILE *file, char *buf )
{
fwrite(buf, 1, 4096, file);
}
void death(const char *msg, FILE *fdesc, const char *fname)
{
printf(msg);
fclose(fdesc);
unlink(fname);
exit(1);
}
int main(int argc, char **argv)
{
char inbuf[4096];
FILE *ramDisk = NULL;
FILE *sysmap = NULL;
FILE *inputVmlinux = NULL;
FILE *outputVmlinux = NULL;
unsigned i = 0;
unsigned long ramFileLen = 0;
unsigned long ramLen = 0;
unsigned long roundR = 0;
unsigned long sysmapFileLen = 0;
unsigned long sysmapLen = 0;
unsigned long sysmapPages = 0;
char* ptr_end = NULL;
unsigned long offset_end = 0;
unsigned long kernelLen = 0;
unsigned long actualKernelLen = 0;
unsigned long round = 0;
unsigned long roundedKernelLen = 0;
unsigned long ramStartOffs = 0;
unsigned long ramPages = 0;
unsigned long roundedKernelPages = 0;
unsigned long hvReleaseData = 0;
u_int32_t eyeCatcher = 0xc8a5d9c4;
unsigned long naca = 0;
unsigned long xRamDisk = 0;
unsigned long xRamDiskSize = 0;
long padPages = 0;
if (argc < 2) {
printf("Name of RAM disk file missing.\n");
exit(1);
}
if (argc < 3) {
printf("Name of System Map input file is missing.\n");
exit(1);
}
if (argc < 4) {
printf("Name of vmlinux file missing.\n");
exit(1);
}
if (argc < 5) {
printf("Name of vmlinux output file missing.\n");
exit(1);
}
ramDisk = fopen(argv[1], "r");
if ( ! ramDisk ) {
printf("RAM disk file \"%s\" failed to open.\n", argv[1]);
exit(1);
}
sysmap = fopen(argv[2], "r");
if ( ! sysmap ) {
printf("System Map file \"%s\" failed to open.\n", argv[2]);
exit(1);
}
inputVmlinux = fopen(argv[3], "r");
if ( ! inputVmlinux ) {
printf("vmlinux file \"%s\" failed to open.\n", argv[3]);
exit(1);
}
outputVmlinux = fopen(argv[4], "w+");
if ( ! outputVmlinux ) {
printf("output vmlinux file \"%s\" failed to open.\n", argv[4]);
exit(1);
}
/* Input Vmlinux file */
fseek(inputVmlinux, 0, SEEK_END);
kernelLen = ftell(inputVmlinux);
fseek(inputVmlinux, 0, SEEK_SET);
printf("kernel file size = %d\n", kernelLen);
if ( kernelLen == 0 ) {
printf("You must have a linux kernel specified as argv[3]\n");
exit(1);
}
actualKernelLen = kernelLen - ElfHeaderSize;
printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen);
round = actualKernelLen % 4096;
roundedKernelLen = actualKernelLen;
if ( round )
roundedKernelLen += (4096 - round);
printf("Vmlinux length rounded up to a 4k multiple = %ld/0x%lx \n", roundedKernelLen, roundedKernelLen);
roundedKernelPages = roundedKernelLen / 4096;
printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages);
/* Input System Map file */
/* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */
fseek(sysmap, 0, SEEK_END);
sysmapFileLen = ftell(sysmap);
fseek(sysmap, 0, SEEK_SET);
printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen);
sysmapLen = sysmapFileLen;
roundR = 4096 - (sysmapLen % 4096);
if (roundR) {
printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
sysmapLen += roundR;
}
printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen);
/* Process the Sysmap file to determine where _end is */
sysmapPages = sysmapLen / 4096;
for (i=0; i<sysmapPages; ++i) {
get4k(sysmap, inbuf);
}
/* search for _end in the last page of the system map */
ptr_end = strstr(inbuf, " _end");
if (!ptr_end) {
printf("Unable to find _end in the sysmap file \n");
printf("inbuf: \n");
printf("%s \n", inbuf);
exit(1);
}
printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
/* convert address of _end in system map to hex offset. */
offset_end = (unsigned int)strtol(ptr_end-10, NULL, 16);
/* calc how many pages we need to insert between the vmlinux and the start of the ram disk */
padPages = offset_end/4096 - roundedKernelPages;
/* Check and see if the vmlinux is already larger than _end in System.map */
if (padPages < 0) {
/* vmlinux is larger than _end - adjust the offset to the start of the embedded ram disk */
offset_end = roundedKernelLen;
printf("vmlinux is larger than _end indicates it needs to be - offset_end = %lx \n", offset_end);
padPages = 0;
printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages);
}
else {
/* _end is larger than vmlinux - use the offset to _end that we calculated from the system map */
printf("vmlinux is smaller than _end indicates is needed - offset_end = %lx \n", offset_end);
printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages);
}
/* Input Ram Disk file */
// Set the offset that the ram disk will be started at.
ramStartOffs = offset_end; /* determined from the input vmlinux file and the system map */
printf("Ram Disk will start at offset = 0x%lx \n", ramStartOffs);
fseek(ramDisk, 0, SEEK_END);
ramFileLen = ftell(ramDisk);
fseek(ramDisk, 0, SEEK_SET);
printf("%s file size = %ld/0x%lx \n", argv[1], ramFileLen, ramFileLen);
ramLen = ramFileLen;
roundR = 4096 - (ramLen % 4096);
if ( roundR ) {
printf("Rounding RAM disk file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
ramLen += roundR;
}
printf("Rounded RAM disk size is %ld/0x%lx \n", ramLen, ramLen);
ramPages = ramLen / 4096;
printf("RAM disk pages to copy = %ld/0x%lx\n", ramPages, ramPages);
// Copy 64K ELF header
for (i=0; i<(ElfPages); ++i) {
get4k( inputVmlinux, inbuf );
put4k( outputVmlinux, inbuf );
}
/* Copy the vmlinux (as full pages). */
fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
for ( i=0; i<roundedKernelPages; ++i ) {
get4k( inputVmlinux, inbuf );
put4k( outputVmlinux, inbuf );
}
/* Insert pad pages (if appropriate) that are needed between */
/* | the end of the vmlinux and the ram disk. */
for (i=0; i<padPages; ++i) {
memset(inbuf, 0, 4096);
put4k(outputVmlinux, inbuf);
}
/* Copy the ram disk (as full pages). */
for ( i=0; i<ramPages; ++i ) {
get4k( ramDisk, inbuf );
put4k( outputVmlinux, inbuf );
}
/* Close the input files */
fclose(ramDisk);
fclose(inputVmlinux);
/* And flush the written output file */
fflush(outputVmlinux);
/* Fixup the new vmlinux to contain the ram disk starting offset (xRamDisk) and the ram disk size (xRamDiskSize) */
/* fseek to the hvReleaseData pointer */
fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET);
if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) {
death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[4]);
}
hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */
printf("hvReleaseData is at %08x\n", hvReleaseData);
/* fseek to the hvReleaseData */
fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET);
if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) {
death("Could not read hvReleaseData\n", outputVmlinux, argv[4]);
}
/* Check hvReleaseData sanity */
if (memcmp(inbuf, &eyeCatcher, 4) != 0) {
death("hvReleaseData is invalid\n", outputVmlinux, argv[4]);
}
/* Get the naca pointer */
naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE;
printf("Naca is at offset 0x%lx \n", naca);
/* fseek to the naca */
fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) {
death("Could not read naca\n", outputVmlinux, argv[4]);
}
xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c]));
xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14]));
/* Make sure a RAM disk isn't already present */
if ((xRamDisk != 0) || (xRamDiskSize != 0)) {
death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[4]);
}
/* Fill in the values */
*((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs);
*((u_int32_t *) &inbuf[0x14]) = htonl(ramPages);
/* Write out the new naca */
fflush(outputVmlinux);
fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) {
death("Could not write naca\n", outputVmlinux, argv[4]);
}
printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08x\n",
ramPages, ramStartOffs);
/* Done */
fclose(outputVmlinux);
/* Set permission to executable */
chmod(argv[4], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <byteswap.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
void xlate( char * inb, char * trb, unsigned len )
{
unsigned i;
for ( i=0; i<len; ++i )
{
char c = *inb++;
char c1 = c >> 4;
char c2 = c & 0xf;
if ( c1 > 9 )
c1 = c1 + 'A' - 10;
else
c1 = c1 + '0';
if ( c2 > 9 )
c2 = c2 + 'A' - 10;
else
c2 = c2 + '0';
*trb++ = c1;
*trb++ = c2;
}
*trb = 0;
}
#define ElfHeaderSize (64 * 1024)
#define ElfPages (ElfHeaderSize / 4096)
void get4k( /*istream *inf*/FILE *file, char *buf )
{
unsigned j;
unsigned num = fread(buf, 1, 4096, file);
for ( j=num; j<4096; ++j )
buf[j] = 0;
}
void put4k( /*ostream *outf*/FILE *file, char *buf )
{
fwrite(buf, 1, 4096, file);
}
int main(int argc, char **argv)
{
char inbuf[4096];
FILE *sysmap = NULL;
char* ptr_end = NULL;
FILE *inputVmlinux = NULL;
FILE *outputVmlinux = NULL;
long i = 0;
unsigned long sysmapFileLen = 0;
unsigned long sysmapLen = 0;
unsigned long roundR = 0;
unsigned long kernelLen = 0;
unsigned long actualKernelLen = 0;
unsigned long round = 0;
unsigned long roundedKernelLen = 0;
unsigned long sysmapStartOffs = 0;
unsigned long sysmapPages = 0;
unsigned long roundedKernelPages = 0;
long padPages = 0;
if ( argc < 2 )
{
printf("Name of System Map file missing.\n");
exit(1);
}
if ( argc < 3 )
{
printf("Name of vmlinux file missing.\n");
exit(1);
}
if ( argc < 4 )
{
printf("Name of vmlinux output file missing.\n");
exit(1);
}
sysmap = fopen(argv[1], "r");
if ( ! sysmap )
{
printf("System Map file \"%s\" failed to open.\n", argv[1]);
exit(1);
}
inputVmlinux = fopen(argv[2], "r");
if ( ! inputVmlinux )
{
printf("vmlinux file \"%s\" failed to open.\n", argv[2]);
exit(1);
}
outputVmlinux = fopen(argv[3], "w");
if ( ! outputVmlinux )
{
printf("output vmlinux file \"%s\" failed to open.\n", argv[3]);
exit(1);
}
fseek(inputVmlinux, 0, SEEK_END);
kernelLen = ftell(inputVmlinux);
fseek(inputVmlinux, 0, SEEK_SET);
printf("kernel file size = %ld\n", kernelLen);
if ( kernelLen == 0 )
{
printf("You must have a linux kernel specified as argv[2]\n");
exit(1);
}
actualKernelLen = kernelLen - ElfHeaderSize;
printf("actual kernel length (minus ELF header) = %ld/%lxx \n", actualKernelLen, actualKernelLen);
round = actualKernelLen % 4096;
roundedKernelLen = actualKernelLen;
if ( round )
roundedKernelLen += (4096 - round);
printf("Kernel length rounded up to a 4k multiple = %ld/%lxx \n", roundedKernelLen, roundedKernelLen);
roundedKernelPages = roundedKernelLen / 4096;
printf("Kernel pages to copy = %ld/%lxx\n", roundedKernelPages, roundedKernelPages);
/* Sysmap file */
fseek(sysmap, 0, SEEK_END);
sysmapFileLen = ftell(sysmap);
fseek(sysmap, 0, SEEK_SET);
printf("%s file size = %ld\n", argv[1], sysmapFileLen);
sysmapLen = sysmapFileLen;
roundR = 4096 - (sysmapLen % 4096);
if (roundR)
{
printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR);
sysmapLen += roundR;
}
printf("Rounded System Map size is %ld\n", sysmapLen);
/* Process the Sysmap file to determine the true end of the kernel */
sysmapPages = sysmapLen / 4096;
printf("System map pages to copy = %ld\n", sysmapPages);
for (i=0; i<sysmapPages; ++i)
{
get4k(sysmap, inbuf);
}
/* search for _end in the last page of the system map */
ptr_end = strstr(inbuf, " _end");
if (!ptr_end)
{
printf("Unable to find _end in the sysmap file \n");
printf("inbuf: \n");
printf("%s \n", inbuf);
exit(1);
}
printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
sysmapStartOffs = (unsigned int)strtol(ptr_end-10, NULL, 16);
/* calc how many pages we need to insert between the vmlinux and the start of the sysmap */
padPages = sysmapStartOffs/4096 - roundedKernelPages;
/* Check and see if the vmlinux is larger than _end in System.map */
if (padPages < 0)
{ /* vmlinux is larger than _end - adjust the offset to start the embedded system map */
sysmapStartOffs = roundedKernelLen;
printf("vmlinux is larger than _end indicates it needs to be - sysmapStartOffs = %lx \n", sysmapStartOffs);
padPages = 0;
printf("will insert %lx pages between the vmlinux and the start of the sysmap \n", padPages);
}
else
{ /* _end is larger than vmlinux - use the sysmapStartOffs we calculated from the system map */
printf("vmlinux is smaller than _end indicates is needed - sysmapStartOffs = %lx \n", sysmapStartOffs);
printf("will insert %lx pages between the vmlinux and the start of the sysmap \n", padPages);
}
/* Copy 64K ELF header */
for (i=0; i<(ElfPages); ++i)
{
get4k( inputVmlinux, inbuf );
put4k( outputVmlinux, inbuf );
}
/* Copy the vmlinux (as full pages). */
fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
for ( i=0; i<roundedKernelPages; ++i )
{
get4k( inputVmlinux, inbuf );
/* Set the offsets (of the start and end) of the embedded sysmap so it is set in the vmlinux.sm */
if ( i == 0 )
{
unsigned long * p;
printf("Storing embedded_sysmap_start at 0x3c\n");
p = (unsigned long *)(inbuf + 0x3c);
#if (BYTE_ORDER == __BIG_ENDIAN)
*p = sysmapStartOffs;
#else
*p = bswap_32(sysmapStartOffs);
#endif
printf("Storing embedded_sysmap_end at 0x44\n");
p = (unsigned long *)(inbuf + 0x44);
#if (BYTE_ORDER == __BIG_ENDIAN)
*p = sysmapStartOffs + sysmapFileLen;
#else
*p = bswap_32(sysmapStartOffs + sysmapFileLen);
#endif
}
put4k( outputVmlinux, inbuf );
}
/* Insert any pad pages between the end of the vmlinux and where the system map needs to be. */
for (i=0; i<padPages; ++i)
{
memset(inbuf, 0, 4096);
put4k(outputVmlinux, inbuf);
}
/* Copy the system map (as full pages). */
fseek(sysmap, 0, SEEK_SET); /* start reading from begining of the system map */
for ( i=0; i<sysmapPages; ++i )
{
get4k( sysmap, inbuf );
put4k( outputVmlinux, inbuf );
}
fclose(sysmap);
fclose(inputVmlinux);
fclose(outputVmlinux);
/* Set permission to executable */
chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
return 0;
}
/*
* Program to hack in a PT_NOTE program header entry in an ELF file.
* This is needed for OF on RS/6000s to load an image correctly.
* Note that OF needs a program header entry for the note, not an
* ELF section.
*
* Copyright 2000 Paul Mackerras.
*
* 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.
*
* Usage: addnote zImage
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
char arch[] = "PowerPC";
#define N_DESCR 6
unsigned int descr[N_DESCR] = {
0xffffffff, /* real-mode = true */
0x00c00000, /* real-base, i.e. where we expect OF to be */
0xffffffff, /* real-size */
0xffffffff, /* virt-base */
0xffffffff, /* virt-size */
0x4000, /* load-base */
};
unsigned char buf[512];
#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2))
#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \
buf[(off) + 1] = (v) & 0xff)
#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \
PUT_16BE((off) + 2, (v)))
/* Structure of an ELF file */
#define E_IDENT 0 /* ELF header */
#define E_PHOFF 28
#define E_PHENTSIZE 42
#define E_PHNUM 44
#define E_HSIZE 52 /* size of ELF header */
#define EI_MAGIC 0 /* offsets in E_IDENT area */
#define EI_CLASS 4
#define EI_DATA 5
#define PH_TYPE 0 /* ELF program header */
#define PH_OFFSET 4
#define PH_FILESZ 16
#define PH_HSIZE 32 /* size of program header */
#define PT_NOTE 4 /* Program header type = note */
#define ELFCLASS32 1
#define ELFDATA2MSB 2
unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
int
main(int ac, char **av)
{
int fd, n, i;
int ph, ps, np;
int nnote, ns;
if (ac != 2) {
fprintf(stderr, "Usage: %s elf-file\n", av[0]);
exit(1);
}
fd = open(av[1], O_RDWR);
if (fd < 0) {
perror(av[1]);
exit(1);
}
nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
n = read(fd, buf, sizeof(buf));
if (n < 0) {
perror("read");
exit(1);
}
if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
goto notelf;
if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
|| buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
av[1]);
exit(1);
}
ph = GET_32BE(E_PHOFF);
ps = GET_16BE(E_PHENTSIZE);
np = GET_16BE(E_PHNUM);
if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
goto notelf;
if (ph + (np + 1) * ps + nnote > n)
goto nospace;
for (i = 0; i < np; ++i) {
if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
fprintf(stderr, "%s already has a note entry\n",
av[1]);
exit(0);
}
ph += ps;
}
/* XXX check that the area we want to use is all zeroes */
for (i = 0; i < ps + nnote; ++i)
if (buf[ph + i] != 0)
goto nospace;
/* fill in the program header entry */
ns = ph + ps;
PUT_32BE(ph + PH_TYPE, PT_NOTE);
PUT_32BE(ph + PH_OFFSET, ns);
PUT_32BE(ph + PH_FILESZ, nnote);
/* fill in the note area we point to */
/* XXX we should probably make this a proper section */
PUT_32BE(ns, strlen(arch) + 1);
PUT_32BE(ns + 4, N_DESCR * 4);
PUT_32BE(ns + 8, 0x1275);
strcpy(&buf[ns + 12], arch);
ns += 12 + strlen(arch) + 1;
for (i = 0; i < N_DESCR; ++i)
PUT_32BE(ns + i * 4, descr[i]);
/* Update the number of program headers */
PUT_16BE(E_PHNUM, np + 1);
/* write back */
lseek(fd, (long) 0, SEEK_SET);
i = write(fd, buf, n);
if (i < 0) {
perror("write");
exit(1);
}
if (i < n) {
fprintf(stderr, "%s: write truncated\n", av[1]);
exit(1);
}
exit(0);
notelf:
fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
exit(1);
nospace:
fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
av[0]);
exit(1);
}
/*
* Copyright (C) Paul Mackerras 1997.
*
* 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.
*
* NOTE: this code runs in 32 bit mode and is packaged as ELF32.
*/
.text
.globl _start
_start:
lis 9,_start@h
lis 8,_etext@ha
addi 8,8,_etext@l
1: dcbf 0,9
icbi 0,9
addi 9,9,0x20
cmplwi 0,9,8
blt 1b
sync
isync
## Clear out the BSS as per ANSI C requirements
lis 7,_end@ha
addi 7,7,_end@l # r7 = &_end
lis 8,__bss_start@ha #
addi 8,8,__bss_start@l # r8 = &_bss_start
## Determine how large an area, in number of words, to clear
subf 7,8,7 # r7 = &_end - &_bss_start + 1
addi 7,7,3 # r7 += 3
srwi. 7,7,2 # r7 = size in words.
beq 3f # If the size is zero, do not bother
addi 8,8,-4 # r8 -= 4
mtctr 7 # SPRN_CTR = number of words to clear
li 0,0 # r0 = 0
2: stwu 0,4(8) # Clear out a word
bdnz 2b # If we are not done yet, keep clearing
3:
b start
/*
* Flush the dcache and invalidate the icache for a range of addresses.
*
* flush_cache(addr, len)
*/
.global flush_cache
flush_cache:
addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
rlwinm. 4,4,27,5,31
mtctr 4
beqlr
1: dcbf 0,3
icbi 0,3
addi 3,3,0x20
bdnz 1b
sync
isync
blr
#define r0 0
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
.globl strcpy
strcpy:
addi r5,r3,-1
addi r4,r4,-1
1: lbzu r0,1(r4)
cmpwi 0,r0,0
stbu r0,1(r5)
bne 1b
blr
.globl strncpy
strncpy:
cmpwi 0,r5,0
beqlr
mtctr r5
addi r6,r3,-1
addi r4,r4,-1
1: lbzu r0,1(r4)
cmpwi 0,r0,0
stbu r0,1(r6)
bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
blr
.globl strcat
strcat:
addi r5,r3,-1
addi r4,r4,-1
1: lbzu r0,1(r5)
cmpwi 0,r0,0
bne 1b
addi r5,r5,-1
1: lbzu r0,1(r4)
cmpwi 0,r0,0
stbu r0,1(r5)
bne 1b
blr
.globl strcmp
strcmp:
addi r5,r3,-1
addi r4,r4,-1
1: lbzu r3,1(r5)
cmpwi 1,r3,0
lbzu r0,1(r4)
subf. r3,r0,r3
beqlr 1
beq 1b
blr
.globl strlen
strlen:
addi r4,r3,-1
1: lbzu r0,1(r4)
cmpwi 0,r0,0
bne 1b
subf r3,r3,r4
blr
.globl memset
memset:
rlwimi r4,r4,8,16,23
rlwimi r4,r4,16,0,15
addi r6,r3,-4
cmplwi 0,r5,4
blt 7f
stwu r4,4(r6)
beqlr
andi. r0,r6,3
add r5,r0,r5
subf r6,r0,r6
rlwinm r0,r5,32-2,2,31
mtctr r0
bdz 6f
1: stwu r4,4(r6)
bdnz 1b
6: andi. r5,r5,3
7: cmpwi 0,r5,0
beqlr
mtctr r5
addi r6,r6,3
8: stbu r4,1(r6)
bdnz 8b
blr
.globl bcopy
bcopy:
mr r6,r3
mr r3,r4
mr r4,r6
b memcpy
.globl memmove
memmove:
cmplw 0,r3,r4
bgt backwards_memcpy
/* fall through */
.globl memcpy
memcpy:
rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
addi r6,r3,-4
addi r4,r4,-4
beq 2f /* if less than 8 bytes to do */
andi. r0,r6,3 /* get dest word aligned */
mtctr r7
bne 5f
1: lwz r7,4(r4)
lwzu r8,8(r4)
stw r7,4(r6)
stwu r8,8(r6)
bdnz 1b
andi. r5,r5,7
2: cmplwi 0,r5,4
blt 3f
lwzu r0,4(r4)
addi r5,r5,-4
stwu r0,4(r6)
3: cmpwi 0,r5,0
beqlr
mtctr r5
addi r4,r4,3
addi r6,r6,3
4: lbzu r0,1(r4)
stbu r0,1(r6)
bdnz 4b
blr
5: subfic r0,r0,4
mtctr r0
6: lbz r7,4(r4)
addi r4,r4,1
stb r7,4(r6)
addi r6,r6,1
bdnz 6b
subf r5,r0,r5
rlwinm. r7,r5,32-3,3,31
beq 2b
mtctr r7
b 1b
.globl backwards_memcpy
backwards_memcpy:
rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
add r6,r3,r5
add r4,r4,r5
beq 2f
andi. r0,r6,3
mtctr r7
bne 5f
1: lwz r7,-4(r4)
lwzu r8,-8(r4)
stw r7,-4(r6)
stwu r8,-8(r6)
bdnz 1b
andi. r5,r5,7
2: cmplwi 0,r5,4
blt 3f
lwzu r0,-4(r4)
subi r5,r5,4
stwu r0,-4(r6)
3: cmpwi 0,r5,0
beqlr
mtctr r5
4: lbzu r0,-1(r4)
stbu r0,-1(r6)
bdnz 4b
blr
5: mtctr r0
6: lbzu r7,-1(r4)
stbu r7,-1(r6)
bdnz 6b
subf r5,r0,r5
rlwinm. r7,r5,32-3,3,31
beq 2b
mtctr r7
b 1b
.globl memcmp
memcmp:
cmpwi 0,r5,0
blelr
mtctr r5
addi r6,r3,-1
addi r4,r4,-1
1: lbzu r3,1(r6)
lbzu r0,1(r4)
subf. r3,r0,r3
bdnzt 2,1b
blr
/*
* Copyright (C) Paul Mackerras 1997.
*
* Updates for PPC64 by Todd Inglett & Dave Engebretsen.
*
* 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.
*/
#define __KERNEL__
#include "zlib.h"
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/bootinfo.h>
void memmove(void *dst, void *im, int len);
extern void *finddevice(const char *);
extern int getprop(void *, const char *, void *, int);
extern void printf(const char *fmt, ...);
extern int sprintf(char *buf, const char *fmt, ...);
void gunzip(void *, int, unsigned char *, int *);
void *claim(unsigned int, unsigned int, unsigned int);
void flush_cache(void *, int);
void pause(void);
static struct bi_record *make_bi_recs(unsigned long);
#define RAM_START 0x00000000
#define RAM_END (64<<20)
#define BOOT_START ((unsigned long)_start)
#define BOOT_END ((unsigned long)_end)
/* Value picked to match that used by yaboot */
#define PROG_START 0x01400000
char *avail_ram;
char *begin_avail, *end_avail;
char *avail_high;
unsigned int heap_use;
unsigned int heap_max;
unsigned long initrd_start = 0;
unsigned long initrd_size = 0;
extern char _end[];
extern char image_data[];
extern int image_len;
extern char initrd_data[];
extern int initrd_len;
extern char sysmap_data[];
extern int sysmap_len;
extern int uncompressed_size;
extern long vmlinux_end;
static char scratch[128<<10]; /* 128kB of scratch space for gunzip */
typedef void (*kernel_entry_t)( unsigned long,
unsigned long,
void *,
struct bi_record *);
void
chrpboot(unsigned long a1, unsigned long a2, void *prom)
{
unsigned len;
void *dst = (void *)-1;
unsigned long claim_addr;
unsigned char *im;
extern char _start;
struct bi_record *bi_recs;
kernel_entry_t kernel_entry;
printf("chrpboot starting: loaded at 0x%x\n\r", (unsigned)&_start);
if (initrd_len) {
initrd_size = initrd_len;
initrd_start = (RAM_END - initrd_size) & ~0xFFF;
a1 = a2 = 0;
claim(initrd_start, RAM_END - initrd_start, 0);
printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
initrd_start, (unsigned long)initrd_data, initrd_size);
memcpy((void *)initrd_start, (void *)initrd_data, initrd_size);
}
im = image_data;
len = image_len;
uncompressed_size = PAGE_ALIGN(uncompressed_size);
for(claim_addr = PROG_START;
claim_addr <= PROG_START * 8;
claim_addr += 0x100000) {
printf(" trying: 0x%08lx\n\r", claim_addr);
dst = claim(claim_addr, uncompressed_size, 0);
if (dst != (void *)-1) break;
}
if (dst == (void *)-1) {
printf("claim error, can't allocate kernel memory\n\r");
return;
}
if (im[0] == 0x1f && im[1] == 0x8b) {
avail_ram = scratch;
begin_avail = avail_high = avail_ram;
end_avail = scratch + sizeof(scratch);
printf("gunzipping (0x%x <- 0x%x:0x%0x)...",
(unsigned)dst, (unsigned)im, (unsigned)im+len);
gunzip(dst, uncompressed_size, im, &len);
printf("done %u bytes\n\r", len);
printf("%u bytes of heap consumed, max in use %u\n\r",
(unsigned)(avail_high - begin_avail), heap_max);
} else {
memmove(dst, im, len);
}
flush_cache(dst, len);
bi_recs = make_bi_recs((unsigned long)dst + vmlinux_end);
kernel_entry = (kernel_entry_t)dst;
printf( "kernel:\n\r"
" entry addr = 0x%lx\n\r"
" a1 = 0x%lx,\n\r"
" a2 = 0x%lx,\n\r"
" prom = 0x%lx,\n\r"
" bi_recs = 0x%lx,\n\r",
(unsigned long)kernel_entry, a1, a2,
(unsigned long)prom, (unsigned long)bi_recs);
kernel_entry( a1, a2, prom, bi_recs );
printf("returned?\n\r");
pause();
}
static struct bi_record *
make_bi_recs(unsigned long addr)
{
struct bi_record *bi_recs;
struct bi_record *rec;
bi_recs = rec = bi_rec_init(addr);
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_FIRST;
/* rec->data[0] = ...; # Written below before return */
/* rec->data[1] = ...; # Written below before return */
rec = bi_rec_alloc_bytes(rec, strlen("chrpboot")+1);
rec->tag = BI_BOOTLOADER_ID;
sprintf( (char *)rec->data, "chrpboot");
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_MACHTYPE;
rec->data[0] = _MACH_pSeries;
rec->data[1] = 1;
if ( initrd_size > 0 ) {
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_INITRD;
rec->data[0] = initrd_start;
rec->data[1] = initrd_size;
}
#if 0
if ( sysmap_len > 0 ) {
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_SYSMAP;
rec->data[0] = (unsigned long)sysmap_data;
rec->data[1] = sysmap_len;
}
#endif
rec = bi_rec_alloc(rec, 1);
rec->tag = BI_LAST;
rec->data[0] = (bi_rec_field)bi_recs;
/* Save the _end_ address of the bi_rec's in the first bi_rec
* data field for easy access by the kernel.
*/
bi_recs->data[0] = (bi_rec_field)rec;
bi_recs->data[1] = (bi_rec_field)rec + rec->size - (bi_rec_field)bi_recs;
return bi_recs;
}
struct memchunk {
unsigned int size;
unsigned int pad;
struct memchunk *next;
};
static struct memchunk *freechunks;
void *zalloc(void *x, unsigned items, unsigned size)
{
void *p;
struct memchunk **mpp, *mp;
size *= items;
size = _ALIGN(size, sizeof(struct memchunk));
heap_use += size;
if (heap_use > heap_max)
heap_max = heap_use;
for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
if (mp->size == size) {
*mpp = mp->next;
return mp;
}
}
p = avail_ram;
avail_ram += size;
if (avail_ram > avail_high)
avail_high = avail_ram;
if (avail_ram > end_avail) {
printf("oops... out of memory\n\r");
pause();
}
return p;
}
void zfree(void *x, void *addr, unsigned nb)
{
struct memchunk *mp = addr;
nb = _ALIGN(nb, sizeof(struct memchunk));
heap_use -= nb;
if (avail_ram == addr + nb) {
avail_ram = addr;
return;
}
mp->size = nb;
mp->next = freechunks;
freechunks = mp;
}
#define HEAD_CRC 2
#define EXTRA_FIELD 4
#define ORIG_NAME 8
#define COMMENT 0x10
#define RESERVED 0xe0
#define DEFLATED 8
void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
{
z_stream s;
int r, i, flags;
/* skip header */
i = 10;
flags = src[3];
if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
printf("bad gzipped data\n\r");
exit();
}
if ((flags & EXTRA_FIELD) != 0)
i = 12 + src[10] + (src[11] << 8);
if ((flags & ORIG_NAME) != 0)
while (src[i++] != 0)
;
if ((flags & COMMENT) != 0)
while (src[i++] != 0)
;
if ((flags & HEAD_CRC) != 0)
i += 2;
if (i >= *lenp) {
printf("gunzip: ran out of data in header\n\r");
exit();
}
s.zalloc = zalloc;
s.zfree = zfree;
r = inflateInit2(&s, -MAX_WBITS);
if (r != Z_OK) {
printf("inflateInit2 returned %d\n\r", r);
exit();
}
s.next_in = src + i;
s.avail_in = *lenp - i;
s.next_out = dst;
s.avail_out = dstlen;
r = inflate(&s, Z_FINISH);
if (r != Z_OK && r != Z_STREAM_END) {
printf("inflate returned %d msg: %s\n\r", r, s.msg);
exit();
}
*lenp = s.next_out - (unsigned char *) dst;
inflateEnd(&s);
}
/*
* Copyright (C) Cort Dougan 1999.
*
* 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.
*
* Generate a note section as per the CHRP specification.
*
*/
#include <stdio.h>
#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
int main(void)
{
/* header */
/* namesz */
PL(strlen("PowerPC")+1);
/* descrsz */
PL(6*4);
/* type */
PL(0x1275);
/* name */
printf("PowerPC"); printf("%c", 0);
/* descriptor */
/* real-mode */
PL(0xffffffff);
/* real-base */
PL(0x00c00000);
/* real-size */
PL(0xffffffff);
/* virt-base */
PL(0xffffffff);
/* virt-size */
PL(0xffffffff);
/* load-base */
PL(0x4000);
return 0;
}
char initrd_data[1];
int initrd_len = 0;
/*
* Copyright 2001 IBM Corp
*
* 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.
*/
#include <stdio.h>
#include <unistd.h>
extern long ce_exec_config[];
int main(int argc, char *argv[])
{
int i, cnt, pos, len;
unsigned int cksum, val;
unsigned char *lp;
unsigned char buf[8192];
if (argc != 2)
{
fprintf(stderr, "usage: %s name <in-file >out-file\n",
argv[0]);
exit(1);
}
fprintf(stdout, "#\n");
fprintf(stdout, "# Miscellaneous data structures:\n");
fprintf(stdout, "# WARNING - this file is automatically generated!\n");
fprintf(stdout, "#\n");
fprintf(stdout, "\n");
fprintf(stdout, "\t.data\n");
fprintf(stdout, "\t.globl %s_data\n", argv[1]);
fprintf(stdout, "%s_data:\n", argv[1]);
pos = 0;
cksum = 0;
while ((len = read(0, buf, sizeof(buf))) > 0)
{
cnt = 0;
lp = (unsigned char *)buf;
len = (len + 3) & ~3; /* Round up to longwords */
for (i = 0; i < len; i += 4)
{
if (cnt == 0)
{
fprintf(stdout, "\t.long\t");
}
fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
val = *(unsigned long *)lp;
cksum ^= val;
lp += 4;
if (++cnt == 4)
{
cnt = 0;
fprintf(stdout, " # %x \n", pos+i-12);
fflush(stdout);
} else
{
fprintf(stdout, ",");
}
}
if (cnt)
{
fprintf(stdout, "0\n");
}
pos += len;
}
fprintf(stdout, "\t.globl %s_len\n", argv[1]);
fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
fflush(stdout);
fclose(stdout);
fprintf(stderr, "cksum = %x\n", cksum);
exit(0);
}
This diff is collapsed.
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.plt : { *(.plt) }
.text :
{
*(.text)
*(.fixup)
*(.got1)
}
. = ALIGN(4096);
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.kstrtab : { *(.kstrtab) }
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = ALIGN(4096);
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.got.plt) *(.got)
*(.dynamic)
CONSTRUCTORS
}
. = ALIGN(4096);
_edata = .;
PROVIDE (edata = .);
.fixup : { *(.fixup) }
. = ALIGN(4096);
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
. = ALIGN(4096);
_end = . ;
PROVIDE (end = .);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* HvLpConfig.c
* Copyright (C) 2001 Kyle A. Lucke, IBM Corporation
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _HVLPCONFIG_H
#include <asm/iSeries/HvLpConfig.h>
#endif
HvLpIndex HvLpConfig_getLpIndex_outline(void)
{
return HvLpConfig_getLpIndex();
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* c 2001 PPC 64 Team, IBM Corp
*
* 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.
*/
#ifndef _PPC_KERNEL_i8259_H
#define _PPC_KERNEL_i8259_H
#include "local_irq.h"
extern struct hw_interrupt_type i8259_pic;
void i8259_init(void);
int i8259_irq(int);
#endif /* _PPC_KERNEL_i8259_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM(init_mm);
/*
* Initial thread structure.
*
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) };
/*
* Initial task structure.
*
* All other task structs will be allocated on slabs in fork.c
*/
struct task_struct init_task = INIT_TASK(init_task);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment