From: hpa Date: Sun, 21 Aug 2005 05:11:50 +0000 (+0000) Subject: Add more low-level API function to load the kernel, and make the X-Git-Tag: syslinux-3.11~46 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=87575da8034373b0bf9ea147329b6d24dc5a825a;p=profile%2Fivi%2Fsyslinux.git Add more low-level API function to load the kernel, and make the menu subsystem use it. --- diff --git a/com32/include/com32.h b/com32/include/com32.h index 29656e4..5706683 100644 --- a/com32/include/com32.h +++ b/com32/include/com32.h @@ -88,18 +88,35 @@ void __farcall(uint16_t __es, uint16_t __eo, * 0..0xFFFFF and real-mode style SEG:OFFS pointers. Note that a * 32-bit linear pointer is not compatible with a SEG:OFFS pointer * stored in two consecutive 16-bit words. + * + * Use OFFS_WRT() if you want to compute an offset relative to a + * specific segment. OFFS_VALID() will return whether or not the + * pointer is actually reachable from the target segment. */ -static inline uint16_t SEG(void *__p) +static inline uint16_t SEG(const volatile void *__p) { return (uint16_t)(((uintptr_t)__p) >> 4); } -static inline uint16_t OFFS(void *__p) +static inline uint16_t OFFS(const volatile void *__p) { /* The double cast here is to shut up gcc */ return (uint16_t)(uintptr_t)__p & 0x000F; } +static inline uint16_t OFFS_WRT(const volatile void *__p, uint16_t seg) +{ + return (uint16_t)((uintptr_t)__p - ((uintptr_t)seg << 4)); +} + +static inline int OFFS_VALID(const volatile void *__p, uint16_t seg) +{ + uintptr_t __segstart = (uintptr_t)seg << 4; + uintptr_t __ptr = (uintptr_t)__p; + + return (__ptr >= __segstart) && (__ptr <= __segstart+0xffff); +} + static inline void *MK_PTR(uint16_t __seg, uint16_t __offs) { return (void *)((__seg << 4) + __offs); diff --git a/com32/modules/menu.c b/com32/modules/menu.c index 85ff8d5..d67f5b5 100644 --- a/com32/modules/menu.c +++ b/com32/modules/menu.c @@ -588,10 +588,11 @@ run_menu(void) static void -execute(const char *cmdline) +execute(char *cmdline) { #ifdef __COM32__ - static com32sys_t ireg; + com32sys_t ireg; + memset(&ireg, 0, sizeof ireg); if ( !strncmp(cmdline, ".localboot", 10) && isspace(cmdline[10]) ) { unsigned long localboot = strtoul(cmdline+10, NULL, 0); @@ -599,10 +600,30 @@ execute(const char *cmdline) ireg.eax.w[0] = 0x0014; /* Local boot */ ireg.edx.w[0] = localboot; } else { - strcpy(__com32.cs_bounce, cmdline); - ireg.eax.w[0] = 0x0003; /* Run command */ - ireg.ebx.w[0] = OFFS(__com32.cs_bounce); - ireg.es = SEG(__com32.cs_bounce); + const char *p; + char *q = __com32.cs_bounce; + const char *kernel, *args; + + kernel = q; + p = cmdline; + while ( *p && !isspace(*p) ) { + *p++ = *q++; + } + *q++ = '\0'; + + args = q; + while ( *p && isspace(*p) ) + p++; + + strcpy(q, p); + + ireg.eax.w[0] = 0x0016; + ireg.esi.w[0] = OFFS(kernel); + ireg.ds = SEG(kernel); + ireg.ebx.w[0] = OFFS(args); + ireg.es = SEG(kernel); + /* ireg.ecx.l = 0; */ /* We do ipappend "manually" */ + /* ireg.edx.l = 0; */ } __intcall(0x22, &ireg, NULL); diff --git a/comboot.doc b/comboot.doc index ec521ad..4af8045 100644 --- a/comboot.doc +++ b/comboot.doc @@ -158,38 +158,45 @@ INT 21h AH=4Ch [2.00] Terminate program All of these terminate the program. + INT 21h AH=01h [2.01] Get Key with Echo Reads a key from the console input, with echo to the console output. The read character is returned in AL. Extended characters received from the keyboard are returned as NUL (00h) + the extended character code. + INT 21h AH=02h [2.01] Write Character Writes a character in DL to the console (video and serial) output. + INT 21h AH=04h [2.01] Write Character to Serial Port Writes a character in DL to the serial console output (if enabled.) If no serial port is configured, this routine does nothing. + INT 21h AH=08h [2.09] Get Key without Echo Reads a key fron the console input, without echoing it to the console output. The read character is returned in AL. + INT 21h AH=09h [2.01] Write DOS String to Console Writes a DOS $-terminated string in DS:DX to the console. + INT 21h AH=0Bh [2.00] Check Keyboard Returns AL=FFh if there is a keystroke waiting (which can then be read with INT 21h, AH=01h or AH=08h), otherwise AL=00h. + INT 21h AH=30h [2.00] Check DOS Version This function returns AX=BX=CX=DX=0, corresponding to a @@ -626,3 +633,29 @@ AX=0015h [3.10] Get feature flags 1 Idle loop call (AX=0013h) is a no-op All other flags are reserved. + + +AX=0016h [3.10] Run kernel image + Input: AX 0016h + DS:SI Filename of kernel image (zero-terminated string) + ES:BX Command line (zero-terminated string) + ECX IPAPPEND flags [PXELINUX] + EDX Reserved - MUST BE ZERO + Output: Does not return if successful; returns with CF=1 if + the kernel image is not found. + + This function is similiar to AX=0003h Run command, except that + the filename and command line are treated as if specified in a + KERNEL and APPEND statement of a LABEL statement, which means: + + - The filename has to be exact; no variants are tried; + - No global APPEND statement is applied; + - ALLOWOPTIONS and IMPLICIT statements in the configuration + file do not apply. It is therefore important that the + COMBOOT module doesn't allow the end user to violate the + intent of the administrator. + + Additionally, this function returns with a failure if the file + doesn't exist, instead of returning to the command line. (It + may still return to the command line if the image is somehow + corrupt, however.) diff --git a/comboot.inc b/comboot.inc index 90d9e4b..91e260a 100644 --- a/comboot.inc +++ b/comboot.inc @@ -681,6 +681,44 @@ comapi_features: clc ret +; +; INT 22h AX=0016h Run kernel image +; +comapi_runkernel: + push ds + mov ds,P_DS + mov si,P_SI + mov di,KernelName + push di + call mangle_name + pop di + pop ds + call searchdir + jz comapi_err ; Kernel doesn't exist + + ; The kernel image was found, so we can load it... + mov [Kernel_SI],si + mov [Kernel_EAX],ax + mov [Kernel_EAX+2],dx + + push es + mov ds,P_ES + mov si,P_BX + push word real_mode_seg + pop es + mov di,cmd_line_here + call strcpy + dec di + mov [CmdLinePtr],di + pop es + +%if IS_PXELINUX + mov al,P_CL + mov [IPAppend],al +%endif + + mov bx,kernel_good_saved + section .data int21_table: int21 00h, comboot_return diff --git a/ui.inc b/ui.inc index 0d7cc40..c656a0c 100644 --- a/ui.inc +++ b/ui.inc @@ -439,6 +439,20 @@ kernel_corrupt: mov si,err_notkernel ; ; Anything else is assumed to be a Linux kernel. ; + section .bss + alignb 4 +Kernel_EAX resd 1 +Kernel_SI resw 1 + + section .text +kernel_good_saved: + ; Alternate entry point for which the return from + ; searchdir is stored in memory. This is used for + ; COMBOOT function INT 22h, AX=0016h. + mov si,[Kernel_SI] + mov eax,[Kernel_EAX] + mov dx,[Kernel_EAX+2] + kernel_good: pusha mov si,KernelName