2010-07-23 16:24:34 +02:00
|
|
|
#include "kernel/kernel.h" /* configures the kernel */
|
|
|
|
#include <minix/config.h>
|
|
|
|
#include <minix/const.h>
|
|
|
|
#include <minix/com.h>
|
2010-08-17 18:44:07 +02:00
|
|
|
#include <machine/asm.h>
|
2010-07-23 16:24:34 +02:00
|
|
|
#include <machine/interrupt.h>
|
|
|
|
#include "archconst.h"
|
|
|
|
#include "kernel/const.h"
|
|
|
|
#include "kernel/proc.h"
|
|
|
|
#include "sconst.h"
|
|
|
|
#include "multiboot.h"
|
|
|
|
|
|
|
|
#define GDT_SET_ENTRY(selector, base, limit) \
|
|
|
|
mov %ebp, %edi; \
|
2010-08-17 18:44:07 +02:00
|
|
|
add $(_C_LABEL(gdt) + selector), %edi; \
|
2010-07-23 16:24:34 +02:00
|
|
|
mov base, %eax; \
|
|
|
|
movw %ax, 2(%edi); \
|
|
|
|
shr $16, %eax; \
|
|
|
|
movb %al, 4(%edi); \
|
|
|
|
and $0xff00, %ax; \
|
|
|
|
andw $0xff, 6(%edi); \
|
|
|
|
or %ax, 6(%edi); \
|
|
|
|
mov limit, %eax; \
|
|
|
|
movw %ax, (%edi); \
|
|
|
|
shr $16, %eax; \
|
|
|
|
and $0xf, %ax; \
|
|
|
|
andb $0xf0, 6(%edi); \
|
|
|
|
or %ax, 6(%edi); \
|
|
|
|
|
2010-08-17 18:44:07 +02:00
|
|
|
IMPORT(pre_init)
|
|
|
|
.extern kernel_init
|
2010-07-23 16:24:34 +02:00
|
|
|
|
2010-08-17 18:44:07 +02:00
|
|
|
.globl multiboot_init
|
2010-07-23 16:24:34 +02:00
|
|
|
multiboot_init:
|
|
|
|
/* Get size of kernel text */
|
|
|
|
mov MULTIBOOT_LOAD_ADDRESS + MULTIBOOT_KERNEL_a_text, %ecx
|
|
|
|
|
|
|
|
/* Get size of kernel text and ceil to 0x1000, and it's the offset
|
|
|
|
of data seg */
|
|
|
|
mov %ecx, %eax
|
|
|
|
dec %eax
|
|
|
|
and $0xfffff000, %eax
|
|
|
|
add $0x1000, %eax
|
|
|
|
|
|
|
|
/* Calculate and save kernel data base address */
|
|
|
|
mov $(MULTIBOOT_LOAD_ADDRESS + MULTIBOOT_ENTRY_OFFSET), %ebp
|
|
|
|
add %eax, %ebp
|
2010-08-17 18:44:07 +02:00
|
|
|
mov %ebp, _C_LABEL(kernel_data_addr)(%ebp)
|
2010-07-23 16:24:34 +02:00
|
|
|
|
|
|
|
/* Init text seg */
|
|
|
|
GDT_SET_ENTRY(CS_SELECTOR, \
|
|
|
|
$(MULTIBOOT_LOAD_ADDRESS + MULTIBOOT_ENTRY_OFFSET), \
|
|
|
|
%ecx)
|
|
|
|
|
|
|
|
/* Init data seg */
|
|
|
|
GDT_SET_ENTRY(DS_SELECTOR, \
|
|
|
|
%ebp, \
|
|
|
|
MULTIBOOT_LOAD_ADDRESS + MULTIBOOT_KERNEL_a_total)
|
|
|
|
|
|
|
|
/* Make up monitor data seg, the same value as DS, different entry */
|
|
|
|
GDT_SET_ENTRY(SS_SELECTOR, \
|
|
|
|
%ebp, \
|
|
|
|
MULTIBOOT_LOAD_ADDRESS + MULTIBOOT_KERNEL_a_total)
|
|
|
|
|
|
|
|
/* Make up monitor text seg, used to return to real mode when poweroff */
|
|
|
|
GDT_SET_ENTRY(MON_CS_SELECTOR, \
|
|
|
|
$BIOS_POWEROFF_ENTRY, \
|
|
|
|
$0xffff)
|
|
|
|
|
|
|
|
mov $(GDT_SIZE*DESC_SIZE), %eax
|
|
|
|
mov %ebp, %edi
|
2010-08-17 18:44:07 +02:00
|
|
|
add $(_C_LABEL(gdt) + GDT_SELECTOR), %edi
|
2010-07-23 16:24:34 +02:00
|
|
|
mov %ax, (%edi)
|
|
|
|
mov %ebp, %eax
|
2010-08-17 18:44:07 +02:00
|
|
|
add $_C_LABEL(gdt), %eax
|
2010-07-23 16:24:34 +02:00
|
|
|
mov %eax, 2(%edi)
|
|
|
|
lgdt (%edi)
|
|
|
|
|
|
|
|
ljmp $(CS_SELECTOR), $reload_cs
|
|
|
|
|
|
|
|
reload_cs:
|
|
|
|
mov $DS_SELECTOR, %eax
|
|
|
|
mov %eax, %ds
|
|
|
|
mov %eax, %ss
|
|
|
|
mov %eax, %es
|
|
|
|
|
|
|
|
mov $(multiboot_stack + MULTIBOOT_STACK_SIZE), %esp
|
|
|
|
|
|
|
|
push %ebx
|
2010-08-17 18:44:07 +02:00
|
|
|
call _C_LABEL(pre_init)
|
2010-07-23 16:24:34 +02:00
|
|
|
|
|
|
|
add $4, %esp
|
|
|
|
|
|
|
|
/* return to old boot code of kernel */
|
|
|
|
push %eax
|
|
|
|
push $MULTIBOOT_PARAM_BUF_SIZE
|
2010-08-17 18:44:07 +02:00
|
|
|
push $_C_LABEL(multiboot_param_buf)
|
2010-07-23 16:24:34 +02:00
|
|
|
push $0
|
|
|
|
|
|
|
|
mov $ES_SELECTOR, %eax
|
|
|
|
mov %eax, %es
|
|
|
|
|
|
|
|
jmp kernel_init
|
|
|
|
|
|
|
|
.data
|
2010-08-17 18:44:07 +02:00
|
|
|
LABEL(kernel_data_addr)
|
|
|
|
.long 0
|
|
|
|
LABEL(a_out_headers)
|
|
|
|
.space NR_BOOT_PROCS * 32 /* is A_MINHDR */
|
2010-07-23 16:24:34 +02:00
|
|
|
|
2010-08-17 18:44:07 +02:00
|
|
|
LABEL(multiboot_param_buf)
|
|
|
|
.space MULTIBOOT_PARAM_BUF_SIZE
|
2010-07-23 16:24:34 +02:00
|
|
|
|
|
|
|
multiboot_stack:
|
|
|
|
.space MULTIBOOT_STACK_SIZE + 4
|