diff --git a/syslinux-3.82-gfxboot.diff b/syslinux-3.82-gfxboot.diff index b393189..f592924 100644 --- a/syslinux-3.82-gfxboot.diff +++ b/syslinux-3.82-gfxboot.diff @@ -406,7 +406,7 @@ index f6ed644..286c9c8 100644 + alignz 4 +KernelStart dd 100000h diff --git a/core/comboot.inc b/core/comboot.inc -index 1a1dbfe..ee3fd77 100644 +index 1a1dbfe..1a147c9 100644 --- a/core/comboot.inc +++ b/core/comboot.inc @@ -962,6 +962,45 @@ comapi_shufraw: @@ -455,7 +455,7 @@ index 1a1dbfe..ee3fd77 100644 section .data %macro int21 2 -@@ -969,6 +1008,88 @@ comapi_shufraw: +@@ -969,6 +1008,108 @@ comapi_shufraw: dw %2 %endmacro @@ -467,6 +467,7 @@ index 1a1dbfe..ee3fd77 100644 +; ES:BX as if it had been entered by the user. +; CS:SI: comboot callback (via far call) +; EDI kernel load address ++; EDX memory end (sets MyHighMemSize if != 0) +; +comapi_run2: + push word P_CS @@ -474,6 +475,14 @@ index 1a1dbfe..ee3fd77 100644 + pop dword [comboot_far] + push dword P_EDI + pop dword [KernelStart] ++ mov edx,P_EDX ++ or edx,edx ++ jz .nohimemsize ++%if HIGHMEM_SLOP != 0 ++ sub edx,HIGHMEM_SLOP ++%endif ++.nohimemsize: ++ mov [AltHighMemSize],edx + mov ds,P_ES + mov si,P_BX + mov di,command_line @@ -494,6 +503,17 @@ index 1a1dbfe..ee3fd77 100644 + clc + ret + ++ ++; ++; INT 22h AX=0028h Get memory size ++; ++comapi_memsize: ++ push dword [HighMemSize] ++ pop dword P_EAX ++ clc ++ ret ++ ++ +; +; Callback function used at various places during kernel/initrd loading. +; @@ -544,13 +564,14 @@ index 1a1dbfe..ee3fd77 100644 int21_table: int21 00h, comboot_return int21 01h, comboot_getkey -@@ -1021,8 +1142,15 @@ int22_table: +@@ -1021,8 +1162,16 @@ int22_table: dw comapi_closedir ; 0022 close directory dw comapi_shufsize ; 0023 query shuffler size dw comapi_shufraw ; 0024 cleanup, shuffle and boot raw + dw comapi_setcwd ; 0025 set current working directory + dw comapi_mount ; 0026 read fs structures (aka mount) + dw comapi_run2 ; 0027 like 0003, but return on error ++ dw comapi_memsize ; 0028 get memory size int22_count equ ($-int22_table)/2 +comboot_sp_save dw 0 @@ -560,22 +581,23 @@ index 1a1dbfe..ee3fd77 100644 APIKeyWait db 0 APIKeyFlag db 0 -@@ -1041,8 +1169,9 @@ feature_flags_len equ ($-feature_flags) +@@ -1041,8 +1190,10 @@ feature_flags_len equ ($-feature_flags) err_notdos db ': attempted DOS system call INT ',0 err_comlarge db 'COMBOOT image too large.', CR, LF, 0 - section .bss1 + section .bss2 alignb 4 ++AltHighMemSize resd 1 DOSErrTramp resd 33 ; Error trampolines +TmpDirName resb FILENAME_MAX ConfigName resb FILENAME_MAX CurrentDirName resb FILENAME_MAX diff --git a/core/comboot.inc b/core/comboot.inc -index ee3fd77..a11b15b 100644 +index 1a147c9..e5dc115 100644 --- a/core/comboot.inc +++ b/core/comboot.inc -@@ -1034,12 +1034,14 @@ comapi_run2: +@@ -1043,12 +1043,14 @@ comapi_run2: mov [comboot_sp_save],sp ; save stack pointer mov word [comboot_hook],comboot_hook_entry or byte [QuietBoot],2 @@ -590,7 +612,7 @@ index ee3fd77..a11b15b 100644 clc ret -@@ -1150,6 +1152,7 @@ int22_count equ ($-int22_table)/2 +@@ -1171,6 +1173,7 @@ int22_count equ ($-int22_table)/2 comboot_sp_save dw 0 comboot_hook dw comboot_hook_nop comboot_far dd 0 @@ -617,10 +639,10 @@ index 2bc56a1..59b5724 100644 pop es mov di,KernelName diff --git a/core/comboot.inc b/core/comboot.inc -index a11b15b..b40c4ae 100644 +index e5dc115..60506ce 100644 --- a/core/comboot.inc +++ b/core/comboot.inc -@@ -1067,6 +1067,7 @@ comboot_hook_entry: +@@ -1087,6 +1087,7 @@ comboot_hook_entry: push fs push es push ds @@ -629,10 +651,22 @@ index a11b15b..b40c4ae 100644 pop ds pop es diff --git a/core/ui.inc b/core/ui.inc -index 59b5724..02c17ff 100644 +index 59b5724..d56c148 100644 --- a/core/ui.inc +++ b/core/ui.inc -@@ -633,6 +633,7 @@ kernel_good: +@@ -612,7 +612,11 @@ kernel_good: + mov [KernelCNameLen],di + + ; Default memory limit, can be overridden by image loaders ++ mov eax,[AltHighMemSize] ++ or eax,eax ++ jnz .altsize + mov eax,[HighMemRsvd] ++.altsize: + mov [MyHighMemSize],eax + + popad +@@ -633,6 +637,7 @@ kernel_good: ; At this point, EAX contains the size of the kernel, SI contains ; the file handle/cluster pointer, and ECX contains the extension (if any.) ; @@ -641,10 +675,10 @@ index 59b5724..02c17ff 100644 add di,di jmp [kerneltype_table+di] diff --git a/doc/comboot.txt b/doc/comboot.txt -index f5fefda..f4ea31b 100644 +index f5fefda..1450021 100644 --- a/doc/comboot.txt +++ b/doc/comboot.txt -@@ -955,3 +955,32 @@ AX=0024h [3.80] Cleanup, shuffle and boot, raw version +@@ -955,3 +955,38 @@ AX=0024h [3.80] Cleanup, shuffle and boot, raw version with read/write data segments, matching the respective code segment. For mode 0, B=0 and the limits will be 64K, for mode 1, B=1 and the limits will be 4 GB. @@ -671,12 +705,18 @@ index f5fefda..f4ea31b 100644 + ES:BX null-terminated command string + SI comboot callback function (called via far call) + EDI kernel load address ++ EDX if != 0: initrd load address (that is: memory end) + Output: Does not return if the kernel loads correctly. + -+ Executes the command line as if it had been entered by the user. ++ Executes the command line as if it had been entered by the user. + Note that this function does return (with CF = 0) if there are + problems or the user aborted the load. Else it terminates the + COMBOOT program and starts the kernel. ++ ++AX=0028h [3.84] Get memory size ++ Input: AX 0028h ++ Output: EAX high memory size (in bytes) ++ diff --git a/modules/Makefile b/modules/Makefile index 80eb995..65661a4 100644 --- a/modules/Makefile @@ -733,10 +773,10 @@ index 0000000..a98f9aa +} diff --git a/modules/gfxboot.c b/modules/gfxboot.c new file mode 100644 -index 0000000..6b0d300 +index 0000000..b4a794c --- /dev/null +++ b/modules/gfxboot.c -@@ -0,0 +1,898 @@ +@@ -0,0 +1,1036 @@ +/* + * + * gfxboot.c @@ -765,6 +805,12 @@ index 0000000..6b0d300 +#define MAX_CONFIG_LINE_LEN 2048 +#define MAX_CMDLINE_LEN 1024 + ++// basic memory layout in MB ++#define GFX_MEMORY_START 1 ++#define GFX_MEMORY_SIZE 7 ++// assume initrd needs at least that much ++#define INITRD_MIN_MEMORY 64 ++ +#define GFX_BC_INIT 0 +#define GFX_BC_DONE 1 +#define GFX_BC_INPUT 2 @@ -837,6 +883,15 @@ index 0000000..6b0d300 +} menu_t; + + ++// e820 mem descriptor ++typedef struct __attribute__ ((packed)) { ++ uint64_t base; ++ uint64_t len; ++ uint32_t type; ++ uint32_t cont; ++} mem_info_t; ++ ++ +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// global file descriptor, implicitly used by read(), getc(), fgets() +fd_t fd; @@ -855,6 +910,9 @@ index 0000000..6b0d300 +unsigned menu_buf, menu_buf_len; +unsigned freemem, freemem_len; + ++unsigned initrd_end; ++unsigned kernel_start; ++ +int timeout; + +char cmdline[MAX_CMDLINE_LEN]; @@ -883,6 +941,7 @@ index 0000000..6b0d300 +unsigned magic_ok(uint32_t buf); +unsigned find_file(uint32_t buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len); + ++int get_mem_info(mem_info_t *mi); +int gfx_init(char *file); +void gfx_done(void); +int gfx_input(void); @@ -892,6 +951,7 @@ index 0000000..6b0d300 +void gfx_infobox(int type, char *str1, char *str2); + +void boot(void); ++void show_message(char *file); + + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -928,7 +988,6 @@ index 0000000..6b0d300 + // comboot api passes low memory end at address 2 + freemem_len = ((*(uint16_t *) 2) << 4) - freemem; + -+ + gfx_config.bootloader = 1; + gfx_config.sysconfig_size = sizeof gfx_config; + gfx_config.bootloader_seg = comboot >> 4; @@ -941,18 +1000,24 @@ index 0000000..6b0d300 + gfx_config.boot_drive = 0; + } + -+ if(argc != 2) { -+ printf("Usage: gfxboot.com \n"); ++ if(argc < 2) { ++ printf("Usage: gfxboot.com bootlogo_file [message_file]\n"); ++ if(argc > 2) show_message(argv[2]); ++ + return 0; + } + + if(read_config_file()) { + printf("Error reading config file\n"); ++ if(argc > 2) show_message(argv[2]); ++ + return 0; + } + + if(gfx_init(argv[1])) { + printf("Error setting up gfxboot\n"); ++ if(argc > 2) show_message(argv[2]); ++ + return 0; + } + @@ -976,6 +1041,8 @@ index 0000000..6b0d300 + boot(); + } + ++ if(argc > 2) show_message(argv[2]); ++ + return 0; +} + @@ -1408,19 +1475,114 @@ index 0000000..6b0d300 +// return: +// 0: ok, 1: error +// -+int gfx_init(char *file) ++int get_mem_info(mem_info_t *mi) +{ + x86regs_t r; + ++ mi->base = mi->len = mi->type = 0; ++ ++ r.eax = 0xe820; ++ r.edx = 0x534d4150; ++ r.ebx = mi->cont; ++ r.ecx = 20; ++ r.es = comboot >> 4; ++ r.edi = (unsigned) mi; ++ x86int(0x15, &r); ++ ++ mi->cont = 0; ++ if(r.eax != 0x534d4150 || (r.eflags & X86_CF)) return 1; ++ mi->cont = r.ebx; ++ ++ return 0; ++} ++ ++ ++// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++// ++// return: ++// 0: ok, 1: error ++// ++int gfx_init(char *file) ++{ ++ x86regs_t r; + int file_max, file_size, ofs; + unsigned u, code_start, file_start = 0, file_len = 0; ++ unsigned start2, len2, end2; ++ mem_info_t mi; + + gfx_config.mem0_start = freemem; + gfx_config.mem0_end = freemem + freemem_len; + -+ gfx_config.bios_mem_size = 256 << 20; // fake ++ kernel_start = (GFX_MEMORY_START + GFX_MEMORY_SIZE) << 20; ++ initrd_end = 0; + -+ gfx_config.xmem_0 = 0x17; // 7MB starting at 16MB ++ gfx_config.xmem_0 = (GFX_MEMORY_START << 4) + GFX_MEMORY_SIZE; ++ ++ r.eax = 0x28; // Get memory size ++ x86int(0x22, &r); ++ u = (r.eflags & X86_CF) ? 0 : r.eax; ++ ++ // round up ++ gfx_config.bios_mem_size = u ? ((u + 0xfffff) >> 20) << 20 : 256; ++ ++ if(u > 0) { ++ // new interface ++ ++ if(u < INITRD_MIN_MEMORY << 20) { ++ // ok, maybe there is a bigger block... ++ ++ mi.cont = 0; ++ start2 = len2 = 0; ++ while(!get_mem_info(&mi)) { ++#if 0 ++ printf( ++ "%08x%08x %08x%08x %08x %08x\n", ++ (unsigned) (mi.base >> 32), (unsigned) mi.base, ++ (unsigned) (mi.len >> 32), (unsigned) mi.len, ++ mi.type, mi.cont ++ ); ++#endif ++ if(mi.type == 1) { ++ if((mi.base >> 32) || (mi.base + mi.len) >> 32) break; ++ if(mi.len > len2) { ++ start2 = mi.base; ++ len2 = mi.len; ++ } ++ } ++ ++ if(!mi.cont) break; ++ } ++ ++#if 0 ++ printf("largest: %08x %08x\n", start2, len2); ++ getchar(); ++#endif ++ ++ if(len2 && len2 > 2 << 20 && len2 > u) { ++ // align to full MBs ++ end2 = (start2 + len2) & ~0xfffff; ++ start2 = (start2 + 0xfffff) & ~0xfffff; ++ len2 = end2 - start2; ++ } ++ else { ++ start2 = len2 = 0; ++ } ++ ++ if(len2) { ++ u = len2; ++ initrd_end = end2; ++ // we could relocate the kernel as well... ++ // kernel_start = start2; ++ } ++ } ++ ++ if(u < INITRD_MIN_MEMORY << 20) { ++ // a bit too small for us ++ printf("%u MB RAM is a bit small... - giving up\n", u >> 20); ++ ++ return 1; ++ } ++ } + +#if 0 + printf("mem = 0x%05x, mem0_start = 0x%05x, mem0_end = 0x%05x\n", @@ -1577,9 +1739,11 @@ index 0000000..6b0d300 + + r.es = comboot >> 4; + r.ebx = (uint32_t) cmdline; -+ r.edi = 8 << 20; // kernel load address: 8MB ++ r.edi = kernel_start; // kernel load address ++ r.edx = initrd_end; // end of initrd load area (or 0) + r.esi = (uint32_t) _syslinux_hook; // cs:si = syslinux callbacks + r.eax = 0x27; // Load & run kernel (extended API) ++ + x86int(0x22, &r); + if(!(r.eflags & X86_CF)) return; + @@ -1635,9 +1799,23 @@ index 0000000..6b0d300 +} + + ++// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++void show_message(char *file) ++{ ++ int c; ++ ++ if(open(file) == -1) return; ++ ++ while((c = getc()) != EOF) { ++ if(c < ' ' && c != '\n' && c != '\t') continue; ++ printf("%c", c); ++ } ++} ++ ++ diff --git a/modules/libio.asm b/modules/libio.asm new file mode 100644 -index 0000000..57bcde3 +index 0000000..1f77b44 --- /dev/null +++ b/modules/libio.asm @@ -0,0 +1,854 @@ @@ -1702,7 +1880,7 @@ index 0000000..57bcde3 + rep stosb + + ; parse args -+ mov bx,80h ++ mov ebx,80h + movzx si,byte [bx] + mov byte [si+81h],0dh ; just make sure + xor ecx,ecx @@ -1829,7 +2007,7 @@ index 0000000..57bcde3 + mov byte [pf_raw_char],0 + jmp printf_10 + -+printf_30: ++printf_30: + cmp al,'u' + jnz printf_35 + @@ -1896,12 +2074,12 @@ index 0000000..57bcde3 +printf_45: + + ; more ... -+ ++ + +printf_70: + call putc + jmp printf_10 -+printf_90: ++printf_90: + popad + + o32 ret @@ -2497,10 +2675,10 @@ index 0000000..57bcde3 + diff --git a/modules/libio.h b/modules/libio.h new file mode 100644 -index 0000000..b7a3dc6 +index 0000000..16af520 --- /dev/null +++ b/modules/libio.h -@@ -0,0 +1,131 @@ +@@ -0,0 +1,133 @@ +/* + * + * libio.h include file for libio @@ -2525,9 +2703,11 @@ index 0000000..b7a3dc6 +#define int8_t char +#define int16_t short +#define int32_t int ++#define int64_t long long +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned ++#define uint64_t unsigned long long + +#define X86_CF 0x0001 +#define X86_PF 0x0004 @@ -2551,17 +2731,17 @@ index 0000000..b7a3dc6 + + +static inline uint16_t comboot_seg(void) -+{ ++{ + uint16_t u; + + asm("mov %%cs, %0" : "=r" (u)); -+ ++ + return u; +} + + +static inline uint8_t _mem8(uint32_t p) -+{ ++{ + uint8_t u; + + asm( @@ -2573,13 +2753,13 @@ index 0000000..b7a3dc6 + "movb %%fs:(%%si),%0\n" + : "=abcd" (u) : "r" (p) : "si" + ); -+ ++ + return u; +} + + +static inline uint16_t _mem16(uint32_t p) -+{ ++{ + uint16_t u; + + asm( @@ -2591,13 +2771,13 @@ index 0000000..b7a3dc6 + "movw %%fs:(%%si),%0\n" + : "=r" (u) : "r" (p) : "si" + ); -+ ++ + return u; +} + + +static inline uint32_t _mem32(uint32_t p) -+{ ++{ + uint32_t u; + + asm( @@ -2609,7 +2789,7 @@ index 0000000..b7a3dc6 + "movl %%fs:(%%si),%0\n" + : "=r" (u) : "r" (p) : "si" + ); -+ ++ + return u; +} + @@ -2632,106 +2812,3 @@ index 0000000..b7a3dc6 + +#endif /* _LIBIO_H */ + -diff --git a/modules/gfxboot.c b/modules/gfxboot.c -index 6b0d300..c7c69fe 100644 ---- a/modules/gfxboot.c -+++ b/modules/gfxboot.c -@@ -153,6 +153,7 @@ void gfx_infobox32(int type, uint32_t str1, uint32_t str2); - void gfx_infobox(int type, char *str1, char *str2); - - void boot(void); -+void show_message(char *file); - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@@ -202,8 +203,8 @@ int main(int argc, char **argv) - gfx_config.boot_drive = 0; - } - -- if(argc != 2) { -- printf("Usage: gfxboot.com \n"); -+ if(argc < 2) { -+ printf("Usage: gfxboot.com bootlogo_file [message_file]\n"); - return 0; - } - -@@ -237,6 +238,10 @@ int main(int argc, char **argv) - boot(); - } - -+ if(argc > 2) { -+ show_message(argv[2]); -+ } -+ - return 0; - } - -@@ -896,3 +901,17 @@ void syslinux_hook(x86regs_t *r) - } - - -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+void show_message(char *file) -+{ -+ int c; -+ -+ if(open(file) == -1) return; -+ -+ while((c = getc()) != EOF) { -+ if(c < ' ' && c != '\n' && c != '\t') continue; -+ printf("%c", c); -+ } -+} -+ -+ -diff --git a/modules/libio.asm b/modules/libio.asm -index 57bcde3..1b31219 100644 ---- a/modules/libio.asm -+++ b/modules/libio.asm -@@ -59,7 +59,7 @@ _start: - rep stosb - - ; parse args -- mov bx,80h -+ mov ebx,80h - movzx si,byte [bx] - mov byte [si+81h],0dh ; just make sure - xor ecx,ecx -diff --git a/modules/gfxboot.c b/modules/gfxboot.c -index c7c69fe..9c9682b 100644 ---- a/modules/gfxboot.c -+++ b/modules/gfxboot.c -@@ -205,16 +205,22 @@ int main(int argc, char **argv) - - if(argc < 2) { - printf("Usage: gfxboot.com bootlogo_file [message_file]\n"); -+ if(argc > 2) show_message(argv[2]); -+ - return 0; - } - - if(read_config_file()) { - printf("Error reading config file\n"); -+ if(argc > 2) show_message(argv[2]); -+ - return 0; - } - - if(gfx_init(argv[1])) { - printf("Error setting up gfxboot\n"); -+ if(argc > 2) show_message(argv[2]); -+ - return 0; - } - -@@ -238,9 +244,7 @@ int main(int argc, char **argv) - boot(); - } - -- if(argc > 2) { -- show_message(argv[2]); -- } -+ if(argc > 2) show_message(argv[2]); - - return 0; - } diff --git a/syslinux.changes b/syslinux.changes index 518b950..47e73e6 100644 --- a/syslinux.changes +++ b/syslinux.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Oct 5 13:44:54 CEST 2009 - snwint@suse.de + +- if first memory area is too small, use largest (bnc #469889, bnc #507952) + ------------------------------------------------------------------- Tue Aug 25 15:53:39 CEST 2009 - snwint@suse.de diff --git a/syslinux.spec b/syslinux.spec index 7b80dd6..e0ee2d8 100644 --- a/syslinux.spec +++ b/syslinux.spec @@ -27,7 +27,7 @@ Requires: mtools AutoReqProv: on Summary: Boot Loader for Linux Version: 3.82 -Release: 6 +Release: 7 Source: %{name}-%{version}.tar.bz2 Source1: isolinux-config Source2: README.gfxboot