From: Arun Thomas Date: Fri, 24 Jun 2011 15:20:25 +0000 (+0200) Subject: boot: Add multiboot support X-Git-Tag: v3.2.0~522 X-Git-Url: http://zhaoyanbai.com/repos/rndc.conf.html?a=commitdiff_plain;h=93ae43f57703c10f35a81cee7a5feb54779c5b75;p=minix.git boot: Add multiboot support Not yet fully spec-compliant; work in progress --- diff --git a/boot/boot/Makefile b/boot/boot/Makefile index c2432003d..8a4c53770 100644 --- a/boot/boot/Makefile +++ b/boot/boot/Makefile @@ -11,7 +11,10 @@ LIBDIR?= /usr/lib/i86 PROG= boot SRCS= boothead.s boot.c bootimage.c rawfs.c -.PATH: ${.CURDIR}/.. +# Need exec_elf.c from libexec +SRCS+= exec_elf.c +.PATH: ${.CURDIR}/.. ${MINIXSRCDIR}/lib/libexec + CPPFLAGS+= -I${MINIXSRCDIR} -I${.CURDIR} -I${.CURDIR}/.. DPADD+= ${LIBSYS} # for kprintf, kmalloc diff --git a/boot/boot/boot.c b/boot/boot/boot.c index 633703098..cec2f29bc 100644 --- a/boot/boot/boot.c +++ b/boot/boot/boot.c @@ -500,6 +500,9 @@ struct biosdev { int device, primary, secondary; } bootdev, tmpdev; +/* Device number in multiboot format */ +u32_t mbdev; + static int get_master(char *master, struct part_entry **table, u32_t pos) /* Read a master boot sector and its partition table. */ { @@ -1225,6 +1228,11 @@ dev_t name2dev(char *name) } } + mbdev = (u32_t)tmpdev.device << 24 + | (u32_t)tmpdev.primary << 16 + | (u32_t)tmpdev.secondary << 8 + | 0xff; + /* Look the name up on the boot device for the UNIX device number. */ if (fsok == -1) fsok= r_super(&block_size) != 0; if (fsok) { diff --git a/boot/boot/boothead.s b/boot/boot/boothead.s index 0c7a348f5..01e203067 100644 --- a/boot/boot/boothead.s +++ b/boot/boot/boothead.s @@ -35,6 +35,9 @@ ESC = 0x1B ! Escape character + MB_BOOT_MAGIC = 0x2BADB002 ! Multiboot BootLoader Magic + MULTIBOOT_STRUCT_ADDR = 0x9500 ! Multiboot Struct's Location + ! Imported variables and functions: .extern _caddr, _daddr, _runsize, _edata, _end ! Runtime environment .extern _device ! BIOS device number @@ -45,6 +48,7 @@ .extern _mem_entries ! Free memory E820 list entries .extern _cdbooted ! Whether we booted from CD .extern _cddevice ! Whether we booted from CD +.extern _do_multiboot ! Whether we are multibooting .text @@ -1157,22 +1161,26 @@ minix386: mov p_gdt_desc+2, ax movb p_gdt_desc+4, dl ! Set base of global descriptor table + cmp _do_multiboot, #1 + je set_monss + mov ax, 12(bp) mov dx, 14(bp) ! Kernel ds (absolute address) mov p_ds_desc+2, ax movb p_ds_desc+4, dl ! Set base of kernel data segment + mov ax, 8(bp) + mov dx, 10(bp) ! Kernel cs (absolute address) + mov p_cs_desc+2, ax + movb p_cs_desc+4, dl + +set_monss: mov dx, ss ! Monitor ss xor ax, ax ! dx:ax = Monitor stack segment call seg2abs ! Minix starts with the stack of the monitor mov p_ss_desc+2, ax movb p_ss_desc+4, dl - mov ax, 8(bp) - mov dx, 10(bp) ! Kernel cs (absolute address) - mov p_cs_desc+2, ax - movb p_cs_desc+4, dl - mov dx, cs ! Monitor cs xor ax, ax ! dx:ax = Monitor code segment call seg2abs @@ -1207,13 +1215,29 @@ noret386: push 6(bp) push 4(bp) ! 32 bit far address to kernel entry point + cmp _do_multiboot, #1 + je multiboot + + call real2prot ! Switch to protected mode + mov ax, #DS_SELECTOR ! Kernel data + mov ds, ax + mov ax, #ES_SELECTOR ! Flat 4 Gb + mov es, ax + + .data1 o32 ! Make a far call to the kernel + retf + +multiboot: call real2prot ! Switch to protected mode mov ax, #DS_SELECTOR ! Kernel data mov ds, ax mov ax, #ES_SELECTOR ! Flat 4 Gb mov es, ax - .data1 o32 ! Make a far call to the kernel - retf +! mov fs, ax +! mov gs, ax + mov bx, #MULTIBOOT_STRUCT_ADDR + .data1 o32 ! Make a far call to the kernel + retf ! Minix-86 returns here on a halt or reboot. ret86: diff --git a/boot/boot/bootimage.c b/boot/boot/bootimage.c index f2274176d..2ab16272e 100644 --- a/boot/boot/bootimage.c +++ b/boot/boot/bootimage.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,10 @@ #include "image.h" #include "boot.h" +#include +#include + + static int block_size = 0; static int verboseboot = VERBOSEBOOT_QUIET; @@ -40,6 +45,7 @@ extern int serial_line; extern u16_t vid_port; /* Video i/o port. */ extern u32_t vid_mem_base; /* Video memory base address. */ extern u32_t vid_mem_size; /* Video memory size. */ +extern u32_t mbdev; /* Device number in multiboot format */ #define click_shift clck_shft /* 7 char clash with click_size. */ @@ -82,9 +88,17 @@ int n_procs; /* Number of processes. */ #define P_SIZ_OFF 0 /* Process' sizes into kernel data. */ #define P_INIT_OFF 4 /* Init cs & sizes into fs data. */ +/* Where multiboot info struct goes in memory */ +#define MULTIBOOT_INFO_ADDR 0x9500 #define between(a, c, z) ((unsigned) ((c) - (a)) <= ((z) - (a))) +char *select_image(char *image); +size_t strspn(const char *string, const char *in); +char * strpbrk(register const char *string, register const char *brk); +char * strtok(register char *string, const char *separators); +char * strdup(const char *s1); + void pretty_image(const char *image) /* Pretty print the name of the image to load. Translate '/' and '_' to * space, first letter goes uppercase. An 'r' before a digit prints as @@ -141,6 +155,7 @@ unsigned click_shift; unsigned click_size; /* click_size = Smallest kernel memory object. */ unsigned k_flags; /* Not all kernels are created equal. */ u32_t reboot_code; /* Obsolete reboot code return pointer. */ +int do_multiboot; int params2params(char *params, size_t psize) /* Repackage the environment settings for the kernel. */ @@ -262,7 +277,7 @@ static u32_t proc_size(const struct image_header *hdr) return len >> SECTOR_SHIFT; } -off_t image_off, image_size; +off_t image_off, image_sectors, image_bytes; u32_t (*vir2sec)(u32_t vsec); /* Where is a sector on disk? */ u32_t file_vir2sec(u32_t vsec) @@ -379,7 +394,7 @@ int get_segment(u32_t *vsec, long *size, u32_t *addr, u32_t limit) cnt= SECTOR_SIZE; } if (*addr + click_size > limit) - { + { DEBUGEXTRA(("get_segment: out of memory; " "addr=0x%lx; limit=0x%lx; size=%lx\n", *addr, limit, size)); @@ -444,6 +459,256 @@ static void restore_screen(void) } } +int split_module_list(char *modules) +{ + int i; + char *c, *s; + + for (s= modules, i= 1; (c= strrchr(s, ' ')) != NULL; i++) { + *c = '\0'; + } + + return i; +} + +void exec_mb(char *kernel, char* modules) +/* Get a Minix image into core, patch it up and execute. */ +{ + int i; + static char hdr[SECTOR_SIZE]; + char *buf; + u32_t vsec, addr, limit, n, totalmem = 0; + u16_t kmagic, mode; + char *console; + char params[SECTOR_SIZE]; + extern char *sbrk(int); + char *verb; + u32_t text_vaddr, text_paddr, text_filebytes, text_membytes; + u32_t data_vaddr, data_paddr, data_filebytes, data_membytes; + u32_t pc; + u32_t text_offset, data_offset; + i32_t segsize; + int r; + u32_t cs, ds; + char *modstring, *mod; + multiboot_info_t *mbinfo; + multiboot_module_t *mbmodinfo; + u32_t mbinfo_size, mbmodinfo_size; + char *memvar; + memory *mp; + u32_t mod_cmdline_start, kernel_cmdline_start; + u32_t modstringlen; + int modnr; + + /* The stack is pretty deep here, so check if heap and stack collide. */ + (void) sbrk(0); + + if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil) + verboseboot = a2l(verb); + + printf("\nLoading %s\n", kernel); + + vsec= 0; /* Load this sector from kernel next. */ + addr= mem[0].base; /* Into this memory block. */ + limit= mem[0].base + mem[0].size; + if (limit > caddr) limit= caddr; + + /* set click size for get_segment */ + click_size = PAGE_SIZE; + + k_flags = K_KHIGH|K_BRET|K_MEML|K_INT86|K_RET|K_HDR + |K_HIGH|K_CHMEM|K_I386; + + /* big kernels must be loaded into extended memory */ + addr= mem[1].base; + limit= mem[1].base + mem[1].size; + + /* Get first sector */ + DEBUGEXTRA(("get_sector\n")); + if ((buf= get_sector(vsec++)) == nil) { + DEBUGEXTRA(("get_sector failed\n")); + return; + } + memcpy(hdr, buf, SECTOR_SIZE); + + /* Get ELF header */ + DEBUGEXTRA(("read_header_elf\n")); + r = read_header_elf(hdr, &text_vaddr, &text_paddr, + &text_filebytes, &text_membytes, + &data_vaddr, &data_paddr, + &data_filebytes, &data_membytes, + &pc, &text_offset, &data_offset); + if (r < 0) { errno= ENOEXEC; return; } + + /* Read the text segment. */ + addr = text_paddr; + segsize = (i32_t) text_filebytes; + vsec = text_offset / SECTOR_SIZE; + DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", + vsec, segsize, addr, limit)); + if (!get_segment(&vsec, &segsize, &addr, limit)) return; + DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " + "addr=0x%lx\n", + vsec, segsize, addr)); + + /* Read the data segment. */ + addr = data_paddr; + segsize = (i32_t) data_filebytes; + vsec = data_offset / SECTOR_SIZE; + + DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", + vsec, segsize, addr, limit)); + if (!get_segment(&vsec, &segsize, &addr, limit)) return; + DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " + "addr=0x%lx\n", + vsec, segsize, addr)); + + n = data_membytes - align(data_filebytes, click_size); + + /* Zero out bss. */ + DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit)); + if (addr + n > limit) { errno= ENOMEM; return; } + raw_clear(addr, n); + DEBUGEXTRA(("done\n")); + addr+= n; + + /* Check the kernel magic number. */ + raw_copy(mon2abs(&kmagic), + data_paddr + MAGIC_OFF, sizeof(kmagic)); + if (kmagic != KERNEL_D_MAGIC) { + printf("Kernel magic number is incorrect (0x%x@0x%lx)\n", + kmagic, data_paddr + MAGIC_OFF); + errno= 0; + return; + } + + /* Translate the boot parameters to what Minix likes best. */ + DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params))); + if (!params2params(params, sizeof(params))) { errno= 0; return; } + DEBUGEXTRA(("done\n")); + + /* Create multiboot info struct */ + mbinfo = malloc(sizeof(multiboot_info_t)); + if (mbinfo == nil) { errno= ENOMEM; return; } + memset(mbinfo, 0, sizeof(multiboot_info_t)); + + /* Module info structs start where kernel ends */ + mbinfo->mods_addr = addr; + + modstring = strdup(modules); + if (modstring == nil) {errno = ENOMEM; return; } + modstringlen = strlen(modules); + mbinfo->mods_count = split_module_list(modules); + + mbmodinfo_size = sizeof(multiboot_module_t) * mbinfo->mods_count; + mbmodinfo = malloc(mbmodinfo_size); + if (mbmodinfo == nil) { errno= ENOMEM; return; } + addr+= mbmodinfo_size; + addr= align(addr, click_size); + + mod_cmdline_start = mbinfo->mods_addr + sizeof(multiboot_module_t) * + mbinfo->mods_count; + + raw_copy(mod_cmdline_start, mon2abs(modules), + modstringlen+1); + + mbmodinfo[0].cmdline = mod_cmdline_start; + modnr = 1; + for (i= 0; i < modstringlen; ++i) { + if (modules[i] == '\0') { + mbmodinfo[modnr].cmdline = mod_cmdline_start + i + 1; + ++modnr; + } + } + + kernel_cmdline_start = mod_cmdline_start + modstringlen + 1; + mbinfo->cmdline = kernel_cmdline_start; + raw_copy(kernel_cmdline_start, mon2abs(kernel), + strlen(kernel)+1); + + mbinfo->flags = MULTIBOOT_INFO_MODS|MULTIBOOT_INFO_CMDLINE| + MULTIBOOT_INFO_BOOTDEV|MULTIBOOT_INFO_MEMORY; + + mbinfo->boot_device = mbdev; + mbinfo->mem_lower = mem[0].size/1024; + mbinfo->mem_upper = mem[1].size/1024; + + for (i = 0, mod = strtok(modstring, " "); mod != nil; + mod = strtok(nil, " "), i++) { + + mod = select_image(mod); + if (mod == nil) {errno = 0; return; } + + mbmodinfo[i].mod_start = addr; + mbmodinfo[i].mod_end = addr + image_bytes; + mbmodinfo[i].pad = 0; + + segsize= image_bytes; + vsec= 0; + DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", + vsec, segsize, addr, limit)); + if (!get_segment(&vsec, &segsize, &addr, limit)) return; + DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " + "addr=0x%lx\n", + vsec, segsize, addr)); + addr+= segsize; + addr= align(addr, click_size); + } + free(modstring); + + DEBUGEXTRA(("modinfo raw_copy: dst 0x%lx src 0x%lx sz 0x%lx\n", + mbinfo->mods_addr, mon2abs(mbmodinfo), + mbmodinfo_size)); + raw_copy(mbinfo->mods_addr, mon2abs(mbmodinfo), + mbmodinfo_size); + free(mbmodinfo); + + raw_copy(MULTIBOOT_INFO_ADDR, mon2abs(mbinfo), + sizeof(multiboot_info_t)); + free(mbinfo); + + /* Run the trailer function just before starting Minix. */ + DEBUGEXTRA(("run_trailer()... ")); + if (!run_trailer()) { errno= 0; return; } + DEBUGEXTRA(("done\n")); + + /* Set the video to the required mode. */ + if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) { + mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE : + MONO_MODE; + } + DEBUGEXTRA(("set_mode(%d)... ", mode)); + set_mode(mode); + DEBUGEXTRA(("done\n")); + + /* Close the disk. */ + DEBUGEXTRA(("dev_close()... ")); + (void) dev_close(); + DEBUGEXTRA(("done\n")); + + /* Minix. */ + cs = ds = text_paddr; + DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n", + pc, cs, ds, params, sizeof(params), 0)); + minix(pc, cs, ds, params, sizeof(params), 0); + + if (!(k_flags & K_BRET)) { + extern u32_t reboot_code; + raw_copy(mon2abs(params), reboot_code, sizeof(params)); + } + parse_code(params); + + /* Return from Minix. Things may have changed, so assume nothing. */ + fsok= -1; + errno= 0; + + /* Read leftover character, if any. */ + scan_keyboard(); + + /* Restore screen contents. */ + restore_screen(); +} + void exec_image(char *image) /* Get a Minix image into core, patch it up and execute. */ { @@ -483,7 +748,7 @@ void exec_image(char *image) raw_clear(aout, PROCESS_MAX * A_MINHDR); /* Read the many different processes: */ - for (i= 0; vsec < image_size; i++) { + for (i= 0; vsec < image_sectors; i++) { u32_t startaddr; startaddr = addr; if (i == PROCESS_MAX) { @@ -778,7 +1043,7 @@ char *select_image(char *image) && numeric(size)) { vir2sec= flat_vir2sec; image_off= a2l(image); - image_size= a2l(size); + image_sectors= a2l(size); strcpy(image, "Minix"); return image; } @@ -790,6 +1055,8 @@ char *select_image(char *image) } r_stat(image_ino, &st); + image_bytes = st.st_size; + if (!S_ISREG(st.st_mode)) { char *version= image + strlen(image); char dots[NAME_MAX + 1]; @@ -809,7 +1076,7 @@ char *select_image(char *image) r_stat(image_ino, &st); } vir2sec= file_vir2sec; - image_size= (st.st_size + SECTOR_SIZE - 1) >> SECTOR_SHIFT; + image_sectors= (st.st_size + SECTOR_SIZE - 1) >> SECTOR_SHIFT; return image; bail_out: free(image); @@ -822,8 +1089,25 @@ void bootminix(void) */ { char *image; + char *mb; + char *kernel; + /* FIXME: modules should come from environment */ + char modules[] = "boot/ds boot/rs boot/pm boot/sched boot/vfs boot/memory boot/log boot/tty boot/mfs boot/vm boot/pfs boot/init"; + + if ((mb = b_value("mb")) != nil) { + do_multiboot = a2l(mb); + kernel = b_value("kernel"); + if (kernel == nil) { + printf("kernel not set\n"); + return; + } + } - if ((image= select_image(b_value("image"))) == nil) return; + if (do_multiboot) { + if ((kernel= select_image(b_value("kernel"))) == nil) return; + } else { + if ((image= select_image(b_value("image"))) == nil) return; + } if(serial_line >= 0) { char linename[2]; @@ -832,26 +1116,105 @@ void bootminix(void) b_setvar(E_VAR, SERVARNAME, linename); } - exec_image(image); + if (do_multiboot) + exec_mb(kernel, modules); + else + exec_image(image); switch (errno) { case ENOEXEC: - printf("%s contains a bad program header\n", image); + printf("%s contains a bad program header\n", + do_multiboot ? kernel : image); break; case ENOMEM: - printf("Not enough memory to load %s\n", image); + printf("Not enough memory to load %s\n", + do_multiboot ? kernel : image); break; case EIO: - printf("Unexpected EOF on %s\n", image); + printf("Unexpected EOF on %s\n", + do_multiboot ? kernel : image); case 0: /* No error or error already reported. */; } - free(image); + + if (do_multiboot) + free(kernel); + else + free(image); if(serial_line >= 0) b_unset(SERVARNAME); } +size_t +strspn(const char *string, const char *in) +{ + register const char *s1, *s2; + + for (s1 = string; *s1; s1++) { + for (s2 = in; *s2 && *s2 != *s1; s2++) + /* EMPTY */ ; + if (*s2 == '\0') + break; + } + return s1 - string; +} + +char * +strpbrk(register const char *string, register const char *brk) +{ + register const char *s1; + + while (*string) { + for (s1 = brk; *s1 && *s1 != *string; s1++) + /* EMPTY */ ; + if (*s1) + return (char *)string; + string++; + } + return (char *)NULL; +} + +char * +strtok(register char *string, const char *separators) +{ + register char *s1, *s2; + static char *savestring = NULL; + + if (string == NULL) { + string = savestring; + if (string == NULL) return (char *)NULL; + } + + s1 = string + strspn(string, separators); + if (*s1 == '\0') { + savestring = NULL; + return (char *)NULL; + } + + s2 = strpbrk(s1, separators); + if (s2 != NULL) + *s2++ = '\0'; + savestring = s2; + return s1; +} + +char * +strdup(const char *s1) +{ + size_t len; + char *s2; + + len= strlen(s1)+1; + + s2= malloc(len); + if (s2 == NULL) + return NULL; + strcpy(s2, s1); + + return s2; +} + /* * $PchId: bootimage.c,v 1.10 2002/02/27 19:39:09 philip Exp $ */ diff --git a/commands/mkimage/Makefile b/commands/mkimage/Makefile new file mode 100644 index 000000000..4ef271bc6 --- /dev/null +++ b/commands/mkimage/Makefile @@ -0,0 +1,13 @@ + +NBSD_LIBC:= yes + +PROG= mkimage +SRCS= mkimage.c +MAN= + +CPPFLAGS+= -D_NETBSD_SOURCE + +DPADD+= ${LIBELF} +LDADD+= -lelf + +.include diff --git a/commands/mkimage/mkimage.c b/commands/mkimage/mkimage.c new file mode 100644 index 000000000..f89d561c8 --- /dev/null +++ b/commands/mkimage/mkimage.c @@ -0,0 +1,120 @@ +/* + * Update physical addresses of boot services + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define BOOTPROG_LOAD_START 0x05000000ULL + +int nflag = 0; + +int stack_kbytes[] = { + /* ds rs pm sched vfs memory log tty mfs vm pfs init */ + 16, 8125, 32, 32, 16, 8, 32, 16, 128, 128, 128, 64 +}; + +static void usage(void); + +GElf_Addr +update_paddr(int nr, char *fname, GElf_Addr startaddr) +{ + int i, fd; + Elf *e; + size_t n; + + GElf_Phdr phdr; + GElf_Addr endaddr = 0; + + if ((fd = open(fname, O_RDWR, 0)) < 0) + err(EX_NOINPUT, "open \"%s\" failed", fname); + + if ((e = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) + errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1)); + + if (elf_kind(e) != ELF_K_ELF) + errx(EX_DATAERR, "\"%s\" is not an ELF object.", fname); + + if (elf_getphdrnum(e, &n) != 0) + errx(EX_DATAERR, "elf_getphdrnum() failed: %s.", elf_errmsg(-1)); + + for (i = 0; i < n; i++) { + if (gelf_getphdr(e, i, &phdr) != &phdr) + errx(EX_SOFTWARE, "getphdr() failed: %s.", + elf_errmsg(-1)); + + if (phdr.p_type == PT_LOAD) { + phdr.p_paddr = startaddr + phdr.p_vaddr; + + endaddr = round_page(phdr.p_paddr + phdr.p_memsz) + + round_page(stack_kbytes[nr] * 1024); + + if (gelf_update_phdr(e, i, &phdr) < 0) + errx(EX_SOFTWARE, + "gelf_update_phdr failed: %s.", + elf_errmsg(-1)); + } + + } + + if (elf_update(e, ELF_C_WRITE) < 0) + errx(EX_SOFTWARE, "elf_update failed: %s.", elf_errmsg(-1)); + + (void) elf_end(e); + (void) close(fd); + + return endaddr; + +} + +int +main(int argc, char **argv) +{ + int i, ch; + GElf_Addr startaddr, endaddr; + + startaddr = BOOTPROG_LOAD_START; + + while ((ch = getopt(argc, argv, "n")) != -1) { + switch (ch) { + case 'n': + nflag = 1; + break; + case '?': + default: + usage(); + exit(EX_USAGE); + } + } + argc -= optind; + argv += optind; + + if (argc < 1) + usage(); + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EX_SOFTWARE, "ELF library intialization failed: %s", + elf_errmsg(-1)); + + startaddr = BOOTPROG_LOAD_START; + for (i = 0; i < argc; i++) { + startaddr = update_paddr(i, argv[i], startaddr); + } + + exit(EX_OK); +} + +static void +usage(void) +{ + (void) fprintf(stderr, "usage: %s [-n] elf1 elf2...\n", getprogname()); +} diff --git a/drivers/log/Makefile b/drivers/log/Makefile index 57eb44376..bab063bcf 100644 --- a/drivers/log/Makefile +++ b/drivers/log/Makefile @@ -10,4 +10,4 @@ MAN= BINDIR?= /usr/sbin INSTALLFLAGS+= -S 32k -.include +.include diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index 7372f6514..4357ec74c 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -1,6 +1,4 @@ # Makefile for memory driver (MEMORY) -.include - PROG= memory SRCS= memory.c imgrd.c @@ -20,4 +18,4 @@ imgrd.d: touch-genfiles touch-genfiles: [ -e ${.CURDIR}/../ramdisk/image.c ] || touch -t 197001010000.00 ${.CURDIR}/../ramdisk/image.c -.include +.include diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index f4676b9de..aaf1b8977 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -1,7 +1,5 @@ # Makefile for terminal driver (TTY) -.include - PROG= tty SRCS= tty.c console.c keyboard.c pty.c rs232.c @@ -18,5 +16,5 @@ SUBDIR= keymaps # Needs kernel/const.h, etc CPPFLAGS+= -I${MINIXSRCDIR} -.include +.include .include diff --git a/include/arch/i386/Makefile b/include/arch/i386/Makefile index a5d660cfe..5637c78b0 100644 --- a/include/arch/i386/Makefile +++ b/include/arch/i386/Makefile @@ -1,6 +1,6 @@ INCSDIR= /usr/include/i386 -INCS+= _align.h asm.h mcontext.h param.h +INCS+= _align.h asm.h mcontext.h multiboot.h param.h .include "../../../common/include/arch/i386/Makefile.inc" diff --git a/kernel/arch/i386/multiboot.h b/include/arch/i386/multiboot.h similarity index 99% rename from kernel/arch/i386/multiboot.h rename to include/arch/i386/multiboot.h index fa960e861..df2bafa37 100644 --- a/kernel/arch/i386/multiboot.h +++ b/include/arch/i386/multiboot.h @@ -15,7 +15,7 @@ #define MULTIBOOT_AOUT_KLUDGE 0x00010000 #define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN) - + /* consts used for Multiboot pre-init */ #define MULTIBOOT_VIDEO_MODE_EGA 1 diff --git a/kernel/arch/i386/arch_system.c b/kernel/arch/i386/arch_system.c index 1cb68c52b..2c32b82c6 100644 --- a/kernel/arch/i386/arch_system.c +++ b/kernel/arch/i386/arch_system.c @@ -25,7 +25,7 @@ #include "oxpcie.h" #include "kernel/proc.h" #include "kernel/debug.h" -#include "multiboot.h" +#include #include "glo.h" diff --git a/kernel/arch/i386/kernel_elf.lds b/kernel/arch/i386/kernel_elf.lds new file mode 100644 index 000000000..2e290f383 --- /dev/null +++ b/kernel/arch/i386/kernel_elf.lds @@ -0,0 +1,43 @@ +OUTPUT_ARCH("i386") +ENTRY(MINIX) +SECTIONS +{ + . = 0x200000 + SIZEOF_HEADERS; + .text . : AT (ADDR(.text) - 0x0000) { + *(.text) + *(.text.*) + . = ALIGN(4096); + } + _etext = .; + etext = .; + + .data . : AT (ADDR(.data) - 0x0000) { + _rodata = .; + /* kernel data starts with this magic number */ + SHORT(0x526f); + *(.rodata) + *(.rodata.*) + _erodata = .; + *(.data) + *(.data.*) + . = ALIGN(4096); + } + _edata = .; + + .bss . : AT (ADDR(.bss) - 0x0000) { + *(.bss) + *(.bss.*) + *(COMMON) + } + _end = .; + end = .; + + /DISCARD/ : + { + *(.eh_frame) + *(.comment) + *(.comment.*) + *(.note) + *(.note.*) + } +} diff --git a/kernel/arch/i386/klib.S b/kernel/arch/i386/klib.S index c60046c64..561c7e5ea 100644 --- a/kernel/arch/i386/klib.S +++ b/kernel/arch/i386/klib.S @@ -9,7 +9,7 @@ #include "archconst.h" #include "kernel/const.h" #include "sconst.h" -#include "multiboot.h" +#include /* * This file contains a number of assembly code utility routines needed by the diff --git a/kernel/arch/i386/klib16.S b/kernel/arch/i386/klib16.S index 5cdad83af..36a0683cc 100644 --- a/kernel/arch/i386/klib16.S +++ b/kernel/arch/i386/klib16.S @@ -8,7 +8,7 @@ #include "archconst.h" #include "kernel/const.h" #include "sconst.h" -#include "multiboot.h" +#include /* * This file contains a number of 16-bit assembly code utility routines needed by the diff --git a/kernel/arch/i386/mpx.S b/kernel/arch/i386/mpx.S index 88fb81bb3..deab7175b 100644 --- a/kernel/arch/i386/mpx.S +++ b/kernel/arch/i386/mpx.S @@ -53,7 +53,7 @@ begbss: #include "kernel/const.h" #include "kernel/proc.h" #include "sconst.h" -#include "multiboot.h" +#include #include "arch_proto.h" /* K_STACK_SIZE */ @@ -84,9 +84,7 @@ 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) + jmp _C_LABEL(multiboot_init) #endif jmp over_flags /* skip over the next few bytes */ diff --git a/kernel/arch/i386/multiboot.S b/kernel/arch/i386/multiboot.S index 5846a9ae2..4fdd0973a 100644 --- a/kernel/arch/i386/multiboot.S +++ b/kernel/arch/i386/multiboot.S @@ -8,7 +8,7 @@ #include "kernel/const.h" #include "kernel/proc.h" #include "sconst.h" -#include "multiboot.h" +#include #define GDT_SET_ENTRY(selector, base, limit) \ mov %ebp, %edi; \ @@ -44,6 +44,8 @@ reload_cs: mov %eax, %ds mov %eax, %ss mov %eax, %es + mov %eax, %fs + mov %eax, %gs mov $(multiboot_stack + MULTIBOOT_STACK_SIZE), %esp diff --git a/kernel/arch/i386/pre_init.c b/kernel/arch/i386/pre_init.c index 5746c5c4f..f84ce23e9 100644 --- a/kernel/arch/i386/pre_init.c +++ b/kernel/arch/i386/pre_init.c @@ -17,7 +17,7 @@ #include "string.h" #include "arch_proto.h" #include "libexec.h" -#include "multiboot.h" +#include #define MULTIBOOT_VERBOSE 1 @@ -279,10 +279,6 @@ PRIVATE void get_parameters(multiboot_info_t *mbi) mb_set_param("memory", mem_value); } - /* FIXME: this is dummy value, - * we can't get real image file name from multiboot */ - mb_set_param("image", "boot/image_latest"); - if (mbi->flags&MULTIBOOT_INFO_CMDLINE) { /* Override values with cmdline argument */ p = mb_cmd_buff; @@ -353,11 +349,9 @@ PRIVATE void mb_extract_image(multiboot_info_t mbi) 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_hex(trunc_page(data_paddr) + data_membytes); 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); diff --git a/lib/libexec/exec_elf.c b/lib/libexec/exec_elf.c index 25d67e1f2..03e3dc8eb 100644 --- a/lib/libexec/exec_elf.c +++ b/lib/libexec/exec_elf.c @@ -14,6 +14,8 @@ /* Support only 32-bit ELF objects */ #define __ELF_WORD_SIZE 32 +#define SECTOR_SIZE 512 + static int __elfN(check_header)(const Elf_Ehdr *hdr); int read_header_elf( @@ -36,8 +38,6 @@ int read_header_elf( unsigned long seg_filebytes, seg_membytes; int i = 0; - assert(exec_hdr != NULL); - *text_vaddr = *text_paddr = 0; *text_filebytes = *text_membytes = 0; *data_vaddr = *data_paddr = 0; @@ -50,8 +50,8 @@ int read_header_elf( return ENOEXEC; } - if ((hdr->e_phoff > PAGE_SIZE) || - (hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE) { + if ((hdr->e_phoff > SECTOR_SIZE) || + (hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > SECTOR_SIZE) { return ENOEXEC; } @@ -60,21 +60,21 @@ int read_header_elf( #ifdef __NBSD_LIBC rounddown((uintptr_t)phdr, sizeof(Elf_Addr)) != (uintptr_t)phdr #else - !_minix_aligned(phdr, Elf_Addr) + !_minix_aligned(hdr->e_phoff, Elf_Addr) #endif ) { return ENOEXEC; } #if ELF_DEBUG - printf("Program header file offset (phoff): %d\n", hdr->e_phoff); - printf("Section header file offset (shoff): %d\n", hdr->e_shoff); + printf("Program header file offset (phoff): %ld\n", hdr->e_phoff); + printf("Section header file offset (shoff): %ld\n", hdr->e_shoff); printf("Program header entry size (phentsize): %d\n", hdr->e_phentsize); printf("Program header entry num (phnum): %d\n", hdr->e_phnum); printf("Section header entry size (shentsize): %d\n", hdr->e_shentsize); printf("Section header entry num (shnum): %d\n", hdr->e_shnum); printf("Section name strings index (shstrndx): %d\n", hdr->e_shstrndx); - printf("Entry Point: 0x%x\n", hdr->e_entry); + printf("Entry Point: 0x%lx\n", hdr->e_entry); #endif for (i = 0; i < hdr->e_phnum; i++) { @@ -108,18 +108,17 @@ int read_header_elf( } #if ELF_DEBUG - printf("Text vaddr: 0x%x\n", *text_vaddr); - printf("Text paddr: 0x%x\n", *text_paddr); - printf("Text filebytes: 0x%x\n", *text_filebytes); - printf("Text membytes: 0x%x\n", *text_membytes); - printf("Data vaddr: 0x%x\n", *data_vaddr); - printf("Data paddr: 0x%x\n", *data_paddr); - printf("Data filebyte: 0x%x\n", *data_filebytes); - printf("Data membytes: 0x%x\n", *data_membytes); - printf("Tot bytes: 0x%x\n", *tot_bytes); - printf("PC: 0x%x\n", *pc); - printf("Text offset: 0x%x\n", *text_offset); - printf("Data offset: 0x%x\n", *data_offset); + printf("Text vaddr: 0x%lx\n", *text_vaddr); + printf("Text paddr: 0x%lx\n", *text_paddr); + printf("Text filebytes: 0x%lx\n", *text_filebytes); + printf("Text membytes: 0x%lx\n", *text_membytes); + printf("Data vaddr: 0x%lx\n", *data_vaddr); + printf("Data paddr: 0x%lx\n", *data_paddr); + printf("Data filebyte: 0x%lx\n", *data_filebytes); + printf("Data membytes: 0x%lx\n", *data_membytes); + printf("PC: 0x%lx\n", *pc); + printf("Text offset: 0x%lx\n", *text_offset); + printf("Data offset: 0x%lx\n", *data_offset); #endif return OK; diff --git a/servers/ds/Makefile b/servers/ds/Makefile index fde1c87cb..f59486e5a 100644 --- a/servers/ds/Makefile +++ b/servers/ds/Makefile @@ -10,4 +10,4 @@ MAN= BINDIR?= /usr/sbin INSTALLFLAGS+= -S 16k -.include +.include diff --git a/servers/init/Makefile b/servers/init/Makefile index 66cee87c3..f48e32e3a 100644 --- a/servers/init/Makefile +++ b/servers/init/Makefile @@ -7,4 +7,4 @@ MAN= BINDIR?= /usr/sbin INSTALLFLAGS+= -S 64k -.include +.include diff --git a/servers/mfs/Makefile b/servers/mfs/Makefile index 88bc62ac2..e893c37b5 100644 --- a/servers/mfs/Makefile +++ b/servers/mfs/Makefile @@ -16,4 +16,4 @@ INSTALLFLAGS+= -S 128k DEFAULT_NR_BUFS= 1024 CPPFLAGS+= -DDEFAULT_NR_BUFS=${DEFAULT_NR_BUFS} -.include +.include diff --git a/servers/pfs/Makefile b/servers/pfs/Makefile index c36260425..ac3312ba5 100644 --- a/servers/pfs/Makefile +++ b/servers/pfs/Makefile @@ -12,4 +12,4 @@ MAN= BINDIR?= /usr/sbin INSTALLFLAGS+= -S 128k -.include +.include diff --git a/servers/pm/Makefile b/servers/pm/Makefile index c1acafd78..43f53c976 100644 --- a/servers/pm/Makefile +++ b/servers/pm/Makefile @@ -17,4 +17,4 @@ CPPFLAGS.misc.c+= -I${MINIXSRCDIR} CPPFLAGS.schedule.c+= -I${MINIXSRCDIR} CPPFLAGS.utility.c+= -I${MINIXSRCDIR} -.include +.include diff --git a/servers/rs/Makefile b/servers/rs/Makefile index 6c86ba22f..6a2e28374 100644 --- a/servers/rs/Makefile +++ b/servers/rs/Makefile @@ -1,6 +1,4 @@ # Makefile for Reincarnation Server (RS) -.include - PROG= rs SRCS= exec.c main.c request.c manager.c table.c utility.c memory.c error.c @@ -14,4 +12,4 @@ INSTALLFLAGS+= -S 8125k CPPFLAGS+= -I${MINIXSRCDIR} -.include +.include diff --git a/servers/sched/Makefile b/servers/sched/Makefile index da3b08115..7d7afc980 100644 --- a/servers/sched/Makefile +++ b/servers/sched/Makefile @@ -14,4 +14,4 @@ CPPFLAGS.main.c+= -I${MINIXSRCDIR} CPPFLAGS.schedule.c+= -I${MINIXSRCDIR} CPPFLAGS.utility.c+= -I${MINIXSRCDIR} -.include +.include diff --git a/servers/vfs/Makefile b/servers/vfs/Makefile index 9989d9a8e..dfe9d197d 100644 --- a/servers/vfs/Makefile +++ b/servers/vfs/Makefile @@ -14,4 +14,4 @@ MAN= BINDIR?= /usr/sbin INSTALLFLAGS+= -S 16k -.include +.include diff --git a/servers/vm/Makefile b/servers/vm/Makefile index ca6ef54d6..f17b3929e 100644 --- a/servers/vm/Makefile +++ b/servers/vm/Makefile @@ -18,4 +18,4 @@ CPPFLAGS+= -I${.CURDIR} -I${.CURDIR}/arch/${ARCH} CPPFLAGS+= -I${MINIXSRCDIR} .include "arch/${ARCH}/Makefile.inc" -.include +.include diff --git a/share/mk/Makefile b/share/mk/Makefile index 36de72ec8..740bc5ba0 100644 --- a/share/mk/Makefile +++ b/share/mk/Makefile @@ -10,6 +10,9 @@ FILES= bsd.ack.mk bsd.dep.mk bsd.files.mk \ bsd.prog.mk bsd.subdir.mk bsd.sys.mk bsd.gcov.mk \ sys.mk +# MINIX-specific files +FILES+= minix.bootprog.mk + FILESDIR=/usr/share/mk .endif diff --git a/share/mk/minix.bootprog.mk b/share/mk/minix.bootprog.mk new file mode 100644 index 000000000..01a8001ff --- /dev/null +++ b/share/mk/minix.bootprog.mk @@ -0,0 +1,8 @@ +# MINIX-specific boot program options +.include + +.if ${OBJECT_FMT} == "ELF" +LDFLAGS+= -Wl,--section-start=.init=0x0 +.endif + +.include diff --git a/tools/Makefile b/tools/Makefile index 11c812220..6c496e9a0 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -2,12 +2,15 @@ .include .include "nbsd.config" +.include + u=/usr MDEC= /usr/mdec GEN_FILES= *.bak image kernel *.iso *.iso.gz cdfdimage rootimage src # Specify the programs that are part of the system image. -PROGRAMS= kernel \ +KERNEL= kernel +PROGRAMS= \ ../servers/ds/ds \ ../servers/rs/rs \ ../servers/pm/pm \ @@ -56,15 +59,17 @@ PAD_KERNEL_TEXT := cp ../kernel/kernel kernel PAD_KERNEL_TEXT := padtext ../kernel/kernel kernel .endif -# for fast complie kernel and generate image, skip servers and drivers -image_mb: includes - cd ../kernel && $(MAKE) +.if ${OBJECT_FMT} == "ELF" +image: includes services ${PAD_KERNEL_TEXT} - installboot -image $@ $(PROGRAMS) - + mkimage $(PROGRAMS) + cp ${KERNEL} ${PROGRAMS} /boot + strip ${KERNEL:T:S/^/\/boot\//} ${PROGRAMS:T:S/^/\/boot\//} +.else image: includes services ${PAD_KERNEL_TEXT} - installboot -image $@ $(PROGRAMS) + installboot -image $@ $(KERNEL) $(PROGRAMS) +.endif # rebuild the program or system libraries includes: @@ -94,9 +99,13 @@ libraries: includes bootable: exec su root mkboot bootable +.if ${OBJECT_FMT} == "ELF" +hdboot: image +.else hdboot: image exec sh mkboot $@ @sync +.endif fdboot: image exec su root mkboot $@