hw: skeleton for building on x86_64

This patch contains the initial code needed to build and bootstrap the
base-hw kernel on x86 64-bit platforms. It gets stuck earlier
because the binary contains 64-bit instructions, but it is started in
32-bit mode. The initial setup of page tables and switch to long mode is
still missing from the crt0 code.
This commit is contained in:
Norman Feske 2015-02-06 17:29:30 +01:00 committed by Christian Helmuth
parent cc00af85bf
commit a974726e26
24 changed files with 1296 additions and 3 deletions

View File

@ -0,0 +1,50 @@
/*
* \brief Interface between kernel and userland
* \author Martin Stein
* \date 2011-11-30
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _KERNEL__INTERFACE_SUPPORT_H_
#define _KERNEL__INTERFACE_SUPPORT_H_
/* Genode includes */
#include <base/stdint.h>
namespace Kernel
{
typedef Genode::uint64_t Call_arg;
typedef Genode::uint64_t Call_ret;
/**
* Registers that are provided by a kernel thread-object for user access
*/
struct Thread_reg_id
{
enum {
SP = 13, /* XXX numbers are arbitrary, taken from ARM version */
IP = 15,
FAULT_TLB = 18,
FAULT_ADDR = 19,
FAULT_WRITES = 20,
FAULT_SIGNAL = 21,
};
};
/**
* Events that are provided by a kernel thread-object for user handling
*/
struct Thread_event_id
{
enum { FAULT = 0 };
};
}
#endif /* _KERNEL__INTERFACE_SUPPORT_H_ */

View File

@ -0,0 +1,19 @@
#
# \brief Build config for Genodes core process
# \author Stefan Kalkowski
# \author Martin Stein
# \date 2012-10-04
#
# add include paths
INC_DIR += $(REP_DIR)/src/core/include/spec/x86
# add C++ sources
SRC_CC += platform_services.cc
SRC_CC += spec/x86/platform_support.cc
SRC_CC += spec/x86/kernel/thread.cc
SRC_CC += spec/x86/kernel/cpu.cc
SRC_CC += kernel/vm_thread.cc
# include less specific configuration
include $(REP_DIR)/lib/mk/core.inc

View File

@ -0,0 +1,3 @@
include $(REP_DIR)/lib/mk/base-common.inc
vpath kernel/interface.cc $(REP_DIR)/src/base/x86_64

View File

@ -0,0 +1,20 @@
#
# \brief Build config for Genodes core process
# \author Stefan Kalkowski
# \author Martin Stein
# \date 2012-10-04
#
# add include paths
INC_DIR += $(REP_DIR)/src/core/include/spec/x86_64
# add assembly sources
SRC_S += spec/x86_64/mode_transition.s
SRC_S += spec/x86_64/kernel/crt0.s
SRC_S += spec/x86_64/crt0.s
# add C++ sources
SRC_CC += spec/x86_64/kernel/thread_base.cc
# include less specific configuration
include $(REP_DIR)/lib/mk/x86/core.inc

View File

@ -0,0 +1,18 @@
#
# \brief Offer build configurations that are specific to base-hw and x86_64
# \author Martin Stein
# \date 2011-12-20
#
# denote wich specs are also fullfilled by this spec
SPECS += hw x86_64
# configure multiprocessor mode
NR_OF_CPUS = 1
# set address where to link text segment at
LD_TEXT_ADDR ?= 0x200000
# include implied specs
include $(call select_from_repositories,mk/spec-hw.mk)
include $(call select_from_repositories,mk/spec-x86_64.mk)

View File

@ -0,0 +1,85 @@
/*
* \brief Interface between kernel and userland
* \author Martin Stein
* \date 2011-11-30
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
#include <kernel/interface.h>
using namespace Kernel;
/******************
** Kernel calls **
******************/
Call_ret Kernel::call(Call_arg arg_0)
{
PDBG("syscall binding not implemented");
for (;;);
return 0;
}
Call_ret Kernel::call(Call_arg arg_0,
Call_arg arg_1)
{
PDBG("syscall binding not implemented");
for (;;);
return 0;
}
Call_ret Kernel::call(Call_arg arg_0,
Call_arg arg_1,
Call_arg arg_2)
{
PDBG("syscall binding not implemented");
for (;;);
return 0;
}
Call_ret Kernel::call(Call_arg arg_0,
Call_arg arg_1,
Call_arg arg_2,
Call_arg arg_3)
{
PDBG("syscall binding not implemented");
for (;;);
return 0;
}
Call_ret Kernel::call(Call_arg arg_0,
Call_arg arg_1,
Call_arg arg_2,
Call_arg arg_3,
Call_arg arg_4)
{
PDBG("syscall binding not implemented");
for (;;);
return 0;
}
Call_ret Kernel::call(Call_arg arg_0,
Call_arg arg_1,
Call_arg arg_2,
Call_arg arg_3,
Call_arg arg_4,
Call_arg arg_5)
{
PDBG("syscall binding not implemented");
for (;;);
return 0;
}

