boot: Add multiboot support
Not yet fully spec-compliant; work in progress
This commit is contained in:
parent
e785381d4d
commit
93ae43f577
31 changed files with 663 additions and 82 deletions
|
@ -11,7 +11,10 @@ LIBDIR?= /usr/lib/i86
|
||||||
PROG= boot
|
PROG= boot
|
||||||
|
|
||||||
SRCS= boothead.s boot.c bootimage.c rawfs.c
|
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}/..
|
CPPFLAGS+= -I${MINIXSRCDIR} -I${.CURDIR} -I${.CURDIR}/..
|
||||||
|
|
||||||
DPADD+= ${LIBSYS} # for kprintf, kmalloc
|
DPADD+= ${LIBSYS} # for kprintf, kmalloc
|
||||||
|
|
|
@ -500,6 +500,9 @@ struct biosdev {
|
||||||
int device, primary, secondary;
|
int device, primary, secondary;
|
||||||
} bootdev, tmpdev;
|
} bootdev, tmpdev;
|
||||||
|
|
||||||
|
/* Device number in multiboot format <drive, part1, part2, part3> */
|
||||||
|
u32_t mbdev;
|
||||||
|
|
||||||
static int get_master(char *master, struct part_entry **table, u32_t pos)
|
static int get_master(char *master, struct part_entry **table, u32_t pos)
|
||||||
/* Read a master boot sector and its partition table. */
|
/* 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. */
|
/* Look the name up on the boot device for the UNIX device number. */
|
||||||
if (fsok == -1) fsok= r_super(&block_size) != 0;
|
if (fsok == -1) fsok= r_super(&block_size) != 0;
|
||||||
if (fsok) {
|
if (fsok) {
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
|
|
||||||
ESC = 0x1B ! Escape character
|
ESC = 0x1B ! Escape character
|
||||||
|
|
||||||
|
MB_BOOT_MAGIC = 0x2BADB002 ! Multiboot BootLoader Magic
|
||||||
|
MULTIBOOT_STRUCT_ADDR = 0x9500 ! Multiboot Struct's Location
|
||||||
|
|
||||||
! Imported variables and functions:
|
! Imported variables and functions:
|
||||||
.extern _caddr, _daddr, _runsize, _edata, _end ! Runtime environment
|
.extern _caddr, _daddr, _runsize, _edata, _end ! Runtime environment
|
||||||
.extern _device ! BIOS device number
|
.extern _device ! BIOS device number
|
||||||
|
@ -45,6 +48,7 @@
|
||||||
.extern _mem_entries ! Free memory E820 list entries
|
.extern _mem_entries ! Free memory E820 list entries
|
||||||
.extern _cdbooted ! Whether we booted from CD
|
.extern _cdbooted ! Whether we booted from CD
|
||||||
.extern _cddevice ! Whether we booted from CD
|
.extern _cddevice ! Whether we booted from CD
|
||||||
|
.extern _do_multiboot ! Whether we are multibooting
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
@ -1157,22 +1161,26 @@ minix386:
|
||||||
mov p_gdt_desc+2, ax
|
mov p_gdt_desc+2, ax
|
||||||
movb p_gdt_desc+4, dl ! Set base of global descriptor table
|
movb p_gdt_desc+4, dl ! Set base of global descriptor table
|
||||||
|
|
||||||
|
cmp _do_multiboot, #1
|
||||||
|
je set_monss
|
||||||
|
|
||||||
mov ax, 12(bp)
|
mov ax, 12(bp)
|
||||||
mov dx, 14(bp) ! Kernel ds (absolute address)
|
mov dx, 14(bp) ! Kernel ds (absolute address)
|
||||||
mov p_ds_desc+2, ax
|
mov p_ds_desc+2, ax
|
||||||
movb p_ds_desc+4, dl ! Set base of kernel data segment
|
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
|
mov dx, ss ! Monitor ss
|
||||||
xor ax, ax ! dx:ax = Monitor stack segment
|
xor ax, ax ! dx:ax = Monitor stack segment
|
||||||
call seg2abs ! Minix starts with the stack of the monitor
|
call seg2abs ! Minix starts with the stack of the monitor
|
||||||
mov p_ss_desc+2, ax
|
mov p_ss_desc+2, ax
|
||||||
movb p_ss_desc+4, dl
|
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
|
mov dx, cs ! Monitor cs
|
||||||
xor ax, ax ! dx:ax = Monitor code segment
|
xor ax, ax ! dx:ax = Monitor code segment
|
||||||
call seg2abs
|
call seg2abs
|
||||||
|
@ -1207,13 +1215,29 @@ noret386:
|
||||||
push 6(bp)
|
push 6(bp)
|
||||||
push 4(bp) ! 32 bit far address to kernel entry point
|
push 4(bp) ! 32 bit far address to kernel entry point
|
||||||
|
|
||||||
|
cmp _do_multiboot, #1
|
||||||
|
je multiboot
|
||||||
|
|
||||||
call real2prot ! Switch to protected mode
|
call real2prot ! Switch to protected mode
|
||||||
mov ax, #DS_SELECTOR ! Kernel data
|
mov ax, #DS_SELECTOR ! Kernel data
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ax, #ES_SELECTOR ! Flat 4 Gb
|
mov ax, #ES_SELECTOR ! Flat 4 Gb
|
||||||
mov es, ax
|
mov es, ax
|
||||||
.data1 o32 ! Make a far call to the kernel
|
|
||||||
retf
|
.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
|
||||||
|
! 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.
|
! Minix-86 returns here on a halt or reboot.
|
||||||
ret86:
|
ret86:
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
@ -27,6 +28,10 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
|
|
||||||
|
#include <machine/multiboot.h>
|
||||||
|
#include <machine/elf.h>
|
||||||
|
|
||||||
|
|
||||||
static int block_size = 0;
|
static int block_size = 0;
|
||||||
static int verboseboot = VERBOSEBOOT_QUIET;
|
static int verboseboot = VERBOSEBOOT_QUIET;
|
||||||
|
|
||||||
|
@ -40,6 +45,7 @@ extern int serial_line;
|
||||||
extern u16_t vid_port; /* Video i/o port. */
|
extern u16_t vid_port; /* Video i/o port. */
|
||||||
extern u32_t vid_mem_base; /* Video memory base address. */
|
extern u32_t vid_mem_base; /* Video memory base address. */
|
||||||
extern u32_t vid_mem_size; /* Video memory size. */
|
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. */
|
#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_SIZ_OFF 0 /* Process' sizes into kernel data. */
|
||||||
#define P_INIT_OFF 4 /* Init cs & sizes into fs 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)))
|
#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)
|
void pretty_image(const char *image)
|
||||||
/* Pretty print the name of the image to load. Translate '/' and '_' to
|
/* Pretty print the name of the image to load. Translate '/' and '_' to
|
||||||
* space, first letter goes uppercase. An 'r' before a digit prints as
|
* 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 click_size; /* click_size = Smallest kernel memory object. */
|
||||||
unsigned k_flags; /* Not all kernels are created equal. */
|
unsigned k_flags; /* Not all kernels are created equal. */
|
||||||
u32_t reboot_code; /* Obsolete reboot code return pointer. */
|
u32_t reboot_code; /* Obsolete reboot code return pointer. */
|
||||||
|
int do_multiboot;
|
||||||
|
|
||||||
int params2params(char *params, size_t psize)
|
int params2params(char *params, size_t psize)
|
||||||
/* Repackage the environment settings for the kernel. */
|
/* 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;
|
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 (*vir2sec)(u32_t vsec); /* Where is a sector on disk? */
|
||||||
|
|
||||||
u32_t file_vir2sec(u32_t vsec)
|
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;
|
cnt= SECTOR_SIZE;
|
||||||
}
|
}
|
||||||
if (*addr + click_size > limit)
|
if (*addr + click_size > limit)
|
||||||
{
|
{
|
||||||
DEBUGEXTRA(("get_segment: out of memory; "
|
DEBUGEXTRA(("get_segment: out of memory; "
|
||||||
"addr=0x%lx; limit=0x%lx; size=%lx\n",
|
"addr=0x%lx; limit=0x%lx; size=%lx\n",
|
||||||
*addr, limit, size));
|
*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)
|
void exec_image(char *image)
|
||||||
/* Get a Minix image into core, patch it up and execute. */
|
/* 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);
|
raw_clear(aout, PROCESS_MAX * A_MINHDR);
|
||||||
|
|
||||||
/* Read the many different processes: */
|
/* Read the many different processes: */
|
||||||
for (i= 0; vsec < image_size; i++) {
|
for (i= 0; vsec < image_sectors; i++) {
|
||||||
u32_t startaddr;
|
u32_t startaddr;
|
||||||
startaddr = addr;
|
startaddr = addr;
|
||||||
if (i == PROCESS_MAX) {
|
if (i == PROCESS_MAX) {
|
||||||
|
@ -778,7 +1043,7 @@ char *select_image(char *image)
|
||||||
&& numeric(size)) {
|
&& numeric(size)) {
|
||||||
vir2sec= flat_vir2sec;
|
vir2sec= flat_vir2sec;
|
||||||
image_off= a2l(image);
|
image_off= a2l(image);
|
||||||
image_size= a2l(size);
|
image_sectors= a2l(size);
|
||||||
strcpy(image, "Minix");
|
strcpy(image, "Minix");
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
@ -790,6 +1055,8 @@ char *select_image(char *image)
|
||||||
}
|
}
|
||||||
|
|
||||||
r_stat(image_ino, &st);
|
r_stat(image_ino, &st);
|
||||||
|
image_bytes = st.st_size;
|
||||||
|
|
||||||
if (!S_ISREG(st.st_mode)) {
|
if (!S_ISREG(st.st_mode)) {
|
||||||
char *version= image + strlen(image);
|
char *version= image + strlen(image);
|
||||||
char dots[NAME_MAX + 1];
|
char dots[NAME_MAX + 1];
|
||||||
|
@ -809,7 +1076,7 @@ char *select_image(char *image)
|
||||||
r_stat(image_ino, &st);
|
r_stat(image_ino, &st);
|
||||||
}
|
}
|
||||||
vir2sec= file_vir2sec;
|
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;
|
return image;
|
||||||
bail_out:
|
bail_out:
|
||||||
free(image);
|
free(image);
|
||||||
|
@ -822,8 +1089,25 @@ void bootminix(void)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
char *image;
|
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 ((image= select_image(b_value("image"))) == nil) return;
|
if ((mb = b_value("mb")) != nil) {
|
||||||
|
do_multiboot = a2l(mb);
|
||||||
|
kernel = b_value("kernel");
|
||||||
|
if (kernel == nil) {
|
||||||
|
printf("kernel not set\n");
|
||||||
|
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) {
|
if(serial_line >= 0) {
|
||||||
char linename[2];
|
char linename[2];
|
||||||
|
@ -832,26 +1116,105 @@ void bootminix(void)
|
||||||
b_setvar(E_VAR, SERVARNAME, linename);
|
b_setvar(E_VAR, SERVARNAME, linename);
|
||||||
}
|
}
|
||||||
|
|
||||||
exec_image(image);
|
if (do_multiboot)
|
||||||
|
exec_mb(kernel, modules);
|
||||||
|
else
|
||||||
|
exec_image(image);
|
||||||
|
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case ENOEXEC:
|
case ENOEXEC:
|
||||||
printf("%s contains a bad program header\n", image);
|
printf("%s contains a bad program header\n",
|
||||||
|
do_multiboot ? kernel : image);
|
||||||
break;
|
break;
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
printf("Not enough memory to load %s\n", image);
|
printf("Not enough memory to load %s\n",
|
||||||
|
do_multiboot ? kernel : image);
|
||||||
break;
|
break;
|
||||||
case EIO:
|
case EIO:
|
||||||
printf("Unexpected EOF on %s\n", image);
|
printf("Unexpected EOF on %s\n",
|
||||||
|
do_multiboot ? kernel : image);
|
||||||
case 0:
|
case 0:
|
||||||
/* No error or error already reported. */;
|
/* No error or error already reported. */;
|
||||||
}
|
}
|
||||||
free(image);
|
|
||||||
|
if (do_multiboot)
|
||||||
|
free(kernel);
|
||||||
|
else
|
||||||
|
free(image);
|
||||||
|
|
||||||
if(serial_line >= 0)
|
if(serial_line >= 0)
|
||||||
b_unset(SERVARNAME);
|
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 $
|
* $PchId: bootimage.c,v 1.10 2002/02/27 19:39:09 philip Exp $
|
||||||
*/
|
*/
|
||||||
|
|
13
commands/mkimage/Makefile
Normal file
13
commands/mkimage/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
NBSD_LIBC:= yes
|
||||||
|
|
||||||
|
PROG= mkimage
|
||||||
|
SRCS= mkimage.c
|
||||||
|
MAN=
|
||||||
|
|
||||||
|
CPPFLAGS+= -D_NETBSD_SOURCE
|
||||||
|
|
||||||
|
DPADD+= ${LIBELF}
|
||||||
|
LDADD+= -lelf
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
120
commands/mkimage/mkimage.c
Normal file
120
commands/mkimage/mkimage.c
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Update physical addresses of boot services
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sysexits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#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());
|
||||||
|
}
|
|
@ -10,4 +10,4 @@ MAN=
|
||||||
BINDIR?= /usr/sbin
|
BINDIR?= /usr/sbin
|
||||||
INSTALLFLAGS+= -S 32k
|
INSTALLFLAGS+= -S 32k
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# Makefile for memory driver (MEMORY)
|
# Makefile for memory driver (MEMORY)
|
||||||
.include <bsd.own.mk>
|
|
||||||
|
|
||||||
PROG= memory
|
PROG= memory
|
||||||
SRCS= memory.c imgrd.c
|
SRCS= memory.c imgrd.c
|
||||||
|
|
||||||
|
@ -20,4 +18,4 @@ imgrd.d: touch-genfiles
|
||||||
touch-genfiles:
|
touch-genfiles:
|
||||||
[ -e ${.CURDIR}/../ramdisk/image.c ] || touch -t 197001010000.00 ${.CURDIR}/../ramdisk/image.c
|
[ -e ${.CURDIR}/../ramdisk/image.c ] || touch -t 197001010000.00 ${.CURDIR}/../ramdisk/image.c
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# Makefile for terminal driver (TTY)
|
# Makefile for terminal driver (TTY)
|
||||||
|
|
||||||
.include <bsd.own.mk>
|
|
||||||
|
|
||||||
PROG= tty
|
PROG= tty
|
||||||
SRCS= tty.c console.c keyboard.c pty.c rs232.c
|
SRCS= tty.c console.c keyboard.c pty.c rs232.c
|
||||||
|
|
||||||
|
@ -18,5 +16,5 @@ SUBDIR= keymaps
|
||||||
# Needs kernel/const.h, etc
|
# Needs kernel/const.h, etc
|
||||||
CPPFLAGS+= -I${MINIXSRCDIR}
|
CPPFLAGS+= -I${MINIXSRCDIR}
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
.include <bsd.subdir.mk>
|
.include <bsd.subdir.mk>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
INCSDIR= /usr/include/i386
|
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"
|
.include "../../../common/include/arch/i386/Makefile.inc"
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||||
|
|
||||||
#define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN)
|
#define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN)
|
||||||
|
|
||||||
/* consts used for Multiboot pre-init */
|
/* consts used for Multiboot pre-init */
|
||||||
|
|
||||||
#define MULTIBOOT_VIDEO_MODE_EGA 1
|
#define MULTIBOOT_VIDEO_MODE_EGA 1
|
|
@ -25,7 +25,7 @@
|
||||||
#include "oxpcie.h"
|
#include "oxpcie.h"
|
||||||
#include "kernel/proc.h"
|
#include "kernel/proc.h"
|
||||||
#include "kernel/debug.h"
|
#include "kernel/debug.h"
|
||||||
#include "multiboot.h"
|
#include <machine/multiboot.h>
|
||||||
|
|
||||||
#include "glo.h"
|
#include "glo.h"
|
||||||
|
|
||||||
|
|
43
kernel/arch/i386/kernel_elf.lds
Normal file
43
kernel/arch/i386/kernel_elf.lds
Normal file
|
@ -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.*)
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
#include "archconst.h"
|
#include "archconst.h"
|
||||||
#include "kernel/const.h"
|
#include "kernel/const.h"
|
||||||
#include "sconst.h"
|
#include "sconst.h"
|
||||||
#include "multiboot.h"
|
#include <machine/multiboot.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file contains a number of assembly code utility routines needed by the
|
* This file contains a number of assembly code utility routines needed by the
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "archconst.h"
|
#include "archconst.h"
|
||||||
#include "kernel/const.h"
|
#include "kernel/const.h"
|
||||||
#include "sconst.h"
|
#include "sconst.h"
|
||||||
#include "multiboot.h"
|
#include <machine/multiboot.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file contains a number of 16-bit assembly code utility routines needed by the
|
* This file contains a number of 16-bit assembly code utility routines needed by the
|
||||||
|
|
|
@ -53,7 +53,7 @@ begbss:
|
||||||
#include "kernel/const.h"
|
#include "kernel/const.h"
|
||||||
#include "kernel/proc.h"
|
#include "kernel/proc.h"
|
||||||
#include "sconst.h"
|
#include "sconst.h"
|
||||||
#include "multiboot.h"
|
#include <machine/multiboot.h>
|
||||||
|
|
||||||
#include "arch_proto.h" /* K_STACK_SIZE */
|
#include "arch_proto.h" /* K_STACK_SIZE */
|
||||||
|
|
||||||
|
@ -84,9 +84,7 @@ MINIX:
|
||||||
/* this is the entry point for the MINIX kernel */
|
/* this is the entry point for the MINIX kernel */
|
||||||
|
|
||||||
#if defined(__ELF__)
|
#if defined(__ELF__)
|
||||||
/* Check if Multibooting */
|
jmp _C_LABEL(multiboot_init)
|
||||||
cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax
|
|
||||||
je _C_LABEL(multiboot_init)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
jmp over_flags /* skip over the next few bytes */
|
jmp over_flags /* skip over the next few bytes */
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "kernel/const.h"
|
#include "kernel/const.h"
|
||||||
#include "kernel/proc.h"
|
#include "kernel/proc.h"
|
||||||
#include "sconst.h"
|
#include "sconst.h"
|
||||||
#include "multiboot.h"
|
#include <machine/multiboot.h>
|
||||||
|
|
||||||
#define GDT_SET_ENTRY(selector, base, limit) \
|
#define GDT_SET_ENTRY(selector, base, limit) \
|
||||||
mov %ebp, %edi; \
|
mov %ebp, %edi; \
|
||||||
|
@ -44,6 +44,8 @@ reload_cs:
|
||||||
mov %eax, %ds
|
mov %eax, %ds
|
||||||
mov %eax, %ss
|
mov %eax, %ss
|
||||||
mov %eax, %es
|
mov %eax, %es
|
||||||
|
mov %eax, %fs
|
||||||
|
mov %eax, %gs
|
||||||
|
|
||||||
mov $(multiboot_stack + MULTIBOOT_STACK_SIZE), %esp
|
mov $(multiboot_stack + MULTIBOOT_STACK_SIZE), %esp
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "arch_proto.h"
|
#include "arch_proto.h"
|
||||||
#include "libexec.h"
|
#include "libexec.h"
|
||||||
#include "multiboot.h"
|
#include <machine/multiboot.h>
|
||||||
|
|
||||||
#define MULTIBOOT_VERBOSE 1
|
#define MULTIBOOT_VERBOSE 1
|
||||||
|
|
||||||
|
@ -279,10 +279,6 @@ PRIVATE void get_parameters(multiboot_info_t *mbi)
|
||||||
mb_set_param("memory", mem_value);
|
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) {
|
if (mbi->flags&MULTIBOOT_INFO_CMDLINE) {
|
||||||
/* Override values with cmdline argument */
|
/* Override values with cmdline argument */
|
||||||
p = mb_cmd_buff;
|
p = mb_cmd_buff;
|
||||||
|
@ -353,11 +349,9 @@ PRIVATE void mb_extract_image(multiboot_info_t mbi)
|
||||||
mb_print("\nKernel: ");
|
mb_print("\nKernel: ");
|
||||||
mb_print_hex(trunc_page(text_paddr));
|
mb_print_hex(trunc_page(text_paddr));
|
||||||
mb_print("-");
|
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(" Entry: ");
|
||||||
mb_print_hex(pc);
|
mb_print_hex(pc);
|
||||||
mb_print(" Stack: ");
|
|
||||||
mb_print_hex(stack_bytes);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mb_module_info = ((multiboot_module_t *)mbi.mods_addr);
|
mb_module_info = ((multiboot_module_t *)mbi.mods_addr);
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
/* Support only 32-bit ELF objects */
|
/* Support only 32-bit ELF objects */
|
||||||
#define __ELF_WORD_SIZE 32
|
#define __ELF_WORD_SIZE 32
|
||||||
|
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
|
||||||
static int __elfN(check_header)(const Elf_Ehdr *hdr);
|
static int __elfN(check_header)(const Elf_Ehdr *hdr);
|
||||||
|
|
||||||
int read_header_elf(
|
int read_header_elf(
|
||||||
|
@ -36,8 +38,6 @@ int read_header_elf(
|
||||||
unsigned long seg_filebytes, seg_membytes;
|
unsigned long seg_filebytes, seg_membytes;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
assert(exec_hdr != NULL);
|
|
||||||
|
|
||||||
*text_vaddr = *text_paddr = 0;
|
*text_vaddr = *text_paddr = 0;
|
||||||
*text_filebytes = *text_membytes = 0;
|
*text_filebytes = *text_membytes = 0;
|
||||||
*data_vaddr = *data_paddr = 0;
|
*data_vaddr = *data_paddr = 0;
|
||||||
|
@ -50,8 +50,8 @@ int read_header_elf(
|
||||||
return ENOEXEC;
|
return ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hdr->e_phoff > PAGE_SIZE) ||
|
if ((hdr->e_phoff > SECTOR_SIZE) ||
|
||||||
(hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE) {
|
(hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > SECTOR_SIZE) {
|
||||||
return ENOEXEC;
|
return ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,21 +60,21 @@ int read_header_elf(
|
||||||
#ifdef __NBSD_LIBC
|
#ifdef __NBSD_LIBC
|
||||||
rounddown((uintptr_t)phdr, sizeof(Elf_Addr)) != (uintptr_t)phdr
|
rounddown((uintptr_t)phdr, sizeof(Elf_Addr)) != (uintptr_t)phdr
|
||||||
#else
|
#else
|
||||||
!_minix_aligned(phdr, Elf_Addr)
|
!_minix_aligned(hdr->e_phoff, Elf_Addr)
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
return ENOEXEC;
|
return ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ELF_DEBUG
|
#if ELF_DEBUG
|
||||||
printf("Program header file offset (phoff): %d\n", hdr->e_phoff);
|
printf("Program header file offset (phoff): %ld\n", hdr->e_phoff);
|
||||||
printf("Section header file offset (shoff): %d\n", hdr->e_shoff);
|
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 size (phentsize): %d\n", hdr->e_phentsize);
|
||||||
printf("Program header entry num (phnum): %d\n", hdr->e_phnum);
|
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 size (shentsize): %d\n", hdr->e_shentsize);
|
||||||
printf("Section header entry num (shnum): %d\n", hdr->e_shnum);
|
printf("Section header entry num (shnum): %d\n", hdr->e_shnum);
|
||||||
printf("Section name strings index (shstrndx): %d\n", hdr->e_shstrndx);
|
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
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < hdr->e_phnum; i++) {
|
for (i = 0; i < hdr->e_phnum; i++) {
|
||||||
|
@ -108,18 +108,17 @@ int read_header_elf(
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ELF_DEBUG
|
#if ELF_DEBUG
|
||||||
printf("Text vaddr: 0x%x\n", *text_vaddr);
|
printf("Text vaddr: 0x%lx\n", *text_vaddr);
|
||||||
printf("Text paddr: 0x%x\n", *text_paddr);
|
printf("Text paddr: 0x%lx\n", *text_paddr);
|
||||||
printf("Text filebytes: 0x%x\n", *text_filebytes);
|
printf("Text filebytes: 0x%lx\n", *text_filebytes);
|
||||||
printf("Text membytes: 0x%x\n", *text_membytes);
|
printf("Text membytes: 0x%lx\n", *text_membytes);
|
||||||
printf("Data vaddr: 0x%x\n", *data_vaddr);
|
printf("Data vaddr: 0x%lx\n", *data_vaddr);
|
||||||
printf("Data paddr: 0x%x\n", *data_paddr);
|
printf("Data paddr: 0x%lx\n", *data_paddr);
|
||||||
printf("Data filebyte: 0x%x\n", *data_filebytes);
|
printf("Data filebyte: 0x%lx\n", *data_filebytes);
|
||||||
printf("Data membytes: 0x%x\n", *data_membytes);
|
printf("Data membytes: 0x%lx\n", *data_membytes);
|
||||||
printf("Tot bytes: 0x%x\n", *tot_bytes);
|
printf("PC: 0x%lx\n", *pc);
|
||||||
printf("PC: 0x%x\n", *pc);
|
printf("Text offset: 0x%lx\n", *text_offset);
|
||||||
printf("Text offset: 0x%x\n", *text_offset);
|
printf("Data offset: 0x%lx\n", *data_offset);
|
||||||
printf("Data offset: 0x%x\n", *data_offset);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
|
@ -10,4 +10,4 @@ MAN=
|
||||||
BINDIR?= /usr/sbin
|
BINDIR?= /usr/sbin
|
||||||
INSTALLFLAGS+= -S 16k
|
INSTALLFLAGS+= -S 16k
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -7,4 +7,4 @@ MAN=
|
||||||
BINDIR?= /usr/sbin
|
BINDIR?= /usr/sbin
|
||||||
INSTALLFLAGS+= -S 64k
|
INSTALLFLAGS+= -S 64k
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -16,4 +16,4 @@ INSTALLFLAGS+= -S 128k
|
||||||
DEFAULT_NR_BUFS= 1024
|
DEFAULT_NR_BUFS= 1024
|
||||||
CPPFLAGS+= -DDEFAULT_NR_BUFS=${DEFAULT_NR_BUFS}
|
CPPFLAGS+= -DDEFAULT_NR_BUFS=${DEFAULT_NR_BUFS}
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -12,4 +12,4 @@ MAN=
|
||||||
BINDIR?= /usr/sbin
|
BINDIR?= /usr/sbin
|
||||||
INSTALLFLAGS+= -S 128k
|
INSTALLFLAGS+= -S 128k
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -17,4 +17,4 @@ CPPFLAGS.misc.c+= -I${MINIXSRCDIR}
|
||||||
CPPFLAGS.schedule.c+= -I${MINIXSRCDIR}
|
CPPFLAGS.schedule.c+= -I${MINIXSRCDIR}
|
||||||
CPPFLAGS.utility.c+= -I${MINIXSRCDIR}
|
CPPFLAGS.utility.c+= -I${MINIXSRCDIR}
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# Makefile for Reincarnation Server (RS)
|
# Makefile for Reincarnation Server (RS)
|
||||||
.include <bsd.own.mk>
|
|
||||||
|
|
||||||
PROG= rs
|
PROG= rs
|
||||||
SRCS= exec.c main.c request.c manager.c table.c utility.c memory.c error.c
|
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}
|
CPPFLAGS+= -I${MINIXSRCDIR}
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -14,4 +14,4 @@ CPPFLAGS.main.c+= -I${MINIXSRCDIR}
|
||||||
CPPFLAGS.schedule.c+= -I${MINIXSRCDIR}
|
CPPFLAGS.schedule.c+= -I${MINIXSRCDIR}
|
||||||
CPPFLAGS.utility.c+= -I${MINIXSRCDIR}
|
CPPFLAGS.utility.c+= -I${MINIXSRCDIR}
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -14,4 +14,4 @@ MAN=
|
||||||
BINDIR?= /usr/sbin
|
BINDIR?= /usr/sbin
|
||||||
INSTALLFLAGS+= -S 16k
|
INSTALLFLAGS+= -S 16k
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -18,4 +18,4 @@ CPPFLAGS+= -I${.CURDIR} -I${.CURDIR}/arch/${ARCH}
|
||||||
CPPFLAGS+= -I${MINIXSRCDIR}
|
CPPFLAGS+= -I${MINIXSRCDIR}
|
||||||
|
|
||||||
.include "arch/${ARCH}/Makefile.inc"
|
.include "arch/${ARCH}/Makefile.inc"
|
||||||
.include <bsd.prog.mk>
|
.include <minix.bootprog.mk>
|
||||||
|
|
|
@ -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 \
|
bsd.prog.mk bsd.subdir.mk bsd.sys.mk bsd.gcov.mk \
|
||||||
sys.mk
|
sys.mk
|
||||||
|
|
||||||
|
# MINIX-specific files
|
||||||
|
FILES+= minix.bootprog.mk
|
||||||
|
|
||||||
FILESDIR=/usr/share/mk
|
FILESDIR=/usr/share/mk
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
|
8
share/mk/minix.bootprog.mk
Normal file
8
share/mk/minix.bootprog.mk
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# MINIX-specific boot program options
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
.if ${OBJECT_FMT} == "ELF"
|
||||||
|
LDFLAGS+= -Wl,--section-start=.init=0x0
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
|
@ -2,12 +2,15 @@
|
||||||
.include <bsd.own.mk>
|
.include <bsd.own.mk>
|
||||||
.include "nbsd.config"
|
.include "nbsd.config"
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
u=/usr
|
u=/usr
|
||||||
MDEC= /usr/mdec
|
MDEC= /usr/mdec
|
||||||
GEN_FILES= *.bak image kernel *.iso *.iso.gz cdfdimage rootimage src
|
GEN_FILES= *.bak image kernel *.iso *.iso.gz cdfdimage rootimage src
|
||||||
|
|
||||||
# Specify the programs that are part of the system image.
|
# Specify the programs that are part of the system image.
|
||||||
PROGRAMS= kernel \
|
KERNEL= kernel
|
||||||
|
PROGRAMS= \
|
||||||
../servers/ds/ds \
|
../servers/ds/ds \
|
||||||
../servers/rs/rs \
|
../servers/rs/rs \
|
||||||
../servers/pm/pm \
|
../servers/pm/pm \
|
||||||
|
@ -56,15 +59,17 @@ PAD_KERNEL_TEXT := cp ../kernel/kernel kernel
|
||||||
PAD_KERNEL_TEXT := padtext ../kernel/kernel kernel
|
PAD_KERNEL_TEXT := padtext ../kernel/kernel kernel
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
# for fast complie kernel and generate image, skip servers and drivers
|
.if ${OBJECT_FMT} == "ELF"
|
||||||
image_mb: includes
|
image: includes services
|
||||||
cd ../kernel && $(MAKE)
|
|
||||||
${PAD_KERNEL_TEXT}
|
${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
|
image: includes services
|
||||||
${PAD_KERNEL_TEXT}
|
${PAD_KERNEL_TEXT}
|
||||||
installboot -image $@ $(PROGRAMS)
|
installboot -image $@ $(KERNEL) $(PROGRAMS)
|
||||||
|
.endif
|
||||||
|
|
||||||
# rebuild the program or system libraries
|
# rebuild the program or system libraries
|
||||||
includes:
|
includes:
|
||||||
|
@ -94,9 +99,13 @@ libraries: includes
|
||||||
bootable:
|
bootable:
|
||||||
exec su root mkboot bootable
|
exec su root mkboot bootable
|
||||||
|
|
||||||
|
.if ${OBJECT_FMT} == "ELF"
|
||||||
|
hdboot: image
|
||||||
|
.else
|
||||||
hdboot: image
|
hdboot: image
|
||||||
exec sh mkboot $@
|
exec sh mkboot $@
|
||||||
@sync
|
@sync
|
||||||
|
.endif
|
||||||
|
|
||||||
fdboot: image
|
fdboot: image
|
||||||
exec su root mkboot $@
|
exec su root mkboot $@
|
||||||
|
|
Loading…
Reference in a new issue