/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
*/
/*
* Copyright 2015 Toomas Soome <tsoome@me.com>
*/
/*
* Primitive linux loader, at the moment only intended to load memtest86+.bin.
*
* Note the linux kernel location conflicts with loader, so we need to
* read in to temporary space and relocate on exec, when btx is stopped.
*/
#include <stand.h>
#include <machine/metadata.h>
#include "linux.h"
#include "bootstrap.h"
#include "libi386.h"
#include "btxv86.h"
static int linux_exec(struct preloaded_file *);
static int linux_execinitrd(struct preloaded_file *);
static void
{
return;
}
static vm_offset_t
{
int entries, i;
printf("no memory smap\n");
return (candidate);
}
for (i = 0; i < entries; i++) {
continue;
continue;
}
return (candidate);
}
static int
{
ssize_t n;
/*
* relocater_data is space allocated in relocater_tramp.S
* There is space for 3 instances + terminating zero in case
* all 3 entries are used.
*/
return (EFTYPE);
/* is kernel already loaded? */
return (EFTYPE);
return (errno);
printf("stat failed\n");
return (error);
}
if (n != sizeof (lh)) {
printf("error reading kernel header\n");
goto end;
}
printf("invalid magic number\n");
goto end;
}
linux_big = 0;
max_cmdline_size = 256;
if (setup_sects > LINUX_MAX_SETUP_SECTS) {
printf("too many setup sectors\n");
goto end;
}
fp = file_alloc();
goto end;
}
if (linux_data_real_addr == -1) {
printf("failed to detect suitable low memory\n");
goto end;
}
}
} else {
}
} else {
/* old kernel */
}
if (setup_sects == 0)
/* temporary location of real mode part */
printf("Linux zImage is too big, use bzImage instead\n");
goto end;
}
printf(" [Linux-%s, setup=0x%x, size=0x%x]\n",
/* copy real mode part to place */
goto end;
}
/* Clear the heap space. */
}
goto end;
}
if (linux_big)
else
/*
* NOTE: f_addr and f_size is used here as hint for module
* allocation, as module location will be f_addr + f_size.
*/
if (linux_big == 0) {
/* make sure the next entry is zeroed */
} else {
/* make sure the next entry is zeroed */
}
end:
return (error);
}
static int
{
int linux_big;
linux_big = 1;
linux_big = 0;
else
return (EFTYPE);
/*
* command line
* if not set in fp, read from boot-args env
*/
/* video mode selection */
else {
long mode;
errno = 0;
/*
* libstand sets ERANGE as only error case;
* however, the actual value is 16bit, so
* additional check is needed.
*/
printf("bad value for video mode\n");
return (EINTR);
}
}
}
}
*dst = 0;
/* set up module relocation */
/*
* XXX: Linux 2.3.xx has a bug in the memory range check,
* so avoid the last page.
* XXX: Linux 2.2.xx has a bug in the memory range check,
* which is worse than that of Linux 2.3.xx, so avoid the
* last 64kb. *sigh*
*/
moveto -= 0x10000;
/* need to relocate initrd first */
if (linux_big == 0) {
} else {
}
}
relocator_ip = 0;
dev_cleanup();
__exec((void *)0x600);
panic("exec returned");
return (EINTR); /* not reached */
}
static int
{
return (EFTYPE);
/* check if the kernel is loaded */
return (EFTYPE);
return (EFTYPE);
return (0);
}
{
return (EFTYPE);
}