diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-07-10 14:55:46 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-07-10 14:55:46 +0000 |
commit | 7fecdc557871231862d4ec6974e7fb58ab598bc7 (patch) | |
tree | 4521dd6c86b685338058c6aefdebd1b15ec3015d | |
parent | 405da05b93269b1c412fab1d9ee181df1119bfd8 (diff) | |
download | xen-7fecdc557871231862d4ec6974e7fb58ab598bc7.tar.gz xen-7fecdc557871231862d4ec6974e7fb58ab598bc7.tar.bz2 xen-7fecdc557871231862d4ec6974e7fb58ab598bc7.zip |
bitkeeper revision 1.1062.1.1 (40f00372K2jgGqY_Vwj24Lvaf0UqRw)
Rewritten bootstrap Elf-header creation to allow encapsulation of x86-64
code for 32-bit bootloaders.
-rw-r--r-- | .rootkeys | 13 | ||||
-rw-r--r-- | BitKeeper/etc/ignore | 4 | ||||
-rw-r--r-- | xen/Makefile | 5 | ||||
-rw-r--r-- | xen/arch/x86/Makefile | 30 | ||||
-rw-r--r-- | xen/arch/x86/boot/mkelf32.c | 280 | ||||
-rw-r--r-- | xen/figlet/LICENSE (renamed from xen/tools/figlet/LICENSE) | 0 | ||||
-rw-r--r-- | xen/figlet/Makefile (renamed from xen/tools/figlet/Makefile) | 0 | ||||
-rw-r--r-- | xen/figlet/README (renamed from xen/tools/figlet/README) | 0 | ||||
-rw-r--r-- | xen/figlet/figlet.c (renamed from xen/tools/figlet/figlet.c) | 0 | ||||
-rw-r--r-- | xen/figlet/xen.flf (renamed from xen/tools/figlet/xen.flf) | 0 | ||||
-rw-r--r-- | xen/tools/Makefile | 14 | ||||
-rw-r--r-- | xen/tools/elf-reloc.c | 115 |
12 files changed, 298 insertions, 163 deletions
@@ -315,6 +315,7 @@ 3ddb79bcBQF85CfLS4i1WGZ4oLLaCA xen/arch/x86/Rules.mk 3e5636e5FAYZ5_vQnmgwFJfSdmO5Mw xen/arch/x86/acpi.c 3ddb79bcsjinG9k1KcvbVBuas1R2dA xen/arch/x86/apic.c +3ddb79c4yGZ7_22QAFFwPzqP4NSHwA xen/arch/x86/boot/mkelf32.c 3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/x86_32.S 40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/x86/boot/x86_64.S 3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c @@ -396,6 +397,11 @@ 3ddb79bfl1H1arbB0pzAEC2uPmY_3g xen/drivers/pci/setup-irq.c 3ddb79bfJaf0bkE1Y67bnll8-kjEPg xen/drivers/pci/setup-res.c 3ddb79bfIcCWJsBDNcQQE3ok2Azn-Q xen/drivers/pci/syscall.c +3eb3c87fc79FXLA6R9TvdBJNTvQDwA xen/figlet/LICENSE +3eb3c87fPL2T_zBb0bHlbZY-ACEKRw xen/figlet/Makefile +3eb3c87fmKYTC5GCh_rydFakZp9ayw xen/figlet/README +3eb3c87fdQKQ5OBGbM-KjZfi9Us4ng xen/figlet/figlet.c +3eb3c87fS7DNbg0i6yhFs28UIqAK5g xen/figlet/xen.flf 40715b2cFpte_UNWnBZW0Du7z9AhTQ xen/include/acpi/acconfig.h 40715b2cEQWX-PaxEH30qI48K1krnQ xen/include/acpi/acdebug.h 40715b2c_7j-oy3ZNAuqE3IFNPzArg xen/include/acpi/acdisasm.h @@ -530,10 +536,3 @@ 3ddb79c0BnA20PbgmuMPSGIBljNRQw xen/include/xen/time.h 403a3edbG9K5uZjuY19_LORbQGmFbA xen/include/xen/trace.h 3ddb79c1-kVvF8cVa0k3ZHDdBMj01Q xen/include/xen/types.h -3ddb79c4x8dvwPtzclghWAKFWpEBFA xen/tools/Makefile -3ddb79c4yGZ7_22QAFFwPzqP4NSHwA xen/tools/elf-reloc.c -3eb3c87fc79FXLA6R9TvdBJNTvQDwA xen/tools/figlet/LICENSE -3eb3c87fPL2T_zBb0bHlbZY-ACEKRw xen/tools/figlet/Makefile -3eb3c87fmKYTC5GCh_rydFakZp9ayw xen/tools/figlet/README -3eb3c87fdQKQ5OBGbM-KjZfi9Us4ng xen/tools/figlet/figlet.c -3eb3c87fS7DNbg0i6yhFs28UIqAK5g xen/tools/figlet/xen.flf diff --git a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore index 88f1211183..2331290f1e 100644 --- a/BitKeeper/etc/ignore +++ b/BitKeeper/etc/ignore @@ -21,14 +21,14 @@ tools/*/build/lib*/*.py tools/misc/miniterm/miniterm tools/misc/xen_cpuperf tools/xentrace/xentrace +xen/arch/x86/boot/mkelf32 xen/drivers/pci/classlist.h xen/drivers/pci/devlist.h xen/drivers/pci/gen-devlist xen/include/asm xen/include/hypervisor-ifs/arch xen/include/xen/compile.h -xen/tools/elf-reloc -xen/tools/figlet/figlet +xen/figlet/figlet xen/xen xen/xen-syms xen/xen.* diff --git a/xen/Makefile b/xen/Makefile index a9fcf91e18..d65f8df8ca 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -27,14 +27,13 @@ dist: $(TARGET) $(MAKE) prefix=`pwd`/../install dist=yes install clean: delete-links - $(MAKE) -C tools clean + $(MAKE) -C figlet clean $(MAKE) -C common clean $(MAKE) -C drivers clean $(MAKE) -C arch/$(TARGET_ARCH) clean rm -f *.o $(TARGET)* *~ core $(GENERATED_FILES) $(TARGET): delete-unfresh-files make-links $(GENERATED_FILES) - $(MAKE) -C tools $(MAKE) -C common $(MAKE) -C drivers $(MAKE) -C arch/$(TARGET_ARCH) @@ -65,7 +64,7 @@ include/xen/compile.h: @LANG=C echo \#define XEN_EXTRAVERSION \"$(XEN_EXTRAVERSION)\" >> $@ @LANG=C echo >> $@ @LANG=C echo \#define XEN_BANNER \\ >> $@ - cd tools/figlet && make && ./figlet Xen $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) 1>>../../$@ && cd ../.. + cd ./figlet && make && ./figlet Xen $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) 1>>../$@ && cd .. @LANG=C echo >> $@ .PHONY: $(GENERATED_FILES) make-links delete-links default diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 1290f0420f..48c3556464 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -9,30 +9,16 @@ endif OBJS += $(patsubst %.S,%.o,$(wildcard $(TARGET_SUBARCH)/*.S)) OBJS += $(patsubst %.c,%.o,$(wildcard $(TARGET_SUBARCH)/*.c)) -ifeq ($(TARGET_SUBARCH),x86_32) -LINK_BASE := 0xFC500000 # Xen is linked here -LOAD_BASE := 0x00100000 # Xen is loaded here -endif - -ifeq ($(TARGET_SUBARCH),x86_64) -LINK_BASE := 0xFFFF830000100000 # Xen is linked here -LOAD_BASE := 0x0000000000100000 # Xen is loaded here -endif - -# What happens here? We link object files together, starting at LINK_BASE -# (a very high address). But the bootloader cannot put things there, so we -# initially load at LOAD_BASE. A tool called `elf-reloc' is used to modify -# segment offsets from LINK_BASE-relative to LOAD_BASE-relative. -# (NB. Linux gets round this by turning its image into raw binary, then -# wrapping that with a low-memory bootstrapper.) -default: boot/$(TARGET_SUBARCH).o $(OBJS) +default: boot/$(TARGET_SUBARCH).o $(OBJS) boot/mkelf32 $(LD) $(LDFLAGS) -r -o arch.o $(OBJS) $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $(TARGET)-syms - objcopy -R .note -R .comment -S $(TARGET)-syms $(TARGET) - $(BASEDIR)/tools/elf-reloc $(LINK_BASE) $(LOAD_BASE) $(TARGET) + ./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 + +boot/mkelf32: boot/mkelf32.c + $(HOSTCC) $(HOSTCFLAGS) -o $@ $< clean: - rm -f *.o *~ core boot/*.o boot/*~ boot/core - rm -f $(TARGET_SUBARCH)/*.o $(TARGET_SUBARCH)/*~ - rm -f $(TARGETSUBARCH)/core + rm -f *.o *~ core boot/*.o boot/*~ boot/core boot/mkelf32 + rm -f x86_32/*.o x86_32/*~ x86_32/core + rm -f x86_64/*.o x86_64/*~ x86_64/core diff --git a/xen/arch/x86/boot/mkelf32.c b/xen/arch/x86/boot/mkelf32.c new file mode 100644 index 0000000000..779dab662b --- /dev/null +++ b/xen/arch/x86/boot/mkelf32.c @@ -0,0 +1,280 @@ +/****************************************************************************** + * mkelf32.c + * + * Usage: elf-prefix <in-image> <out-image> <load-base> + * + * Converts an Elf32 or Elf64 executable binary <in-image> into a simple Elf32 + * image <out-image> comprising a single chunk to be loaded at <load-base>. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +/* + * Here I'm taking care not to conflict with possible typedef's in + * standard headers by instead using the macro namespace. + */ +#undef u8 +#undef u16 +#undef u32 +#undef u64 +#undef s8 +#undef s16 +#undef s32 +#undef s64 +#define u8 unsigned char +#define u16 unsigned short +#define u32 unsigned int +#define s8 signed char +#define s16 signed short +#define s32 signed int +#if defined(__i386__) +#define u64 unsigned long long +#define s64 signed long long +#else +#define u64 unsigned long +#define s64 signed long +#endif + +#include "../../../include/xen/elf.h" + +#define DYNAMICALLY_FILLED 0 +#define RAW_OFFSET 128 + +static Elf32_Ehdr out_ehdr = { + { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, /* EI_MAG{0-3} */ + ELFCLASS32, /* EI_CLASS */ + ELFDATA2LSB, /* EI_DATA */ + EV_CURRENT, /* EI_VERSION */ + 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* e_ident */ + ET_EXEC, /* e_type */ + EM_386, /* e_machine */ + EV_CURRENT, /* e_version */ + DYNAMICALLY_FILLED, /* e_entry */ + sizeof(Elf32_Ehdr), /* e_phoff */ + DYNAMICALLY_FILLED, /* e_shoff */ + 0, /* e_flags */ + sizeof(Elf32_Ehdr), /* e_ehsize */ + sizeof(Elf32_Phdr), /* e_phentsize */ + 1, /* e_phnum */ + sizeof(Elf32_Shdr), /* e_shentsize */ + 3, /* e_shnum */ + 2 /* e_shstrndx */ +}; + +static Elf32_Phdr out_phdr = { + PT_LOAD, /* p_type */ + RAW_OFFSET, /* p_offset */ + DYNAMICALLY_FILLED, /* p_vaddr */ + DYNAMICALLY_FILLED, /* p_paddr */ + DYNAMICALLY_FILLED, /* p_filesz */ + DYNAMICALLY_FILLED, /* p_memsz */ + PF_R|PF_W|PF_X, /* p_flags */ + 64 /* p_align */ +}; + +static u8 out_shstrtab[] = "\0.text\0.shstrtab"; + +static Elf32_Shdr out_shdr[] = { + { 0 }, + { 1, /* sh_name */ + SHT_PROGBITS, /* sh_type */ + SHF_WRITE|SHF_ALLOC|SHF_EXECINSTR, /* sh_flags */ + DYNAMICALLY_FILLED, /* sh_addr */ + RAW_OFFSET, /* sh_offset */ + DYNAMICALLY_FILLED, /* sh_size */ + 0, /* sh_link */ + 0, /* sh_info */ + 64, /* sh_addralign */ + 0 /* sh_entsize */ + }, + { 7, /* sh_name */ + SHT_STRTAB, /* sh_type */ + 0, /* sh_flags */ + 0, /* sh_addr */ + DYNAMICALLY_FILLED, /* sh_offset */ + sizeof(out_shstrtab), /* sh_size */ + 0, /* sh_link */ + 0, /* sh_info */ + 1, /* sh_addralign */ + 0 /* sh_entsize */ + } +}; + +static void do_write(int fd, void *data, int len) +{ + int done, left = len; + char *p = data; + + while ( left != 0 ) + { + if ( (done = write(fd, p, left)) == -1 ) + { + if ( errno == EINTR ) + continue; + fprintf(stderr, "Error writing output image: %d (%s).\n", + errno, strerror(errno)); + exit(1); + } + + left -= done; + p += done; + } +} + +static void do_read(int fd, void *data, int len) +{ + int done, left = len; + char *p = data; + + while ( left != 0 ) + { + if ( (done = read(fd, p, left)) == -1 ) + { + if ( errno == EINTR ) + continue; + fprintf(stderr, "Error reading input image: %d (%s).\n", + errno, strerror(errno)); + exit(1); + } + + left -= done; + p += done; + } +} + +int main(int argc, char **argv) +{ + u32 loadbase, dat_siz, mem_siz; + char *inimage, *outimage; + int infd, outfd; + char buffer[1024]; + int bytes, todo; + + Elf32_Ehdr in32_ehdr; + Elf32_Phdr in32_phdr; + + Elf64_Ehdr in64_ehdr; + Elf64_Phdr in64_phdr; + + if ( argc != 4 ) + { + fprintf(stderr, "Usage: mkelf32 <in-image> <out-image> <load-base>\n"); + return 1; + } + + inimage = argv[1]; + outimage = argv[2]; + loadbase = strtoul(argv[3], NULL, 16); + + infd = open(inimage, O_RDONLY); + if ( infd == -1 ) + { + fprintf(stderr, "Failed to open input image '%s': %d (%s).\n", + inimage, errno, strerror(errno)); + return 1; + } + + do_read(infd, &in32_ehdr, sizeof(in32_ehdr)); + if ( !IS_ELF(in32_ehdr) || + (in32_ehdr.e_ident[EI_DATA] != ELFDATA2LSB) ) + { + fprintf(stderr, "Input image must be a little-endian Elf image.\n"); + return 1; + } + + switch ( in32_ehdr.e_ident[EI_CLASS] ) + { + case ELFCLASS32: + if ( in32_ehdr.e_phentsize != sizeof(in32_phdr) ) + { + fprintf(stderr, "Bad program header size (%d != %d).\n", + (int)in32_ehdr.e_phentsize, (int)sizeof(in32_phdr)); + return 1; + } + + (void)lseek(infd, in32_ehdr.e_phoff, SEEK_SET); + do_read(infd, &in32_phdr, sizeof(in32_phdr)); + + (void)lseek(infd, in32_phdr.p_offset, SEEK_SET); + dat_siz = (u32)in32_phdr.p_filesz; + mem_siz = (u32)in32_phdr.p_memsz; + break; + + case ELFCLASS64: + (void)lseek(infd, 0, SEEK_SET); + do_read(infd, &in64_ehdr, sizeof(in64_ehdr)); + + if ( in64_ehdr.e_phentsize != sizeof(in64_phdr) ) + { + fprintf(stderr, "Bad program header size (%d != %d).\n", + (int)in64_ehdr.e_phentsize, (int)sizeof(in64_phdr)); + return 1; + } + + (void)lseek(infd, in64_ehdr.e_phoff, SEEK_SET); + do_read(infd, &in64_phdr, sizeof(in64_phdr)); + + (void)lseek(infd, in64_phdr.p_offset, SEEK_SET); + dat_siz = (u32)in64_phdr.p_filesz; + mem_siz = (u32)in64_phdr.p_memsz; + break; + + default: + fprintf(stderr, "Input image must be a 32- or 64-bit Elf image.\n"); + return 1; + } + + out_ehdr.e_entry = loadbase; + out_ehdr.e_shoff = RAW_OFFSET + dat_siz; + + out_phdr.p_vaddr = loadbase; + out_phdr.p_paddr = loadbase; + out_phdr.p_filesz = dat_siz; + out_phdr.p_memsz = mem_siz; + + out_shdr[1].sh_addr = loadbase; + out_shdr[1].sh_size = dat_siz; + out_shdr[2].sh_offset = RAW_OFFSET + dat_siz + sizeof(out_shdr); + + outfd = open(outimage, O_WRONLY|O_CREAT|O_TRUNC, 0775); + if ( outfd == -1 ) + { + fprintf(stderr, "Failed to open output image '%s': %d (%s).\n", + outimage, errno, strerror(errno)); + return 1; + } + + do_write(outfd, &out_ehdr, sizeof(out_ehdr)); + do_write(outfd, &out_phdr, sizeof(out_phdr)); + + if ( (bytes = RAW_OFFSET - sizeof(out_ehdr) - sizeof(out_phdr)) < 0 ) + { + fprintf(stderr, "Header overflow.\n"); + return 1; + } + do_write(outfd, buffer, bytes); + + for ( bytes = 0; bytes < dat_siz; bytes += todo ) + { + todo = ((dat_siz - bytes) > sizeof(buffer)) ? + sizeof(buffer) : (dat_siz - bytes); + do_read(infd, buffer, todo); + do_write(outfd, buffer, todo); + } + + do_write(outfd, &out_shdr[0], sizeof(out_shdr)); + do_write(outfd, out_shstrtab, sizeof(out_shstrtab)); + do_write(outfd, buffer, 4-((sizeof(out_shstrtab)+dat_siz)&3)); + + close(infd); + close(outfd); + + return 0; +} diff --git a/xen/tools/figlet/LICENSE b/xen/figlet/LICENSE index 59fd244536..59fd244536 100644 --- a/xen/tools/figlet/LICENSE +++ b/xen/figlet/LICENSE diff --git a/xen/tools/figlet/Makefile b/xen/figlet/Makefile index 9ed8fdff9c..9ed8fdff9c 100644 --- a/xen/tools/figlet/Makefile +++ b/xen/figlet/Makefile diff --git a/xen/tools/figlet/README b/xen/figlet/README index b4c58b3a5b..b4c58b3a5b 100644 --- a/xen/tools/figlet/README +++ b/xen/figlet/README diff --git a/xen/tools/figlet/figlet.c b/xen/figlet/figlet.c index 8e79e83170..8e79e83170 100644 --- a/xen/tools/figlet/figlet.c +++ b/xen/figlet/figlet.c diff --git a/xen/tools/figlet/xen.flf b/xen/figlet/xen.flf index e13e842fd7..e13e842fd7 100644 --- a/xen/tools/figlet/xen.flf +++ b/xen/figlet/xen.flf diff --git a/xen/tools/Makefile b/xen/tools/Makefile deleted file mode 100644 index a143ffdcbf..0000000000 --- a/xen/tools/Makefile +++ /dev/null @@ -1,14 +0,0 @@ - -all: figlet elf-reloc - -figlet: - $(MAKE) -C figlet - -elf-reloc: elf-reloc.c - gcc -O2 -Wall -o $@ $< - -clean: - rm -f elf-reloc *~ core - $(MAKE) -C figlet clean - -.PHONY: figlet diff --git a/xen/tools/elf-reloc.c b/xen/tools/elf-reloc.c deleted file mode 100644 index e2a5860e27..0000000000 --- a/xen/tools/elf-reloc.c +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * elf-reloc.c - * - * Usage: elf-reloc <old base> <new base> <image> - * - * Relocates <image> from <old base> address to <new base> address by - * frobbing the Elf headers. Segment contents are unmodified. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -typedef unsigned long Elf32_Addr; -typedef unsigned short Elf32_Half; -typedef unsigned long Elf32_Off; -typedef unsigned long Elf32_Word; - -typedef struct { - unsigned char e_ident[16]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; -} Elf32_Ehdr; - -typedef struct { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; - -#define offsetof(_f,_p) ((unsigned long)&(((_p *)0)->_f)) - - -/* Add @reloc_distance to address at offset @off in file @fp. */ -void reloc(FILE *fp, long off, unsigned long reloc_distance) -{ - unsigned long base; - fseek(fp, off, SEEK_SET); - fread(&base, sizeof(base), 1, fp); - base += reloc_distance; - fseek(fp, off, SEEK_SET); - fwrite(&base, sizeof(base), 1, fp); - -} - - -int main(int argc, char **argv) -{ - unsigned long old_base, new_base, reloc_distance; - long virt_section, phys_section; - char *image_name; - FILE *fp; - Elf32_Off phoff; - Elf32_Half phnum, phentsz; - int i; - - if ( argc != 4 ) - { - fprintf(stderr, "Usage: elf-reloc <old base> <new base> <image>\n"); - return(1); - } - - old_base = strtoul(argv[1], NULL, 16); - new_base = strtoul(argv[2], NULL, 16); - image_name = argv[3]; - - fp = fopen(image_name, "rb+"); - if ( !fp ) - { - fprintf(stderr, "Failed to load image!\n"); - return(1); - } - - reloc_distance = new_base - old_base; - - /* First frob the entry address. */ - reloc(fp, offsetof(e_entry, Elf32_Ehdr), reloc_distance); - - fseek(fp, offsetof(e_phoff, Elf32_Ehdr), SEEK_SET); - fread(&phoff, sizeof(phoff), 1, fp); - fseek(fp, offsetof(e_phnum, Elf32_Ehdr), SEEK_SET); - fread(&phnum, sizeof(phnum), 1, fp); - fseek(fp, offsetof(e_phentsize, Elf32_Ehdr), SEEK_SET); - fread(&phentsz, sizeof(phentsz), 1, fp); - - virt_section = (long)phoff + offsetof(p_vaddr, Elf32_Phdr); - phys_section = (long)phoff + offsetof(p_paddr, Elf32_Phdr); - for ( i = 0; i < phnum; i++ ) - { - reloc(fp, phys_section, reloc_distance); - reloc(fp, virt_section, reloc_distance); - phys_section += phentsz; - virt_section += phentsz; - } - - fclose(fp); - - return(0); -} |