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 From bf3fd44448fb81ac481a2a1ac6d90f5a27e4d1de Mon Sep 17 00:00:00 2001 From: Steffen Winterfeldt Date: Mon, 19 Apr 2010 15:17:57 +0200 Subject: [PATCH] fix menu label handling Signed-off-by: Steffen Winterfeldt --- com32/gfxboot/gfxboot.c | 48 +++++++++++++++++++++++++++------------------- 1 files changed, 28 insertions(+), 20 deletions(-) diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c index c5112f4..a6c95fe 100644 --- a/com32/gfxboot/gfxboot.c +++ b/com32/gfxboot/gfxboot.c @@ -116,14 +116,15 @@ typedef struct __attribute__ ((packed)) { // menu description typedef struct menu_s { struct menu_s *next; - char *label; - char *kernel; - char *alt_kernel; - char *linux; - char *localboot; - char *initrd; - char *append; - char *ipappend; + char *label; // config entry name + char *menu_label; // text to show in boot menu + char *kernel; // name of program to load + char *alt_kernel; // alternative name in case user has replaced it + char *linux; // de facto an alias for 'kernel' + char *localboot; // boot from local disk + char *initrd; // initrd as separate line (instead of as part of 'append') + char *append; // kernel args + char *ipappend; // append special pxelinux args (see doc) } menu_t; @@ -345,7 +346,7 @@ int read_config_file(void) menu_ptr = *menu_next = calloc(1, sizeof **menu_next); menu_next = &menu_ptr->next; menu_idx++; - menu_ptr->label = strdup(t); + menu_ptr->label = menu_ptr->menu_label = strdup(t); u = strlen(t); if(u > label_size) label_size = u; continue; @@ -390,7 +391,7 @@ int read_config_file(void) t = skip_spaces(t); if(!strcasecmp(s, "label")) { - menu_ptr->label = strdup(t); + menu_ptr->menu_label = strdup(t); u = strlen(t); if(u > label_size) label_size = u; continue; @@ -404,15 +405,22 @@ int read_config_file(void) label_size++; append_size++; - gfx_menu.entries = menu_idx; - gfx_menu.label_size = label_size; - gfx_menu.arg_size = append_size; + // ensure we have a default entry + if(!menu_default->label) menu_default->label = menu->label; - gfx_menu.default_entry = menu_default->label; - if(!gfx_menu.default_entry && menu) { - gfx_menu.default_entry = menu->label; + if(menu_default->label) { + for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next) { + if(!strcmp(menu_default->label, menu_ptr->label)) { + menu_default->menu_label = menu_ptr->menu_label; + break; + } + } } + gfx_menu.entries = menu_idx; + gfx_menu.label_size = label_size; + gfx_menu.arg_size = append_size; + gfx_menu.default_entry = menu_default->menu_label; gfx_menu.label_list = calloc(menu_idx, label_size); gfx_menu.arg_list = calloc(menu_idx, append_size); @@ -420,7 +428,7 @@ int read_config_file(void) if(!menu_ptr->append) menu_ptr->append = menu_default->append; if(!menu_ptr->ipappend) menu_ptr->ipappend = menu_default->ipappend; - if(menu_ptr->label) strcpy(gfx_menu.label_list + u * label_size, menu_ptr->label); + if(menu_ptr->menu_label) strcpy(gfx_menu.label_list + u * label_size, menu_ptr->menu_label); if(menu_ptr->append) strcpy(gfx_menu.arg_list + u * append_size, menu_ptr->append); } @@ -789,13 +797,13 @@ void boot(int index) } // invalid index or menu entry - if(!menu_ptr || !menu_ptr->label) return; + if(!menu_ptr || !menu_ptr->menu_label) return; arg = skip_spaces(cmdline); - label_len = strlen(menu_ptr->label); + label_len = strlen(menu_ptr->menu_label); // if it does not start with label string, assume first word is kernel name - if(strncmp(arg, menu_ptr->label, label_len)) { + if(strncmp(arg, menu_ptr->menu_label, label_len)) { alt_kernel = arg; arg = skip_nonspaces(arg); if(*arg) *arg++ = 0; -- 1.6.4.2