diff --git a/build/jam/BuildSetup b/build/jam/BuildSetup index 9fed859d33..1d4cd81a58 100644 --- a/build/jam/BuildSetup +++ b/build/jam/BuildSetup @@ -122,6 +122,16 @@ if $(HAIKU_GCC_VERSION[1]) >= 3 { HAIKU_KERNEL_C++FLAGS += -fno-use-cxa-atexit ; } +HAIKU_KERNEL_PIC_CCFLAGS = -fno-pic ; +HAIKU_KERNEL_PIC_LINKFLAGS = ; +if $(HAIKU_ARCH) = ppc { + # Build a position independent PPC kernel. We need to be able to relocate + # the kernel, since the virtual address space layout at boot time is not + # fixed. + HAIKU_KERNEL_PIC_CCFLAGS = -fPIE ; + HAIKU_KERNEL_PIC_LINKFLAGS = -shared -fPIE ; +} + # If the environment variable DEBUG_PRINTF is defined we define an equally # named macro to the variable value. Some components use the macro to allow # another function than printf() to print the debug output. The variable should @@ -322,6 +332,16 @@ HOST_KERNEL_CCFLAGS += -finline -fno-builtin HOST_KERNEL_C++FLAGS += -finline -fno-builtin -fno-exceptions -DBOCHS_DEBUG_HACK=$(BOCHS_DEBUG_HACK) -D_KERNEL_MODE ; +HOST_KERNEL_PIC_CCFLAGS = -fno-pic ; +HOST_KERNEL_PIC_LINKFLAGS = ; +if $(HOST_ARCH) = ppc { + # Build a position independent PPC kernel. We need to be able to relocate + # the kernel, since the virtual address space layout at boot time is not + # fixed. + HOST_KERNEL_PIC_CCFLAGS = -fPIE ; + HOST_KERNEL_PIC_LINKFLAGS = -shared -fPIE ; +} + # warning flags HOST_WARNING_CCFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wcast-align -Wsign-compare ; @@ -486,6 +506,7 @@ local buildVars = ARFLAGS UNARFLAGS KERNEL_CCFLAGS KERNEL_C++FLAGS + KERNEL_PIC_CCFLAGS KERNEL_PIC_LINKFLAGS WARNING_CCFLAGS WARNING_C++FLAGS KERNEL_WARNING_CCFLAGS KERNEL_WARNING_C++FLAGS diff --git a/build/jam/KernelRules b/build/jam/KernelRules index 34e32472ca..7574bc089f 100644 --- a/build/jam/KernelRules +++ b/build/jam/KernelRules @@ -95,7 +95,7 @@ rule KernelAddon Depends $(target) : $(beginGlue) $(endGlue) ; # compile and link - SetupKernel $(sources) : -fno-pic ; + SetupKernel $(sources) : $(TARGET_KERNEL_PIC_FLAGS) ; local linkFlags = -nostdlib -Xlinker -soname=\"$(target)\" ; LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] $(linkFlags) ; Main $(target) : $(sources) ; diff --git a/headers/private/kernel/boot/arch.h b/headers/private/kernel/boot/arch.h new file mode 100644 index 0000000000..7d7dadd44e --- /dev/null +++ b/headers/private/kernel/boot/arch.h @@ -0,0 +1,28 @@ +/* + * Copyright 2005, Ingo Weinhold . + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_BOOT_ARCH_H +#define KERNEL_BOOT_ARCH_H + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* ELF support */ + +extern status_t boot_arch_elf_relocate_rel(struct preloaded_image *image, + struct Elf32_Rel *rel, int rel_len); +extern status_t boot_arch_elf_relocate_rela(struct preloaded_image *image, + struct Elf32_Rela *rel, int rel_len); + + +#ifdef __cplusplus +} +#endif + +#endif /* KERNEL_BOOT_ARCH_H */ diff --git a/headers/private/kernel/boot/elf.h b/headers/private/kernel/boot/elf.h index e6bb4ebc5f..0165b87ac4 100644 --- a/headers/private/kernel/boot/elf.h +++ b/headers/private/kernel/boot/elf.h @@ -19,6 +19,15 @@ struct preloaded_image { addr_range dynamic_section; struct Elf32_Ehdr elf_header; + struct Elf32_Sym *syms; + struct Elf32_Rel *rel; + int rel_len; + struct Elf32_Rela *rela; + int rela_len; + struct Elf32_Rel *pltrel; + int pltrel_len; + int pltrel_type; + struct Elf32_Sym *debug_symbols; const char *debug_string_table; uint32 num_debug_symbols, debug_string_table_size; @@ -28,4 +37,15 @@ struct preloaded_image { // the ID field will be filled out in the kernel }; +#ifdef __cplusplus +extern "C" { +#endif + +extern status_t boot_elf_resolve_symbol(struct preloaded_image *image, + struct Elf32_Sym *symbol, addr_t *symbolAddress); + +#ifdef __cplusplus +} +#endif + #endif /* KERNEL_BOOT_ELF_H */ diff --git a/headers/private/kernel/boot/platform/openfirmware/platform_arch.h b/headers/private/kernel/boot/platform/openfirmware/platform_arch.h index 5c87528485..7d21e2ab8b 100644 --- a/headers/private/kernel/boot/platform/openfirmware/platform_arch.h +++ b/headers/private/kernel/boot/platform/openfirmware/platform_arch.h @@ -8,10 +8,13 @@ #include +struct kernel_args; #ifdef __cplusplus extern "C" { #endif + +/* memory management */ extern status_t arch_set_callback(void); extern void *arch_mmu_allocate(void *address, size_t size, uint8 protection, @@ -19,6 +22,15 @@ extern void *arch_mmu_allocate(void *address, size_t size, uint8 protection, extern status_t arch_mmu_free(void *address, size_t size); extern status_t arch_mmu_init(void); +/* CPU */ + +extern status_t boot_arch_cpu_init(void); + +/* kernel start */ + +status_t arch_start_kernel(struct kernel_args *kernelArgs, addr_t kernelEntry, + addr_t kernelStackTop); + #ifdef __cplusplus } #endif diff --git a/headers/private/kernel/platform.h b/headers/private/kernel/platform.h new file mode 100644 index 0000000000..28a61462ad --- /dev/null +++ b/headers/private/kernel/platform.h @@ -0,0 +1,23 @@ +/* + * Copyright 2005, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_PLATFORM_H +#define _KERNEL_PLATFORM_H + +#include + +struct kernel_args; + +#ifdef __cplusplus +extern "C" { +#endif + +status_t platform_init(struct kernel_args *kernelArgs); + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif // _KERNEL_PLATFORM_H diff --git a/src/system/boot/platform/openfirmware/openfirmware.h b/headers/private/kernel/platform/openfirmware/openfirmware.h similarity index 100% rename from src/system/boot/platform/openfirmware/openfirmware.h rename to headers/private/kernel/platform/openfirmware/openfirmware.h diff --git a/src/system/boot/Jamfile b/src/system/boot/Jamfile index 098507c395..3f487b40cf 100644 --- a/src/system/boot/Jamfile +++ b/src/system/boot/Jamfile @@ -31,6 +31,7 @@ if $(TARGET_ARCH) = x86 { KernelLd boot_loader : boot_platform_$(TARGET_BOOT_PLATFORM).o + boot_arch_$(TARGET_ARCH).o boot_loader.a boot_net.a boot_partitions.a @@ -68,5 +69,6 @@ actions BuildZbeos { BuildZbeos zbeos : boot_loader ; -SubInclude HAIKU_TOP src system boot platform ; +SubInclude HAIKU_TOP src system boot arch $(TARGET_ARCH) ; SubInclude HAIKU_TOP src system boot loader ; +SubInclude HAIKU_TOP src system boot platform ; diff --git a/src/system/boot/arch/ppc/Jamfile b/src/system/boot/arch/ppc/Jamfile new file mode 100644 index 0000000000..69ebe2f5dd --- /dev/null +++ b/src/system/boot/arch/ppc/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src system boot arch ppc ; + +SubDirC++Flags -fno-rtti ; + +KernelMergeObject boot_arch_ppc.o : + elf.cpp +; diff --git a/src/system/boot/arch/ppc/elf.cpp b/src/system/boot/arch/ppc/elf.cpp new file mode 100644 index 0000000000..02d14074ce --- /dev/null +++ b/src/system/boot/arch/ppc/elf.cpp @@ -0,0 +1,378 @@ +/* + * Copyright 2005, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ +/* +** Copyright 2002, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ + +#include + +#include + +#include +#include + + +#define CHATTY 0 + + +status_t +boot_arch_elf_relocate_rel(struct preloaded_image *image, + struct Elf32_Rel *rel, int rel_len) +{ + // there are no rel entries in PPC elf + return B_NO_ERROR; +} + + +static inline void +write_word32(addr_t P, Elf32_Word value) +{ + *(Elf32_Word*)P = value; +} + + +static inline void +write_word30(addr_t P, Elf32_Word value) +{ + // bits 0:29 + *(Elf32_Word*)P = (*(Elf32_Word*)P & 0x3) | (value << 2); +} + + +static inline bool +write_low24_check(addr_t P, Elf32_Word value) +{ + // bits 6:29 +// TODO: This check doesn't work, since negative values are allowed, too. +// if (value & 0xff000000) +// return false; + *(Elf32_Word*)P = (*(Elf32_Word*)P & 0xfc000003) | (value << 2); + return true; +} + + +static inline bool +write_low14_check(addr_t P, Elf32_Word value) +{ + // bits 16:29 +// if (value & 0xffffc000) +// return false; + *(Elf32_Word*)P = (*(Elf32_Word*)P & 0xffff0003) | (value << 2); + return true; +} + + +static inline void +write_half16(addr_t P, Elf32_Word value) +{ + // bits 16:29 + *(Elf32_Half*)P = (Elf32_Half)value; +} + + +static inline bool +write_half16_check(addr_t P, Elf32_Word value) +{ + // bits 16:29 +// if (value & 0xffff0000) +// return false; + *(Elf32_Half*)P = (Elf32_Half)value; + return true; +} + + +static inline Elf32_Word +lo(Elf32_Word value) +{ + return (value & 0xffff); +} + + +static inline Elf32_Word +hi(Elf32_Word value) +{ + return ((value >> 16) & 0xffff); +} + + +static inline Elf32_Word +ha(Elf32_Word value) +{ + return (((value >> 16) + (value & 0x8000 ? 1 : 0)) & 0xffff); +} + + +status_t +boot_arch_elf_relocate_rela(struct preloaded_image *image, + struct Elf32_Rela *rel, int rel_len) +{ + int i; + struct Elf32_Sym *sym; + int vlErr; + addr_t S = 0; // symbol address + addr_t R = 0; // section relative symbol address + + addr_t G = 0; // GOT address + addr_t L = 0; // PLT address + + #define P ((addr_t)(image->text_region.delta + rel[i].r_offset)) + #define A ((addr_t)rel[i].r_addend) + #define B (image->text_region.delta) + + // TODO: Get the GOT address! + #define REQUIRE_GOT \ + if (G == 0) { \ + dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \ + return B_ERROR; \ + } + + // TODO: Get the PLT address! + #define REQUIRE_PLT \ + if (L == 0) { \ + dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \ + return B_ERROR; \ + } + + for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) { +#if CHATTY + dprintf("looking at rel type %d, offset 0x%x, sym 0x%x, addend 0x%x\n", + ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); +#endif + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_PPC_SECTOFF: + case R_PPC_SECTOFF_LO: + case R_PPC_SECTOFF_HI: + case R_PPC_SECTOFF_HA: + dprintf("arch_elf_relocate_rela(): Getting section relative " + "symbol addresses not yet supported!\n"); + return B_ERROR; + + case R_PPC_ADDR32: + case R_PPC_ADDR24: + case R_PPC_ADDR16: + case R_PPC_ADDR16_LO: + case R_PPC_ADDR16_HI: + case R_PPC_ADDR16_HA: + case R_PPC_ADDR14: + case R_PPC_ADDR14_BRTAKEN: + case R_PPC_ADDR14_BRNTAKEN: + case R_PPC_REL24: + case R_PPC_REL14: + case R_PPC_REL14_BRTAKEN: + case R_PPC_REL14_BRNTAKEN: + case R_PPC_GLOB_DAT: + case R_PPC_UADDR32: + case R_PPC_UADDR16: + case R_PPC_REL32: + case R_PPC_SDAREL16: + case R_PPC_ADDR30: + case R_PPC_JMP_SLOT: + sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); + + vlErr = boot_elf_resolve_symbol(image, sym, &S); + if (vlErr<0) + return vlErr; + break; + } + + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_PPC_NONE: + break; + + case R_PPC_COPY: + // TODO: Implement! + dprintf("arch_elf_relocate_rela(): R_PPC_COPY not yet " + "supported!\n"); + return B_ERROR; + + case R_PPC_ADDR32: + case R_PPC_GLOB_DAT: + case R_PPC_UADDR32: + write_word32(P, S + A); + break; + + case R_PPC_ADDR24: + if (write_low24_check(P, (S + A) >> 2)) + break; +dprintf("R_PPC_ADDR24 overflow\n"); + return B_BAD_DATA; + + case R_PPC_ADDR16: + case R_PPC_UADDR16: + if (write_half16_check(P, S + A)) + break; +dprintf("R_PPC_ADDR16 overflow\n"); + return B_BAD_DATA; + + case R_PPC_ADDR16_LO: + write_half16(P, lo(S + A)); + break; + + case R_PPC_ADDR16_HI: + write_half16(P, hi(S + A)); + break; + + case R_PPC_ADDR16_HA: + write_half16(P, ha(S + A)); + break; + + case R_PPC_ADDR14: + case R_PPC_ADDR14_BRTAKEN: + case R_PPC_ADDR14_BRNTAKEN: + if (write_low14_check(P, (S + A) >> 2)) + break; +dprintf("R_PPC_ADDR14 overflow\n"); + return B_BAD_DATA; + + case R_PPC_REL24: + if (write_low24_check(P, (S + A - P) >> 2)) + break; +dprintf("R_PPC_REL24 overflow: 0x%lx\n", (S + A - P) >> 2); + return B_BAD_DATA; + + case R_PPC_REL14: + case R_PPC_REL14_BRTAKEN: + case R_PPC_REL14_BRNTAKEN: + if (write_low14_check(P, (S + A - P) >> 2)) + break; +dprintf("R_PPC_REL14 overflow\n"); + return B_BAD_DATA; + + case R_PPC_GOT16: + REQUIRE_GOT; + if (write_half16_check(P, G + A)) + break; +dprintf("R_PPC_GOT16 overflow\n"); + return B_BAD_DATA; + + case R_PPC_GOT16_LO: + REQUIRE_GOT; + write_half16(P, lo(G + A)); + break; + + case R_PPC_GOT16_HI: + REQUIRE_GOT; + write_half16(P, hi(G + A)); + break; + + case R_PPC_GOT16_HA: + REQUIRE_GOT; + write_half16(P, ha(G + A)); + break; + + case R_PPC_JMP_SLOT: + { + // If the relative offset is small enough, we fabricate a + // relative branch instruction ("b "). + addr_t jumpOffset = S - P; + if ((jumpOffset & 0xfc000000) != 0 + && (~jumpOffset & 0xfe000000) != 0) { + // Offset > 24 bit. + // TODO: Implement! + // See System V PPC ABI supplement, p. 5-6! + dprintf("arch_elf_relocate_rela(): R_PPC_JMP_SLOT: " + "Offsets > 24 bit currently not supported!\n"); +dprintf("jumpOffset: %p\n", (void*)jumpOffset); + return B_ERROR; + } else { + // Offset <= 24 bit + // 0:5 opcode (= 18), 6:29 address, 30 AA, 31 LK + // "b" instruction: opcode = 18, AA = 0, LK = 0 + // address: 24 high-order bits of 26 bit offset + *(uint32*)P = 0x48000000 | ((jumpOffset) & 0x03fffffc); + } + break; + } + + case R_PPC_RELATIVE: + write_word32(P, B + A); + break; + + case R_PPC_LOCAL24PC: +// TODO: Implement! +// low24* +// if (write_low24_check(P, ?) +// break; +// return B_BAD_DATA; + dprintf("arch_elf_relocate_rela(): R_PPC_LOCAL24PC not yet " + "supported!\n"); + return B_ERROR; + + case R_PPC_REL32: + write_word32(P, S + A - P); + break; + + case R_PPC_PLTREL24: + REQUIRE_PLT; + if (write_low24_check(P, (L + A - P) >> 2)) + break; +dprintf("R_PPC_PLTREL24 overflow\n"); + return B_BAD_DATA; + + case R_PPC_PLT32: + REQUIRE_PLT; + write_word32(P, L + A); + break; + + case R_PPC_PLTREL32: + REQUIRE_PLT; + write_word32(P, L + A - P); + break; + + case R_PPC_PLT16_LO: + REQUIRE_PLT; + write_half16(P, lo(L + A)); + break; + + case R_PPC_PLT16_HI: + REQUIRE_PLT; + write_half16(P, hi(L + A)); + break; + + case R_PPC_PLT16_HA: + write_half16(P, ha(L + A)); + break; + + case R_PPC_SDAREL16: +// TODO: Implement! +// if (write_half16_check(P, S + A - _SDA_BASE_)) +// break; +// return B_BAD_DATA; + dprintf("arch_elf_relocate_rela(): R_PPC_SDAREL16 not yet " + "supported!\n"); + return B_ERROR; + + case R_PPC_SECTOFF: + if (write_half16_check(P, R + A)) + break; +dprintf("R_PPC_SECTOFF overflow\n"); + return B_BAD_DATA; + + case R_PPC_SECTOFF_LO: + write_half16(P, lo(R + A)); + break; + + case R_PPC_SECTOFF_HI: + write_half16(P, hi(R + A)); + break; + + case R_PPC_SECTOFF_HA: + write_half16(P, ha(R + A)); + break; + + case R_PPC_ADDR30: + write_word30(P, (S + A - P) >> 2); + break; + + default: + dprintf("arch_elf_relocate_rela: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); + return B_ERROR; + } + } + + return B_NO_ERROR; +} + diff --git a/src/system/boot/arch/x86/Jamfile b/src/system/boot/arch/x86/Jamfile new file mode 100644 index 0000000000..5afcfbffc3 --- /dev/null +++ b/src/system/boot/arch/x86/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src system boot arch x86 ; + +SubDirC++Flags -fno-rtti ; + +KernelMergeObject boot_arch_x86.o : + elf.cpp +; diff --git a/src/system/boot/arch/x86/elf.cpp b/src/system/boot/arch/x86/elf.cpp new file mode 100644 index 0000000000..1c03982ef9 --- /dev/null +++ b/src/system/boot/arch/x86/elf.cpp @@ -0,0 +1,135 @@ +/* +** Copyright 2002, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ + + +#include + +#include + +#include +#include + + +//#define TRACE_ARCH_ELF +#ifdef TRACE_ARCH_ELF +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +#ifdef TRACE_ARCH_ELF +static const char *kRelocations[] = { + "R_386_NONE", + "R_386_32", /* add symbol value */ + "R_386_PC32", /* add PC relative symbol value */ + "R_386_GOT32", /* add PC relative GOT offset */ + "R_386_PLT32", /* add PC relative PLT offset */ + "R_386_COPY", /* copy data from shared object */ + "R_386_GLOB_DAT", /* set GOT entry to data address */ + "R_386_JMP_SLOT", /* set GOT entry to code address */ + "R_386_RELATIVE", /* add load address of shared object */ + "R_386_GOTOFF", /* add GOT relative symbol address */ + "R_386_GOTPC", /* add PC relative GOT table address */ +}; +#endif + + +status_t +boot_arch_elf_relocate_rel(struct preloaded_image *image, + struct Elf32_Rel *rel, int rel_len) +{ + struct Elf32_Sym *sym; + addr_t S; + addr_t A; + addr_t P; + addr_t final_val; + int i; + + S = A = P = 0; + + for (i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) { + TRACE(("looking at rel type %s, offset 0x%lx\n", kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset)); + + // calc S + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_386_32: + case R_386_PC32: + case R_386_GLOB_DAT: + case R_386_JMP_SLOT: + case R_386_GOTOFF: + { + int vlErr; + + sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); + + vlErr = boot_elf_resolve_symbol(image, sym, &S); + if (vlErr < 0) + return vlErr; + TRACE(("S %p (%s)\n", (void *)S, SYMNAME(image, sym))); + } + } + // calc A + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_386_32: + case R_386_PC32: + case R_386_GOT32: + case R_386_PLT32: + case R_386_RELATIVE: + case R_386_GOTOFF: + case R_386_GOTPC: + A = *(addr_t *)(image->text_region.delta + rel[i].r_offset); + TRACE(("A %p\n", (void *)A)); + break; + } + // calc P + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_386_PC32: + case R_386_GOT32: + case R_386_PLT32: + case R_386_GOTPC: + P = image->text_region.delta + rel[i].r_offset; + TRACE(("P %p\n", (void *)P)); + break; + } + + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_386_NONE: + continue; + case R_386_32: + final_val = S + A; + break; + case R_386_PC32: + final_val = S + A - P; + break; + case R_386_RELATIVE: + // B + A; + final_val = image->text_region.delta + A; + break; + case R_386_JMP_SLOT: + case R_386_GLOB_DAT: + final_val = S; + break; + + default: + dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); + return EPERM; + } + *(addr_t *)(image->text_region.delta + rel[i].r_offset) = final_val; + TRACE(("-> offset %p = %p\n", (void *)(image->text_region.delta + rel[i].r_offset), (void *)final_val)); + } + + return B_NO_ERROR; +} + + +status_t +boot_arch_elf_relocate_rela(struct preloaded_image *image, + struct Elf32_Rela *rel, int rel_len) +{ + dprintf("arch_elf_relocate_rela: not supported on x86\n"); + return B_ERROR; +} + diff --git a/src/system/boot/loader/elf.cpp b/src/system/boot/loader/elf.cpp index 8c70585974..4d74e2e92c 100644 --- a/src/system/boot/loader/elf.cpp +++ b/src/system/boot/loader/elf.cpp @@ -6,6 +6,7 @@ #include "elf.h" +#include #include #include #include @@ -37,6 +38,69 @@ verify_elf_header(struct Elf32_Ehdr &header) } +static status_t +elf_parse_dynamic_section(struct preloaded_image *image) +{ + image->syms = 0; + image->rel = 0; + image->rel_len = 0; + image->rela = 0; + image->rela_len = 0; + image->pltrel = 0; + image->pltrel_len = 0; + image->pltrel_type = 0; + + struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_section.start; + if (!d) + return B_ERROR; + + for (int i = 0; d[i].d_tag != DT_NULL; i++) { + switch (d[i].d_tag) { + case DT_HASH: +// image->symhash = (uint32 *)(d[i].d_un.d_ptr + image->text_region.delta); + break; + case DT_STRTAB: +// image->strtab = (char *)(d[i].d_un.d_ptr + image->text_region.delta); + break; + case DT_SYMTAB: + image->syms = (struct Elf32_Sym *)(d[i].d_un.d_ptr + image->text_region.delta); + break; + case DT_REL: + image->rel = (struct Elf32_Rel *)(d[i].d_un.d_ptr + image->text_region.delta); + break; + case DT_RELSZ: + image->rel_len = d[i].d_un.d_val; + break; + case DT_RELA: + image->rela = (struct Elf32_Rela *)(d[i].d_un.d_ptr + image->text_region.delta); + break; + case DT_RELASZ: + image->rela_len = d[i].d_un.d_val; + break; + case DT_JMPREL: + image->pltrel = (struct Elf32_Rel *)(d[i].d_un.d_ptr + image->text_region.delta); + break; + case DT_PLTRELSZ: + image->pltrel_len = d[i].d_un.d_val; + break; + case DT_PLTREL: + image->pltrel_type = d[i].d_un.d_val; + break; + + default: + continue; + } + } + + // lets make sure we found all the required sections +// if (!image->symhash || !image->syms || !image->strtab) + if (/* !image->symhash ||*/ !image->syms /*|| !image->strtab*/) + return B_ERROR; + + return B_OK; +} + + static status_t load_elf_symbol_table(int fd, preloaded_image *image) { @@ -288,8 +352,10 @@ elf_load_image(int fd, preloaded_image *image) memset((void *)(region->start + offset), 0, region->size - offset); } - // modify the dynamic section by the delta of the regions + // offset dynamic section, and program entry addresses by the delta of the + // regions image->dynamic_section.start += image->text_region.delta; + image->elf_header.e_entry += image->text_region.delta; image->num_debug_symbols = 0; image->debug_symbols = NULL; @@ -361,3 +427,69 @@ elf_load_image(Directory *directory, const char *path) return status; } + +status_t +elf_relocate_image(struct preloaded_image *image) +{ + status_t status = elf_parse_dynamic_section(image); + if (status != B_OK) + return status; + + // deal with the rels first + if (image->rel) { + TRACE(("total %i relocs\n", + image->rel_len / (int)sizeof(struct Elf32_Rel))); + + status = boot_arch_elf_relocate_rel(image, image->rel, image->rel_len); + if (status < B_OK) + return status; + } + + if (image->pltrel) { + TRACE(("total %i plt-relocs\n", + image->pltrel_len / (int)sizeof(struct Elf32_Rel))); + + if (image->pltrel_type == DT_REL) { + status = boot_arch_elf_relocate_rel(image, image->pltrel, + image->pltrel_len); + } else { + status = boot_arch_elf_relocate_rela(image, + (struct Elf32_Rela *)image->pltrel, image->pltrel_len); + } + if (status < B_OK) + return status; + } + + if (image->rela) { + status = boot_arch_elf_relocate_rela(image, image->rela, + image->rela_len); + if (status < B_OK) + return status; + } + + return B_OK; +} + + +status_t +boot_elf_resolve_symbol(struct preloaded_image *image, + struct Elf32_Sym *symbol, addr_t *symbolAddress) +{ + switch (symbol->st_shndx) { + case SHN_UNDEF: + // Since we do that only for the kernel, there shouldn't be + // undefined symbols. + return B_MISSING_SYMBOL; + case SHN_ABS: + *symbolAddress = symbol->st_value; + return B_NO_ERROR; + case SHN_COMMON: + // ToDo: finish this + TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n")); + return B_ERROR; + default: + // standard symbol + *symbolAddress = symbol->st_value + image->text_region.delta; + return B_NO_ERROR; + } +} diff --git a/src/system/boot/loader/elf.h b/src/system/boot/loader/elf.h index d96dadcd93..29b991ee6a 100644 --- a/src/system/boot/loader/elf.h +++ b/src/system/boot/loader/elf.h @@ -13,4 +13,6 @@ extern status_t elf_load_image(Directory *directory, const char *path); extern status_t elf_load_image(int fd, preloaded_image *image); +extern status_t elf_relocate_image(struct preloaded_image *image); + #endif /* LOADER_ELF_H */ diff --git a/src/system/boot/loader/loader.cpp b/src/system/boot/loader/loader.cpp index afb7ba10d9..e8d28cbd3d 100644 --- a/src/system/boot/loader/loader.cpp +++ b/src/system/boot/loader/loader.cpp @@ -65,7 +65,13 @@ load_kernel(stage2_args *args, Directory *volume) close(fd); if (status < B_OK) { - dprintf("loading kernel failed: %ld!\n", status); + dprintf("loading kernel failed: %lx!\n", status); + return status; + } + + status = elf_relocate_image(&gKernelArgs.kernel_image); + if (status < B_OK) { + dprintf("relocating kernel failed: %lx!\n", status); return status; } diff --git a/src/system/boot/platform/openfirmware/Handle.cpp b/src/system/boot/platform/openfirmware/Handle.cpp index fd16be320b..00ff3a2706 100644 --- a/src/system/boot/platform/openfirmware/Handle.cpp +++ b/src/system/boot/platform/openfirmware/Handle.cpp @@ -5,10 +5,10 @@ #include +#include #include #include "Handle.h" -#include "openfirmware.h" Handle::Handle(int handle, bool takeOwnership) diff --git a/src/system/boot/platform/openfirmware/Jamfile b/src/system/boot/platform/openfirmware/Jamfile index 2abc008add..4a14c20c80 100644 --- a/src/system/boot/platform/openfirmware/Jamfile +++ b/src/system/boot/platform/openfirmware/Jamfile @@ -11,11 +11,12 @@ KernelMergeObject boot_platform_openfirmware.o : menu.cpp mmu.cpp network.cpp - openfirmware.c start.c support.cpp video.cpp + openfirmware.c + # generic text_menu.cpp : @@ -24,5 +25,7 @@ KernelMergeObject boot_platform_openfirmware.o : SEARCH on [ FGristFiles text_menu.cpp ] = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ; +SEARCH on [ FGristFiles openfirmware.c ] + = [ FDirName $(HAIKU_TOP) src system kernel platform openfirmware ] ; SubInclude HAIKU_TOP src system boot platform openfirmware arch ; diff --git a/src/system/boot/platform/openfirmware/arch/ppc/Jamfile b/src/system/boot/platform/openfirmware/arch/ppc/Jamfile index 20b9f4f068..c9ea45160a 100644 --- a/src/system/boot/platform/openfirmware/arch/ppc/Jamfile +++ b/src/system/boot/platform/openfirmware/arch/ppc/Jamfile @@ -7,9 +7,10 @@ SubDirC++Flags -fno-rtti ; KernelStaticLibrary boot_platform_openfirmware_ppc : arch_mmu.cpp arch_cpu_asm.S + arch_start_kernel.S + cpu.cpp mmu.cpp - : - ; +; SEARCH on [ FGristFiles arch_cpu_asm.S arch_mmu.cpp ] = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; diff --git a/src/system/boot/platform/openfirmware/arch/ppc/arch_start_kernel.S b/src/system/boot/platform/openfirmware/arch/ppc/arch_start_kernel.S new file mode 100644 index 0000000000..89400d2e57 --- /dev/null +++ b/src/system/boot/platform/openfirmware/arch/ppc/arch_start_kernel.S @@ -0,0 +1,44 @@ +/* + * Copyright 2005, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#define FUNCTION(x) .global x; .type x,@function; x + +/* status_t arch_start_kernel(struct kernel_args *kernelArgs, + addr_t kernelEntry, addr_t kernelStackTop); + + r3 - kernelArgs + r4 - kernelEntry + r5 - kernelStackTop +*/ +FUNCTION(arch_start_kernel): + // push a stack frame + stwu %r1, -32(%r1) + mflr %r0 + stw %r0, 36(%r1) + + // save the old stack pointer in r29 + stw %r29, 20(%r1) + mr %r29, %r1 + + // set up the kernel stack + subi %r1, %r5, 16 + + // enter the kernel + mtlr %r4 + blrl + + /* Actually we should never get here, but at least for debugging purposes + it's quite nice to return in an orderly manner. */ + + // reset the boot loader stack + mr %r1, %r29 + lwz %r29, 20(%r1) + + // pop the stack frame + lwz %r0, 36(%r1) + mtlr %r0 + addi %r1, %r1, 32 + blr + diff --git a/src/system/boot/platform/openfirmware/arch/ppc/cpu.cpp b/src/system/boot/platform/openfirmware/arch/ppc/cpu.cpp new file mode 100644 index 0000000000..4e103e8899 --- /dev/null +++ b/src/system/boot/platform/openfirmware/arch/ppc/cpu.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2005, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include + +#include + +#include + +#include +#include +#include +#include + +#include "devices.h" + +#define TRACE_CPU +#ifdef TRACE_CPU +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +status_t +boot_arch_cpu_init(void) +{ + // iterate through the "/cpus" node to find all CPUs + int cpus = of_finddevice("/cpus"); + if (cpus == OF_FAILED) { + printf("arch_cpu_init(): Failed to open \"/cpus\"!\n"); + return B_ERROR; + } + + char cpuPath[256]; + int cookie = 0; + int cpuCount = 0; + while (platform_get_next_device(&cookie, cpus, "cpu", cpuPath, + sizeof(cpuPath)) == B_OK) { + TRACE(("found CPU: %s\n", cpuPath)); + + cpuCount++; + } + + if (cpuCount == 0) { + printf("arch_cpu_init(): Found no CPUs!\n"); + return B_ERROR; + } + + gKernelArgs.num_cpus = cpuCount; + + // allocate the kernel stacks (the memory stuff is already initialized + // at this point) + addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000, + cpuCount * KERNEL_STACK_SIZE, B_READ_AREA | B_WRITE_AREA, false); + if (!stack) { + printf("arch_cpu_init(): Failed to allocate kernel stack(s)!\n"); + return B_NO_MEMORY; + } + + for (int i = 0; i < cpuCount; i++) { + gKernelArgs.cpu_kstack[i].start = stack; + gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE; + stack += KERNEL_STACK_SIZE; + } + + return B_OK; +} + diff --git a/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp b/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp index bdde388ca8..974ae1af5a 100644 --- a/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp +++ b/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp @@ -4,12 +4,11 @@ */ -#include "openfirmware.h" - #include #include #include #include +#include #include #include #include @@ -352,7 +351,6 @@ find_allocated_ranges(void *pageTable, page_table_entry_group **_physicalPageTab for (int i = 0; i < length; i++) { struct translation_map *map = &translations[i]; //printf("%i: map: %p, length %d -> physical: %p, mode %d\n", i, map->virtual_address, map->length, map->physical_address, map->mode); -printf("%i: map: %p, length %d -> physical: %p, mode %d\n", i, map->virtual_address, map->length, map->physical_address, map->mode); // insert range in physical allocated, if it points to physical memory @@ -476,18 +474,19 @@ find_free_virtual_range(void *base, size_t size) extern "C" void * -arch_mmu_allocate(void *_virtualAddress, size_t size, uint8 protection, +arch_mmu_allocate(void *_virtualAddress, size_t size, uint8 _protection, bool exactAddress) { // we only know page sizes size = ROUNDUP(size, B_PAGE_SIZE); - // set protection to WIMGxPP: -I--xPP + // set protection to WIMGNPP: -I---PP // PP: 00 - no access // 01 - read only // 10 - read/write // 11 - read only - if (protection & B_WRITE_AREA) + uint8 protection = 0; + if (_protection & B_WRITE_AREA) protection = 0x22; else protection = 0x21; diff --git a/src/system/boot/platform/openfirmware/console.cpp b/src/system/boot/platform/openfirmware/console.cpp index 868c3dc802..a639feac58 100644 --- a/src/system/boot/platform/openfirmware/console.cpp +++ b/src/system/boot/platform/openfirmware/console.cpp @@ -6,11 +6,11 @@ #include #include +#include #include #include "Handle.h" #include "console.h" -#include "openfirmware.h" class ConsoleHandle : public Handle { diff --git a/src/system/boot/platform/openfirmware/debug.c b/src/system/boot/platform/openfirmware/debug.c index d79620d5da..351aa050aa 100644 --- a/src/system/boot/platform/openfirmware/debug.c +++ b/src/system/boot/platform/openfirmware/debug.c @@ -6,10 +6,9 @@ #include #include +#include #include -#include "openfirmware.h" - /** ToDo: this works only after console_init() was called. * But it probably should do something before as well... diff --git a/src/system/boot/platform/openfirmware/devices.cpp b/src/system/boot/platform/openfirmware/devices.cpp index bb458ebde3..0f2e9d34ea 100644 --- a/src/system/boot/platform/openfirmware/devices.cpp +++ b/src/system/boot/platform/openfirmware/devices.cpp @@ -3,9 +3,8 @@ * Distributed under the terms of the MIT License. */ - +#include "devices.h" #include "Handle.h" -#include "openfirmware.h" #include "machine.h" #include @@ -14,6 +13,7 @@ #include #include #include +#include #include #include @@ -23,21 +23,41 @@ char sBootPath[192]; /** Gets all device types of the specified type by doing a - * depth-first searchi of the OpenFirmware device tree. + * depth-first search of the OpenFirmware device tree. + * If a root != 0 is given, the function only traverses the subtree spanned + * by the root (inclusively). Otherwise the whole device tree is searched. * * The cookie has to be initialized to zero. */ -static status_t -get_next_device(int *_cookie, const char *type, char *path, size_t pathSize) +status_t +platform_get_next_device(int *_cookie, int root, const char *type, char *path, + size_t pathSize) { int node = *_cookie; - if (node == 0) - node = of_peer(0); - while (true) { - int next = of_child(node); + int next; + + if (node == 0) { + // node is NULL, meaning that this is the initial function call. + // If a root was supplied, we take that, otherwise the device tree + // root. + if (root != 0) + node = root; + else + node = of_peer(0); + + if (node == OF_FAILED) + return B_ERROR; + if (node == 0) + return B_ENTRY_NOT_FOUND; + + // We want to visit the root first. + next = node; + } else + next = of_child(node); + if (next == OF_FAILED) return B_ERROR; @@ -55,7 +75,7 @@ get_next_device(int *_cookie, const char *type, char *path, size_t pathSize) if (next == OF_FAILED) return B_ERROR; - if (next == 0) { + if (next == root || next == 0) { // We have searched the whole device tree return B_ENTRY_NOT_FOUND; } @@ -209,7 +229,8 @@ platform_add_block_devices(stage2_args *args, NodeList *devicesList) int cookie = 0; char path[256]; status_t status; - while ((status = get_next_device(&cookie, "block", path, sizeof(path))) == B_OK) { + while ((status = platform_get_next_device(&cookie, 0, "block", path, + sizeof(path))) == B_OK) { if (!strcmp(path, sBootPath)) { // don't add the boot device twice continue; diff --git a/src/system/boot/platform/openfirmware/devices.h b/src/system/boot/platform/openfirmware/devices.h new file mode 100644 index 0000000000..b080324e65 --- /dev/null +++ b/src/system/boot/platform/openfirmware/devices.h @@ -0,0 +1,22 @@ +/* + * Copyright 2005, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef OPENFIRMWARE_DEVICES_H +#define OPENFIRMWARE_DEVICES_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +status_t platform_get_next_device(int *_cookie, int root, const char *type, + char *path, size_t pathSize); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OPENFIRMWARE_DEVICES_H */ diff --git a/src/system/boot/platform/openfirmware/heap.cpp b/src/system/boot/platform/openfirmware/heap.cpp index 768882ac4c..706130d683 100644 --- a/src/system/boot/platform/openfirmware/heap.cpp +++ b/src/system/boot/platform/openfirmware/heap.cpp @@ -8,7 +8,7 @@ #include #include #include -#include "openfirmware.h" +#include #define TRACE_HEAP 1 diff --git a/src/system/boot/platform/openfirmware/mmu.cpp b/src/system/boot/platform/openfirmware/mmu.cpp index 7f81c74eea..e948a98477 100644 --- a/src/system/boot/platform/openfirmware/mmu.cpp +++ b/src/system/boot/platform/openfirmware/mmu.cpp @@ -7,10 +7,9 @@ #include #include #include +#include #include -#include "openfirmware.h" - status_t platform_allocate_region(void **_address, size_t size, uint8 protection, diff --git a/src/system/boot/platform/openfirmware/network.cpp b/src/system/boot/platform/openfirmware/network.cpp index 46e84e2197..6a02ccddbc 100644 --- a/src/system/boot/platform/openfirmware/network.cpp +++ b/src/system/boot/platform/openfirmware/network.cpp @@ -13,8 +13,7 @@ #include #include - -#include "openfirmware.h" +#include //#define TRACE_NETWORK diff --git a/src/system/boot/platform/openfirmware/start.c b/src/system/boot/platform/openfirmware/start.c index 6334e5e41b..ca09ca06cd 100644 --- a/src/system/boot/platform/openfirmware/start.c +++ b/src/system/boot/platform/openfirmware/start.c @@ -8,11 +8,11 @@ #include #include #include +#include #include #include -#include "openfirmware.h" #include "console.h" #include "machine.h" @@ -81,8 +81,21 @@ determine_machine(void) void platform_start_kernel(void) { - printf("kernel entry at %p\n", (void *)gKernelArgs.kernel_image.elf_header.e_entry); - of_exit(); + addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry; + addr_t stackTop = gKernelArgs.cpu_kstack[0].start + + gKernelArgs.cpu_kstack[0].size; + + printf("kernel entry at %p\n", (void*)kernelEntry); + printf("kernel stack top: %p\n", (void*)stackTop); + + /* TODO: ? + mmu_init_for_kernel(); + smp_boot_other_cpus(); + */ + + status_t error = arch_start_kernel(&gKernelArgs, kernelEntry, stackTop); + + panic("Kernel returned! Return value: %ld\n", error); } @@ -130,11 +143,16 @@ start(void *openFirmwareEntry) // Initialize and take over MMU and set the OpenFirmware callbacks - it // will ask us for memory after that instead of maintaining it itself // (the kernel will need to adjust the callback later on as well) - arch_mmu_init(); arch_set_callback(); + arch_mmu_init(); + + if (boot_arch_cpu_init() != B_OK) + platform_exit(); + + gKernelArgs.platform_args.openfirmware_entry = openFirmwareEntry; main(&args); - // if everything wents fine, main() never returns + // if everything goes fine, main() never returns of_exit(); } diff --git a/src/system/boot/platform/openfirmware/support.cpp b/src/system/boot/platform/openfirmware/support.cpp index 278c17a386..d7b3baf177 100644 --- a/src/system/boot/platform/openfirmware/support.cpp +++ b/src/system/boot/platform/openfirmware/support.cpp @@ -5,7 +5,7 @@ #include -#include "openfirmware.h" +#include bigtime_t system_time(void) diff --git a/src/system/kernel/Jamfile b/src/system/kernel/Jamfile index be1a9d86a6..a8a3904a9e 100644 --- a/src/system/kernel/Jamfile +++ b/src/system/kernel/Jamfile @@ -37,7 +37,7 @@ KernelMergeObject kernel_core.o : thread.c timer.c - : -fno-pic + : $(TARGET_KERNEL_PIC_CCFLAGS) ; # We need to specify the dependency on the generated syscalls files explicitly. @@ -63,6 +63,7 @@ KernelLd kernel_$(TARGET_ARCH) : kernel_debug.o lib$(TARGET_ARCH).a + lib$(TARGET_BOOT_PLATFORM).a linkhack.so @@ -75,6 +76,7 @@ KernelLd kernel_$(TARGET_ARCH) : : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/kernel.ld : -Bdynamic -export-dynamic -dynamic-linker /foo/bar + $(TARGET_KERNEL_PIC_LINKFLAGS) : ; @@ -90,6 +92,7 @@ KernelLd kernel.so : kernel_debug.o lib$(TARGET_ARCH).a + lib$(TARGET_BOOT_PLATFORM).a linkhack.so @@ -102,6 +105,7 @@ KernelLd kernel.so : : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/kernel.ld : -Bdynamic -shared -export-dynamic -dynamic-linker /foo/bar + $(TARGET_KERNEL_PIC_LINKFLAGS) ; NotFile kernel ; @@ -120,3 +124,7 @@ SubInclude HAIKU_TOP src system kernel lib ; SubInclude HAIKU_TOP src system kernel messaging ; SubInclude HAIKU_TOP src system kernel util ; SubInclude HAIKU_TOP src system kernel vm ; + +if $(TARGET_BOOT_PLATFORM) { + SubInclude HAIKU_TOP src system kernel platform $(TARGET_BOOT_PLATFORM) ; +} diff --git a/src/system/kernel/arch/ppc/Jamfile b/src/system/kernel/arch/ppc/Jamfile index 2e49b46551..78dd758083 100644 --- a/src/system/kernel/arch/ppc/Jamfile +++ b/src/system/kernel/arch/ppc/Jamfile @@ -20,5 +20,5 @@ KernelStaticLibrary libppc : arch_vm_translation_map.cpp arch_asm.S : - -fno-pic -Wno-unused - ; + $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused +; diff --git a/src/system/kernel/arch/ppc/arch_debug_console.c b/src/system/kernel/arch/ppc/arch_debug_console.c index 815ba24a69..88a6c093c6 100644 --- a/src/system/kernel/arch/ppc/arch_debug_console.c +++ b/src/system/kernel/arch/ppc/arch_debug_console.c @@ -11,10 +11,15 @@ #include #include #include +#include #include +static int sInput = -1; +static int sOutput = -1; + + char arch_debug_blue_screen_getchar(void) { @@ -22,7 +27,6 @@ arch_debug_blue_screen_getchar(void) } - char arch_debug_serial_getchar(void) { @@ -33,6 +37,10 @@ arch_debug_serial_getchar(void) void arch_debug_serial_putchar(const char c) { + if (c == '\n') + of_write(sOutput, "\r\n", 2); + else + of_write(sOutput, &c, 1); } @@ -56,6 +64,11 @@ arch_debug_serial_early_boot_message(const char *string) status_t arch_debug_console_init(kernel_args *args) { + if (of_getprop(gChosen, "stdin", &sInput, sizeof(int)) == OF_FAILED) + return B_ERROR; + if (of_getprop(gChosen, "stdout", &sOutput, sizeof(int)) == OF_FAILED) + return B_ERROR; + return B_OK; } @@ -63,5 +76,6 @@ arch_debug_console_init(kernel_args *args) status_t arch_debug_console_init_settings(kernel_args *args) { + return B_OK; } diff --git a/src/system/kernel/arch/x86/Jamfile b/src/system/kernel/arch/x86/Jamfile index 374d454cf1..675b8737fd 100644 --- a/src/system/kernel/arch/x86/Jamfile +++ b/src/system/kernel/arch/x86/Jamfile @@ -24,8 +24,8 @@ KernelStaticLibrary libx86 : bios.cpp cpuid.S : - -fno-pic -Wno-unused - ; + $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused +; # We need to specify the dependency on the generated syscalls file explicitly. Includes [ FGristFiles arch_x86.S arch_interrupts.S ] diff --git a/src/system/kernel/cache/Jamfile b/src/system/kernel/cache/Jamfile index 820324d5b4..1b9613d403 100644 --- a/src/system/kernel/cache/Jamfile +++ b/src/system/kernel/cache/Jamfile @@ -6,5 +6,5 @@ KernelMergeObject kernel_cache.o : file_cache.cpp vnode_store.cpp - : -fno-pic -Wno-unused - ; + : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused +; diff --git a/src/system/kernel/debug/Jamfile b/src/system/kernel/debug/Jamfile index 13e3b641ce..763c5c1a3b 100644 --- a/src/system/kernel/debug/Jamfile +++ b/src/system/kernel/debug/Jamfile @@ -9,5 +9,5 @@ KernelMergeObject kernel_debug.o : gdb.c user_debugger.cpp - : -fno-pic -Wno-unused - ; + : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused +; diff --git a/src/system/kernel/device_manager/Jamfile b/src/system/kernel/device_manager/Jamfile index d375000d0f..c2c5c4b48d 100644 --- a/src/system/kernel/device_manager/Jamfile +++ b/src/system/kernel/device_manager/Jamfile @@ -18,5 +18,5 @@ KernelMergeObject kernel_device_manager.o : scan.c settings.cpp : - -fno-pic -Wno-unused - ; + $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused +; diff --git a/src/system/kernel/disk_device_manager/Jamfile b/src/system/kernel/disk_device_manager/Jamfile index d239797c70..6d21c3a38a 100644 --- a/src/system/kernel/disk_device_manager/Jamfile +++ b/src/system/kernel/disk_device_manager/Jamfile @@ -52,7 +52,7 @@ KernelMergeObject kernel_disk_device_manager.o : # disk device types DiskDeviceTypes.cpp - : -fno-pic -Wno-unused + : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused ; # KFileDiskDevice.cpp needs the virtualdrive.h Header. Add it here to not diff --git a/src/system/kernel/fs/Jamfile b/src/system/kernel/fs/Jamfile index 66078fd7db..69707e4ff1 100644 --- a/src/system/kernel/fs/Jamfile +++ b/src/system/kernel/fs/Jamfile @@ -18,5 +18,5 @@ KernelMergeObject kernel_fs.o : IOScheduler.cpp KPath.cpp - : -fno-pic -Wno-unused + : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused ; diff --git a/src/system/kernel/lib/Jamfile b/src/system/kernel/lib/Jamfile index b72a0f1f36..d26ab47646 100644 --- a/src/system/kernel/lib/Jamfile +++ b/src/system/kernel/lib/Jamfile @@ -5,7 +5,7 @@ SubDir HAIKU_TOP src system kernel lib ; KernelMergeObject kernel_os_main.o : driver_settings.c fs_info.c - : -fno-pic + : $(TARGET_KERNEL_PIC_CCFLAGS) ; SEARCH on [ FGristFiles driver_settings.c fs_info.c ] @@ -103,7 +103,7 @@ KernelMergeObject kernel_posix.o : strstr.c strtok.c - : -fno-pic + : $(TARGET_KERNEL_PIC_CCFLAGS) ; SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ; @@ -113,5 +113,5 @@ KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o : byteorder.S system_time.S - : -fno-pic + : $(TARGET_KERNEL_PIC_CCFLAGS) ; diff --git a/src/system/kernel/main.c b/src/system/kernel/main.c index b6438e1225..38118a8cd7 100644 --- a/src/system/kernel/main.c +++ b/src/system/kernel/main.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -80,6 +81,9 @@ _start(kernel_args *bootKernelArgs, int currentCPU) if (smp_trap_non_boot_cpus(currentCPU)) { thread_id thread; + // init platform + platform_init(&sKernelArgs); + // setup debug output debug_init(&sKernelArgs); set_dprintf_enabled(true); diff --git a/src/system/kernel/messaging/Jamfile b/src/system/kernel/messaging/Jamfile index 0b7b8dbdf8..509046dda6 100644 --- a/src/system/kernel/messaging/Jamfile +++ b/src/system/kernel/messaging/Jamfile @@ -12,5 +12,5 @@ KernelMergeObject kernel_messaging.o : KMessage.cpp MessagingService.cpp - : -fno-pic -Wno-unused - ; + : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused +; diff --git a/src/system/kernel/platform/bios_ia32/Jamfile b/src/system/kernel/platform/bios_ia32/Jamfile new file mode 100644 index 0000000000..497fe79acb --- /dev/null +++ b/src/system/kernel/platform/bios_ia32/Jamfile @@ -0,0 +1,8 @@ +SubDir HAIKU_TOP src system kernel platform bios_ia32 ; + +SubDirCcFlags $(TARGET_KERNEL_PIC_CCFLAGS) ; +SubDirC++Flags $(TARGET_KERNEL_PIC_CCFLAGS) ; + +KernelStaticLibrary libbios_ia32.a : + platform.cpp +; diff --git a/src/system/kernel/platform/bios_ia32/platform.cpp b/src/system/kernel/platform/bios_ia32/platform.cpp new file mode 100644 index 0000000000..f106f49383 --- /dev/null +++ b/src/system/kernel/platform/bios_ia32/platform.cpp @@ -0,0 +1,14 @@ +/* + * Copyright 2005, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include + +#include + +status_t +platform_init(struct kernel_args *kernelArgs) +{ + return B_OK; +} diff --git a/src/system/kernel/platform/openfirmware/Jamfile b/src/system/kernel/platform/openfirmware/Jamfile new file mode 100644 index 0000000000..cfcd130dba --- /dev/null +++ b/src/system/kernel/platform/openfirmware/Jamfile @@ -0,0 +1,9 @@ +SubDir HAIKU_TOP src system kernel platform openfirmware ; + +SubDirCcFlags $(TARGET_KERNEL_PIC_CCFLAGS) ; +SubDirC++Flags $(TARGET_KERNEL_PIC_CCFLAGS) ; + +KernelStaticLibrary libopenfirmware.a : + openfirmware.c + platform.cpp +; diff --git a/src/system/boot/platform/openfirmware/openfirmware.c b/src/system/kernel/platform/openfirmware/openfirmware.c similarity index 99% rename from src/system/boot/platform/openfirmware/openfirmware.c rename to src/system/kernel/platform/openfirmware/openfirmware.c index 44350f0355..f30c1a3308 100644 --- a/src/system/boot/platform/openfirmware/openfirmware.c +++ b/src/system/kernel/platform/openfirmware/openfirmware.c @@ -3,8 +3,8 @@ * Distributed under the terms of the MIT License. */ +#include -#include "openfirmware.h" #include diff --git a/src/system/kernel/platform/openfirmware/platform.cpp b/src/system/kernel/platform/openfirmware/platform.cpp new file mode 100644 index 0000000000..9b54ec2c63 --- /dev/null +++ b/src/system/kernel/platform/openfirmware/platform.cpp @@ -0,0 +1,16 @@ +/* + * Copyright 2005, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include + +#include +#include + +status_t +platform_init(struct kernel_args *kernelArgs) +{ + return of_init( + (int(*)(void*))kernelArgs->platform_args.openfirmware_entry); +} diff --git a/src/system/kernel/util/Jamfile b/src/system/kernel/util/Jamfile index 8cfed16d0d..b62ff5724d 100644 --- a/src/system/kernel/util/Jamfile +++ b/src/system/kernel/util/Jamfile @@ -10,5 +10,5 @@ KernelMergeObject kernel_util.o : queue.c ring_buffer.cpp - : -fno-pic -Wno-unused -DUSING_LIBGCC - ; + : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused -DUSING_LIBGCC +; diff --git a/src/system/kernel/vm/Jamfile b/src/system/kernel/vm/Jamfile index 49934791f9..0e95fb7e63 100644 --- a/src/system/kernel/vm/Jamfile +++ b/src/system/kernel/vm/Jamfile @@ -12,5 +12,5 @@ KernelMergeObject kernel_vm.o : vm_store_null.c #vm_tests.c - : -fno-pic -Wno-unused - ; + : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused +;