[syslinux] [PATCH 10/19] ldlinux: Loading a config file should cause re-initialisation
Paulo Alcantara
pcacjr at zytor.com
Sat Mar 24 09:20:25 PDT 2012
Hi Matt,
On Fri, Mar 23, 2012 at 06:02:44PM +0000, Matt Fleming wrote:
> From: Matt Fleming <matt.fleming at intel.com>
>
> There are a number of initialisation steps that need to be performed
> *every* time a config file is loaded. Reload ldlinux.c32 so that we
> can re-initialise the environment whenever a new config file is
> loaded. This involves unloading all the modules that have been loaded
> since ldlinux.c32. Luckily the list of loaded modules is sorted by
> load order, which means it's trivial to "pop" them from the front of
> the list.
>
> Signed-off-by: Matt Fleming <matt.fleming at intel.com>
> ---
> com32/elflink/ldlinux/execute.c | 14 +++++++---
> com32/elflink/ldlinux/ldlinux.c | 6 ++++-
> com32/include/linux/list.h | 13 ++++++++++
> com32/include/sys/module.h | 6 ++++
> com32/lib/sys/module/elf_module.c | 4 +-
> core/elflink/config.c | 41 -------------------------------
> core/elflink/load_env32.c | 48 +++++++++++++++++++++++++++++++++++-
> 7 files changed, 82 insertions(+), 50 deletions(-)
> delete mode 100644 core/elflink/config.c
>
> diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
> index 2b265a1..c01d63f 100644
> --- a/com32/elflink/ldlinux/execute.c
> +++ b/com32/elflink/ldlinux/execute.c
> @@ -19,6 +19,7 @@
> #include <sys/exec.h>
> #include "core.h"
> #include "menu.h"
> +#include "fs.h"
>
> /* Must match enum kernel_type */
> const char *const kernel_types[] = {
> @@ -74,8 +75,10 @@ void execute(const char *cmdline, enum kernel_type type)
> /* 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);
> + }
> }
> }
>
> @@ -88,9 +91,12 @@ void execute(const char *cmdline, enum kernel_type 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) {
> diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
> index 03e2f60..6c306ad 100644
> --- a/com32/elflink/ldlinux/ldlinux.c
> +++ b/com32/elflink/ldlinux/ldlinux.c
> @@ -118,10 +118,14 @@ int main(int argc, char **argv)
> 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);
> diff --git a/com32/include/linux/list.h b/com32/include/linux/list.h
> index 3b92e25..afe8980 100644
> --- a/com32/include/linux/list.h
> +++ b/com32/include/linux/list.h
> @@ -338,6 +338,19 @@ static inline void list_splice_init(struct list_head *list,
> 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.
> diff --git a/com32/include/sys/module.h b/com32/include/sys/module.h
> index d10eae9..a9ddb60 100644
> --- a/com32/include/sys/module.h
> +++ b/com32/include/sys/module.h
> @@ -199,6 +199,12 @@ extern struct list_head modules_head;
> #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.
> diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c
> index ffdcd52..6b4d548 100644
> --- a/com32/lib/sys/module/elf_module.c
> +++ b/com32/lib/sys/module/elf_module.c
> @@ -5,7 +5,7 @@
> * Author: Stefan Bucur <stefanb at zytor.com>
> */
>
> -
> +#include <errno.h>
> #include <stdlib.h>
> #include <string.h>
> #include <stdio.h>
> @@ -475,7 +475,7 @@ int module_load(struct elf_module *module) {
> // 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
> diff --git a/core/elflink/config.c b/core/elflink/config.c
> deleted file mode 100644
> index b27aa82..0000000
> --- a/core/elflink/config.c
> +++ /dev/null
> @@ -1,41 +0,0 @@
> -/* ----------------------------------------------------------------------- *
> - *
> - * 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]);
> -}
> diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
> index 7ffe185..75f5629 100644
> --- a/core/elflink/load_env32.c
> +++ b/core/elflink/load_env32.c
> @@ -71,6 +71,50 @@ static void call_constr(void)
> (*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
s/initialsation/initialisation
> + * 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)
> {
> @@ -97,7 +141,7 @@ 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
> @@ -112,7 +156,7 @@ void load_env32(com32sys_t * regs)
> 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)
> --
> 1.7.4.4
>
> _______________________________________________
> Syslinux mailing list
> Submissions to Syslinux at zytor.com
> Unsubscribe or set options at:
> http://www.zytor.com/mailman/listinfo/syslinux
> Please do not send private replies to mailing list traffic.
Reviewed-by: Paulo Alcantara <pcacjr at zytor.com>
--
-Paulo
More information about the Syslinux
mailing list