]> Zhao Yanbai Git Server - minix.git/commitdiff
ELF multiboot support
authorArun Thomas <arun@minix3.org>
Wed, 4 May 2011 16:51:43 +0000 (18:51 +0200)
committerArun Thomas <arun@minix3.org>
Wed, 4 May 2011 16:51:43 +0000 (18:51 +0200)
15 files changed:
common/include/minix/const.h
kernel/Makefile
kernel/arch/i386/arch_system.c
kernel/arch/i386/include/arch_proto.h
kernel/arch/i386/mpx.S
kernel/arch/i386/multiboot.S
kernel/arch/i386/multiboot.h
kernel/arch/i386/pre_init.c
kernel/main.c
kernel/table.c
kernel/type.h
servers/pm/exec.c
servers/pm/param.h
servers/vm/utility.c
servers/vm/vm.h

index 6e2958123ba65a805ecd9be7f3acd25149cd5dbc..892483172992214df2af34efd167d32c5b5514f0 100644 (file)
 #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. */
index 1df57137ef875f4efafaf8d941b271d98361ce2b..feb2978ac3311b07f58f51755b58b0bcb697d51b 100644 (file)
@@ -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}
index 146df926723185fa33486fa976e34818fc32fe85..ddd7278a921e2d5887a35560c0fdd67e11d1b764 100644 (file)
@@ -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();
index 89c57bc82d2efb4f33f9049ede459ec5bf40b58d..af605c6ed2e7ed0df0143eade6eb3084e542887e 100644 (file)
@@ -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;
index 65d8855b6602e312f17fa6a9910b4ae149d8fb6f..88fb81bb3576533afe11fa37bcbde64740f7cc64 100644 (file)
@@ -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
index 07c7d8099ae3a17563d2aae77f0c55cb46f1037d..5846a9ae210f5195d2f857de5a3313900c28174c 100644 (file)
        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
 
index 98e833a8ee99a875be808c315d466764139e3809..fa960e8613dc9949fdfe1fe91da0f61abd0cf12c 100644 (file)
@@ -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
 #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
 /* 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__ */
index feecf95c9165deb583718e5fbebbd9ba9524ce1e..2d0898a099a044ea8f82af1416443caa590d2742 100644 (file)
 #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)
 /* 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;
 }
index c9c5ea71136829246333ab9b46974c1cd2d9011f..9d58b41cebaf5d2a393b2013dc81ae5387f54b28 100644 (file)
@@ -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
index d65a9dc796b1deb2f3b355ec446179e6dd2afad9..7909eabdba11ed3b83bd3fc4124bbebdc53586d9 100644 (file)
  * 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.
index 61e79ef84db7df0fe9872c817ae3559ad5e86c1d..27aa46e2872480f1f30084fe3e83c95a70800d23 100644 (file)
@@ -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;    
index de58d4a0f34bfb9eceaa04b49244b4bf2b867472..c243188b8b104a614105f606cda80b2790bce6b2 100644 (file)
@@ -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);
 
index 1fc1ceec65504bb828c1287b046e3f1c1444d114..83024fa7ff720284490bc3d7e27b9fd72c4491d6 100644 (file)
@@ -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
index b25395bac9622f579ed0382ff19151788e1e8b5c..4dbaddb784b3ad67016e2b6001178e7cbe75e75c 100644 (file)
@@ -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;
index 99a068f673a930f6ed7c613c20c214c0d6d16bc8..85d218142ae4a03e27767e253e741e6bf68330ba 100644 (file)
@@ -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