View File

@ -0,0 +1,233 @@
/*
* \brief CPU driver for core
* \author Martin stein
* \date 2011-11-03
*/
/*
* Copyright (C) 2011-2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CPU_H_
#define _CPU_H_
#include <util/register.h>
#include <kernel/interface_support.h>
#include <cpu/cpu_state.h>
namespace Genode
{
/**
* Part of CPU state that is not switched on every mode transition
*/
class Cpu_lazy_state { };
/**
* CPU driver for core
*/
class Cpu;
}
namespace Kernel { using Genode::Cpu_lazy_state; }
class Genode::Cpu
{
public:
static constexpr addr_t exception_entry = 0x0; /* XXX */
static constexpr addr_t mtc_size = 1 << 13;
/**
* Extend basic CPU state by members relevant for 'base-hw' only
*/
struct Context : Cpu_state
{
/**
* Return base of assigned translation table
*/
addr_t translation_table() const { return 0UL; }
/**
* Assign translation-table base 'table'
*/
void translation_table(addr_t const table) { }
/**
* Assign protection domain
*/
void protection_domain(unsigned const id) { }
};
/**
* An usermode execution state
*/
struct User_context : Context
{
/**
* Constructor
*/
User_context();
/**
* Support for kernel calls
*/
void user_arg_0(Kernel::Call_arg const arg) { /* XXX */ }
void user_arg_1(Kernel::Call_arg const arg) { /* XXX */ }
void user_arg_2(Kernel::Call_arg const arg) { /* XXX */ }
void user_arg_3(Kernel::Call_arg const arg) { /* XXX */ }
void user_arg_4(Kernel::Call_arg const arg) { /* XXX */ }
void user_arg_5(Kernel::Call_arg const arg) { /* XXX */ }
void user_arg_6(Kernel::Call_arg const arg) { /* XXX */ }
void user_arg_7(Kernel::Call_arg const arg) { /* XXX */ }
Kernel::Call_arg user_arg_0() const { return 0UL; }
Kernel::Call_arg user_arg_1() const { return 0UL; }
Kernel::Call_arg user_arg_2() const { return 0UL; }
Kernel::Call_arg user_arg_3() const { return 0UL; }
Kernel::Call_arg user_arg_4() const { return 0UL; }
Kernel::Call_arg user_arg_5() const { return 0UL; }
Kernel::Call_arg user_arg_6() const { return 0UL; }
Kernel::Call_arg user_arg_7() const { return 0UL; }
/**
* Initialize thread context
*
* \param table physical base of appropriate translation table
* \param pd_id kernel name of appropriate protection domain
*/
void init_thread(addr_t const table, unsigned const pd_id)
{
protection_domain(pd_id);
translation_table(table);
}
};
/**
* Returns true if current execution context is running in user mode
*/
static bool is_user()
{
PDBG("not implemented");
return false;
}
/**
* Invalidate all entries of all instruction caches
*/
__attribute__((always_inline)) static void invalidate_instr_caches() { }
/**
* Flush all entries of all data caches
*/
inline static void flush_data_caches() { }
/**
* Invalidate all entries of all data caches
*/
inline static void invalidate_data_caches() { }
/**
* Flush all caches
*/
static void flush_caches()
{
flush_data_caches();
invalidate_instr_caches();
}
/**
* Invalidate all TLB entries of the address space named 'pid'
*/
static void flush_tlb_by_pid(unsigned const pid)
{
flush_caches();
}
/**
* Invalidate all TLB entries
*/
static void flush_tlb()
{
flush_caches();
}
/**
* Flush data-cache entries for virtual region ['base', 'base + size')
*/
static void
flush_data_caches_by_virt_region(addr_t base, size_t const size)
{ }
/**
* Bin instr.-cache entries for virtual region ['base', 'base + size')
*/
static void
invalidate_instr_caches_by_virt_region(addr_t base, size_t const size)
{ }
static void inval_branch_predicts() { };
/**
* Switch to the virtual mode in kernel
*
* \param table base of targeted translation table
* \param process_id process ID of the kernel address-space
*/
static void
init_virt_kernel(addr_t const table, unsigned const process_id)
{ }
inline static void finish_init_phys_kernel()
{ }
/**
* Configure this module appropriately for the first kernel run
*/
static void init_phys_kernel()
{ }
/**
* Finish all previous data transfers
*/
static void data_synchronization_barrier()
{ }
/**
* Enable secondary CPUs with instr. pointer 'ip'
*/
static void start_secondary_cpus(void * const ip)
{ }
/**
* Wait for the next interrupt as cheap as possible
*/
static void wait_for_interrupt() { }
/**
* Return wether to retry an undefined user instruction after this call
*/
bool retry_undefined_instr(Cpu_lazy_state *) { return false; }
/**
* Return kernel name of the executing CPU
*/
static unsigned executing_id() { return 0; }
/**
* Return kernel name of the primary CPU
*/
static unsigned primary_id() { return 0; }
/*************
** Dummies **
*************/
static void tlb_insertions() { inval_branch_predicts(); }
static void translation_added(addr_t, size_t) { }
static void prepare_proceeding(Cpu_lazy_state *, Cpu_lazy_state *) { }
};
#endif /* _CPU_H_ */

