* Introduced new build system variables
{HAIKU,HOST,TARGET}_KERNEL_PIC_{CC,LINK}FLAGS which define the compiler/linker flags specifying the kind of position independence the kernel shall have. For x86 we had and still have -fno-pic, but the PPC kernel has -fPIE (position independent executable) now, as we need to relocate it. * The boot loader relocates the kernel now. Mostly copied the relocation code from the kernel ELF loader. Almost completely rewrote the PPC specific relocation code, though. It's more correct and more complete now (some things are still missing though). * Added boot platform awareness to the kernel. Moved the generic Open Firmware code (openfirmware.c/h) from the boot loader to the kernel. * The kernel PPC serial debug output is sent to the console for the time being. * The PPC boot loader counts the CPUs now and allocates the kernel stacks (made OF device iteration a bit more flexible on the way -- the search can be restricted to subtree). Furthermore we really enter the kernel... (Yay! :-) ... and crash in the first dprintf() (in the atomic_set() called by acquire_spinlock()). kprintf() works, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15756 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
456d0d082b
commit
957a1b17eb
@ -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
|
||||
|
@ -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) ;
|
||||
|
28
headers/private/kernel/boot/arch.h
Normal file
28
headers/private/kernel/boot/arch.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef KERNEL_BOOT_ARCH_H
|
||||
#define KERNEL_BOOT_ARCH_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <boot/elf.h>
|
||||
|
||||
|
||||
#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 */
|
@ -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 */
|
||||
|
@ -8,10 +8,13 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
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
|
||||
|
23
headers/private/kernel/platform.h
Normal file
23
headers/private/kernel/platform.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_PLATFORM_H
|
||||
#define _KERNEL_PLATFORM_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
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
|
@ -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 ;
|
||||
|
7
src/system/boot/arch/ppc/Jamfile
Normal file
7
src/system/boot/arch/ppc/Jamfile
Normal file
@ -0,0 +1,7 @@
|
||||
SubDir HAIKU_TOP src system boot arch ppc ;
|
||||
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
KernelMergeObject boot_arch_ppc.o :
|
||||
elf.cpp
|
||||
;
|
378
src/system/boot/arch/ppc/elf.cpp
Normal file
378
src/system/boot/arch/ppc/elf.cpp
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* 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 <boot/arch.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <elf_priv.h>
|
||||
#include <arch/elf.h>
|
||||
|
||||
|
||||
#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>").
|
||||
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;
|
||||
}
|
||||
|
7
src/system/boot/arch/x86/Jamfile
Normal file
7
src/system/boot/arch/x86/Jamfile
Normal file
@ -0,0 +1,7 @@
|
||||
SubDir HAIKU_TOP src system boot arch x86 ;
|
||||
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
KernelMergeObject boot_arch_x86.o :
|
||||
elf.cpp
|
||||
;
|
135
src/system/boot/arch/x86/elf.cpp
Normal file
135
src/system/boot/arch/x86/elf.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
** Copyright 2002, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <boot/arch.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <elf_priv.h>
|
||||
#include <arch/elf.h>
|
||||
|
||||
|
||||
//#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;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "elf.h"
|
||||
|
||||
#include <boot/arch.h>
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <elf32.h>
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include "Handle.h"
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
Handle::Handle(int handle, bool takeOwnership)
|
||||
|
@ -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 ;
|
||||
|
@ -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) ] ;
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* 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
|
||||
|
71
src/system/boot/platform/openfirmware/arch/ppc/cpu.cpp
Normal file
71
src/system/boot/platform/openfirmware/arch/ppc/cpu.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <boot/platform/openfirmware/platform_arch.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <kernel.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -4,12 +4,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "openfirmware.h"
|
||||
|
||||
#include <platform_arch.h>
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <boot/stdio.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <arch_cpu.h>
|
||||
#include <arch_mmu.h>
|
||||
#include <kernel.h>
|
||||
@ -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;
|
||||
|
@ -6,11 +6,11 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <string.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include "Handle.h"
|
||||
#include "console.h"
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
class ConsoleHandle : public Handle {
|
||||
|
@ -6,10 +6,9 @@
|
||||
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stdio.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
/** ToDo: this works only after console_init() was called.
|
||||
* But it probably should do something before as well...
|
||||
|
@ -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 <boot/platform.h>
|
||||
@ -14,6 +13,7 @@
|
||||
#include <boot/stage2.h>
|
||||
#include <boot/net/NetStack.h>
|
||||
#include <boot/net/RemoteDisk.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include <string.h>
|
||||
@ -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;
|
||||
|
22
src/system/boot/platform/openfirmware/devices.h
Normal file
22
src/system/boot/platform/openfirmware/devices.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef OPENFIRMWARE_DEVICES_H
|
||||
#define OPENFIRMWARE_DEVICES_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#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 */
|
@ -8,7 +8,7 @@
|
||||
#include <boot/platform.h>
|
||||
#include <boot/heap.h>
|
||||
#include <boot/stdio.h>
|
||||
#include "openfirmware.h"
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
|
||||
#define TRACE_HEAP 1
|
||||
|
@ -7,10 +7,9 @@
|
||||
#include <platform_arch.h>
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stdio.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
status_t
|
||||
platform_allocate_region(void **_address, size_t size, uint8 protection,
|
||||
|
@ -13,8 +13,7 @@
|
||||
|
||||
#include <boot/net/Ethernet.h>
|
||||
#include <boot/net/NetStack.h>
|
||||
|
||||
#include "openfirmware.h"
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
|
||||
//#define TRACE_NETWORK
|
||||
|
@ -8,11 +8,11 @@
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <boot/heap.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <platform_arch.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include "openfirmware.h"
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
|
@ -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) ;
|
||||
}
|
||||
|
@ -20,5 +20,5 @@ KernelStaticLibrary libppc :
|
||||
arch_vm_translation_map.cpp
|
||||
arch_asm.S
|
||||
:
|
||||
-fno-pic -Wno-unused
|
||||
;
|
||||
$(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
|
||||
;
|
||||
|
@ -11,10 +11,15 @@
|
||||
#include <vm.h>
|
||||
#include <boot/kernel_args.h>
|
||||
#include <arch/debug_console.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 ]
|
||||
|
4
src/system/kernel/cache/Jamfile
vendored
4
src/system/kernel/cache/Jamfile
vendored
@ -6,5 +6,5 @@ KernelMergeObject kernel_cache.o :
|
||||
file_cache.cpp
|
||||
vnode_store.cpp
|
||||
|
||||
: -fno-pic -Wno-unused
|
||||
;
|
||||
: $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
|
||||
;
|
||||
|
@ -9,5 +9,5 @@ KernelMergeObject kernel_debug.o :
|
||||
gdb.c
|
||||
user_debugger.cpp
|
||||
|
||||
: -fno-pic -Wno-unused
|
||||
;
|
||||
: $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
|
||||
;
|
||||
|
@ -18,5 +18,5 @@ KernelMergeObject kernel_device_manager.o :
|
||||
scan.c
|
||||
settings.cpp
|
||||
:
|
||||
-fno-pic -Wno-unused
|
||||
;
|
||||
$(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
|
||||
;
|
||||
|
@ -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
|
||||
|
@ -18,5 +18,5 @@ KernelMergeObject kernel_fs.o :
|
||||
IOScheduler.cpp
|
||||
KPath.cpp
|
||||
|
||||
: -fno-pic -Wno-unused
|
||||
: $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
|
||||
;
|
||||
|
@ -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)
|
||||
;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <kscheduler.h>
|
||||
#include <ksyscalls.h>
|
||||
#include <messaging.h>
|
||||
#include <platform.h>
|
||||
#include <port.h>
|
||||
#include <real_time_clock.h>
|
||||
#include <sem.h>
|
||||
@ -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);
|
||||
|
@ -12,5 +12,5 @@ KernelMergeObject kernel_messaging.o :
|
||||
KMessage.cpp
|
||||
MessagingService.cpp
|
||||
|
||||
: -fno-pic -Wno-unused
|
||||
;
|
||||
: $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
|
||||
;
|
||||
|
8
src/system/kernel/platform/bios_ia32/Jamfile
Normal file
8
src/system/kernel/platform/bios_ia32/Jamfile
Normal file
@ -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
|
||||
;
|
14
src/system/kernel/platform/bios_ia32/platform.cpp
Normal file
14
src/system/kernel/platform/bios_ia32/platform.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
|
||||
status_t
|
||||
platform_init(struct kernel_args *kernelArgs)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
9
src/system/kernel/platform/openfirmware/Jamfile
Normal file
9
src/system/kernel/platform/openfirmware/Jamfile
Normal file
@ -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
|
||||
;
|
@ -3,8 +3,8 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
#include "openfirmware.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
|
16
src/system/kernel/platform/openfirmware/platform.cpp
Normal file
16
src/system/kernel/platform/openfirmware/platform.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
status_t
|
||||
platform_init(struct kernel_args *kernelArgs)
|
||||
{
|
||||
return of_init(
|
||||
(int(*)(void*))kernelArgs->platform_args.openfirmware_entry);
|
||||
}
|
@ -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
|
||||
;
|
||||
|
@ -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
|
||||
;
|
||||
|
Loading…
Reference in New Issue
Block a user