[syslinux:elflink] move core/elflink over

syslinux-bot for Feng Tang feng.tang at intel.com
Thu Aug 12 21:03:09 PDT 2010


Commit-ID:  8f33a3dff6cd44fa2d12e626354479e020e25bdc
Gitweb:     http://syslinux.zytor.com/commit/8f33a3dff6cd44fa2d12e626354479e020e25bdc
Author:     Feng Tang <feng.tang at intel.com>
AuthorDate: Tue, 1 Jun 2010 16:18:42 +0800
Committer:  Feng Tang <feng.tang at intel.com>
CommitDate: Tue, 20 Jul 2010 11:10:03 +0800

move core/elflink over



---
 MCONFIG.devel                                    |    2 -
 core/elflink/abort_new.c                         |   29 ++
 {com32/lib/syslinux => core/elflink}/adv.c       |    0
 {com32/lib/syslinux => core/elflink}/advwrite.c  |    0
 core/elflink/cli.c                               |  406 ++++++++++++++++++++++
 core/elflink/cli.h                               |   23 ++
 {com32/menu => core/elflink}/colors.c            |    0
 core/elflink/common.h                            |   62 ++++
 {com32/lib/syslinux => core/elflink}/config.c    |    0
 core/elflink/core-elf.h                          |   16 +
 core/elflink/elfutils.h                          |   67 ++++
 core/elflink/execute.c                           |   85 +++++
 {com32/libutil => core/elflink}/get_key.c        |    8 +-
 {com32/lib/syslinux => core/elflink}/getadv.c    |    2 +-
 {com32/libutil/include => core/elflink}/getkey.h |    0
 {com32/lib/syslinux => core/elflink}/ipappend.c  |    0
 core/elflink/kernel.c                            |  130 +++++++
 core/elflink/load_env32.c                        |  128 +++++++
 {com32/menu => core/elflink}/menu.h              |   17 +-
 {com32/menu => core/elflink}/readconfig.c        |  264 ++++++++++-----
 {com32/menu => core/elflink}/refstr.c            |    1 +
 {com32/menu => core/elflink}/refstr.h            |    0
 {com32/lib/syslinux => core/elflink}/setadv.c    |    0
 23 files changed, 1141 insertions(+), 99 deletions(-)