View File

@ -0,0 +1,46 @@
/*
* \brief Hardware specific base of kernel thread-objects
* \author Martin Stein
* \date 2013-11-13
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _KERNEL__THREAD_BASE_H_
#define _KERNEL__THREAD_BASE_H_
/* core includes */
#include <kernel/thread_event.h>
namespace Kernel
{
/**
* Hardware specific base of kernel thread-objects
*/
class Thread_base;
}
class Kernel::Thread_base
{
protected:
Thread_event _fault;
addr_t _fault_pd;
addr_t _fault_addr;
addr_t _fault_writes;
addr_t _fault_signal;
/**
* Constructor
*
* \param t generic part of kernel thread-object
*/
Thread_base(Thread * const t);
};
#endif /* _KERNEL__THREAD_BASE_H_ */

View File

@ -0,0 +1,25 @@
/*
* \brief CPU context of a virtual machine
* \author Martin Stein
* \date 2013-10-30
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _KERNEL__VM_STATE_H_
#define _KERNEL__VM_STATE_H_
namespace Kernel
{
/**
* Dummy
*/
struct Vm_state { };
}
#endif /* _KERNEL__VM_STATE_H_ */

View File

@ -0,0 +1,16 @@
/*
* \brief Macros that are used by multiple assembly files
* \author Martin Stein
* \date 2014-01-13
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
.include "spec/x86/macros_support.s"

View File

@ -0,0 +1,20 @@
/*
* \brief Macros that are used by multiple assembly files
* \author Martin Stein
* \date 2014-01-13
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/***************************************************
** Constant values that are pretty commonly used **
***************************************************/
/* alignment constraints */
.set MIN_PAGE_SIZE_LOG2, 12
.set DATA_ACCESS_ALIGNM_LOG2, 2

View File

@ -0,0 +1,67 @@
/*
* \brief Programmable interrupt controller for core
* \author Norman Feske
* \date 2013-04-05
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _PIC_H_
#define _PIC_H_
namespace Genode
{
/**
* Programmable interrupt controller for core
*/
class Pic;
}
class Genode::Pic
{
public:
enum {
/*
* FIXME: dummy ipi value on non-SMP platform, should be removed
* when SMP is an aspect of CPUs only compiled where necessary
*/
IPI = 255,
NR_OF_IRQ = 256,
};
/**
* Constructor
*/
Pic() { }
void init_cpu_local() { }
bool take_request(unsigned &irq) { return false; }
void finish_request() { }
void mask() { }
void unmask(unsigned const i, unsigned) { }
void mask(unsigned const i) { }
/*
* Dummies
*/
bool is_ip_interrupt(unsigned, unsigned) { return false; }
void trigger_ip_interrupt(unsigned) { }
};
namespace Kernel { class Pic : public Genode::Pic { }; }
#endif /* _PIC_H_ */

