And switch start_elf() over to use it.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/x86/context.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-)
diff --git a/arch/x86/context.c b/arch/x86/context.c index de852f4..6d57bfa 100644 --- a/arch/x86/context.c +++ b/arch/x86/context.c @@ -10,6 +10,8 @@ #include "kernel/kernel.h" #include "segment.h" #include "context.h" +#include "libopenbios/bindings.h" +#include "libopenbios/initprogram.h" #include "libopenbios/sys_info.h" #include "boot.h" #include "openbios.h" @@ -93,6 +95,16 @@ init_context(uint8_t *stack, uint32_t stack_size, int num_params) (stack + stack_size - (sizeof(*ctx) + num_params*sizeof(uint32_t))); memset(ctx, 0, sizeof(*ctx));
+ return ctx; +} + +/* init-program */ +int +arch_init_program(void) +{ + struct context volatile *ctx = __context; + ucell type, entry, param; + /* Fill in reasonable default for flat memory model */ ctx->gdt_base = virt_to_phys(gdt); ctx->gdt_limit = GDT_LIMIT; @@ -104,8 +116,26 @@ init_context(uint8_t *stack, uint32_t stack_size, int num_params) ctx->ss = FLAT_DS; ctx->esp = virt_to_phys(ESP_LOC(ctx)); ctx->return_addr = virt_to_phys(__exit_context); + + /* Set param */ + feval("load-state >ls.param @"); + param = POP(); + ctx->param[0] = param;
- return ctx; + /* Only elf-boot type has a param */ + feval("load-state >ls.file-type @"); + type = POP(); + if (type == 0) { + ctx->eax = 0xe1fb007; + ctx->ebx = param; + } + + /* Set entry point */ + feval("load-state >ls.entry @"); + entry = POP(); + ctx->eip = entry; + + return 0; }
/* Switch to another context. */ @@ -127,10 +157,10 @@ unsigned int start_elf(unsigned long entry_point, unsigned long param) { struct context *ctx = client_ctx;
- ctx->eip = entry_point; - ctx->param[0] = param; - ctx->eax = 0xe1fb007; - ctx->ebx = param; + PUSH(param); + feval("load-state >ls.param !"); + + arch_init_program();
ctx = switch_to(ctx); return ctx->eax;