From: Arun Thomas Date: Wed, 4 May 2011 16:51:43 +0000 (+0200) Subject: ELF multiboot support X-Git-Tag: v3.2.0~564 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/man.rndc-confgen.html?a=commitdiff_plain;h=350b60661a48a596332ad0c202255d77aab627b1;p=minix.git ELF multiboot support --- diff --git a/common/include/minix/const.h b/common/include/minix/const.h index 6e2958123..892483172 100644 --- a/common/include/minix/const.h +++ b/common/include/minix/const.h @@ -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. */ diff --git a/kernel/Makefile b/kernel/Makefile index 1df57137e..feb2978ac 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -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} diff --git a/kernel/arch/i386/arch_system.c b/kernel/arch/i386/arch_system.c index 146df9267..ddd7278a9 100644 --- a/kernel/arch/i386/arch_system.c +++ b/kernel/arch/i386/arch_system.c @@ -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(); diff --git a/kernel/arch/i386/include/arch_proto.h b/kernel/arch/i386/include/arch_proto.h index 89c57bc82..af605c6ed 100644 --- a/kernel/arch/i386/include/arch_proto.h +++ b/kernel/arch/i386/include/arch_proto.h @@ -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; diff --git a/kernel/arch/i386/mpx.S b/kernel/arch/i386/mpx.S index 65d8855b6..88fb81bb3 100644 --- a/kernel/arch/i386/mpx.S +++ b/kernel/arch/i386/mpx.S @@ -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 diff --git a/kernel/arch/i386/multiboot.S b/kernel/arch/i386/multiboot.S index 07c7d8099..5846a9ae2 100644 --- a/kernel/arch/i386/multiboot.S +++ b/kernel/arch/i386/multiboot.S @@ -26,58 +26,19 @@ and $0xf, %ax; \ andb $0xf0, 6(%edi); \ or %ax, 6(%edi); \ - + 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: mov $DS_SELECTOR, %eax mov %eax, %ds @@ -90,24 +51,19 @@ reload_cs: call _C_LABEL(pre_init) add $4, %esp - + /* return to old boot code of kernel */ push %eax push $MULTIBOOT_PARAM_BUF_SIZE push $_C_LABEL(multiboot_param_buf) push $0 - + mov $ES_SELECTOR, %eax mov %eax, %es - + 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 diff --git a/kernel/arch/i386/multiboot.h b/kernel/arch/i386/multiboot.h index 98e833a8e..fa960e861 100644 --- a/kernel/arch/i386/multiboot.h +++ b/kernel/arch/i386/multiboot.h @@ -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 @@ -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__ */ diff --git a/kernel/arch/i386/pre_init.c b/kernel/arch/i386/pre_init.c index feecf95c9..2d0898a09 100644 --- a/kernel/arch/i386/pre_init.c +++ b/kernel/arch/i386/pre_init.c @@ -11,13 +11,19 @@ #include #include #include -#include +#include #include #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; - } + dev += 0x80 + + (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; - } + + /* FIXME: use faster function */ + for (i = start; i < end; i++) + phys_copy((phys_bytes)&empty, i, 1); + + return 0; +} + +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; } - 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); + +#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 u32_t pre_init(u32_t ebx) +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; } diff --git a/kernel/main.c b/kernel/main.c index c9c5ea711..9d58b41ce 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -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 diff --git a/kernel/table.c b/kernel/table.c index d65a9dc79..7909eabdb 100644 --- a/kernel/table.c +++ b/kernel/table.c @@ -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. diff --git a/kernel/type.h b/kernel/type.h index 61e79ef84..27aa46e28 100644 --- a/kernel/type.h +++ b/kernel/type.h @@ -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; diff --git a/servers/pm/exec.c b/servers/pm/exec.c index de58d4a0f..c243188b8 100644 --- a/servers/pm/exec.c +++ b/servers/pm/exec.c @@ -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); diff --git a/servers/pm/param.h b/servers/pm/param.h index 1fc1ceec6..83024fa7f 100644 --- a/servers/pm/param.h +++ b/servers/pm/param.h @@ -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 diff --git a/servers/vm/utility.c b/servers/vm/utility.c index b25395bac..4dbaddb78 100644 --- a/servers/vm/utility.c +++ b/servers/vm/utility.c @@ -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)->size = memp->base + memp->size - - (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 + - progend; memp->size = map_ptr[T].mem_phys - memp->base; } break; diff --git a/servers/vm/vm.h b/servers/vm/vm.h index 99a068f67..85d218142 100644 --- a/servers/vm/vm.h +++ b/servers/vm/vm.h @@ -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