View File

@ -0,0 +1,148 @@
/*
* \brief Serial output driver for core
* \author Stefan Kalkowski
* \date 2012-10-24
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _SERIAL_H_
#define _SERIAL_H_
/* Genode includes */
#include <base/stdint.h>
/**
* Read byte from I/O port
*/
inline Genode::uint8_t inb(Genode::uint16_t port)
{
Genode::uint8_t res;
asm volatile ("inb %%dx, %0" :"=a"(res) :"Nd"(port));
return res;
}
/**
* Write byte to I/O port
*/
inline void outb(Genode::uint16_t port, Genode::uint8_t val)
{
asm volatile ("outb %b0, %w1" : : "a" (val), "Nd" (port));
}
/**
* Definitions of PC serial ports
*/
enum {
COMPORT_DATA_OFFSET = 0,
COMPORT_STATUS_OFFSET = 5,
STATUS_THR_EMPTY = 0x20, /* transmitter hold register empty */
STATUS_DHR_EMPTY = 0x40, /* data hold register empty
- data completely sent */
};
/**
* Initialize serial port
*
* Based on 'init_serial' of L4ka::Pistachio's 'kdb/platform/pc99/io.cc'
*/
static void init_comport(Genode::uint16_t port, unsigned baud)
{
if (!port)
return;
const unsigned
IER = port + 1,
EIR = port + 2,
LCR = port + 3,
MCR = port + 4,
LSR = port + 5,
MSR = port + 6,
DLLO = port + 0,
DLHI = port + 1;
outb(LCR, 0x80); /* select bank 1 */
// for (volatile int i = 10000000; i--; );
outb(DLLO, (115200/baud) >> 0);
outb(DLHI, (115200/baud) >> 8);
outb(LCR, 0x03); /* set 8,N,1 */
outb(IER, 0x00); /* disable interrupts */
outb(EIR, 0x07); /* enable FIFOs */
outb(MCR, 0x0b); /* force data terminal ready */
outb(IER, 0x01); /* enable RX interrupts */
inb(IER);
inb(EIR);
inb(LCR);
inb(MCR);
inb(LSR);
inb(MSR);
}
/**
* Output character to serial port
*/
inline void serial_out_char(Genode::uint16_t comport, Genode::uint8_t c)
{
/* wait until serial port is ready */
Genode::uint8_t ready = STATUS_THR_EMPTY;
while ((inb(comport + COMPORT_STATUS_OFFSET) & ready) != ready);
/* output character */
outb(comport + COMPORT_DATA_OFFSET, c);
}
namespace Genode {
/**
* Serial output driver for core
*/
class Serial
{
private:
uint16_t _comport;
public:
void put_char(char c)
{
if (!_comport)
return;
if (c == '\n')
serial_out_char(_comport, '\r');
serial_out_char(_comport, c);
}
/**
* Constructor
*
* XXX: The 'baud_rate' argument is ignored for now.
*/
Serial(unsigned) : _comport(0x3f8)
{
init_comport(_comport, 115200);
}
Serial(const char *s) : _comport(0x3f8)
{
init_comport(_comport, 115200);
while (*s)
put_char(*s++);
}
};
}
#endif /* _SERIAL_H_ */

View File

@ -0,0 +1,63 @@
/*
* \brief Timer driver for core
* \author Norman Feske
* \date 2013-04-05
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#include <base/stdint.h>
#include <base/printf.h>
namespace Genode
{
/**
* Timer driver for core
*
* Timer channel 0 apparently doesn't work on the RPI, so we use channel 1
*/
class Timer;
}
class Genode::Timer
{
public:
Timer() { }
static unsigned interrupt_id(int)
{
PDBG("not implemented");
return 0;
}
inline void start_one_shot(uint32_t const tics, unsigned)
{
PDBG("not implemented");
}
static uint32_t ms_to_tics(unsigned const ms)
{
PDBG("not implemented");
return 0;
}
unsigned value(unsigned)
{
PDBG("not implemented");
return 0;
}
};
namespace Kernel { class Timer : public Genode::Timer { }; }
#endif /* _TIMER_H_ */

View File

