diff --git a/syslinux-3.86-com32.diff b/syslinux-3.86-com32.diff new file mode 100644 index 0000000..23bb085 --- /dev/null +++ b/syslinux-3.86-com32.diff @@ -0,0 +1,571 @@ +From b6b0153590283ea5c19973837b2978710f170b29 Mon Sep 17 00:00:00 2001 +From: Steffen Winterfeldt +Date: Tue, 13 Apr 2010 17:38:39 +0200 +Subject: [PATCH 1/4] support MENU LABEL statement + + +Signed-off-by: Steffen Winterfeldt +--- + com32/gfxboot/gfxboot.c | 49 +++++++++++++++++++++++++++++++++++++--------- + 1 files changed, 39 insertions(+), 10 deletions(-) + +diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c +index bfdd8cc..e0ff8f5 100644 +--- a/com32/gfxboot/gfxboot.c ++++ b/com32/gfxboot/gfxboot.c +@@ -165,7 +165,7 @@ void gfx_done(void); + int gfx_input(void); + ssize_t save_read(int fd, void *buf, size_t size); + void *load_one(char *file, ssize_t *file_size); +-void boot(void); ++void boot(int index); + void boot_entry(menu_t *menu_ptr, char *arg); + + +@@ -234,7 +234,7 @@ int main(int argc, char **argv) + } + + // does not return if it succeeds +- boot(); ++ boot(menu_index); + } + + if(argc > 2) show_message(argv[2]); +@@ -374,6 +374,20 @@ int read_config_file(void) + (menu_ptr ?: menu_default)->ipappend = strdup(t); + continue; + } ++ ++ if(!strcmp(s, "menu") && menu_ptr) { ++ s = skip_spaces(t); ++ t = skip_nonspaces(s); ++ if(*t) *t++ = 0; ++ t = skip_spaces(t); ++ ++ if(!strcmp(s, "label")) { ++ menu_ptr->label = strdup(t); ++ u = strlen(t); ++ if(u > label_size) label_size = u; ++ continue; ++ } ++ } + } + + fclose(f); +@@ -686,20 +700,35 @@ void *load_one(char *file, ssize_t *file_size) + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-// Locate menu entry and boot. ++// Boot menu entry. + // +-void boot(void) ++// cmdline can optionally start with label string. ++// ++void boot(int index) + { +- char *label, *arg, *s; ++ char *arg; + menu_t *menu_ptr; ++ int label_len; ++ ++ for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, index--) { ++ if(!index) break; ++ } ++ ++ // invalid index or menu entry ++ if(!menu_ptr || !menu_ptr->label) return; + +- label = skip_spaces(cmdline); +- arg = skip_spaces(s = skip_nonspaces(label)); +- *s = 0; ++ arg = skip_spaces(cmdline); ++ label_len = strlen(menu_ptr->label); + +- for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next) { +- if(menu_ptr->label && !strcmp(menu_ptr->label, label)) break; ++ // if it does not start with label string, skip first word ++ if(strncmp(arg, menu_ptr->label, label_len)) { ++ arg = skip_nonspaces(arg); + } ++ else { ++ arg += label_len; ++ } ++ ++ arg = skip_spaces(arg); + + boot_entry(menu_ptr, arg); + } +-- +1.6.4.2 + +From 190f963602576b46ef3b01543f5a586bea84156c Mon Sep 17 00:00:00 2001 +From: Steffen Winterfeldt +Date: Tue, 13 Apr 2010 17:39:46 +0200 +Subject: [PATCH 2/4] make config statements case-insensitive + + +Signed-off-by: Steffen Winterfeldt +--- + com32/gfxboot/gfxboot.c | 22 +++++++++++----------- + 1 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c +index e0ff8f5..c300dcb 100644 +--- a/com32/gfxboot/gfxboot.c ++++ b/com32/gfxboot/gfxboot.c +@@ -321,19 +321,19 @@ int read_config_file(void) + if(*t) *t++ = 0; + t = skip_spaces(t); + +- if(!strcmp(s, "timeout")) { ++ if(!strcasecmp(s, "timeout")) { + timeout = atoi(t); + continue; + } + +- if(!strcmp(s, "default")) { ++ if(!strcasecmp(s, "default")) { + menu_default->label = strdup(t); + u = strlen(t); + if(u > label_size) label_size = u; + continue; + } + +- if(!strcmp(s, "label")) { ++ if(!strcasecmp(s, "label")) { + menu_ptr = *menu_next = calloc(1, sizeof **menu_next); + menu_next = &menu_ptr->next; + menu_idx++; +@@ -343,45 +343,45 @@ int read_config_file(void) + continue; + } + +- if(!strcmp(s, "kernel") && menu_ptr) { ++ if(!strcasecmp(s, "kernel") && menu_ptr) { + menu_ptr->kernel = strdup(t); + continue; + } + +- if(!strcmp(s, "linux") && menu_ptr) { ++ if(!strcasecmp(s, "linux") && menu_ptr) { + menu_ptr->linux = strdup(t); + continue; + } + +- if(!strcmp(s, "localboot") && menu_ptr) { ++ if(!strcasecmp(s, "localboot") && menu_ptr) { + menu_ptr->localboot = strdup(t); + continue; + } + +- if(!strcmp(s, "initrd") && menu_ptr) { ++ if(!strcasecmp(s, "initrd") && menu_ptr) { + menu_ptr->initrd = strdup(t); + continue; + } + +- if(!strcmp(s, "append")) { ++ if(!strcasecmp(s, "append")) { + (menu_ptr ?: menu_default)->append = strdup(t); + u = strlen(t); + if(u > append_size) append_size = u; + continue; + } + +- if(!strcmp(s, "ipappend")) { ++ if(!strcasecmp(s, "ipappend")) { + (menu_ptr ?: menu_default)->ipappend = strdup(t); + continue; + } + +- if(!strcmp(s, "menu") && menu_ptr) { ++ if(!strcasecmp(s, "menu") && menu_ptr) { + s = skip_spaces(t); + t = skip_nonspaces(s); + if(*t) *t++ = 0; + t = skip_spaces(t); + +- if(!strcmp(s, "label")) { ++ if(!strcasecmp(s, "label")) { + menu_ptr->label = strdup(t); + u = strlen(t); + if(u > label_size) label_size = u; +-- +1.6.4.2 + +From 0c511ba970405ea54c8fd6c351f20137966b5e89 Mon Sep 17 00:00:00 2001 +From: Steffen Winterfeldt +Date: Tue, 13 Apr 2010 17:42:12 +0200 +Subject: [PATCH 3/4] handle IPAPPEND + + +Signed-off-by: Steffen Winterfeldt +--- + com32/gfxboot/gfxboot.c | 12 ++++++++++++ + 1 files changed, 12 insertions(+), 0 deletions(-) + +diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c +index c300dcb..daf0056 100644 +--- a/com32/gfxboot/gfxboot.c ++++ b/com32/gfxboot/gfxboot.c +@@ -709,6 +709,8 @@ void boot(int index) + char *arg; + menu_t *menu_ptr; + int label_len; ++ unsigned u, ipapp; ++ const struct syslinux_ipappend_strings *ipappend; + + for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, index--) { + if(!index) break; +@@ -730,6 +732,16 @@ void boot(int index) + + arg = skip_spaces(arg); + ++ // handle IPAPPEND ++ if(menu_ptr->ipappend && (ipapp = atoi(menu_ptr->ipappend))) { ++ ipappend = syslinux_ipappend_strings(); ++ for(u = 0; u < ipappend->count; u++) { ++ if((ipapp & (1 << u)) && ipappend->ptr[u]) { ++ sprintf(arg + strlen(arg), " %s", ipappend->ptr[u]); ++ } ++ } ++ } ++ + boot_entry(menu_ptr, arg); + } + +-- +1.6.4.2 + +From 9a0a0e2307ffa0140fe6ea4a31c2f4040176513d Mon Sep 17 00:00:00 2001 +From: Steffen Winterfeldt +Date: Tue, 13 Apr 2010 17:42:44 +0200 +Subject: [PATCH 4/4] turn off graphics before starting kernel + + +Signed-off-by: Steffen Winterfeldt +--- + com32/gfxboot/gfxboot.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c +index daf0056..96aadd8 100644 +--- a/com32/gfxboot/gfxboot.c ++++ b/com32/gfxboot/gfxboot.c +@@ -848,6 +848,8 @@ void boot_entry(menu_t *menu_ptr, char *arg) + + __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_DONE], &r, &r); + ++ gfx_done(); ++ + syslinux_boot_linux(kernel, kernel_size, initrd, arg); + } + +-- +1.6.4.2 + +From 6d89bc005f25b923728822706bf508ea7ebc1714 Mon Sep 17 00:00:00 2001 +From: Steffen Winterfeldt +Date: Wed, 14 Apr 2010 17:43:16 +0200 +Subject: [PATCH] fix localboot + + +Signed-off-by: Steffen Winterfeldt +--- + com32/gfxboot/gfxboot.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c +index 96aadd8..3460c18 100644 +--- a/com32/gfxboot/gfxboot.c ++++ b/com32/gfxboot/gfxboot.c +@@ -766,7 +766,7 @@ void boot_entry(menu_t *menu_ptr, char *arg) + + if(menu_ptr->localboot) { + gfx_done(); +- syslinux_local_boot(atoi(arg)); ++ syslinux_local_boot(strtol(menu_ptr->localboot, NULL, 0)); + + return; + } +-- +1.6.4.2 + +From 19dfdc33016f69e7d20f6c8eda9eb420b91577f9 Mon Sep 17 00:00:00 2001 +From: Steffen Winterfeldt +Date: Fri, 16 Apr 2010 13:18:46 +0200 +Subject: [PATCH] better error handling + + +Signed-off-by: Steffen Winterfeldt +--- + com32/gfxboot/gfxboot.c | 118 +++++++++++++++++++++++++++++++++++++--------- + 1 files changed, 95 insertions(+), 23 deletions(-) + +diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c +index 3460c18..c5112f4 100644 +--- a/com32/gfxboot/gfxboot.c ++++ b/com32/gfxboot/gfxboot.c +@@ -118,6 +118,7 @@ typedef struct menu_s { + struct menu_s *next; + char *label; + char *kernel; ++ char *alt_kernel; + char *linux; + char *localboot; + char *initrd; +@@ -149,6 +150,9 @@ char cmdline[MAX_CMDLINE_LEN]; + void *save_buf; + unsigned save_buf_size; + ++// progress bar is visible ++unsigned progress_active; ++ + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + void show_message(char *file); +@@ -163,6 +167,10 @@ int gfx_init(char *file); + int gfx_menu_init(void); + void gfx_done(void); + int gfx_input(void); ++void gfx_infobox(int type, char *str1, char *str2); ++void gfx_progress_init(ssize_t kernel_size, char *label); ++void gfx_progress_update(ssize_t size); ++void gfx_progress_done(void); + ssize_t save_read(int fd, void *buf, size_t size); + void *load_one(char *file, ssize_t *file_size); + void boot(int index); +@@ -486,6 +494,8 @@ int gfx_init(char *file) + void *lowmem = lowmem_buf; + unsigned lowmem_size = lowmem_buf_size; + ++ progress_active = 0; ++ + printf("Loading %s...\n", file); + if(loadfile(file, &archive, &archive_size)) return 1; + +@@ -603,6 +613,8 @@ void gfx_done(void) + { + com32sys_t r; + ++ gfx_progress_done(); ++ + __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_DONE], &r, &r); + } + +@@ -631,6 +643,61 @@ int gfx_input(void) + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++void gfx_infobox(int type, char *str1, char *str2) ++{ ++ com32sys_t r; ++ ++ r.eax.l = type; ++ r.esi.l = (uint32_t) str1; ++ r.edi.l = (uint32_t) str2; ++ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INFOBOX_INIT], &r, &r); ++ r.edi.l = r.eax.l = 0; ++ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INPUT], &r, &r); ++ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INFOBOX_DONE], &r, &r); ++} ++ ++ ++// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++void gfx_progress_init(ssize_t kernel_size, char *label) ++{ ++ com32sys_t r; ++ ++ if(!progress_active) { ++ r.eax.l = kernel_size >> gfx_config.sector_shift; // in sectors ++ r.esi.l = (uint32_t) label; ++ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_INIT], &r, &r); ++ } ++ ++ progress_active = 1; ++} ++ ++ ++// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++void gfx_progress_update(ssize_t advance) ++{ ++ com32sys_t r; ++ ++ if(progress_active) { ++ r.eax.l = advance >> gfx_config.sector_shift; // in sectors ++ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_UPDATE], &r, &r); ++ } ++} ++ ++ ++// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++void gfx_progress_done(void) ++{ ++ com32sys_t r; ++ ++ if(progress_active) { ++ __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_DONE], &r, &r); ++ } ++ ++ progress_active = 0; ++} ++ ++ ++// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Like read(2) but preserve bounce buffer. + // + ssize_t save_read(int fd, void *buf, size_t size) +@@ -652,14 +719,16 @@ void *load_one(char *file, ssize_t *file_size) + { + int fd; + void *buf = NULL; ++ char *str; + struct stat sbuf; + ssize_t size = 0, cur, i; +- com32sys_t r; + + *file_size = 0; + + if((fd = open(file, O_RDONLY)) == -1) { +- printf("%s: file not found\n", file); ++ asprintf(&str, "%s: file not found", file); ++ gfx_infobox(0, str, NULL); ++ free(str); + return buf; + } + +@@ -671,23 +740,26 @@ void *load_one(char *file, ssize_t *file_size) + buf = malloc(size); + for(i = 1, cur = 0 ; cur < size && i > 0; cur += i) { + i = save_read(fd, buf + cur, CHUNK_SIZE); +- r.eax.l = i >> gfx_config.sector_shift; +- __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_UPDATE], &r, &r); ++ if(i == -1) break; ++ gfx_progress_update(i); + } + } + else { + do { + buf = realloc(buf, size + CHUNK_SIZE); + i = save_read(fd, buf + size, CHUNK_SIZE); ++ if(i == -1) break; + size += i; +- r.eax.l = i >> gfx_config.sector_shift; +- __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_UPDATE], &r, &r); ++ gfx_progress_update(i); + } while(i > 0); + } + + close(fd); + + if(i == -1) { ++ asprintf(&str, "%s: read error @ %d", file, size); ++ gfx_infobox(0, str, NULL); ++ free(str); + free(buf); + buf = NULL; + size = 0; +@@ -706,10 +778,10 @@ void *load_one(char *file, ssize_t *file_size) + // + void boot(int index) + { +- char *arg; ++ char *arg, *alt_kernel; + menu_t *menu_ptr; +- int label_len; +- unsigned u, ipapp; ++ int i, label_len; ++ unsigned ipapp; + const struct syslinux_ipappend_strings *ipappend; + + for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, index--) { +@@ -722,9 +794,12 @@ void boot(int index) + arg = skip_spaces(cmdline); + label_len = strlen(menu_ptr->label); + +- // if it does not start with label string, skip first word ++ // if it does not start with label string, assume first word is kernel name + if(strncmp(arg, menu_ptr->label, label_len)) { ++ alt_kernel = arg; + arg = skip_nonspaces(arg); ++ if(*arg) *arg++ = 0; ++ if(*alt_kernel) menu_ptr->alt_kernel = alt_kernel; + } + else { + arg += label_len; +@@ -735,14 +810,16 @@ void boot(int index) + // handle IPAPPEND + if(menu_ptr->ipappend && (ipapp = atoi(menu_ptr->ipappend))) { + ipappend = syslinux_ipappend_strings(); +- for(u = 0; u < ipappend->count; u++) { +- if((ipapp & (1 << u)) && ipappend->ptr[u]) { +- sprintf(arg + strlen(arg), " %s", ipappend->ptr[u]); ++ for(i = 0; i < ipappend->count; i++) { ++ if((ipapp & (1 << i)) && ipappend->ptr[i]) { ++ sprintf(arg + strlen(arg), " %s", ipappend->ptr[i]); + } + } + } + + boot_entry(menu_ptr, arg); ++ ++ gfx_progress_done(); + } + + +@@ -759,7 +836,6 @@ void boot_entry(menu_t *menu_ptr, char *arg) + char *file, *cmd_buf; + int fd; + struct stat sbuf; +- com32sys_t r; + char *s, *s0, *t, *initrd_arg; + + if(!menu_ptr) return; +@@ -771,7 +847,8 @@ void boot_entry(menu_t *menu_ptr, char *arg) + return; + } + +- file = menu_ptr->kernel; ++ file = menu_ptr->alt_kernel; ++ if(!file) file = menu_ptr->kernel; + if(!file) file = menu_ptr->linux; + if(!file) { + gfx_done(); +@@ -782,21 +859,18 @@ void boot_entry(menu_t *menu_ptr, char *arg) + + // first, load kernel + +- r.eax.l = 0; // kernel size in sectors ++ kernel_size = 0; + + if((fd = open(file, O_RDONLY)) >= 0) { +- if(!fstat(fd, &sbuf) && S_ISREG(sbuf.st_mode)) r.eax.l = sbuf.st_size >> gfx_config.sector_shift; ++ if(!fstat(fd, &sbuf) && S_ISREG(sbuf.st_mode)) kernel_size = sbuf.st_size; + close(fd); + } + +- r.esi.l = (uint32_t) file; +- __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_INIT], &r, &r); ++ gfx_progress_init(kernel_size, file); + + kernel = load_one(file, &kernel_size); + + if(!kernel) { +- gfx_done(); +- printf("%s: read error\n", file); + return; + } + +@@ -846,8 +920,6 @@ void boot_entry(menu_t *menu_ptr, char *arg) + + free(s0); + +- __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_DONE], &r, &r); +- + gfx_done(); + + syslinux_boot_linux(kernel, kernel_size, initrd, arg); +-- +1.6.4.2 + diff --git a/syslinux.changes b/syslinux.changes index 4e2f9cf..84ad1b0 100644 --- a/syslinux.changes +++ b/syslinux.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Fri Apr 16 13:23:24 CEST 2010 - snwint@suse.de + +- gfxboot.c32: + * support MENU LABEL + * handle IPAPPEND + * fix LOCALBOOT (bnc #592779) + * better error handling + ------------------------------------------------------------------- Thu Apr 8 16:54:00 CEST 2010 - snwint@suse.de diff --git a/syslinux.spec b/syslinux.spec index 94decc3..e4547ab 100644 --- a/syslinux.spec +++ b/syslinux.spec @@ -34,6 +34,7 @@ Source2: README.gfxboot Patch0: %{name}-%{version}-gfxboot.diff Patch1: %{name}-%{version}-suse.diff Patch2: %{name}-%{version}-compat.diff +Patch3: %{name}-%{version}-com32.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -53,6 +54,7 @@ Authors: %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch3 -p1 %build cp %{SOURCE2} .