#include <sys/exec.h>
#include "core.h"
#include "menu.h"
+#include "fs.h"
/* Must match enum kernel_type */
const char *const kernel_types[] = {
/* It might be a type specifier */
enum kernel_type type = KT_NONE;
for (pp = kernel_types; *pp; pp++, type++) {
- if (!strcmp(kernel + 1, *pp))
- execute(p, type); /* Strip the type specifier and retry */
+ if (!strcmp(kernel + 1, *pp)) {
+ /* Strip the type specifier and retry */
+ execute(p, type);
+ }
}
}
* the assembly runkernel.inc any more */
new_linux_kernel(kernel, cmdline);
} else if (type == KT_CONFIG) {
+ char *argv[] = { "ldlinux.c32", NULL };
+
/* kernel contains the config file name */
- char *spawn_load_param[2] = { args, NULL };
- spawn_load(kernel, 1, spawn_load_param);
+ realpath(ConfigName, kernel, FILENAME_MAX);
+
+ start_ldlinux("ldlinux.c32", 1, argv);
} else {
/* process the image need int 22 support */
if (type == KT_LOCALBOOT) {
com32sys_t ireg, oreg;
uint8_t *adv;
int count = 0;
+ char *config_argv[2] = { NULL, NULL };
openconsole(&dev_rawcon_r, &dev_ansiserial_w);
- parse_configs(NULL);
+ if (ConfigName[0])
+ config_argv[0] = ConfigName;
+
+ parse_configs(config_argv);
__syslinux_init();
adv = syslinux_getadv(ADV_BOOTONCE, &count);
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+* @pos: the type * to use as a loop cursor.
+* @n: another type * to use as temporary storage
+* @head: the head for your list.
+* @member: the name of the list_struct within the struct.
+*/
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
#define for_each_module(m) list_for_each_entry(m, &modules_head, list)
/**
+ * for_each_module - iterator loop through the list of loaded modules safe against removal.
+ */
+#define for_each_module_safe(m, n) \
+ list_for_each_entry_safe(m, n, &modules_head, list)
+
+/**
* modules_init - initialize the module subsystem.
*
* This function must be called before any module operation is to be performed.
* Author: Stefan Bucur <stefanb@zytor.com>
*/
-
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// Do not allow duplicate modules
if (module_find(module->name) != NULL) {
DBG_PRINT("Module %s is already loaded.\n", module->name);
- return -1;
+ return EEXIST;
}
// Get a mapping/copy of the ELF file in memory
+++ /dev/null
-/* ----------------------------------------------------------------------- *
- *
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall
- * be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * ----------------------------------------------------------------------- */
-
-#include <syslinux/config.h>
-#include <klibc/compiler.h>
-#include <com32.h>
-
-const char *__syslinux_config_file;
-
-void __constructor __syslinux_get_config_file_name(void)
-{
- static com32sys_t reg;
-
- reg.eax.w[0] = 0x000e;
- __intcall(0x22, ®, ®);
- __syslinux_config_file = MK_PTR(reg.es, reg.ebx.w[0]);
-}
(*p) ();
}
+int start_ldlinux(char **argv)
+{
+ int rv;
+
+again:
+ rv = spawn_load(LDLINUX, 1, argv);
+ if (rv == EEXIST) {
+ struct elf_module *m, *mod, *begin = NULL;
+
+ /*
+ * If a COM32 module calls execute() we may need to
+ * unload all the modules loaded since ldlinux.c32,
+ * and restart initialisation. This is especially
+ * important for config files.
+ */
+ for_each_module(mod) {
+ if (!strcmp(mod->name, LDLINUX)) {
+ begin = mod;
+ break;
+ }
+ }
+
+ for_each_module_safe(mod, m) {
+ if (mod == begin)
+ break;
+
+ if (mod != begin)
+ module_unload(mod);
+ }
+
+ /*
+ * Finally unload LDLINUX.
+ *
+ * We'll reload it when we jump to 'again' which will
+ * cause all the initialsation steps to be executed
+ * again.
+ */
+ module_unload(begin);
+ goto again;
+ }
+
+ return rv;
+}
+
/* note to self: do _*NOT*_ use static key word on this function */
void load_env32(com32sys_t * regs)
{
init_module_subsystem(&core_module);
- spawn_load(LDLINUX, 1, argv);
+ start_ldlinux(argv);
/*
* If we failed to load LDLINUX it could be because our
fp = &__file_info[fd];
if (!search_config(&fp->i.fd, search_directories, filenames))
- spawn_load(LDLINUX, 1, argv);
+ start_ldlinux(argv);
}
int create_args_and_load(char *cmdline)