@ -0,0 +1,85 @@
/*
* \brief x86_64 translation table definitions for core
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2012-02-22
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _TRANSLATION_TABLE_H_
#define _TRANSLATION_TABLE_H_
#include <page_flags.h>
#include <assert.h>
#include <page_slab.h>
namespace Genode
{
/**
* First level translation table
*/
class Translation_table;
}
class Genode::Translation_table
{
public:
enum {
ALIGNM_LOG2 = 12,
MIN_PAGE_SIZE_LOG2 = 12,
MAX_COSTS_PER_TRANSLATION = 4*4096
};
void * operator new (size_t, void * p) { return p; }
/**
* Constructor
*/
Translation_table() { }
/**
* Maximum virtual offset that can be translated by this table
*/
static addr_t max_virt_offset()
{
PDBG("not implemented");
return 0;
}
/**
* Insert translations into this table
*
* \param vo offset of virt. transl. region in virt. table region
* \param pa base of physical backing store
* \param size size of translated region
* \param f mapping flags
* \param s second level page slab allocator
*/
void insert_translation(addr_t vo, addr_t pa, size_t size,
Page_flags const & f, Page_slab * const s)
{
PDBG("not implemented");
}
/**
* Remove translations that overlap with a given virtual region
*
* \param vo region offset within the tables virtual region
* \param size region size
* \param slab second level page slab allocator
*/
void remove_translation(addr_t vo, size_t size, Page_slab * slab)
{
PDBG("not implemented");
}
};
#endif /* _TRANSLATION_TABLE_H_ */

View File

@ -0,0 +1,26 @@
/*
* \brief Class for kernel data that is needed to manage a specific CPU
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2014-01-14
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <kernel/cpu.h>
using namespace Kernel;
Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::min, 0) {
PDBG("not implemented"); }
void Cpu_idle::exception(unsigned const cpu) {
PDBG("not implemented"); }

View File

@ -0,0 +1,30 @@
/*
* \brief Kernel backend for execution contexts in userland
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2014-01-14
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <kernel/thread.h>
using namespace Kernel;
Thread::Thread(unsigned const priority, unsigned const quota,
char const * const label)
:
Thread_base(this), Cpu_job(priority, quota), _state(AWAITS_START), _pd(0),
_utcb_phys(0), _signal_receiver(0), _label(label)
{ PDBG("not implemented"); }
void Thread::exception(unsigned const cpu) {
PDBG("not implemented"); }

View File

@ -0,0 +1,22 @@
/*
* \brief Kernel backend for virtual machines
* \author Martin Stein
* \date 2013-10-30
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <kernel/vm.h>
using namespace Kernel;
void Vm::exception(unsigned const cpu) {
PDBG("not implemented"); }

View File

@ -0,0 +1,50 @@
/*
* \brief Platform implementations specific for base-hw and Raspberry Pi
* \author Norman Feske
* \date 2013-04-05
*
* XXX dimension allocators according to the available physical memory
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <platform.h>
#include <cpu.h>
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
{
static Native_region _regions[] =
{
{ 2*1024*1024, 1024*1024*254 }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Cpu::User_context::User_context() { }

View File

@ -0,0 +1,45 @@
/**
* \brief Startup code for Genode 64Bit applications
* \author Sebastian Sumpf
* \author Martin Stein
* \date 2011-05-11
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/**************************
** .text (program code) **
**************************/
.section ".text"
/* program entry-point */
.global _core_start
_core_start:
/* initialize GLOBAL OFFSET TABLE */
leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
/* create proper environment for the main thread */
call init_main_thread
/* apply environment that was created by init_main_thread */
movq init_main_thread_result@GOTPCREL(%rip), %rax
movq (%rax), %rsp
/* clear the base pointer in order that stack backtraces will work */
xorq %rbp, %rbp
/*
* We jump into initial C code instead of calling it as it should never
* return on the one hand and because the alignment of the stack pointer
* that init_main_thread returned expects a jump at the other hand. The
* latter matters because GCC expects the initial stack pointer to be
* aligned to 16 byte for at least the handling of floating points.
*/
jmp _main

View File

