Files
xen/extras/mini-os/main.c
T
Daniel De Graaf 434a41d817 mini-os: make frontends and xenbus optional
This adds compile-time logic to disable certain frontends in mini-os:
 - pcifront is disabled by default, enabled for ioemu
 - blkfront, netfront, fbfront, kbdfront, consfront are enabled by default
 - xenbus is required for any frontend, and is enabled by default

If all frontends and xenbus are disabled, mini-os will run without
needing to communicate with xenstore, making it suitable to run the
xenstore daemon. The console frontend is not required for the initial
console, only consoles opened via openpt or ptmx.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Committed-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
2012-02-09 18:33:32 +00:00

193 lines
4.1 KiB
C

/*
* POSIX-compatible main layer
*
* Samuel Thibault <Samuel.Thibault@eu.citrix.net>, October 2007
*/
#ifdef HAVE_LIBC
#include <os.h>
#include <sched.h>
#include <console.h>
#include <netfront.h>
#include <pcifront.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <xenbus.h>
#include <events.h>
extern int main(int argc, char *argv[], char *envp[]);
extern void __libc_init_array(void);
extern void __libc_fini_array(void);
extern unsigned long __CTOR_LIST__[];
extern unsigned long __DTOR_LIST__[];
#if 0
#include <stdio.h>
int main(int argc, char *argv[], char *envp[])
{
printf("Hello, World!\n");
return 1;
}
#endif
void _init(void)
{
}
void _fini(void)
{
}
extern char __app_bss_start, __app_bss_end;
static void call_main(void *p)
{
char *c, quote;
#ifdef CONFIG_QEMU_XS_ARGS
char *domargs, *msg;
#endif
int argc;
char **argv;
char *envp[] = { NULL };
#ifdef CONFIG_QEMU_XS_ARGS
char *vm;
char path[128];
int domid;
#endif
int i;
/* Let other parts initialize (including console output) before maybe
* crashing. */
//sleep(1);
#ifdef CONFIG_SPARSE_BSS
sparse((unsigned long) &__app_bss_start, &__app_bss_end - &__app_bss_start);
#endif
#if defined(HAVE_LWIP) && defined(CONFIG_START_NETWORK) && defined(CONFIG_NETFRONT)
start_networking();
#endif
#ifdef CONFIG_PCIFRONT
create_thread("pcifront", pcifront_watches, NULL);
#endif
#ifdef CONFIG_QEMU_XS_ARGS
/* Fetch argc, argv from XenStore */
domid = xenbus_read_integer("target");
if (domid == -1) {
printk("Couldn't read target\n");
do_exit();
}
snprintf(path, sizeof(path), "/local/domain/%d/vm", domid);
msg = xenbus_read(XBT_NIL, path, &vm);
if (msg) {
printk("Couldn't read vm path\n");
do_exit();
}
printk("dom vm is at %s\n", vm);
snprintf(path, sizeof(path), "%s/image/dmargs", vm);
free(vm);
msg = xenbus_read(XBT_NIL, path, &domargs);
if (msg) {
printk("Couldn't get stubdom args: %s\n", msg);
domargs = strdup("");
}
#endif
argc = 1;
#define PARSE_ARGS(ARGS,START,QUOTE,END) \
c = ARGS; \
quote = 0; \
while (*c) { \
if (*c != ' ') { \
START; \
while (*c) { \
if (quote) { \
if (*c == quote) { \
quote = 0; \
QUOTE; \
continue; \
} \
} else if (*c == ' ') \
break; \
if (*c == '"' || *c == '\'') { \
quote = *c; \
QUOTE; \
continue; \
} \
c++; \
} \
} else { \
END; \
while (*c == ' ') \
c++; \
} \
} \
if (quote) {\
printk("Warning: unterminated quotation %c\n", quote); \
quote = 0; \
}
#define PARSE_ARGS_COUNT(ARGS) PARSE_ARGS(ARGS, argc++, c++, )
#define PARSE_ARGS_STORE(ARGS) PARSE_ARGS(ARGS, argv[argc++] = c, memmove(c, c + 1, strlen(c + 1) + 1), *c++ = 0)
PARSE_ARGS_COUNT((char*)start_info.cmd_line);
#ifdef CONFIG_QEMU_XS_ARGS
PARSE_ARGS_COUNT(domargs);
#endif
argv = alloca((argc + 1) * sizeof(char *));
argv[0] = "main";
argc = 1;
PARSE_ARGS_STORE((char*)start_info.cmd_line)
#ifdef CONFIG_QEMU_XS_ARGS
PARSE_ARGS_STORE(domargs)
#endif
argv[argc] = NULL;
for (i = 0; i < argc; i++)
printf("\"%s\" ", argv[i]);
printf("\n");
__libc_init_array();
environ = envp;
for (i = 0; __CTOR_LIST__[i] != 0; i++)
((void((*)(void)))__CTOR_LIST__[i]) ();
tzset();
exit(main(argc, argv, envp));
}
void _exit(int ret)
{
int i;
for (i = 0; __DTOR_LIST__[i] != 0; i++)
((void((*)(void)))__DTOR_LIST__[i]) ();
close_all_files();
__libc_fini_array();
printk("main returned %d\n", ret);
#if defined(HAVE_LWIP) && defined(CONFIG_NETFRONT)
stop_networking();
#endif
stop_kernel();
if (!ret) {
/* No problem, just shutdown. */
struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
}
do_exit();
}
int app_main(start_info_t *si)
{
printk("Dummy main: start_info=%p\n", si);
main_thread = create_thread("main", call_main, si);
return 0;
}
#endif