From fbedff5e909777a1d646947bd4f9beca6ddf7024 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Fri, 20 Aug 2010 18:11:26 -0500 Subject: Add linker in preparation for modules. --- .gitignore | 1 + config.mk | 18 ++++-- makefile | 3 +- obj/hbicore/.gitignore | 0 obj/modules/.gitignore | 0 src/bld/.gitignore | 1 + src/bld/linker.C | 155 +++++++++++++++++++++++++++++++++++++++++++++++++ src/bld/makefile | 7 +++ src/kernel.ld | 14 +---- src/kernel/makefile | 7 ++- src/kernel/start.S | 4 -- src/lib/makefile | 6 +- src/libc++/makefile | 6 +- src/makefile | 14 +++-- src/sys/init/makefile | 6 +- src/sys/makefile | 9 +-- src/sys/vfs/makefile | 6 +- 17 files changed, 214 insertions(+), 43 deletions(-) create mode 100644 obj/hbicore/.gitignore create mode 100644 obj/modules/.gitignore create mode 100644 src/bld/.gitignore create mode 100644 src/bld/linker.C create mode 100644 src/bld/makefile diff --git a/.gitignore b/.gitignore index 24effd849..7240ef031 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.o +*.so *.swp *.bin *.elf diff --git a/config.mk b/config.mk index d74cd051f..5d2b2c028 100644 --- a/config.mk +++ b/config.mk @@ -7,9 +7,10 @@ CFLAGS = ${COMMONFLAGS} -mcpu=power7 -nostdinc -g -msoft-float -mno-altivec \ -Wall ASMFLAGS = ${COMMONFLAGS} -mcpu=power7 CXXFLAGS = ${CFLAGS} -nostdinc++ -fno-rtti -fno-exceptions -Wall -LDFLAGS = -static --sort-common -Map $@.map ${COMMONFLAGS} +LDFLAGS = --nostdlib --sort-common ${COMMONFLAGS} +LDMAPFLAGS = -Map $@.map -INCDIR = ${OBJDIR}/../src/include/ +INCDIR = ${ROOTPATH}/src/include/ ${OBJDIR}/%.o : %.C ${CXX} -c ${CXXFLAGS} $< -o $@ -I ${INCDIR} @@ -20,11 +21,16 @@ ${OBJDIR}/%.o : %.c ${OBJDIR}/%.o : %.S ${CC} -c ${ASMFLAGS} $< -o $@ -Wa,-I${INCDIR} -${IMGDIR}/%.elf: kernel.ld ${OBJDIR}/*.o - ${LD} ${LDFLAGS} ${OBJDIR}/*.o -T kernel.ld -o $@ +${OBJDIR}/%.so : ${OBJECTS} ${ROOTPATH}/src/module.ld + ${LD} -shared -z now --gc-sections ${LDFLAGS} $< \ + -T ${ROOTPATH}/src/module.ld -o $@ -${IMGDIR}/%.bin: kernel.ld ${OBJDIR}/*.o - ${LD} ${LDFLAGS} ${OBJDIR}/*.o --oformat=binary -T kernel.ld -o $@ +${IMGDIR}/%.elf: kernel.ld ${OBJDIR}/*.o ${ROOTPATH}/src/kernel.ld + ${LD} -static ${LDFLAGS} ${LDMAPFLAGS} ${OBJDIR}/*.o \ + -T ${ROOTPATH}/src/kernel.ld -o $@ + +${IMGDIR}/%.bin: ${IMGDIR}/%.elf $(wildcard ${IMGDIR}/*.so) + ${ROOTPATH}/src/bld/linker $@ $^ %.d: cd ${basename $@} && ${MAKE} diff --git a/makefile b/makefile index ccd8fed68..3bda10c6c 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,6 @@ SUBDIRS = src.d -include ./config.mk all: ${SUBDIRS} clean: $(patsubst %.d,%.clean, ${SUBDIRS}) + +include ./config.mk diff --git a/obj/hbicore/.gitignore b/obj/hbicore/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/obj/modules/.gitignore b/obj/modules/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/src/bld/.gitignore b/src/bld/.gitignore new file mode 100644 index 000000000..6b243f5f3 --- /dev/null +++ b/src/bld/.gitignore @@ -0,0 +1 @@ +linker diff --git a/src/bld/linker.C b/src/bld/linker.C new file mode 100644 index 000000000..59cbf6416 --- /dev/null +++ b/src/bld/linker.C @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::cout; +using std::endl; +using std::string; +using std::vector; + +struct Section +{ + string name; + size_t vma_offset; + size_t size; + + bfd_byte* data; +}; + +struct Object +{ + public: + bfd* image; + Section text; + Section data; + + bool read_object(char* file); + bool write_object(FILE* file); +}; + +vector objects; +FILE* output; + +int main(int argc, char** argv) +{ + if (argc <= 2) + { + cout << argv[0] << " " << endl; + return -1; + } + + // Open output file. + output = fopen(argv[1], "w+"); + if (NULL == output) + { + int error = errno; + cout << "Error opening " << argv[1] << endl; + cout << strerror(error) << endl; + } + + // Read input objects. + for (int files = 2; files < argc; files++) + { + Object o; + if (o.read_object(argv[files])) + { + objects.push_back(o); + } + } + + for (vector::iterator i = objects.begin(); + i != objects.end(); + ++i) + { + i->write_object(output); + } + return 0; +} + +bool Object::read_object(char* file) +{ + // Open BFD file. + image = bfd_openr(file, NULL); + if (!bfd_check_format(image, bfd_object)) + { + cout << "Unsupported file format: " << file << endl; + return false; + } + + cout << "File " << file << endl; + + // Read sections. + bfd_section* image_section = image->sections; + while(image_section != NULL) + { + Section* s = NULL; + if (string(".text") == bfd_get_section_name(image, image_section)) + { + s = &this->text; + } + if (string(".data") == bfd_get_section_name(image, image_section)) + { + s = &this->data; + } + if (NULL != s) + { + s->name = bfd_get_section_name(image, image_section); + s->vma_offset = bfd_get_section_vma(image, image_section); + s->size = bfd_get_section_size(image_section); + + bfd_malloc_and_get_section(image, image_section, &s->data); + + cout << "Section " << s->name << endl; + cout << "\tSize " << std::dec << s->size << endl; + cout << "\tVMA " << std::hex << s->vma_offset << endl; + cout << "\tData " << std::hex << bfd_getb64(s->data) + << "..." << endl; + } + + image_section = image_section->next; + } + + cout << endl; + + return true; +} + +#define advance_to_page_align(f) \ + { \ + long pos = ftell(f); \ + if (pos % 4096) \ + { \ + fseek((f), 4096 - (pos % 4096), SEEK_CUR); \ + } \ + } + +bool Object::write_object(FILE* file) +{ + // Start outputing object at page boundary. + advance_to_page_align(file); + long start_pos = ftell(file); + + // Output TEXT section. + fseek(file, text.vma_offset, SEEK_CUR); + if (text.size != fwrite(text.data, 1, text.size, file)) + { + int error = errno; + cout << "Error writing to output." << endl; + cout << strerror(error) << endl; + } + + // Output DATA section. + fseek(file, start_pos + data.vma_offset, SEEK_SET); + if (data.size != fwrite(data.data, 1, data.size, file)) + { + int error = errno; + cout << "Error writing to output." << endl; + cout << strerror(error) << endl; + } +} diff --git a/src/bld/makefile b/src/bld/makefile new file mode 100644 index 000000000..37fd2e4b1 --- /dev/null +++ b/src/bld/makefile @@ -0,0 +1,7 @@ +linker: linker.C + g++ -O3 linker.C -o linker -lbfd + +all: linker + +clean: + (rm -f linker) diff --git a/src/kernel.ld b/src/kernel.ld index b3749aefb..1078122c8 100644 --- a/src/kernel.ld +++ b/src/kernel.ld @@ -1,18 +1,14 @@ rom_offset = 0xfff00000; base_load_address = 0x00000000; text_load_address = 0x00003000; -hreset_load_address = 0x000ffffc; SECTIONS { . = base_load_address; - .text.intvects ALIGN(0x1000): AT(base_load_address + rom_offset) { + .text ALIGN(0x1000): AT(base_load_address + rom_offset) { *(.text.intvects) - } - - . = text_load_address; - .text ALIGN(0x1000): { + . = text_load_address; *(.text) *(.text._*) *(.rodata) @@ -21,7 +17,6 @@ SECTIONS ctor_start_address = .; *(.ctors) ctor_end_address = .; - } .data ALIGN(0x1000): { @@ -43,11 +38,6 @@ SECTIONS end_load_address = .; - . = hreset_load_address; - .text.hreset : { - *(.text.hreset) - } - /DISCARD/ : { *(.comment) *(.gnu.attributes) diff --git a/src/kernel/makefile b/src/kernel/makefile index 7d33a056e..397df1618 100644 --- a/src/kernel/makefile +++ b/src/kernel/makefile @@ -1,5 +1,5 @@ -OBJDIR = ../../obj -include ../../config.mk +ROOTPATH = ../.. +OBJDIR = ${ROOTPATH}/obj/hbicore OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o taskmgr.o cpumgr.o OBJS += syscall.o scheduler.o spinlock.o exception.o vmmmgr.o @@ -9,3 +9,6 @@ all: ${OBJECTS} clean: (rm -f ${OBJECTS} ) + +include ../../config.mk + diff --git a/src/kernel/start.S b/src/kernel/start.S index 3f7c2a5f8..538c5dbb5 100644 --- a/src/kernel/start.S +++ b/src/kernel/start.S @@ -309,7 +309,3 @@ kernel_stack: .global kernel_other_thread_spinlock kernel_other_thread_spinlock: .space 8 - -.section .text.hreset -hreset: - b _start diff --git a/src/lib/makefile b/src/lib/makefile index e1e0f1e50..3349ce5bb 100644 --- a/src/lib/makefile +++ b/src/lib/makefile @@ -1,5 +1,5 @@ -OBJDIR = ../../obj -include ../../config.mk +ROOTPATH = ../.. +OBJDIR = ${ROOTPATH}/obj/hbicore OBJS = string.o stdlib.o OBJS += syscall_stub.o syscall_task.o syscall_mutex.o syscall_msg.o @@ -10,3 +10,5 @@ all: ${OBJECTS} clean: (rm -f ${OBJECTS} ) + +include ../../config.mk diff --git a/src/libc++/makefile b/src/libc++/makefile index 9f7cd97aa..1835a238c 100644 --- a/src/libc++/makefile +++ b/src/libc++/makefile @@ -1,5 +1,5 @@ -OBJDIR = ../../obj -include ../../config.mk +ROOTPATH = ../.. +OBJDIR = ${ROOTPATH}/obj/hbicore OBJS = builtins.o OBJECTS = $(addprefix ${OBJDIR}/, ${OBJS}) @@ -8,3 +8,5 @@ all: ${OBJECTS} clean: (rm -f ${OBJECTS} ) + +include ../../config.mk diff --git a/src/makefile b/src/makefile index ba538037f..6045de28b 100644 --- a/src/makefile +++ b/src/makefile @@ -1,13 +1,15 @@ -IMGDIR = ../img -OBJDIR = ../obj -include ../config.mk +ROOTPATH = .. +IMGDIR = ${ROOTPATH}/img +OBJDIR = ${ROOTPATH}/obj/hbicore -SUBDIRS = kernel.d lib.d libc++.d sys.d -IMAGES += ${IMGDIR}/kernel.elf -IMAGES += ${IMGDIR}/kernel.bin +SUBDIRS = kernel.d lib.d libc++.d sys.d bld.d +IMAGES += ${IMGDIR}/hbicore.elf +IMAGES += ${IMGDIR}/hbicore.bin all: ${SUBDIRS} ${MAKE} ${IMAGES} clean: $(patsubst %.d,%.clean, ${SUBDIRS}) (rm -f ${IMAGES} $(addsuffix .map, ${IMAGES}) ) + +include ../config.mk diff --git a/src/sys/init/makefile b/src/sys/init/makefile index 4a1ecf48b..ba07a8647 100644 --- a/src/sys/init/makefile +++ b/src/sys/init/makefile @@ -1,5 +1,5 @@ -OBJDIR = ../../../obj -include ../../../config.mk +ROOTPATH = ../../.. +OBJDIR = ${ROOTPATH}/obj/hbicore OBJS = init_main.o OBJECTS = $(addprefix ${OBJDIR}/, ${OBJS}) @@ -8,3 +8,5 @@ all: ${OBJECTS} clean: (rm -f ${OBJECTS} ) + +include ../../../config.mk diff --git a/src/sys/makefile b/src/sys/makefile index 0eb552a44..9fd0b8d5c 100644 --- a/src/sys/makefile +++ b/src/sys/makefile @@ -1,10 +1,11 @@ -IMGDIR = ../../img -OBJDIR = ../../obj -include ../../config.mk +ROOTPATH = ../.. +IMGDIR = ${ROOTPATH}/img +OBJDIR = ${ROOTPATH}/obj/hbicore SUBDIRS = init.d vfs.d all: ${SUBDIRS} clean: $(patsubst %.d,%.clean, ${SUBDIRS}) - (rm -f ${IMAGES} ) + +include ../../config.mk diff --git a/src/sys/vfs/makefile b/src/sys/vfs/makefile index 94ca71bbf..616c8bf43 100644 --- a/src/sys/vfs/makefile +++ b/src/sys/vfs/makefile @@ -1,5 +1,5 @@ -OBJDIR = ../../../obj -include ../../../config.mk +ROOTPATH = ../../.. +OBJDIR = ${ROOTPATH}/obj/hbicore OBJS = vfs_main.o OBJECTS = $(addprefix ${OBJDIR}/, ${OBJS}) @@ -8,3 +8,5 @@ all: ${OBJECTS} clean: (rm -f ${OBJECTS} ) + +include ../../../config.mk -- cgit v1.2.1