@ -0,0 +1,66 @@
/*
* \brief Startup code for core
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2011-10-01
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
.section ".text.crt0"
/* magic multi-boot header to make GRUB happy */
.long 0x1badb002
.long 0x0
.long 0xe4524ffe
/**********************************
** Startup code for primary CPU **
**********************************/
.code32
.global _start
_start:
/*
* Install initial temporary environment that is replaced later by the
* environment that init_main_thread creates.
*/
leaq _stack_high@GOTPCREL(%rip),%rax
movq (%rax), %rsp
/* uniprocessor kernel-initialization which activates multiprocessor */
call init_kernel_up
/*********************************************
** Startup code that is common to all CPUs **
*********************************************/
.global _start_secondary_cpus
_start_secondary_cpus:
/* do multiprocessor kernel-initialization */
call init_kernel_mp
/* call the kernel main-routine */
call kernel
/* catch erroneous return of the kernel main-routine */
1: jmp 1b
/*********************************
** .bss (non-initialized data) **
*********************************/
.bss
/* stack of the temporary initial environment */
.p2align 8
.space 32 * 1024
_stack_high:

View File

@ -0,0 +1,83 @@
/*
* \brief CPU specific implementations of core
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2013-11-11
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <kernel/thread.h>
#include <kernel/pd.h>
#include <kernel/kernel.h>
using namespace Kernel;
/*************************
** Kernel::Thread_base **
*************************/
Thread_base::Thread_base(Thread * const t)
:
_fault(t),
_fault_pd(0),
_fault_addr(0),
_fault_writes(0),
_fault_signal(0)
{ }
/********************
** Kernel::Thread **
********************/
addr_t Thread::* Thread::_reg(addr_t const id) const
{
PDBG("not implemented");
return 0UL;
}
Thread_event Thread::* Thread::_event(unsigned const id) const
{
PDBG("not implemented");
return nullptr;
}
void Thread::_mmu_exception()
{
PDBG("not implemented");
}
/*************************
** Kernel::Cpu_context **
*************************/
void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table)
{ }
/*************************
** CPU-state utilities **
*************************/
typedef Thread_reg_id Reg_id;
static addr_t const _cpu_state_regs[] = { };
addr_t const * cpu_state_regs() { return _cpu_state_regs; }
size_t cpu_state_regs_length()
{
return sizeof(_cpu_state_regs)/sizeof(_cpu_state_regs[0]);
}

View File

@ -0,0 +1,68 @@
/*
* \brief Transition between kernel/userland, and secure/non-secure world
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2011-11-15
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
.include "macros.s"
.section .text
/*
* Page aligned base of mode transition code.
*
* This position independent code switches between a kernel context and a
* user context and thereby between their address spaces. Due to the latter
* it must be mapped executable to the same region in every address space.
* To enable such switching, the kernel context must be stored within this
* region, thus one should map it solely accessable for privileged modes.
*/
.p2align MIN_PAGE_SIZE_LOG2
.global _mt_begin
_mt_begin:
/* space for a copy of the kernel context */
.p2align 2
.global _mt_master_context_begin
_mt_master_context_begin:
/* space must be at least as large as 'Cpu_state' */
.space 32*4
.global _mt_master_context_end
_mt_master_context_end:
/* space for a client context-pointer per CPU */
.p2align 2
.global _mt_client_context_ptr
_mt_client_context_ptr:
/* a globally mapped buffer per CPU */
.p2align 2
.global _mt_buffer
_mt_buffer:
/*
* On user exceptions the CPU has to jump to one of the following
* seven entry vectors to switch to a kernel context.
*/
.global _mt_kernel_entry_pic
_mt_kernel_entry_pic:
1: jmp 1b
.global _mt_user_entry_pic
_mt_user_entry_pic:
1: jmp 1b
/* end of the mode transition code */
.global _mt_end
_mt_end:
1: jmp 1b

View File

@ -139,9 +139,14 @@ proc run_boot_dir {binaries {core_type core}} {
# offer ELF image
set elf_img "[run_dir]/image.elf"
#exec cp -L bin/$core_bin $elf_img
exec [cross_dev_prefix]objcopy -O elf32-i386 bin/$core_bin $elf_img
#exec [cross_dev_prefix]strip $elf_img
if {[have_spec "x86_64"]} {
# as startup is done in 32 bit mode, GRUB expects a 32 bit image
exec [cross_dev_prefix]objcopy -O elf32-i386 bin/$core_bin $elf_img
}
if {[expr [have_spec "arm"] || [have_spec "x86_32"]]} {
exec cp -L bin/$core_bin $elf_img
}
exec [cross_dev_prefix]strip $elf_img
if {[have_include "image/iso"] || [have_include "image/disk"]} {
#