diff --git a/MCONFIG.devel b/MCONFIG.devel
deleted file mode 100644
index 104207f..0000000
--- a/MCONFIG.devel
+++ /dev/null
@@ -1,2 +0,0 @@
-# Useful while doing development, but not for production.
-GCCWARN += -Wno-clobbered -Werror
diff --git a/core/elflink/abort_new.c b/core/elflink/abort_new.c
new file mode 100644
index 0000000..39ba226
--- /dev/null
+++ b/core/elflink/abort_new.c
@@ -0,0 +1,29 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+
+//#include <syslinux/loadfile.h>
+//#include <syslinux/linux.h>
+//#include <syslinux/pxe.h>
+
+#include "core.h"
+#include "core-elf.h"
+#include "menu.h"
+
+void abort_load_new(com32sys_t *reg)
+{
+	char *str;
+
+	str = (void *)reg->esi.l;
+
+	printf("Error!\n");
+	if (str)
+		printf("%s\n", str);
+
+	if (onerrorlen)
+		execute(start_menu->onerror, KT_NONE);
+	enter_cmdline();
+	return;
+}
diff --git a/com32/lib/syslinux/adv.c b/core/elflink/adv.c
similarity index 100%
copy from com32/lib/syslinux/adv.c
copy to core/elflink/adv.c
diff --git a/com32/lib/syslinux/advwrite.c b/core/elflink/advwrite.c
similarity index 100%
copy from com32/lib/syslinux/advwrite.c
copy to core/elflink/advwrite.c
diff --git a/core/elflink/cli.c b/core/elflink/cli.c
new file mode 100644
index 0000000..2e223ae
--- /dev/null
+++ b/core/elflink/cli.c
@@ -0,0 +1,406 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+#include <syslinux/adv.h>
+#include <syslinux/config.h>
+#include <setjmp.h>
+#include <netinet/in.h>
+#include <limits.h>
+#include <minmax.h>
+#include <linux/list.h>
+#include <sys/exec.h>
+#include <sys/module.h>
+#include "getkey.h"
+
+#include "common.h"
+#include "menu.h"
+#include "cli.h"
+
+void clear_screen(void)
+{
+    fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
+}
+
+int mygetkey(clock_t timeout)
+{
+    clock_t t0, t;
+    clock_t tto, to;
+    int key;
+
+    if (!totaltimeout)
+	return get_key(stdin, timeout);
+
+    for (;;) {
+	tto = min(totaltimeout, INT_MAX);
+	to = timeout ? min(tto, timeout) : tto;
+
+	t0 = times(NULL);
+	key = get_key(stdin, to);
+	t = times(NULL) - t0;
+
+	if (totaltimeout <= t)
+	    longjmp(timeout_jump, 1);
+
+	totaltimeout -= t;
+
+	if (key != KEY_NONE)
+	    return key;
+
+	if (timeout) {
+	    if (timeout <= t)
+		return KEY_NONE;
+
+	    timeout -= t;
+	}
+    }
+}
+
+const char *edit_cmdline(const char *input, int top /*, int width */ ,
+			 int (*pDraw_Menu) (int, int, int),
+			 void (*show_fkey) (int))
+{
+    static char cmdline[MAX_CMDLINE_LEN];
+    char temp_cmdline[MAX_CMDLINE_LEN] = { };
+    int key, len, prev_len, cursor;
+    int redraw = 1;		/* We enter with the menu already drawn */
+    int x, y;
+    bool done = false;
+    const char *ret;
+    int width = 0;
+    struct cli_command *comm_counter;
+    comm_counter =
+	list_entry(cli_history_head.next->prev, typeof(*comm_counter), list);
+
+    if (!width) {
+	int height;
+	if (getscreensize(1, &height, &width))
+	    width = 80;
+    }
+    //printf("width = %d\n", width);
+
+    strncpy(cmdline, input, MAX_CMDLINE_LEN);
+    cmdline[MAX_CMDLINE_LEN - 1] = '\0';
+
+    len = cursor = strlen(cmdline);
+    prev_len = 0;
+    x = y = 0;
+
+    while (!done) {
+	if (redraw > 1 && pDraw_Menu != NULL) {
+	    /* Clear and redraw whole screen */
+	    /* Enable ASCII on G0 and DEC VT on G1; do it in this order
+	       to avoid confusing the Linux console */
+	    /* clear_screen();
+	       draw_menu(-1, top, 1); */
+	    clear_screen();
+	    (*pDraw_Menu) (-1, top, 1);
+	    prev_len = 0;
+	    // printf("\033[0m\033[2J\033[H");
+	}
+
+	if (redraw > 0) {
+	    int dy, at;
+
+	    prev_len = max(len, prev_len);
+
+	    /* Redraw the command line */
+	    printf("\033[?7l\033[?25l");
+	    if (y)
+		printf("\033[%dA", y);
+	    printf("\033[1G\033[1;36m> \033[0m");
+
+	    x = 2;
+	    y = 0;
+	    at = 0;
+	    while (at < prev_len) {
+		putchar(at >= len ? ' ' : cmdline[at]);
+		at++;
+		x++;
+		if (x >= width) {
+		    printf("\r\n");
+		    x = 0;
+		    y++;
+		}
+	    }
+	    printf("\033[K\r");
+
+	    dy = y - (cursor + 2) / width;
+	    x = (cursor + 2) % width;
+
+	    if (dy) {
+		printf("\033[%dA", dy);
+		y -= dy;
+	    }
+	    if (x)
+		printf("\033[%dC", x);
+	    printf("\033[?25h");
+	    prev_len = len;
+	    redraw = 0;
+	}
+
+	key = mygetkey(0);
+
+	switch (key) {
+	case KEY_CTRL('L'):
+	    redraw = 2;
+	    break;
+
+	case KEY_ENTER:
+	case KEY_CTRL('J'):
+	    ret = cmdline;
+	    done = true;
+	    break;
+
+	case KEY_ESC:
+	case KEY_CTRL('C'):
+	    ret = NULL;
+	    done = true;
+	    break;
+
+	case KEY_BACKSPACE:
+	case KEY_DEL:
+	    if (cursor) {
+		memmove(cmdline + cursor - 1, cmdline + cursor,
+			len - cursor + 1);
+		len--;
+		cursor--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('D'):
+	case KEY_DELETE:
+	    if (cursor < len) {
+		memmove(cmdline + cursor, cmdline + cursor + 1, len - cursor);
+		len--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('U'):
+	    if (len) {
+		len = cursor = 0;
+		cmdline[len] = '\0';
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('W'):
+	    if (cursor) {
+		int prevcursor = cursor;
+
+		while (cursor && my_isspace(cmdline[cursor - 1]))
+		    cursor--;
+
+		while (cursor && !my_isspace(cmdline[cursor - 1]))
+		    cursor--;
+
+#if 0
+		memmove(cmdline + cursor, cmdline + prevcursor,
+			len - prevcursor + 1);
+#else
+		{
+		    int i;
+		    char *q = cmdline + cursor;
+		    char *p = cmdline + prevcursor;
+		    for (i = 0; i < len - prevcursor + 1; i++)
+			*q++ = *p++;
+		}
+#endif
+		len -= (prevcursor - cursor);
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_LEFT:
+	case KEY_CTRL('B'):
+	    if (cursor) {
+		cursor--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_RIGHT:
+	case KEY_CTRL('F'):
+	    if (cursor < len) {
+		putchar(cmdline[cursor]);
+		cursor++;
+		x++;
+		if (x >= width) {
+		    printf("\r\n");
+		    y++;
+		    x = 0;
+		}
+	    }
+	    break;
+
+	case KEY_CTRL('K'):
+	    if (cursor < len) {
+		cmdline[len = cursor] = '\0';
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_HOME:
+	case KEY_CTRL('A'):
+	    if (cursor) {
+		cursor = 0;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_END:
+	case KEY_CTRL('E'):
+	    if (cursor != len) {
+		cursor = len;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_F1:
+	case KEY_F2:
+	case KEY_F3:
+	case KEY_F4:
+	case KEY_F5:
+	case KEY_F6:
+	case KEY_F7:
+	case KEY_F8:
+	case KEY_F9:
+	case KEY_F10:
+	case KEY_F11:
+	case KEY_F12:
+	    if (show_fkey != NULL) {
+		(*show_fkey) (key);
+		redraw = 1;
+	    }
+	    break;
+	case KEY_UP:
+	    {
+		if (!list_empty(&cli_history_head)) {
+		    comm_counter =
+			list_entry(comm_counter->list.next,
+				   typeof(*comm_counter), list);
+		    if (&comm_counter->list == &cli_history_head) {
+			strcpy(cmdline, temp_cmdline);
+		    } else {
+			strcpy(cmdline, comm_counter->command);
+		    }
+		    cursor = len = strlen(cmdline);
+		    redraw = 1;
+		}
+	    }
+	    break;
+	case KEY_DOWN:
+	    {
+		if (!list_empty(&cli_history_head)) {
+		    comm_counter =
+			list_entry(comm_counter->list.prev,
+				   typeof(*comm_counter), list);
+		    if (&comm_counter->list == &cli_history_head) {
+			strcpy(cmdline, temp_cmdline);
+		    } else {
+			strcpy(cmdline, comm_counter->command);
+		    }
+		    cursor = len = strlen(cmdline);
+		    redraw = 1;
+		}
+	    }
+	    break;
+	default:
+	    if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) {
+		if (cursor == len) {
+		    temp_cmdline[len] = key;
+		    cmdline[len++] = key;
+		    temp_cmdline[len] = cmdline[len] = '\0';
+		    putchar(key);
+		    cursor++;
+		    x++;
+		    if (x >= width) {
+			printf("\r\n\033[K");
+			y++;
+			x = 0;
+		    }
+		    prev_len++;
+		} else {
+		    memmove(cmdline + cursor + 1, cmdline + cursor,
+			    len - cursor + 1);
+		    memmove(temp_cmdline + cursor + 1, temp_cmdline + cursor,
+			    len - cursor + 1);
+		    temp_cmdline[cursor] = key;
+		    cmdline[cursor++] = key;
+		    len++;
+		    redraw = 1;
+		}
+	    }
+	    break;
+	}
+    }
+
+    printf("\033[?7h");
+    return ret;
+}
+
+void process_command(const char *cmd)
+{
+	char **argv = malloc((MAX_COMMAND_ARGS + 1) * sizeof(char *));
+	char *temp_cmd = (char *)malloc(sizeof(char) * (strlen(cmd) + 1));
+	int argc = 1, len_mn;
+	char *crt_arg, *module_name;
+
+	/* return if user only press enter */
+	if (cmd[0] == '\0') {
+		printf("\n");
+		return;
+	}
+
+	strcpy(temp_cmd, cmd);
+	module_name = strtok(cmd, COMMAND_DELIM);
+	len_mn = strlen(module_name);
+
+	printf("\n");
+	mp("enter, cmd = %s, module_name = %s",cmd, module_name);
+
+	if (!strcmp(module_name + len_mn - 4, ".c32")) {
+		if (module_find(module_name) != NULL) {
+			/* make module re-enterable */
+			mp("Module %s is already running");
+			//goto cleanup;
+		}
+		do {
+			argv[0] = module_name;
+			crt_arg = strtok(NULL, COMMAND_DELIM);
+			if (crt_arg != NULL && strlen(crt_arg) > 0) {
+				argv[argc] = crt_arg;
+				argc++;
+			} else
+				break;
+		} while (argc < MAX_COMMAND_ARGS);
+		argv[argc] = NULL;
+		module_load_dependencies(module_name, MODULES_DEP);
+		spawn_load(module_name, argv);
+	} else if (!strcmp(module_name + len_mn - 2, ".0")) {
+		execute(cmd, KT_PXE);
+	} else if (!strcmp(module_name + len_mn - 3, ".bs")) {
+	} else if (!strcmp(module_name + len_mn - 4, ".img")) {
+		execute(cmd, KT_FDIMAGE);
+	} else if (!strcmp(module_name + len_mn - 4, ".bin")) {
+	} else if (!strcmp(module_name + len_mn - 4, ".bss")) {
+		execute(cmd, KT_BSS);
+	} else if (!strcmp(module_name + len_mn - 4, ".com")
+	       || !strcmp(module_name + len_mn - 4, ".cbt")) {
+		execute(cmd, KT_COMBOOT);
+	} else if (!strcmp(module_name + len_mn - 4, ".cfg")
+	       || !strcmp(module_name + len_mn - 5, ".conf")
+	       || !strcmp(module_name + len_mn - 7, ".config")) {
+		execute(module_name, KT_CONFIG);
+	}
+	/* use KT_KERNEL as default */
+	else
+		execute(temp_cmd, KT_KERNEL);
+
+cleanup:
+	free(argv);
+	free(temp_cmd);
+}
diff --git a/core/elflink/cli.h b/core/elflink/cli.h
new file mode 100644
index 0000000..9cd8c16
--- /dev/null
+++ b/core/elflink/cli.h
@@ -0,0 +1,23 @@
+#ifndef CLI_H
+#define CLI_H
+
+#define MAX_CMD_HISTORY 64
+#define COMMAND_DELIM		" \t\n"	// Whitespace delimiters
+#define MAX_COMMAND_ARGS	40
+
+struct cli_command {
+    struct list_head list;
+    char *command;
+};
+
+struct list_head cli_history_head;
+
+extern void clear_screen(void);
+extern int mygetkey(clock_t timeout);
+extern const char *edit_cmdline(const char *input, int top /*, int width */ ,
+				int (*pDraw_Menu) (int, int, int),
+				void (*show_fkey) (int));
+extern void process_command(const char *cmd);
+
+extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list, *default_menu;
+#endif
diff --git a/com32/menu/colors.c b/core/elflink/colors.c
similarity index 100%
copy from com32/menu/colors.c
copy to core/elflink/colors.c
diff --git a/core/elflink/common.h b/core/elflink/common.h
new file mode 100644
index 0000000..e288d1e
--- /dev/null
+++ b/core/elflink/common.h
@@ -0,0 +1,62 @@
+/*
+ * common.h - Common internal operations performed by the module subsystem
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb at zytor.com>
+ */
+
+#ifndef COMMON_H_
+#define COMMON_H_
+
+#include <stdio.h>
+
+#include <sys/module.h>
+#include <linux/list.h>
+
+#include "elfutils.h"
+
+// Performs an operation and jumps to a given label if an error occurs
+#define CHECKED(res, expr, error)		\
+	do { 								\
+		(res) = (expr);					\
+		if ((res) < 0)					\
+			goto error;					\
+	} while (0)
+
+#define MIN(x,y)	(((x) < (y)) ? (x) : (y))
+#define MAX(x,y)	(((x) > (y)) ? (x) : (y))
+
+//#define ELF_DEBUG
+
+#ifdef ELF_DEBUG
+#define DBG_PRINT(fmt, args...)	fprintf(stderr, "[ELF] " fmt, ##args)
+#else
+#define DBG_PRINT(fmt, args...)	// Expand to nothing
+#endif
+
+// User-space debugging routines
+#ifdef ELF_DEBUG
+extern void print_elf_ehdr(Elf32_Ehdr * ehdr);
+extern void print_elf_symbols(struct elf_module *module);
+#endif //ELF_DEBUG
+
+/*
+ * Image files manipulation routines
+ */
+
+extern int image_load(struct elf_module *module);
+extern int image_unload(struct elf_module *module);
+extern int image_read(void *buff, size_t size, struct elf_module *module);
+extern int image_skip(size_t size, struct elf_module *module);
+extern int image_seek(Elf32_Off offset, struct elf_module *module);
+
+extern struct module_dep *module_dep_alloc(struct elf_module *module);
+
+extern int check_header_common(Elf32_Ehdr * elf_hdr);
+
+extern int enforce_dependency(struct elf_module *req, struct elf_module *dep);
+extern int clear_dependency(struct elf_module *req, struct elf_module *dep);
+
+extern int check_symbols(struct elf_module *module);
+
+#endif /* COMMON_H_ */
diff --git a/com32/lib/syslinux/config.c b/core/elflink/config.c
similarity index 100%
copy from com32/lib/syslinux/config.c
copy to core/elflink/config.c
diff --git a/core/elflink/core-elf.h b/core/elflink/core-elf.h
new file mode 100644
index 0000000..1edd174
--- /dev/null
+++ b/core/elflink/core-elf.h
@@ -0,0 +1,16 @@
+#ifndef _CORE_ELF_H
+#define _coRE_ELF_H
+
+extern char *append;
+extern char *ippappend;
+extern char *globaldefault;
+extern short onerrorlen;
+
+extern void parse_configs(char **argv);
+extern int new_linux_kernel(char *okernel, char *ocmdline);
+
+/* load_env32.c, should be moved out */
+extern void enter_cmdline(void);
+
+extern void start_ui(char *config_file);
+#endif
diff --git a/core/elflink/elfutils.h b/core/elflink/elfutils.h
new file mode 100644
index 0000000..3c8e70f
--- /dev/null
+++ b/core/elflink/elfutils.h
@@ -0,0 +1,67 @@
+#ifndef ELF_UTILS_H_
+#define ELF_UTILS_H_
+
+#include <elf.h>
+#include <stdlib.h>
+
+/**
+ * elf_get_header - Returns a pointer to the ELF header structure.
+ * @elf_image: pointer to the ELF file image in memory
+ */
+static inline Elf32_Ehdr *elf_get_header(void *elf_image)
+{
+    return (Elf32_Ehdr *) elf_image;
+}
+
+/**
+ * elf_get_pht - Returns a pointer to the first entry in the PHT.
+ * @elf_image: pointer to the ELF file image in memory
+ */
+static inline Elf32_Phdr *elf_get_pht(void *elf_image)
+{
+    Elf32_Ehdr *elf_hdr = elf_get_header(elf_image);
+
+    return (Elf32_Phdr *) ((Elf32_Off) elf_hdr + elf_hdr->e_phoff);
+}
+
+//
+/**
+ * elf_get_ph - Returns the element with the given index in the PTH
+ * @elf_image: pointer to the ELF file image in memory
+ * @index: the index of the PHT entry to look for
+ */
+static inline Elf32_Phdr *elf_get_ph(void *elf_image, int index)
+{
+    Elf32_Phdr *elf_pht = elf_get_pht(elf_image);
+    Elf32_Ehdr *elf_hdr = elf_get_header(elf_image);
+
+    return (Elf32_Phdr *) ((Elf32_Off) elf_pht + index * elf_hdr->e_phentsize);
+}
+
+/**
+ * elf_hash - Returns the index in a SysV hash table for the symbol name.
+ * @name: the name of the symbol to look for
+ */
+extern unsigned long elf_hash(const unsigned char *name);
+
+/**
+ * elf_gnu_hash - Returns the index in a GNU hash table for the symbol name.
+ * @name: the name of the symbol to look for
+ */
+extern unsigned long elf_gnu_hash(const unsigned char *name);
+
+/**
+ * elf_malloc - Allocates memory to be used by ELF module contents.
+ * @memptr: pointer to a variable to hold the address of the allocated block.
+ * @alignment: alignment constraints of the block
+ * @size: the required size of the block
+ */
+extern int elf_malloc(void **memptr, size_t alignment, size_t size);
+
+/**
+ * elf_free - Releases memory previously allocated by elf_malloc.
+ * @memptr: the address of the allocated block
+ */
+extern void elf_free(void *memptr);
+
+#endif /*ELF_UTILS_H_ */
diff --git a/core/elflink/execute.c b/core/elflink/execute.c
new file mode 100644
index 0000000..1a7ce79
--- /dev/null
+++ b/core/elflink/execute.c
@@ -0,0 +1,85 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <com32.h>
+#include "menu.h"
+
+void execute(const char *cmdline, enum kernel_type type)
+{
+	com32sys_t ireg;
+	const char *p, *const *pp;
+	char *q = __com32.cs_bounce;
+	const char *kernel, *args;
+
+	/* work around for spawn_load parameter */
+	char *spawn_load_param[2] = { NULL, NULL};
+
+	memset(&ireg, 0, sizeof ireg);
+
+	kernel = q;
+	p = cmdline;
+	while (*p && !my_isspace(*p))
+		*q++ = *p++;
+	*q++ = '\0';
+
+	args = q;
+	while (*p && my_isspace(*p))
+		p++;
+
+	strcpy(q, p);
+
+	mp("kernel is %s, args = %s  type = %d \n", kernel, args, type);
+
+	if (kernel[0] == '.' && type == KT_NONE) {
+		/* 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 (type == KT_COM32) {
+		/* new entry for elf format c32 */
+		spawn_load_param[0] = args;
+		module_load_dependencies(kernel, "modules.dep");
+		spawn_load(kernel, spawn_load_param);
+	} else if (type <= KT_KERNEL) {
+		/* Need add one item for kernel load, as we don't use
+		* the assembly runkernel.inc any more */
+		new_linux_kernel(kernel, cmdline);
+	} else if (type == KT_CONFIG) {
+		/* kernel contains the config file name */
+		start_ui(kernel);
+	} else {
+		/* process the image need int 22 support */
+		if (type == KT_LOCALBOOT) {
+			ireg.eax.w[0] = 0x0014;	/* Local boot */
+			ireg.edx.w[0] = strtoul(kernel, NULL, 0);
+		}
+		ireg.eax.w[0] = 0x0016;	/* Run kernel image */
+		ireg.esi.w[0] = OFFS(kernel);
+		ireg.ds = SEG(kernel);
+		ireg.ebx.w[0] = OFFS(args);
+		ireg.es = SEG(args);
+		ireg.edx.l = type - KT_KERNEL;
+		/* ireg.ecx.l    = 0; *//* We do ipappend "manually" */
+
+		__intcall(0x22, &ireg, NULL);
+	}
+
+	/* If this returns, something went bad; return to menu */
+}
diff --git a/com32/libutil/get_key.c b/core/elflink/get_key.c
similarity index 97%
copy from com32/libutil/get_key.c
copy to core/elflink/get_key.c
index f277b43..ce82fd1 100644
--- a/com32/libutil/get_key.c
+++ b/core/elflink/get_key.c
@@ -39,8 +39,8 @@
 #include <unistd.h>
 #include <time.h>
 #include <sys/times.h>
-#include <getkey.h>
-#include <libutil.h>
+#include <sys/module.h>
+#include "getkey.h"
 
 struct keycode {
     int code;
@@ -49,7 +49,7 @@ struct keycode {
 };
 
 #define MAXLEN 8
-#define CODE(x,y) { x, (sizeof y)-1, (const unsigned char *)(y) }
+#define CODE(x,y) { x, (sizeof y)-1, y }
 
 static const struct keycode keycodes[] = {
     /* First, the BIOS combined codes */
@@ -145,7 +145,7 @@ int get_key(FILE * f, clock_t timeout)
 	    } else if (!nc && timeout && lateness > timeout)
 		return KEY_NONE;	/* timeout before sequence */
 
-	    do_idle();
+	    syslinux_idle();
 
 	    another = 1;
 	    continue;
diff --git a/com32/lib/syslinux/getadv.c b/core/elflink/getadv.c
similarity index 98%
copy from com32/lib/syslinux/getadv.c
copy to core/elflink/getadv.c
index 5578313..456084b 100644
--- a/com32/lib/syslinux/getadv.c
+++ b/core/elflink/getadv.c
@@ -39,7 +39,7 @@
 const void *syslinux_getadv(int tag, size_t * size)
 {
     const uint8_t *p;
-    size_t left;
+    size_t left, len;
 
     p = syslinux_adv_ptr();
     left = syslinux_adv_size();
diff --git a/com32/libutil/include/getkey.h b/core/elflink/getkey.h
similarity index 100%
copy from com32/libutil/include/getkey.h
copy to core/elflink/getkey.h
diff --git a/com32/lib/syslinux/ipappend.c b/core/elflink/ipappend.c
similarity index 100%
copy from com32/lib/syslinux/ipappend.c
copy to core/elflink/ipappend.c
diff --git a/core/elflink/kernel.c b/core/elflink/kernel.c
new file mode 100644
index 0000000..f8efa16
--- /dev/null
+++ b/core/elflink/kernel.c
@@ -0,0 +1,130 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/linux.h>
+#include <syslinux/pxe.h>
+#include "core.h"
+#include "core-elf.h"
+
+/* Will be called from readconfig.c */
+int new_linux_kernel(char *okernel, char *ocmdline)
+{
+	const char *kernel_name;
+	struct initramfs *initramfs;
+	char *temp;
+	void *kernel_data;
+	size_t kernel_len;
+	bool opt_quiet = false;
+	char initrd_name[256];
+	char cmdline_buf[256], *cmdline;
+	int i;
+
+	/* to make malloc works for code in com32/lib */
+	/*
+	openconsole(&dev_null_r, &dev_stdcon_w);
+	init_memory_arena();
+	*/
+
+	mp("okernel = %s, ocmdline = %s", okernel, ocmdline);
+
+	cmdline = cmdline_buf;
+
+	temp = cmdline;
+	/*
+	strcpy(temp, "BOOT_IMAGE=");
+	temp += 11;
+	*/
+
+	if (okernel)
+		kernel_name = okernel;
+	else if (globaldefault)
+		kernel_name = globaldefault;
+
+	strcpy(temp, kernel_name);
+	temp += strlen(kernel_name);
+
+	/* in elflink branch, KernelCName no more exist */	
+	/*
+	else {
+		strcpy(temp, KernelCName);
+		temp += strlen(KernelCName);
+		kernel_name = KernelCName;
+	}
+	*/
+
+	*temp = ' ';
+	temp++;
+	if (ocmdline)
+		strcpy(temp, ocmdline);
+	else if (append)
+		strcpy(temp, append);
+	/*	
+	else if (*(char *)CmdOptPtr)
+		strcpy(temp, (char *)CmdOptPtr);
+	else if (AppendLen) {
+		for (i = 0; i < AppendLen; i++)
+			*temp++ = AppendBuf[i];
+		*temp = '\0';
+	}
+	*/
+
+	printf("cmdline = %s\n", cmdline);
+	/*
+	printf("VkernelEnd = %x\n", VKernelEnd);
+	printf("HighMemSize = %x\n", __com32.cs_memsize);
+	*/
+
+	/* "keeppxe" handling */
+#if IS_PXELINUX
+	extern char KeepPXE;
+
+	if (strstr(cmdline, "keeppxe"))
+		KeepPXE |= 1;
+#endif
+
+	if (strstr(cmdline, "quiet"))
+		opt_quiet = true;
+
+	if (!opt_quiet)
+		printf("Loading %s... ", kernel_name);
+
+	if (loadfile(kernel_name, &kernel_data, &kernel_len)) {
+		if (opt_quiet)
+			printf("Loading %s ", kernel_name);
+		printf("failed!\n");
+		goto bail;
+	}
+
+	if (!opt_quiet)
+		printf("ok\n");
+
+	/* Initialize the initramfs chain */
+	initramfs = initramfs_init();
+	if (!initramfs)
+		goto bail;
+
+	/* Find and load initramfs */
+	temp = strstr(cmdline, "initrd=");
+	if (temp) {
+		i = 0;
+
+		temp += strlen("initrd=");
+		while (*temp != ' ' && *temp)
+			initrd_name[i++] = *temp++;
+		initrd_name[i] = '\0';
+
+		initramfs_load_archive(initramfs, initrd_name);
+	}
+
+	//mp("loading initrd done");
+
+	/* This should not return... */
+	syslinux_boot_linux(kernel_data, kernel_len, initramfs, cmdline);
+
+bail:
+	printf("Kernel load failure (insufficient memory?)\n");
+	return 1;
+}
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
new file mode 100644
index 0000000..4004162
--- /dev/null
+++ b/core/elflink/load_env32.c
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+#include <syslinux/adv.h>
+#include <syslinux/config.h>
+#include <setjmp.h>
+#include <linux/list.h>
+#include <netinet/in.h>
+#include <sys/cpu.h>
+
+#include <sys/exec.h>
+#include <sys/module.h>
+#include "common.h"
+#include "menu.h"
+#include "cli.h"
+#include "core-elf.h"
+
+typedef void (*constructor_t) (void);
+constructor_t __ctors_start[], __ctors_end[];
+
+extern char __dynstr_start[];
+extern char __dynstr_len[], __dynsym_len[];
+extern char __dynsym_start[];
+extern char __got_start[];
+extern Elf32_Dyn __dynamic_start[];
+extern Elf32_Word __gnu_hash_start[];
+
+struct elf_module core_module = {
+    .name		= "(core)",
+    .shallow		= true,
+    .required		= LIST_HEAD_INIT((core_module.required)),
+    .dependants		= LIST_HEAD_INIT((core_module.dependants)),
+    .list		= LIST_HEAD_INIT((core_module.list)),
+    .module_addr	= (void *)0x0,
+    .base_addr		= (Elf32_Addr) 0x0,
+    .ghash_table	= __gnu_hash_start,
+    .str_table		= __dynstr_start,
+    .sym_table		= __dynsym_start,
+    .got		= __got_start,
+    .dyn_table		= __dynamic_start,
+    .strtable_size	= (size_t) __dynstr_len,
+    .syment_size	= sizeof(Elf32_Sym),
+    .symtable_size	= (size_t) __dynsym_len
+};
+
+/*
+	Initializes the module subsystem by taking the core module ( shallow module ) and placing
+	it on top of the modules_head_list. Since the core module is initialized when declared
+	we technically don't need the exec_init() and module_load_shallow() procedures
+*/
+void init_module_subsystem(struct elf_module *module)
+{
+    list_add(&module->list, &modules_head);
+}
+
+/* call_constr: initializes sme things related */
+static void call_constr(void)
+{
+	constructor_t *p;
+
+	for (p = __ctors_start; p < __ctors_end; p++)
+		(*p) ();
+}
+
+void enter_cmdline(void)
+{
+	struct cli_command  *comm, *aux;
+	char *cmdline;
+
+	/* Enter endless command line prompt, should support "exit" */
+	while (1) {
+		cmdline = edit_cmdline("", 1, NULL, NULL);
+		/* feng: give up the aux check here */
+		//aux = list_entry(cli_history_head.next, typeof(*aux), list);
+		//if (strcmp(aux->command, cmdline)) {
+			comm = (struct cli_command *)malloc(sizeof(struct cli_command *));
+			comm->command =
+				(char *)malloc(sizeof(char) * (strlen(cmdline) + 1));
+			strcpy(comm->command, cmdline);
+			list_add(&(comm->list), &cli_history_head);
+			process_command(cmdline);
+		//}
+	}
+}
+
+/* parameter is the config file name if any */
+void start_ui(char *config_file)
+{
+	char *cmdline;
+	char *argv[2] = {config_file, NULL};
+
+	parse_configs(argv);
+	/* run the default menu if found */
+	/*
+	if (default_menu) {
+		cmdline = default_menu->menu_entries[default_menu->defentry]->cmdline;
+		if (*cmdline == '.') {
+			while (*cmdline++ != ' ');
+		}
+		process_command(cmdline);
+	}
+	*/
+
+	/* try to run a default linux kernel */
+	/*
+	if (append || globaldefault)
+		new_linux_kernel(NULL, NULL);
+	*/
+
+	/* Should never return */
+	enter_cmdline();
+}
+
+/* note to self: do _*NOT*_ use static key word on this function */
+void load_env32(com32sys_t * regs)
+{
+	call_constr();
+	openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+	INIT_LIST_HEAD(&cli_history_head);
+
+	printf("Starting 32 bit elf module subsystem...\n");
+	init_module_subsystem(&core_module);
+
+	start_ui(NULL);
+}
diff --git a/com32/menu/menu.h b/core/elflink/menu.h
similarity index 94%
copy from com32/menu/menu.h
copy to core/elflink/menu.h
index 63e1859..3bdf2d4 100644
--- a/com32/menu/menu.h
+++ b/core/elflink/menu.h
@@ -26,11 +26,9 @@
 #include <unistd.h>
 #include <colortbl.h>
 #include <stdbool.h>
+#include <setjmp.h>
 #include "refstr.h"
 
-/* #define DEBUG 1 */
-#include <dprintf.h>
-
 #ifndef CLK_TCK
 # define CLK_TCK sysconf(_SC_CLK_TCK)
 #endif
@@ -63,7 +61,6 @@ struct menu_entry {
     int entry;			/* Entry number inside menu */
     enum menu_action action;
     unsigned char hotkey;
-    bool immediate;		/* Hotkey action does not require Enter */
     bool save;			/* Save this entry if selected */
 };
 
@@ -157,7 +154,6 @@ struct menu {
     int timeout;
 
     bool allowedit;
-    bool immediate;		/* MENU IMMEDIATE default for this menu */
     bool save;			/* MENU SAVE default for this menu */
 
     int curentry;
@@ -182,14 +178,11 @@ extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
 /* These are global parameters regardless of which menu we're displaying */
 extern int shiftkey;
 extern int hiddenmenu;
-extern int clearmenu;
 extern long long totaltimeout;
+jmp_buf timeout_jump;
 
 void parse_configs(char **argv);
-int draw_background(const char *filename);
-void set_resolution(int x, int y);
-void start_console(void);
-void local_cursor_enable(bool);
+extern int draw_background(const char *filename);
 
 static inline int my_isspace(char c)
 {
@@ -201,6 +194,10 @@ unsigned int hexval(char c);
 unsigned int hexval2(const char *p);
 uint32_t parse_argb(char **p);
 
+int menu_main(int argc, char *argv[]);
+void console_prepare(void);
+void console_cleanup(void);
+
 extern const int message_base_color, menu_color_table_size;
 int mygetkey(clock_t timeout);
 int show_message_file(const char *filename, const char *background);
diff --git a/com32/menu/readconfig.c b/core/elflink/readconfig.c
similarity index 81%
copy from com32/menu/readconfig.c
copy to core/elflink/readconfig.c
index 5685e6f..faeda02 100644
--- a/com32/menu/readconfig.c
+++ b/core/elflink/readconfig.c
@@ -1,7 +1,7 @@
 /* ----------------------------------------------------------------------- *
  *
  *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
- *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -25,21 +25,52 @@
 
 #include "menu.h"
 
+const struct menu_parameter mparm[NPARAMS] = {
+    [P_WIDTH] = {"width", 0},
+    [P_MARGIN] = {"margin", 10},
+    [P_PASSWD_MARGIN] = {"passwordmargin", 3},
+    [P_MENU_ROWS] = {"rows", 12},
+    [P_TABMSG_ROW] = {"tabmsgrow", 18},
+    [P_CMDLINE_ROW] = {"cmdlinerow", 18},
+    [P_END_ROW] = {"endrow", -1},
+    [P_PASSWD_ROW] = {"passwordrow", 11},
+    [P_TIMEOUT_ROW] = {"timeoutrow", 20},
+    [P_HELPMSG_ROW] = {"helpmsgrow", 22},
+    [P_HELPMSGEND_ROW] = {"helpmsgendrow", -1},
+    [P_HSHIFT] = {"hshift", 0},
+    [P_VSHIFT] = {"vshift", 0},
+    [P_HIDDEN_ROW] = {"hiddenrow", -2},
+};
+
+short uappendlen;		//bytes in append= command
+short ontimeoutlen;		//bytes in ontimeout command
+short onerrorlen;		//bytes in onerror command
+short forceprompt;		//force prompt
+short noescape;			//no escape
+short nocomplete;		//no label completion on TAB key
+short allowimplicit = 1;	//allow implicit kernels
+short allowoptions = 1;		//user-specified options allowed
+short includelevel = 1;		//nesting level
+short defaultlevel;		//the current level of default
+short vkernel;			//have we seen any "label" statements?
+short displaycon = 1;		//conio.inc
+short nohalt = 1;		//idle.inc
+
+
 /* Empty refstring */
 const char *empty_string;
 
 /* Root menu, starting menu, hidden menu, and list of all menus */
-struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
+struct menu *root_menu, *start_menu, *hide_menu, *menu_list, *default_menu;
 
 /* These are global parameters regardless of which menu we're displaying */
 int shiftkey = 0;		/* Only display menu if shift key pressed */
 int hiddenmenu = 0;
-int clearmenu = 0;
 long long totaltimeout = 0;
 
 /* Keep track of global default */
 static int has_ui = 0;		/* DEFAULT only counts if UI is found */
-static const char *globaldefault = NULL;
+char *globaldefault = NULL;
 static bool menusave = false;	/* True if there is any "menu save" */
 
 /* Linked list of all entires, hidden or not; used by unlabel() */
@@ -153,6 +184,8 @@ static struct menu *new_menu(struct menu *parent,
 {
     struct menu *m = calloc(1, sizeof(struct menu));
     int i;
+	
+	//mp("enter: menu_label = %s", label);
 
     m->label = label;
     m->title = refstr_get(empty_string);
@@ -172,7 +205,6 @@ static struct menu *new_menu(struct menu *parent,
 	m->allowedit = parent->allowedit;
 	m->timeout = parent->timeout;
 	m->save = parent->save;
-	m->immediate = parent->immediate;
 
 	m->ontimeout = refstr_get(parent->ontimeout);
 	m->onerror = refstr_get(parent->onerror);
@@ -220,7 +252,6 @@ struct labeldata {
     unsigned int menuindent;
     enum menu_action action;
     int save;
-    int immediate;
     struct menu *submenu;
 };
 
@@ -243,6 +274,8 @@ static struct menu_entry *new_entry(struct menu *m)
 {
     struct menu_entry *me;
 
+    //mp("enter, call from menu %s", m->label);
+
     if (m->nentries >= m->nentries_space) {
 	if (!m->nentries_space)
 	    m->nentries_space = 1;
@@ -280,18 +313,17 @@ static void consider_for_hotkey(struct menu *m, struct menu_entry *me)
 
 static void record(struct menu *m, struct labeldata *ld, const char *append)
 {
-    int i;
-    struct menu_entry *me;
-    const struct syslinux_ipappend_strings *ipappend;
+	int i;
+	struct menu_entry *me;
+	const struct syslinux_ipappend_strings *ipappend;
 
-    if (!ld->label)
-	return;			/* Nothing defined */
+	if (!ld->label)
+		return;			/* Nothing defined */
 
-    /* Hidden entries are recorded on a special "hidden menu" */
-    if (ld->menuhide)
-	m = hide_menu;
+	/* Hidden entries are recorded on a special "hidden menu" */
+	if (ld->menuhide)
+		m = hide_menu;
 
-    if (ld->label) {
 	char ipoptions[4096], *ipp;
 	const char *a;
 	char *s;
@@ -306,7 +338,6 @@ static void record(struct menu *m, struct labeldata *ld, const char *append)
 	me->hotkey = 0;
 	me->action = ld->action ? ld->action : MA_CMD;
 	me->save = ld->save ? (ld->save > 0) : m->save;
-	me->immediate = ld->immediate ? (ld->immediate > 0) : m->immediate;
 
 	if (ld->menuindent) {
 	    const char *dn;
@@ -354,12 +385,13 @@ static void record(struct menu *m, struct labeldata *ld, const char *append)
 	    if (!a || (a[0] == '-' && !a[1]))
 		a = "";
 	    s = a[0] ? " " : "";
-	    if (ld->type == KT_KERNEL) {
+
+	    if (ld->type == KT_KERNEL)
 		rsprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions);
-	    } else {
+	    else
 		rsprintf(&me->cmdline, ".%s %s%s%s%s",
 			 kernel_types[ld->type], ld->kernel, s, a, ipoptions);
-	    }
+		mp("type = %s, cmd = %s", kernel_types[ld->type], me->cmdline);
 	    break;
 
 	case MA_GOTO_UNRES:
@@ -378,7 +410,6 @@ static void record(struct menu *m, struct labeldata *ld, const char *append)
 
 	if (ld->menudefault && me->action == MA_CMD)
 	    m->defentry = m->nentries - 1;
-    }
 
     clear_label_data(ld);
 }
@@ -547,8 +578,10 @@ uint32_t parse_argb(char **p)
  * files work as expected, which is that everything works the
  * same way as if the files had been concatenated together.
  */
-static const char *append = NULL;
-static unsigned int ipappend = 0;
+//static const char *append = NULL;
+char *append = NULL;
+//static unsigned int ipappend = 0;
+unsigned int ipappend = 0;
 static struct labeldata ld;
 
 static int parse_one_config(const char *filename);
@@ -606,9 +639,9 @@ static char *is_fkey(char *cmdstr, int *fkeyno)
 static void parse_config_file(FILE * f)
 {
     char line[MAX_LINE], *p, *ep, ch;
-    enum kernel_type type = -1;
-    enum message_number msgnr = -1;
-    int fkeyno = 0;
+    enum kernel_type type;
+    enum message_number msgnr;
+    int fkeyno;
     struct menu *m = current_menu;
 
     while (fgets(line, sizeof line, f)) {
@@ -622,32 +655,33 @@ static void parse_config_file(FILE * f)
 	p = skipspace(line);
 
 	if (looking_at(p, "menu")) {
+
 	    p = skipspace(p + 4);
 
 	    if (looking_at(p, "label")) {
-		if (ld.label) {
-		    refstr_put(ld.menulabel);
-		    ld.menulabel = refstrdup(skipspace(p + 5));
-		} else if (m->parent_entry) {
-		    refstr_put(m->parent_entry->displayname);
-		    m->parent_entry->displayname = refstrdup(skipspace(p + 5));
-		    consider_for_hotkey(m->parent, m->parent_entry);
-		    if (!m->title[0]) {
-			/* MENU LABEL -> MENU TITLE on submenu */
+			if (ld.label) {
+				refstr_put(ld.menulabel);
+				ld.menulabel = refstrdup(skipspace(p + 5));
+			} else if (m->parent_entry) {
+				refstr_put(m->parent_entry->displayname);
+				m->parent_entry->displayname = refstrdup(skipspace(p + 5));
+				consider_for_hotkey(m->parent, m->parent_entry);
+				if (!m->title[0]) {
+				/* MENU LABEL -> MENU TITLE on submenu */
+				refstr_put(m->title);
+				m->title = strip_caret(m->parent_entry->displayname);
+				}
+			}
+			} else if (looking_at(p, "title")) {
 			refstr_put(m->title);
-			m->title = strip_caret(m->parent_entry->displayname);
-		    }
-		}
-	    } else if (looking_at(p, "title")) {
-		refstr_put(m->title);
-		m->title = refstrdup(skipspace(p + 5));
-		if (m->parent_entry) {
-		    /* MENU TITLE -> MENU LABEL on submenu */
-		    if (m->parent_entry->displayname == m->label) {
-			refstr_put(m->parent_entry->displayname);
-			m->parent_entry->displayname = refstr_get(m->title);
-		    }
-		}
+			m->title = refstrdup(skipspace(p + 5));
+			if (m->parent_entry) {
+				/* MENU TITLE -> MENU LABEL on submenu */
+				if (m->parent_entry->displayname == m->label) {
+				refstr_put(m->parent_entry->displayname);
+				m->parent_entry->displayname = refstr_get(m->title);
+				}
+			}
 	    } else if (looking_at(p, "default")) {
 		if (ld.label) {
 		    ld.menudefault = 1;
@@ -677,19 +711,10 @@ static void parse_config_file(FILE * f)
 		    ld.save = -1;
 		else
 		    m->save = false;
-	    } else if (looking_at(p, "immediate")) {
-		if (ld.label)
-		    ld.immediate = 1;
-		else
-		    m->immediate = true;
-	    } else if (looking_at(p, "noimmediate")) {
-		if (ld.label)
-		    ld.immediate = -1;
-		else
-		    m->immediate = false;
 	    } else if (looking_at(p, "onerror")) {
 		refstr_put(m->onerror);
 		m->onerror = refstrdup(skipspace(p + 7));
+		onerrorlen = strlen(m->onerror);
 	    } else if (looking_at(p, "master")) {
 		p = skipspace(p + 6);
 		if (looking_at(p, "passwd")) {
@@ -704,8 +729,6 @@ static void parse_config_file(FILE * f)
 		m->menu_background = refdup_word(&p);
 	    } else if ((ep = looking_at(p, "hidden"))) {
 		hiddenmenu = 1;
-	    } else if ((ep = looking_at(p, "clear"))) {
-		clearmenu = 1;
 	    } else if ((ep = is_message_name(p, &msgnr))) {
 		refstr_put(m->messages[msgnr]);
 		m->messages[msgnr] = refstrdup(skipspace(ep));
@@ -834,11 +857,6 @@ static void parse_config_file(FILE * f)
 		}
 	    } else if (looking_at(p, "start")) {
 		start_menu = m;
-	    } else if ((ep = looking_at(p, "resolution"))) {
-		int x, y;
-		x = strtoul(ep, &ep, 0);
-		y = strtoul(skipspace(ep), NULL, 0);
-		set_resolution(x, y);
 	    } else {
 		/* Unknown, check for layout parameters */
 		enum parameter_number mp;
@@ -849,7 +867,11 @@ static void parse_config_file(FILE * f)
 		    }
 		}
 	    }
-	} else if (looking_at(p, "text")) {
+	}
+	/* feng: menu handling end */	
+	else if (looking_at(p, "text")) {
+
+		/* loop till we fined the "endtext" */
 	    enum text_cmd {
 		TEXT_UNKNOWN,
 		TEXT_HELP
@@ -923,6 +945,7 @@ do_include:
 		refstr_put(append);
 		append = a;
 	    }
+	    //mp("we got a append: %s", a);
 	} else if (looking_at(p, "initrd")) {
 	    const char *a = refstrdup(skipspace(p + 6));
 	    if (ld.label) {
@@ -933,9 +956,11 @@ do_include:
 	    }
 	} else if (looking_at(p, "label")) {
 	    p = skipspace(p + 5);
+	    /* when first time see "label", it will not really record anything */
 	    record(m, &ld, append);
 	    ld.label = refstrdup(p);
 	    ld.kernel = refstrdup(p);
+	    /* feng: this is the default type for all */
 	    ld.type = KT_KERNEL;
 	    ld.passwd = NULL;
 	    ld.append = NULL;
@@ -950,6 +975,7 @@ do_include:
 		refstr_put(ld.kernel);
 		ld.kernel = refstrdup(skipspace(ep));
 		ld.type = type;
+		//mp("got a kernel: %s, type = %d", ld.kernel, ld.type);
 	    }
 	} else if (looking_at(p, "timeout")) {
 	    m->timeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10;
@@ -965,33 +991,84 @@ do_include:
 	    else
 		ipappend = atoi(skipspace(p + 8));
 	} else if (looking_at(p, "default")) {
-	    refstr_put(globaldefault);
-	    globaldefault = refstrdup(skipspace(p + 7));
+		/* default could be a kernel image or another label */
+		refstr_put(globaldefault);
+		globaldefault = refstrdup(skipspace(p + 7));
 	} else if (looking_at(p, "ui")) {
 	    has_ui = 1;
 	}
+	
+	/*
+	 * subset 1:  pc_opencmd 
+	 * display/font/kbdmap are rather similar, open a file then do sth
+	 */
+	else if (looking_at(p, "display")) {
+
+	} else if (looking_at(p, "font")) {
+
+	} else if (looking_at(p, "kbdmap")) {
+
+	}
+	/*
+	 * subset 2:  pc_setint16
+	 * set a global flag
+	 */
+	else if (looking_at(p, "implicit")) {
+		allowimplicit = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "prompt")) {
+		forceprompt = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "console")) {
+		displaycon = atoi(skipspace(p + 7));
+	} else if (looking_at(p, "allowoptions")) {
+		allowoptions = atoi(skipspace(p + 12));
+	} else if (looking_at(p, "noescape")) {
+		noescape = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "nocomplete")) {
+		nocomplete = atoi(skipspace(p + 10));
+	} else if (looking_at(p, "nohalt")) {
+		nohalt = atoi(skipspace(p + 8));
+	}
+
+	/* serial setting, bps, flow control */
+	else if (looking_at(p, "serial")) {
+		/* core/conio.inc
+		 * should be able to find some code in com32
+		 */
+
+	} else if (looking_at(p, "say")) {
+		printf("%s\n", p + 4);
+	}
     }
 }
 
 static int parse_one_config(const char *filename)
 {
-    FILE *f;
+	FILE *f;
+	int i;
 
-    if (!strcmp(filename, "~"))
-	filename = syslinux_config_file();
+	/*
+	if (!strcmp(filename, "~"))
+		filename = syslinux_config_file();
+	*/
 
-    dprintf("Opening config file: %s ", filename);
+	f = fopen(filename, "r");
+	if (f)
+		goto config_found;
 
-    f = fopen(filename, "r");
-    dprintf("%s\n", f ? "ok" : "failed");
-    
-    if (!f)
-	return -1;
+	/* force to use hard coded config file name */
+	f = fopen("extlinux.conf", "r");
+	if (f)
+		goto config_found;
 
-    parse_config_file(f);
-    fclose(f);
+	f = fopen("isolinux.cfg", "r");
+	if (f)
+		goto config_found;
 
-    return 0;
+	return -1;
+config_found:
+	parse_config_file(f);
+	fclose(f);
+	return 0;
 }
 
 static void resolve_gotos(void)
@@ -1014,14 +1091,31 @@ static void resolve_gotos(void)
     }
 }
 
+static void dump_menu(struct menu *menu)
+{
+	mp("will dump menu for %s:", menu->label);
+	printf("entries num: %d\n", menu->nentries);
+	printf("defentry: %d, nam = %s\n",
+		menu->defentry, menu->menu_entries[menu->defentry]->label);
+	printf("save: %d\n", menu->save);
+	//printf("", menu->);
+	//printf("", menu->);
+	//printf("", menu->);
+}
+
 void parse_configs(char **argv)
 {
     const char *filename;
     struct menu *m;
     struct menu_entry *me;
+    char *cmdline;
 
     empty_string = refstrdup("");
 
+    /* feng: reset current menu_list and entry list */
+    menu_list = NULL;
+    all_entries = NULL;
+
     /* Initialize defaults for the root and hidden menus */
     hide_menu = new_menu(NULL, NULL, refstrdup(".hidden"));
     root_menu = new_menu(NULL, NULL, refstrdup(".top"));
@@ -1032,11 +1126,14 @@ void parse_configs(char **argv)
 
     /* Actually process the files */
     current_menu = root_menu;
-    if (!*argv) {
+
+    if (!argv || !*argv) {
 	parse_one_config("~");
     } else {
-	while ((filename = *argv++))
+	while ((filename = *argv++)) {
+		mp("Parsing config: %s", filename);
 	    parse_one_config(filename);
+	}
     }
 
     /* On final EOF process the last label statement */
@@ -1046,11 +1143,14 @@ void parse_configs(char **argv)
     resolve_gotos();
 
     /* Handle global default */
-    if (has_ui && globaldefault) {
+    //if (has_ui && globaldefault) {
+    if (globaldefault) {
+	mp("gloabldefault = %s", globaldefault);
 	me = find_label(globaldefault);
 	if (me && me->menu != hide_menu) {
 	    me->menu->defentry = me->entry;
 	    start_menu = me->menu;
+	    default_menu = me->menu;
 	}
     }
 
diff --git a/com32/menu/refstr.c b/core/elflink/refstr.c
similarity index 98%
copy from com32/menu/refstr.c
copy to core/elflink/refstr.c
index 97ab1ed..f9d98e1 100644
--- a/com32/menu/refstr.c
+++ b/core/elflink/refstr.c
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <sys/module.h>
 #include "refstr.h"
 
 /* Allocate space for a refstring of len bytes, plus final null */
diff --git a/com32/menu/refstr.h b/core/elflink/refstr.h
similarity index 100%
copy from com32/menu/refstr.h
copy to core/elflink/refstr.h
diff --git a/com32/lib/syslinux/setadv.c b/core/elflink/setadv.c
similarity index 100%
copy from com32/lib/syslinux/setadv.c
copy to core/elflink/setadv.c



More information about the Syslinux-commits mailing list