ELF multiboot support
This commit is contained in:
parent
455b809b17
commit
350b60661a
15 changed files with 258 additions and 219 deletions
|
@ -117,6 +117,9 @@
|
|||
#define hclick_to_physb(n) ((phys_bytes) (n) << HCLICK_SHIFT)
|
||||
#define physb_to_hclick(n) ((n) >> HCLICK_SHIFT)
|
||||
|
||||
#define CLICK2ABS(v) ((v) << CLICK_SHIFT)
|
||||
#define ABS2CLICK(a) ((a) >> CLICK_SHIFT)
|
||||
|
||||
#define ABS -999 /* this process means absolute memory */
|
||||
|
||||
/* Flag bits for i_mode in the inode. */
|
||||
|
|
|
@ -13,8 +13,8 @@ SRCS+= start.c table.c main.c proc.c \
|
|||
SRCS += smp.c
|
||||
.endif
|
||||
|
||||
DPADD+= ${LIBTIMERS} ${LIBSYS}
|
||||
LDADD+= -ltimers -lsys
|
||||
DPADD+= ${LIBTIMERS} ${LIBSYS} ${LIBEXEC}
|
||||
LDADD+= -ltimers -lsys -lexec
|
||||
|
||||
CFLAGS += -D__kernel__
|
||||
|
||||
|
@ -22,7 +22,11 @@ CFLAGS += -D__kernel__
|
|||
LDFLAGS+= -.o
|
||||
.elif ${COMPILER_TYPE} == "gnu"
|
||||
CPPFLAGS+= -ffreestanding -fno-stack-protector
|
||||
.if ${OBJECT_FMT} == "ELF"
|
||||
LDFLAGS+= -T ${.CURDIR}/arch/${ARCH}/kernel_elf.lds
|
||||
.else
|
||||
LDFLAGS+= -T ${.CURDIR}/arch/${ARCH}/kernel.lds
|
||||
.endif
|
||||
LDFLAGS+= -nostdlib -L${LIBDIR}
|
||||
CFLAGS+=-march=i386
|
||||
DPADD+= ${LIBC}
|
||||
|
|
|
@ -73,7 +73,7 @@ PRIVATE __dead void arch_bios_poweroff(void)
|
|||
write_cr0(cr0);
|
||||
/* Copy 16-bit poweroff code to below 1M */
|
||||
phys_copy(
|
||||
FUNC2PHY(&poweroff16),
|
||||
(u32_t)&poweroff16,
|
||||
BIOS_POWEROFF_ENTRY,
|
||||
(u32_t)&poweroff16_end-(u32_t)&poweroff16);
|
||||
poweroff_jmp();
|
||||
|
|
|
@ -111,6 +111,9 @@ _PROTOTYPE(void __switch_address_space, (struct proc * p,
|
|||
|
||||
_PROTOTYPE(void refresh_tlb, (void));
|
||||
|
||||
/* multiboot.c */
|
||||
_PROTOTYPE( void multiboot_init, (void) );
|
||||
|
||||
/* protect.c */
|
||||
struct tss_s {
|
||||
reg_t backlink;
|
||||
|
|
|
@ -69,6 +69,7 @@ IMPORT(params_size)
|
|||
IMPORT(params_offset)
|
||||
IMPORT(mon_ds)
|
||||
IMPORT(switch_to_user)
|
||||
IMPORT(multiboot_init)
|
||||
|
||||
/* Exported variables. */
|
||||
.globl begbss
|
||||
|
@ -81,6 +82,13 @@ IMPORT(switch_to_user)
|
|||
.global MINIX
|
||||
MINIX:
|
||||
/* this is the entry point for the MINIX kernel */
|
||||
|
||||
#if defined(__ELF__)
|
||||
/* Check if Multibooting */
|
||||
cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax
|
||||
je _C_LABEL(multiboot_init)
|
||||
#endif
|
||||
|
||||
jmp over_flags /* skip over the next few bytes */
|
||||
.short CLICK_SHIFT /* for the monitor: memory granularity */
|
||||
|
||||
|
@ -104,16 +112,11 @@ multiboot_flags:
|
|||
.long MULTIBOOT_FLAGS
|
||||
multiboot_checksum:
|
||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_FLAGS)
|
||||
multiboot_header_addr:
|
||||
.long (MULTIBOOT_LOAD_ADDRESS + MULTIBOOT_ENTRY_OFFSET + multiboot_magic)
|
||||
multiboot_load_addr:
|
||||
.long MULTIBOOT_LOAD_ADDRESS
|
||||
multiboot_load_end_addr:
|
||||
.long 0
|
||||
multiboot_bss_end_addr:
|
||||
.long 0
|
||||
multiboot_entry_addr:
|
||||
.long (MULTIBOOT_LOAD_ADDRESS + MULTIBOOT_ENTRY_OFFSET + multiboot_init)
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
/* Video mode */
|
||||
multiboot_mode_type:
|
||||
.long MULTIBOOT_VIDEO_MODE_EGA
|
||||
|
@ -164,7 +167,9 @@ copygdt:
|
|||
mov 8(%ebp), %ebx /* boot parameters offset */
|
||||
mov 12(%ebp), %edx /* boot parameters length */
|
||||
mov 16(%ebp), %eax /* address of a.out headers */
|
||||
#if !defined(__ELF__)
|
||||
movl %eax, _C_LABEL(aout)
|
||||
#endif
|
||||
mov %ds, %ax /* kernel data */
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
|
|
|
@ -30,52 +30,13 @@
|
|||
IMPORT(pre_init)
|
||||
.extern kernel_init
|
||||
|
||||
.globl multiboot_init
|
||||
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
|
||||
mov %ebp, _C_LABEL(kernel_data_addr)(%ebp)
|
||||
|
||||
/* 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)
|
||||
|
||||
ENTRY(multiboot_init)
|
||||
mov $(GDT_SIZE*DESC_SIZE), %eax
|
||||
mov %ebp, %edi
|
||||
add $(_C_LABEL(gdt) + GDT_SELECTOR), %edi
|
||||
mov $(_C_LABEL(gdt) + GDT_SELECTOR), %edi
|
||||
mov %ax, (%edi)
|
||||
mov %ebp, %eax
|
||||
add $_C_LABEL(gdt), %eax
|
||||
mov $_C_LABEL(gdt), %eax
|
||||
mov %eax, 2(%edi)
|
||||
lgdt (%edi)
|
||||
|
||||
ljmp $(CS_SELECTOR), $reload_cs
|
||||
|
||||
reload_cs:
|
||||
|
@ -103,11 +64,6 @@ reload_cs:
|
|||
jmp kernel_init
|
||||
|
||||
.data
|
||||
LABEL(kernel_data_addr)
|
||||
.long 0
|
||||
LABEL(a_out_headers)
|
||||
.space NR_BOOT_PROCS * 32 /* is A_MINHDR */
|
||||
|
||||
LABEL(multiboot_param_buf)
|
||||
.space MULTIBOOT_PARAM_BUF_SIZE
|
||||
|
||||
|
|
|
@ -6,22 +6,18 @@
|
|||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
/* Must pass memory information to OS. */
|
||||
#define MULTIBOOT_PAGE_ALIGN 0x00000001
|
||||
|
||||
#define MULTIBOOT_MEMORY_INFO 0x00000002
|
||||
|
||||
#define MULTIBOOT_VIDEO_MODE 0x00000004
|
||||
|
||||
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||
|
||||
#define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO | \
|
||||
MULTIBOOT_VIDEO_MODE | \
|
||||
MULTIBOOT_AOUT_KLUDGE)
|
||||
#define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN)
|
||||
|
||||
/* consts used for Multiboot pre-init */
|
||||
|
||||
#define MULTIBOOT_ENTRY_OFFSET 0x200
|
||||
|
||||
#define MULTIBOOT_LOAD_ADDRESS 0x200000-MULTIBOOT_ENTRY_OFFSET
|
||||
|
||||
#define MULTIBOOT_VIDEO_MODE_EGA 1
|
||||
|
||||
#define MULTIBOOT_VIDEO_BUFFER 0xB8000
|
||||
|
@ -36,10 +32,6 @@
|
|||
#define MULTIBOOT_STACK_SIZE 4096
|
||||
#define MULTIBOOT_PARAM_BUF_SIZE 1024
|
||||
|
||||
#define MULTIBOOT_KERNEL_a_text 0x48
|
||||
#define MULTIBOOT_KERNEL_a_data (0x48+4)
|
||||
#define MULTIBOOT_KERNEL_a_total (0x48+16)
|
||||
|
||||
/* Flags to be set in the ’flags’ member of the multiboot info structure. */
|
||||
|
||||
#define MULTIBOOT_INFO_MEMORY 0x00000001
|
||||
|
@ -53,15 +45,6 @@
|
|||
/* Are there modules to do something with? */
|
||||
#define MULTIBOOT_INFO_MODS 0x00000008
|
||||
|
||||
/* get physical address by data pointer*/
|
||||
#define PTR2PHY(ptr) (kernel_data_addr+(u32_t)(ptr))
|
||||
|
||||
/* get data pointer by physical address*/
|
||||
#define PHY2PTR(phy) ((char *)((u32_t)(phy)-kernel_data_addr))
|
||||
|
||||
/* Get physical address by function pointer*/
|
||||
#define FUNC2PHY(fun) (MULTIBOOT_LOAD_ADDRESS + MULTIBOOT_ENTRY_OFFSET + (u32_t)(fun))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <minix/types.h>
|
||||
|
@ -126,11 +109,20 @@ struct multiboot_info
|
|||
};
|
||||
typedef struct multiboot_info multiboot_info_t;
|
||||
|
||||
struct multiboot_mod_list
|
||||
{
|
||||
/* Memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||
u32_t mod_start;
|
||||
u32_t mod_end;
|
||||
/* Module command line */
|
||||
u32_t cmdline;
|
||||
/* Pad struct to 16 bytes (must be zero) */
|
||||
u32_t pad;
|
||||
};
|
||||
typedef struct multiboot_mod_list multiboot_module_t;
|
||||
|
||||
/* Buffer for multiboot parameters */
|
||||
extern char multiboot_param_buf[];
|
||||
|
||||
/* Physical address of kernel data segment */
|
||||
extern phys_bytes kernel_data_addr;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __MULTIBOOT_H__ */
|
||||
|
|
|
@ -11,13 +11,19 @@
|
|||
#include <minix/types.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/a.out.h>
|
||||
#include <sys/param.h>
|
||||
#include <machine/partition.h>
|
||||
#include "../../../boot/image.h"
|
||||
#include "string.h"
|
||||
#include "arch_proto.h"
|
||||
#include "libexec.h"
|
||||
#include "multiboot.h"
|
||||
|
||||
#define MULTIBOOT_VERBOSE 1
|
||||
|
||||
/* FIXME: Share this define with kernel linker script */
|
||||
#define MULTIBOOT_KERNEL_ADDR 0x00200000UL
|
||||
|
||||
/* Granularity used in image file and copying */
|
||||
#define GRAN 512
|
||||
#define SECT_CEIL(x) ((((x) - 1) / GRAN + 1) * GRAN)
|
||||
|
@ -25,15 +31,14 @@
|
|||
/* String length used for mb_itoa */
|
||||
#define ITOA_BUFFER_SIZE 20
|
||||
|
||||
/* The a.out headers to pass to kernel.
|
||||
* Not using struct exec because only using short form */
|
||||
extern char a_out_headers[];
|
||||
/* Info on boot modules */
|
||||
phys_bytes mulitboot_modules_addr;
|
||||
|
||||
#define mb_load_phymem(buf, phy, len) \
|
||||
phys_copy((phy), PTR2PHY(buf), (len))
|
||||
phys_copy((phy), (u32_t)(buf), (len))
|
||||
|
||||
#define mb_save_phymem(buf, phy, len) \
|
||||
phys_copy(PTR2PHY(buf), (phy), (len))
|
||||
phys_copy((u32_t)(buf), (phy), (len))
|
||||
|
||||
FORWARD _PROTOTYPE(void mb_print, (char *str));
|
||||
|
||||
|
@ -253,21 +258,20 @@ PRIVATE void get_parameters(multiboot_info_t *mbi)
|
|||
multiboot_param_buf[i] = 0;
|
||||
|
||||
if (mbi->flags & MULTIBOOT_INFO_BOOTDEV) {
|
||||
sub = 0xff;
|
||||
disk = ((mbi->boot_device&0xff000000) >> 24)-0x80;
|
||||
prim = (mbi->boot_device&0xff0000) == 0xff0000 ?
|
||||
0 : (mbi->boot_device & 0xff0000) >> 16;
|
||||
prim = (mbi->boot_device & 0xff0000) >> 16;
|
||||
if (prim == 0xff)
|
||||
prim = 0;
|
||||
sub = (mbi->boot_device & 0xff00) >> 8;
|
||||
if (sub == 0xff)
|
||||
sub = 0;
|
||||
ctrlr = 0;
|
||||
dev = dev_cNd0[ctrlr];
|
||||
|
||||
/* Determine the value of rootdev */
|
||||
if ((mbi->boot_device & 0xff00) == 0xff00) {
|
||||
dev += disk * (NR_PARTITIONS + 1) + (prim + 1);
|
||||
} else {
|
||||
sub = (mbi->boot_device & 0xff00) >> 8;
|
||||
dev += 0x80
|
||||
+ (disk * NR_PARTITIONS + prim) * NR_PARTITIONS
|
||||
+ sub;
|
||||
}
|
||||
+ (disk * NR_PARTITIONS + prim) * NR_PARTITIONS + sub;
|
||||
|
||||
mb_itoa(dev, temp);
|
||||
mb_set_param("rootdev", temp);
|
||||
mb_set_param("ramimagedev", temp);
|
||||
|
@ -322,96 +326,138 @@ PRIVATE void get_parameters(multiboot_info_t *mbi)
|
|||
}
|
||||
}
|
||||
|
||||
PRIVATE void mb_extract_image(void)
|
||||
PRIVATE int mb_clear_memrange(phys_bytes start, phys_bytes end)
|
||||
{
|
||||
int empty = 0;
|
||||
int i;
|
||||
u32_t text_addr[NR_BOOT_PROCS];
|
||||
u32_t imghdr_addr = MULTIBOOT_LOAD_ADDRESS;
|
||||
int off_sum = 0;
|
||||
struct exec *aout_hdr;
|
||||
int empty, clear_size, j;
|
||||
u32_t p;
|
||||
/* Extract the image to align segments and clear up BSS
|
||||
*/
|
||||
for (i = 0; i < LAST_SPECIAL_PROC_NR + 2; i++) {
|
||||
aout_hdr = (struct exec *) (a_out_headers + A_MINHDR * i);
|
||||
mb_load_phymem(aout_hdr, imghdr_addr + IM_NAME_MAX + 1, A_MINHDR);
|
||||
text_addr[i] = imghdr_addr + GRAN;
|
||||
if (aout_hdr->a_flags & A_SEP) {
|
||||
off_sum += CLICK_CEIL(aout_hdr->a_total)
|
||||
- SECT_CEIL(aout_hdr->a_data)
|
||||
+ CLICK_CEIL(aout_hdr->a_text)
|
||||
- SECT_CEIL(aout_hdr->a_text)
|
||||
- GRAN;
|
||||
imghdr_addr += SECT_CEIL(aout_hdr->a_text)
|
||||
+ SECT_CEIL(aout_hdr->a_data)
|
||||
+ GRAN;
|
||||
} else {
|
||||
off_sum += CLICK_CEIL(aout_hdr->a_total)
|
||||
- SECT_CEIL(aout_hdr->a_data + aout_hdr->a_text)
|
||||
- GRAN;
|
||||
imghdr_addr += SECT_CEIL(aout_hdr->a_text + aout_hdr->a_data)
|
||||
+ GRAN;
|
||||
}
|
||||
}
|
||||
for (i = LAST_SPECIAL_PROC_NR + 1; i >= 0;i--) {
|
||||
struct exec * aout_hdr = (struct exec *) (a_out_headers + A_MINHDR * i);
|
||||
if (aout_hdr->a_flags & A_SEP)
|
||||
off_sum -= CLICK_CEIL(aout_hdr->a_total)
|
||||
- SECT_CEIL(aout_hdr->a_data)
|
||||
+ CLICK_CEIL(aout_hdr->a_text)
|
||||
- SECT_CEIL(aout_hdr->a_text)
|
||||
- GRAN;
|
||||
else
|
||||
off_sum -= CLICK_CEIL(aout_hdr->a_total)
|
||||
- SECT_CEIL(aout_hdr->a_data + aout_hdr->a_text)
|
||||
- GRAN;
|
||||
if (i > 0) { /* if not kernel */
|
||||
if (aout_hdr->a_flags & A_SEP) {
|
||||
mb_phys_move(text_addr[i], text_addr[i] + off_sum,
|
||||
SECT_CEIL(aout_hdr->a_text));
|
||||
mb_phys_move(text_addr[i] + SECT_CEIL(aout_hdr->a_text),
|
||||
text_addr[i] + off_sum + CLICK_CEIL(aout_hdr->a_text),
|
||||
SECT_CEIL(aout_hdr->a_data));
|
||||
} else {
|
||||
mb_phys_move(text_addr[i], text_addr[i] + off_sum,
|
||||
SECT_CEIL(aout_hdr->a_text + aout_hdr->a_data));
|
||||
}
|
||||
}
|
||||
aout_hdr->a_syms = text_addr[i] + off_sum;
|
||||
|
||||
/* Clear out for expanded text, BSS and stack */
|
||||
empty = 0;
|
||||
if (aout_hdr->a_flags & A_SEP) {
|
||||
p = text_addr[i] + off_sum
|
||||
+ CLICK_CEIL(aout_hdr->a_text)
|
||||
+ aout_hdr->a_data;
|
||||
clear_size = CLICK_CEIL(aout_hdr->a_total) - aout_hdr->a_data;
|
||||
} else {
|
||||
p = text_addr[i] + off_sum
|
||||
+ aout_hdr->a_text
|
||||
+ aout_hdr->a_data;
|
||||
clear_size = CLICK_CEIL(aout_hdr->a_total)
|
||||
- aout_hdr->a_data
|
||||
- aout_hdr->a_text;
|
||||
}
|
||||
/* FIXME: use faster function */
|
||||
for (j = 0; j < clear_size; j++)
|
||||
mb_save_phymem(&empty, p + j, 1);
|
||||
}
|
||||
for (i = start; i < end; i++)
|
||||
phys_copy((phys_bytes)&empty, i, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PUBLIC u32_t pre_init(u32_t ebx)
|
||||
PRIVATE void mb_extract_image(multiboot_info_t mbi)
|
||||
{
|
||||
multiboot_module_t *mb_module_info;
|
||||
multiboot_module_t *module;
|
||||
u32_t mods_count = mbi.mods_count;
|
||||
int r, i;
|
||||
vir_bytes text_vaddr, text_filebytes, text_membytes;
|
||||
vir_bytes data_vaddr, data_filebytes, data_membytes;
|
||||
phys_bytes text_paddr, data_paddr;
|
||||
vir_bytes stack_bytes;
|
||||
vir_bytes pc;
|
||||
off_t text_offset, data_offset;
|
||||
|
||||
/* Save memory map for kernel tasks */
|
||||
r = read_header_elf((const char *)MULTIBOOT_KERNEL_ADDR,
|
||||
&text_vaddr, &text_paddr,
|
||||
&text_filebytes, &text_membytes,
|
||||
&data_vaddr, &data_paddr,
|
||||
&data_filebytes, &data_membytes,
|
||||
&pc, &text_offset, &data_offset);
|
||||
|
||||
for (i = 0; i < NR_TASKS; ++i) {
|
||||
image[i].memmap.text_vaddr = trunc_page(text_vaddr);
|
||||
image[i].memmap.text_paddr = trunc_page(text_paddr);
|
||||
image[i].memmap.text_bytes = text_membytes;
|
||||
image[i].memmap.data_vaddr = trunc_page(data_vaddr);
|
||||
image[i].memmap.data_paddr = trunc_page(data_paddr);
|
||||
image[i].memmap.data_bytes = data_membytes;
|
||||
image[i].memmap.stack_bytes = 0;
|
||||
image[i].memmap.entry = pc;
|
||||
}
|
||||
|
||||
#ifdef MULTIBOOT_VERBOSE
|
||||
mb_print("\nKernel: ");
|
||||
mb_print_hex(trunc_page(text_paddr));
|
||||
mb_print("-");
|
||||
mb_print_hex(trunc_page(data_paddr) + data_membytes + stack_bytes);
|
||||
mb_print(" Entry: ");
|
||||
mb_print_hex(pc);
|
||||
mb_print(" Stack: ");
|
||||
mb_print_hex(stack_bytes);
|
||||
#endif
|
||||
|
||||
mb_module_info = ((multiboot_module_t *)mbi.mods_addr);
|
||||
module = &mb_module_info[0];
|
||||
|
||||
/* Load boot image services into memory and save memory map */
|
||||
for (i = 0; module < &mb_module_info[mods_count]; ++module, ++i) {
|
||||
char zero = 0;
|
||||
|
||||
r = read_header_elf((const char *)module->mod_start,
|
||||
&text_vaddr, &text_paddr,
|
||||
&text_filebytes, &text_membytes,
|
||||
&data_vaddr, &data_paddr,
|
||||
&data_filebytes, &data_membytes,
|
||||
&pc, &text_offset, &data_offset);
|
||||
if (r) {
|
||||
mb_print("fatal: ELF parse failure\n");
|
||||
/* Spin here */
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
stack_bytes = round_page(image[NR_TASKS+i].stack_kbytes * 1024);
|
||||
|
||||
/* Load text segment */
|
||||
phys_copy(module->mod_start+text_offset, text_paddr,
|
||||
text_filebytes);
|
||||
mb_clear_memrange(text_paddr+text_filebytes,
|
||||
trunc_page(text_paddr) + text_membytes);
|
||||
|
||||
/* Load data and stack segments */
|
||||
phys_copy(module->mod_start+data_offset, data_paddr,
|
||||
data_filebytes);
|
||||
mb_clear_memrange(data_paddr+data_filebytes,
|
||||
trunc_page(data_paddr) + data_membytes
|
||||
+ stack_bytes);
|
||||
|
||||
/* Save memmap for non-kernel tasks, so subscript past kernel
|
||||
tasks. */
|
||||
image[NR_TASKS+i].memmap.text_vaddr = trunc_page(text_vaddr);
|
||||
image[NR_TASKS+i].memmap.text_paddr = trunc_page(text_paddr);
|
||||
image[NR_TASKS+i].memmap.text_bytes = text_membytes;
|
||||
image[NR_TASKS+i].memmap.data_vaddr = trunc_page(data_vaddr);
|
||||
image[NR_TASKS+i].memmap.data_paddr = trunc_page(data_paddr);
|
||||
image[NR_TASKS+i].memmap.data_bytes = data_membytes;
|
||||
image[NR_TASKS+i].memmap.stack_bytes = stack_bytes;
|
||||
image[NR_TASKS+i].memmap.entry = pc;
|
||||
|
||||
#ifdef MULTIBOOT_VERBOSE
|
||||
mb_print("\n");
|
||||
mb_print_hex(i);
|
||||
mb_print(": ");
|
||||
mb_print_hex(trunc_page(text_paddr));
|
||||
mb_print("-");
|
||||
mb_print_hex(trunc_page(data_paddr) + data_membytes + stack_bytes);
|
||||
mb_print(" Entry: ");
|
||||
mb_print_hex(pc);
|
||||
mb_print(" Stack: ");
|
||||
mb_print_hex(stack_bytes);
|
||||
mb_print(" ");
|
||||
mb_print((char *)module->cmdline);
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PUBLIC phys_bytes pre_init(u32_t ebx)
|
||||
{
|
||||
multiboot_info_t mbi;
|
||||
|
||||
/* Do pre-initialization for multiboot, returning physical address of
|
||||
* a_out_headers
|
||||
* of multiboot module info
|
||||
*/
|
||||
mb_cls();
|
||||
mb_print("\nMINIX booting... ");
|
||||
mb_load_phymem(&mbi, ebx, sizeof(mbi));
|
||||
get_parameters(&mbi);
|
||||
mb_print("\nLoading image... ");
|
||||
mb_extract_image();
|
||||
return PTR2PHY(a_out_headers);
|
||||
mb_extract_image(mbi);
|
||||
return mbi.mods_addr;
|
||||
}
|
||||
|
|
|
@ -126,11 +126,13 @@ PUBLIC int main(void)
|
|||
struct boot_image *ip; /* boot image pointer */
|
||||
register struct proc *rp; /* process pointer */
|
||||
register int i, j;
|
||||
int hdrindex; /* index to array of a.out headers */
|
||||
phys_clicks text_base;
|
||||
vir_clicks text_clicks, data_clicks, st_clicks;
|
||||
struct exec e_hdr; /* for a copy of an a.out header */
|
||||
size_t argsz; /* size of arguments passed to crtso on stack */
|
||||
#if !defined(__ELF__)
|
||||
int hdrindex; /* index to array of a.out headers */
|
||||
struct exec e_hdr; /* for a copy of an a.out header */
|
||||
#endif
|
||||
|
||||
BKL_LOCK();
|
||||
/* Global value to test segment sanity. */
|
||||
|
@ -217,7 +219,21 @@ PUBLIC int main(void)
|
|||
/* Don't let the process run for now. */
|
||||
RTS_SET(rp, RTS_NO_PRIV | RTS_NO_QUANTUM);
|
||||
}
|
||||
|
||||
#if defined(__ELF__)
|
||||
rp->p_memmap[T].mem_vir = ABS2CLICK(ip->memmap.text_vaddr);
|
||||
rp->p_memmap[T].mem_phys = ABS2CLICK(ip->memmap.text_paddr);
|
||||
rp->p_memmap[T].mem_len = ABS2CLICK(ip->memmap.text_bytes);
|
||||
rp->p_memmap[D].mem_vir = ABS2CLICK(ip->memmap.data_vaddr);
|
||||
rp->p_memmap[D].mem_phys = ABS2CLICK(ip->memmap.data_paddr);
|
||||
rp->p_memmap[D].mem_len = ABS2CLICK(ip->memmap.data_bytes);
|
||||
rp->p_memmap[S].mem_phys = ABS2CLICK(ip->memmap.data_paddr +
|
||||
ip->memmap.data_bytes +
|
||||
ip->memmap.stack_bytes);
|
||||
rp->p_memmap[S].mem_vir = ABS2CLICK(ip->memmap.data_vaddr +
|
||||
ip->memmap.data_bytes +
|
||||
ip->memmap.stack_bytes);
|
||||
rp->p_memmap[S].mem_len = 0;
|
||||
#else
|
||||
if (iskerneln(proc_nr)) { /* part of the kernel? */
|
||||
hdrindex = 0; /* all use the first a.out header */
|
||||
} else {
|
||||
|
@ -248,12 +264,13 @@ PUBLIC int main(void)
|
|||
rp->p_memmap[S].mem_phys = text_base + text_clicks + st_clicks;
|
||||
rp->p_memmap[S].mem_vir = st_clicks;
|
||||
rp->p_memmap[S].mem_len = 0;
|
||||
#endif
|
||||
|
||||
/* Set initial register values. The processor status word for tasks
|
||||
* is different from that of other processes because tasks can
|
||||
* access I/O; this is not allowed to less-privileged processes
|
||||
*/
|
||||
rp->p_reg.pc = 0; /* we cannot start anything else */
|
||||
rp->p_reg.pc = ip->memmap.entry;
|
||||
rp->p_reg.psw = (iskerneln(proc_nr)) ? INIT_TASK_PSW : INIT_PSW;
|
||||
|
||||
/* Initialize the server stack pointer. Take it down three words
|
||||
|
|
|
@ -49,32 +49,29 @@
|
|||
* the highest priority. DS must be the first system process in the list to
|
||||
* allow reliable asynchronous publishing of system events. RS comes right after
|
||||
* to prioritize ping messages periodically delivered to system processes.
|
||||
*
|
||||
* Each entry provides the process number, flags, and a name for the process
|
||||
* table.
|
||||
*/
|
||||
|
||||
PUBLIC struct boot_image image[] = {
|
||||
/* process nr, flags, name */
|
||||
{ASYNCM, 0, "asyncm"},
|
||||
{IDLE, 0, "idle" },
|
||||
{CLOCK, 0, "clock" },
|
||||
{SYSTEM, 0, "system"},
|
||||
{HARDWARE, 0, "kernel"},
|
||||
/* process nr, flags, stack size, name */
|
||||
{ASYNCM, 0, 0, "asyncm"},
|
||||
{IDLE, 0, 0, "idle" },
|
||||
{CLOCK, 0, 0, "clock" },
|
||||
{SYSTEM, 0, 0, "system"},
|
||||
{HARDWARE, 0, 0, "kernel"},
|
||||
|
||||
{DS_PROC_NR, BVM_F, "ds" },
|
||||
{RS_PROC_NR, 0, "rs" },
|
||||
{DS_PROC_NR, BVM_F, 16, "ds" },
|
||||
{RS_PROC_NR, 0, 8125, "rs" },
|
||||
|
||||
{PM_PROC_NR, OVM_F, "pm" },
|
||||
{SCHED_PROC_NR,OVM_F, "sched" },
|
||||
{VFS_PROC_NR, BVM_F, "vfs" },
|
||||
{MEM_PROC_NR, BVM_F, "memory"},
|
||||
{LOG_PROC_NR, BVM_F, "log" },
|
||||
{TTY_PROC_NR, BVM_F, "tty" },
|
||||
{MFS_PROC_NR, BVM_F, "mfs" },
|
||||
{VM_PROC_NR, 0, "vm" },
|
||||
{PFS_PROC_NR, BVM_F, "pfs" },
|
||||
{INIT_PROC_NR, BVM_F, "init" },
|
||||
{PM_PROC_NR, OVM_F, 32, "pm" },
|
||||
{SCHED_PROC_NR,OVM_F, 32, "sched" },
|
||||
{VFS_PROC_NR, BVM_F, 16, "vfs" },
|
||||
{MEM_PROC_NR, BVM_F, 8, "memory"},
|
||||
{LOG_PROC_NR, BVM_F, 32, "log" },
|
||||
{TTY_PROC_NR, BVM_F, 16, "tty" },
|
||||
{MFS_PROC_NR, BVM_F, 128, "mfs" },
|
||||
{VM_PROC_NR, 0, 128, "vm" },
|
||||
{PFS_PROC_NR, BVM_F, 128, "pfs" },
|
||||
{INIT_PROC_NR, BVM_F, 64, "init" },
|
||||
};
|
||||
|
||||
/* Verify the size of the system image table at compile time.
|
||||
|
|
|
@ -11,11 +11,24 @@ typedef struct { /* bitmap for system indexes */
|
|||
bitchunk_t chunk[BITMAP_CHUNKS(NR_SYS_PROCS)];
|
||||
} sys_map_t;
|
||||
|
||||
struct boot_image_memmap {
|
||||
phys_bytes text_vaddr; /* Virtual start address of text */
|
||||
phys_bytes text_paddr; /* Physical start address of text */
|
||||
phys_bytes text_bytes; /* Text segment's size (bytes) */
|
||||
phys_bytes data_vaddr; /* Virtual start address of data */
|
||||
phys_bytes data_paddr; /* Physical start address of data */
|
||||
phys_bytes data_bytes; /* Data segment's size (bytes) */
|
||||
phys_bytes stack_bytes; /* Size of stack set aside (bytes) */
|
||||
phys_bytes entry; /* Entry point of executable */
|
||||
};
|
||||
|
||||
struct boot_image {
|
||||
proc_nr_t proc_nr; /* process number to use */
|
||||
int flags; /* process flags */
|
||||
int stack_kbytes; /* stack size (in KB) */
|
||||
char proc_name[P_NAME_LEN]; /* name in process table */
|
||||
endpoint_t endpoint; /* endpoint number when started */
|
||||
struct boot_image_memmap memmap; /* memory map info for boot image */
|
||||
};
|
||||
|
||||
typedef unsigned long irq_policy_t;
|
||||
|
|
|
@ -45,8 +45,8 @@ PUBLIC int do_exec()
|
|||
m.PM_PROC = mp->mp_endpoint;
|
||||
m.PM_PATH = m_in.exec_name;
|
||||
m.PM_PATH_LEN = m_in.exec_len;
|
||||
m.PM_FRAME = m_in.stack_ptr;
|
||||
m.PM_FRAME_LEN = m_in.stack_bytes;
|
||||
m.PM_FRAME = m_in.frame_ptr;
|
||||
m.PM_FRAME_LEN = m_in.frame_len;
|
||||
|
||||
tell_vfs(mp, &m);
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#define new_val m1_p1
|
||||
#define old_val m1_p2
|
||||
#define sig m6_i1
|
||||
#define stack_bytes m1_i2
|
||||
#define stack_ptr m1_p2
|
||||
#define frame_len m1_i2
|
||||
#define frame_ptr m1_p2
|
||||
#define status m1_i1
|
||||
#define usr_id m1_i1
|
||||
#define request m2_i2
|
||||
|
|
|
@ -103,11 +103,16 @@ struct mem_map *map_ptr; /* memory to remove */
|
|||
if(memp->base <= map_ptr[T].mem_phys
|
||||
&& memp->base+memp->size >= map_ptr[T].mem_phys)
|
||||
{
|
||||
phys_bytes progsz = map_ptr[S].mem_phys
|
||||
- map_ptr[T].mem_phys;
|
||||
phys_bytes progend = map_ptr[S].mem_phys;
|
||||
|
||||
if (memp->base == map_ptr[T].mem_phys) {
|
||||
memp->base += map_ptr[T].mem_len + map_ptr[S].mem_vir;
|
||||
memp->size -= map_ptr[T].mem_len + map_ptr[S].mem_vir;
|
||||
memp->base += progsz;
|
||||
memp->size -= progsz;
|
||||
} else {
|
||||
struct memory *mempr;
|
||||
|
||||
/* have to split mem_chunks */
|
||||
if(mem_chunks[NR_MEMS-1].size>0)
|
||||
panic("reserve_proc_mem: can't find free mem_chunks to map: 0x%lx",
|
||||
|
@ -116,9 +121,10 @@ struct mem_map *map_ptr; /* memory to remove */
|
|||
*mempr=*(mempr-1);
|
||||
}
|
||||
assert(memp < &mem_chunks[NR_MEMS-1]);
|
||||
(memp+1)->base = map_ptr[T].mem_phys + map_ptr[T].mem_len + map_ptr[S].mem_vir;
|
||||
|
||||
(memp+1)->base = progend;
|
||||
(memp+1)->size = memp->base + memp->size
|
||||
- (map_ptr[T].mem_phys + map_ptr[T].mem_len + map_ptr[S].mem_vir);
|
||||
- progend;
|
||||
memp->size = map_ptr[T].mem_phys - memp->base;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
/* special value for v in pt_allocmap */
|
||||
#define AM_AUTO ((u32_t) -1)
|
||||
|
||||
#define CLICK2ABS(v) ((v) << CLICK_SHIFT)
|
||||
#define ABS2CLICK(a) ((a) >> CLICK_SHIFT)
|
||||
|
||||
/* Compile in asserts and custom sanity checks at all? */
|
||||
#define SANITYCHECKS 0
|
||||
#define VMSTATS 0
|
||||
|
|
Loading…
Reference in a new issue