--- trunk/mkinitrd-magellan/isolinux/comboot.inc 2010/08/19 08:27:19 1132 +++ trunk/mkinitrd-magellan/isolinux/comboot.inc 2010/08/19 09:50:43 1133 @@ -1,7 +1,7 @@ -;; $Id: comboot.inc,v 1.1 2007-09-01 22:44:04 niro Exp $ ;; ----------------------------------------------------------------------- -;; -;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved +;; +;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved +;; 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 @@ -13,7 +13,7 @@ ;; ;; comboot.inc -;; +;; ;; Common code for running a COMBOOT image ;; @@ -26,6 +26,7 @@ %define P_FLAGSH byte [bp+45] %define P_CS word [bp+42] %define P_IP word [bp+40] +%define P_CSIP dword [bp+40] %define P_DS word [bp+38] %define P_ES word [bp+36] %define P_FS word [bp+34] @@ -62,8 +63,9 @@ ; Looks like a COMBOOT image but too large comboot_too_large: + call close_file mov si,err_comlarge - call cwritestr + call writestr jmp enter_command ; @@ -72,11 +74,6 @@ ; do, however, allow the execution of INT 20h to return to SYSLINUX. ; is_comboot_image: - and dx,dx - jnz comboot_too_large - cmp ax,0ff00h ; Max size in bytes - jae comboot_too_large - push si ; Save file handle call make_plain_cmdline @@ -127,14 +124,13 @@ ; Now actually load the file... pop si ; File handle mov bx,100h ; Load at :0100h - mov cx,0FF00h >> SECTOR_SHIFT + mov cx,10000h >> SECTOR_SHIFT ; Absolute maximum # of sectors call getfssec + cmp ecx,65536-256-2 ; Maximum size + ja comboot_too_large ; And invoke the program... - mov [SavedSSSP],sp - mov [SavedSSSP+2],ss ; Save away SS:SP - mov ax,es mov ds,ax mov ss,ax @@ -144,8 +140,11 @@ jmp comboot_seg:100h ; Run it ; Proper return vector -comboot_return: cli ; Don't trust anyone - xor ax,ax +; Note: this gets invoked both via INT 21h and directly via INT 20h. +; We don't need to cld explicitly here, because comboot_exit does that +; when invoking RESET_STACK_AND_SEGS. +comboot_return: cli ; May not have a safe stack + push enter_command ; Normal return to command prompt jmp comboot_exit ; @@ -153,20 +152,77 @@ ; by the COM32 code. ; comboot_setup_api: - mov di,4*0x20 ; DOS interrupt vectors - mov eax,comboot_return ; INT 20h = exit - stosd - mov ax,comboot_int21 ; INT 21h = DOS-compatible syscalls - stosd - mov ax,comboot_int22 ; INT 22h = proprietary syscalls - stosd - mov ax,comboot_bogus - mov cx,29 ; All remaining DOS vectors - rep stosd - ret + mov di,DOSErrTramp ; Error trampolines + mov cx,32 + push cx + mov eax,02EB206Ah ; push 20h; jmp $+4 +.loop1: stosd + inc ah + loop .loop1 + dec di + mov byte [di-1],0E9h + mov ax,comboot_bogus-2 + sub ax,di + stosw + + pop cx ; CX <- 32 + mov si,4*20h ; DOS interrupt vectors + mov bx,comboot_vectors + mov di,DOSSaveVectors +.loop2: + movsd + movzx eax,word [bx] + inc bx + inc bx + mov [si-4],eax + loop .loop2 + ret + + section .bss + alignb 4 +DOSSaveVectors resd 32 + + section .data +%define comboot_err(x) (DOSErrTramp+4*((x)-20h)) + +comboot_vectors: + dw comboot_return ; INT 20 = exit + dw comboot_int21 ; INT 21 = DOS-compatible system calls + dw comboot_int22 ; INT 22 = native system calls + dw comboot_err(23h) ; INT 23 = DOS Ctrl-C handler + dw comboot_err(24h) ; INT 24 = DOS critical error handler + dw comboot_err(25h) ; INT 25 = DOS absolute disk read + dw comboot_err(26h) ; INT 26 = DOS absolute disk write + dw comboot_err(27h) ; INT 27 = DOS TSR + dw comboot_int28 ; INT 28 = DOS idle interrupt + dw comboot_int29 ; INT 29 = DOS fast console output + dw comboot_err(2Ah) ; INT 2A = DOS network API (NetBIOS) + dw comboot_err(2Bh) ; INT 2B = DOS reserved + dw comboot_err(2Ch) ; INT 2C = DOS reserved + dw comboot_iret ; INT 2D = DOS reserved, AMIS + dw comboot_err(2Eh) ; INT 2E = DOS run command + dw comboot_iret ; INT 2F = DOS multiplex interrupt + dw comboot_err(30h) ; INT 30 = DOS CP/M system calls + dw comboot_err(31h) ; INT 31 = DPMI + dw comboot_err(32h) ; INT 32 = DOS reserved + dw comboot_iret ; INT 33 = DOS mouse API + dw comboot_err(34h) ; INT 34 = DOS FPU emulation + dw comboot_err(35h) ; INT 35 = DOS FPU emulation + dw comboot_err(36h) ; INT 36 = DOS FPU emulation + dw comboot_err(37h) ; INT 37 = DOS FPU emulation + dw comboot_err(38h) ; INT 38 = DOS FPU emulation + dw comboot_err(39h) ; INT 39 = DOS FPU emulation + dw comboot_err(3Ah) ; INT 3A = DOS FPU emulation + dw comboot_err(3Bh) ; INT 3B = DOS FPU emulation + dw comboot_err(3Ch) ; INT 3C = DOS FPU emulation + dw comboot_err(3Dh) ; INT 3D = DOS FPU emulation + dw comboot_err(3Eh) ; INT 3E = DOS FPU emulation + dw comboot_err(3Fh) ; INT 3F = DOS overlay manager + + section .text ; INT 21h: generic DOS system call -comboot_int21: cli +comboot_int21: sti push ds push es push fs @@ -191,39 +247,67 @@ clc call ax ; Call the invoked function comboot_resume: + mov bp,sp ; In case the function clobbers BP setc P_FLAGSL ; Propagate CF->error popad pop gs pop fs pop es pop ds +comboot_iret: iret -; Attempted to execute non-21h DOS system call -comboot_bogus: cli ; Don't trust anyone - mov ax,err_notdos +comboot_bad_int21: + mov ax,P_AX + push P_CSIP + push 21h + ; Fall through + +; Attempted to execute invalid DOS system call +; The interrupt number is on the stack. +comboot_bogus: pop dx ; Interrupt number + pop edi ; CS:IP + mov cx,err_notdos + push comboot_bogus_tail + jmp comboot_exit_msg +comboot_bogus_tail: + xchg ax,dx + call writehex2 ; Interrupt number + mov al,' ' + call writechr + xchg ax,dx + call writehex4 ; Function number (AX) + mov al,' ' + call writechr + mov eax,edi + call writehex8 ; CS:IP of the origin + call crlf + jmp enter_command + ; ; Generic COMBOOT return to command line code -; AX -> message (if any) -; BX -> where to go next +; stack -> where to go next +; CX -> message (for _msg version) ; comboot_exit: - mov bx,enter_command ; Normal return to command prompt -comboot_exit_special: - xor dx,dx - mov ds,dx - mov es,dx - lss sp,[SavedSSSP] - sti - cld + xor cx,cx +comboot_exit_msg: + pop bx ; Return address + RESET_STACK_AND_SEGS SI ; Contains sti, cld call adjust_screen ; The COMBOOT program might have changed the screen - and ax,ax - je .nomsg + pusha + mov si,DOSSaveVectors + mov di,4*20h + mov cx,20h + rep movsd ; Restore DOS-range vectors + popa + jcxz .nomsg mov si,KernelCName - call cwritestr - xchg si,ax - call cwritestr -.nomsg: jmp bx + call writestr + mov si,cx + call writestr +.nomsg: + jmp bx ; ; INT 21h system calls @@ -298,11 +382,29 @@ jmp .done ; +; INT 28h - DOS idle +; +comboot_int28: + sti + cld + call do_idle + iret + +; +; INT 29h - DOS fast write character +; +comboot_int29: + sti + cld + call writechr ; Preserves registers! + iret + +; ; INT 22h - SYSLINUX-specific system calls ; System call number in ax ; comboot_int22: - cli + sti push ds push es push fs @@ -339,7 +441,7 @@ ; Number of API functions supported mov P_AX,int22_count ; SYSLINUX version - mov P_CX,(VER_MAJOR << 8)+VER_MINOR + mov P_CX,(VERSION_MAJOR << 8)+VERSION_MINOR ; SYSLINUX derivative ID byte mov P_DX,my_id ; For future use @@ -347,9 +449,9 @@ mov P_ES,ds ; ES:SI -> version banner - mov P_SI,syslinux_banner + mov P_SI,syslinux_banner + 2 ; Skip leading CR LF ; ES:DI -> copyright string - mov P_DI,copyright_str + mov P_DI,copyright_str + 1 ; Skip leading space comapi_nop: clc @@ -378,19 +480,18 @@ mov si,P_BX mov di,command_line call strcpy - xor ax,ax - mov bx,load_kernel ; Run a new kernel - jmp comboot_exit_special ; Terminate task, clean up + push load_kernel ; Run a new kernel + jmp comboot_exit ; Terminate task, clean up ; -; INT 22h AX=0004h Run default command +; INT 22h AX=0004h Run default command ; ; Terminates the COMBOOT program and executes the default command line ; as if a timeout had happened or the user pressed . ; comapi_run_default: - mov bx,auto_boot - jmp comboot_exit_special + push auto_boot + jmp comboot_exit ; ; INT 22h AX=0005h Force text mode @@ -406,18 +507,16 @@ ; INT 22h AX=0006h Open file ; comapi_open: + call reset_idle push ds mov ds,P_ES mov si,P_SI mov di,InitRD - push di call mangle_name - pop di pop ds call searchdir jz comapi_err - mov P_AX,ax - mov P_HAX,dx + mov P_EAX,eax mov P_CX,SECTOR_SIZE mov P_SI,si clc @@ -427,6 +526,7 @@ ; INT 22h AX=0007h Read file ; comapi_read: + call reset_idle mov es,P_ES mov bx,P_BX mov si,P_SI @@ -435,14 +535,15 @@ jnc .noteof xor si,si ; SI <- 0 on EOF, CF <- 0 .noteof: mov P_SI,si + mov P_ECX,ecx ret ; ; INT 22h AX=0008h Close file ; comapi_close: - ; Do nothing for now. Eventually implement - ; an internal API for this. + mov si,P_SI + call close_file clc ret @@ -455,8 +556,8 @@ mov es,P_ES mov di,P_DI call pxenv + mov ax,[PXEStatus] mov P_AX,ax - clc ret %else comapi_pxecall equ comapi_err ; Not available @@ -467,12 +568,7 @@ ; comapi_derinfo: mov P_AL,my_id -%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX - mov al,[DriveNumber] - mov P_DL,al - mov P_ES,cs - mov P_BX,PartInfo -%elif IS_PXELINUX +%if IS_PXELINUX mov ax,[APIVer] mov P_DX,ax mov ax,[StrucPtr] @@ -483,11 +579,27 @@ mov P_SI,ax mov ax,[InitStack+2] mov P_FS,ax -%elif IS_ISOLINUX - mov al,[DriveNo] + mov eax,[MyIP] + mov P_ECX,eax +%else + ; Physical medium... + + mov P_CL,SECTOR_SHIFT + mov al,[DriveNumber] mov P_DL,al + mov P_FS,cs + mov P_SI,OrigESDI +%if IS_SYSLINUX || IS_EXTLINUX + mov P_ES,cs + mov P_BX,PartInfo +%elif IS_ISOLINUX mov P_ES,cs mov P_BX,spec_packet + mov ax,[BIOSType] + sub ax,bios_cdrom + shr ax,2 + mov P_CH,al ; Mode (el torito/cbios/ebios) +%endif %endif clc ret @@ -523,15 +635,12 @@ sub bp,sp ; unload_pxe may move the stack around call unload_pxe add bp,sp ; restore frame pointer... -%elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX +%elif IS_SYSLINUX || IS_EXTLINUX ; Restore original FDC table mov eax,[OrigFDCTabPtr] mov [fdctab],eax %endif - ; Reset the floppy disk subsystem - xor ax,ax - xor dx,dx - int 13h + call cleanup_hardware clc ret @@ -546,13 +655,12 @@ mov [trackbuf+8],eax ; Total bytes mov eax,7C00h mov [trackbuf],eax ; Copy to - mov [EntryPoint],eax ; CS:IP entry point + push eax ; Entry point on stack mov esi,P_ESI mov edx,P_EBX mov bx,P_DS jmp replace_bootstrap_one - ; ; INT 22h AX=000Eh Get configuration file name ; @@ -565,7 +673,6 @@ ; ; INT 22h AX=000Fh Get IPAPPEND strings ; -%if IS_PXELINUX comapi_ipappend: mov P_ES,cs mov P_CX,numIPAppends @@ -573,18 +680,6 @@ clc ret - section .data - alignb 2, db 0 -IPAppends dw IPOption - dw BOOTIFStr -numIPAppends equ ($-IPAppends)/2 - -%else -comapi_ipappend equ comapi_err -%endif - - section .text - ; ; INT 22h AX=0010h Resolve hostname ; @@ -594,80 +689,40 @@ mov si,P_BX call dns_resolv mov P_EAX,eax + clc ret %else comapi_dnsresolv equ comapi_err %endif - + section .text ; -; INT 22h AX=0011h Maximum number of shuffle descriptors +; INT 22h AX=0011h Obsolete ; -comapi_maxshuffle: - mov P_CX,(2*trackbufsize)/12 - ret ; -; INT 22h AX=0012h Cleanup, shuffle and boot +; INT 22h AX=0012h Obsolete ; -comapi_shuffle: - call comapi_cleanup - mov cx,P_CX - cmp cx,(2*trackbufsize)/12 - ja .error - - push cx ; On stack: descriptor count - - lea cx,[ecx+ecx*2] ; CX *= 3 - - mov fs,P_ES - mov si,P_DI - mov di,trackbuf - push di ; On stack: descriptor list address - fs rep movsd ; Copy the list - - mov eax,P_EBP - mov [EntryPoint],eax ; CS:IP entry point - mov esi,P_ESI - mov edx,P_EBX - mov bx,P_DS - jmp replace_bootstrap -.error: - stc - ret ; ; INT 22h AX=0013h Idle call ; -; -; *** FIX THIS *** -; The idle call seems to have detrimental effects on some machines when -; called from a COM32 context (WHY?) -- disable it for now. -; -%if 0 ; def HAVE_IDLE - comapi_idle: - DO_IDLE + call do_idle clc ret -%else - -comapi_idle equ comapi_err - -%endif - ; ; INT 22h AX=0014h Local boot ; -%if IS_PXELINUX || IS_ISOLINUX +%if HAS_LOCALBOOT comapi_localboot: mov ax,P_DX jmp local_boot %else comapi_localboot equ comapi_err -%endif +%endif ; HAS_LOCALBOOT ; ; INT 22h AX=0015h Feature flags @@ -683,34 +738,32 @@ ; INT 22h AX=0016h Run kernel image ; comapi_runkernel: + mov al,P_DL + cmp al,VK_TYPES-1 + ja .error + mov [KernelType],al 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 ; The kernel image was found, so we can load it... mov [Kernel_SI],si - mov [Kernel_EAX],ax - mov [Kernel_EAX+2],dx - + mov [Kernel_EAX],eax + ; It's not just possible, but quite likely, that ES:BX - ; points into real_mode_seg, so we need to exercise some - ; special care here... use xfer_buf_seg as an intermediary + ; points into real_mode_seg or xfer_buf_seg, so we + ; need to exercise some special care here... use + ; trackbuf as an intermediary push ds - push es - mov ax,xfer_buf_seg mov ds,P_ES mov si,P_BX - mov es,ax - xor di,di + mov di,trackbuf call strcpy - pop es pop ds %if IS_PXELINUX @@ -718,31 +771,208 @@ mov [IPAppend],al %endif - xor ax,ax - mov bx,.finish - jmp comboot_exit_special + call comboot_exit .finish: ; Copy the command line into its proper place - push ds push es - mov ax,xfer_buf_seg mov dx,real_mode_seg - mov ds,ax mov es,dx - xor si,si + mov si,trackbuf mov di,cmd_line_here call strcpy mov byte [es:di-1],' ' ; Simulate APPEND pop es - pop ds mov [CmdLinePtr],di mov word [CmdOptPtr],zero_string jmp kernel_good_saved +.error equ comapi_usingvga.error + +; +; INT 22h AX=0017h Report video mode change +; +comapi_usingvga: + mov ax,P_BX + cmp ax,0Fh ; Unknown flags = failure + ja .error + mov [UsingVGA],al + mov cx,P_CX + mov dx,P_DX + mov [GXPixCols],cx + mov [GXPixRows],dx + test al,08h + jnz .notext + call adjust_screen +.notext: + clc + ret +.error: + stc + ret + +; +; INT 22h AX=0018h Query custom font +; +comapi_userfont: + mov al,[UserFont] + and al,al + jz .done + mov al,[VGAFontSize] + mov P_ES,aux_seg + mov P_BX,aux.fontbuf + +.done: ; CF=0 here + mov P_AL,al + ret + +; +; INT 22h AX=0019h Read disk +; +%if IS_SYSLINUX || IS_ISOLINUX || IS_EXTLINUX +comapi_readdisk: + call reset_idle + mov esi,P_ESI ; Enforce ESI == EDI == 0, these + or esi,P_EDI ; are reserved for future expansion + jnz .err + mov eax,P_EDX + mov es,P_ES + mov bx,P_BX + mov bp,P_CX ; WE CANNOT use P_* after touching bp! + call getlinsec + clc + ret +.err: + stc + ret +%else +comapi_readdisk equ comapi_err +%endif + +; +; INT 22h AX=001Ah Obsolete +; + +; +; INT 22h AX=001Bh Obsolete +; + +; +; INT 22h AX=001Ch Get pointer to auxillary data vector +; +comapi_getadv: + mov P_ES,ds + mov P_BX,adv0.data + mov P_CX,ADV_LEN + ret + +; +; INT 22h AX=001Dh Write auxillary data vector +; +comapi_writeadv equ adv_write + +; +; INT 22h AX=001Eh Keyboard remapping table +comapi_kbdtable: + cmp P_DX,0 + jne .err + mov P_AX,1 ; Version + mov P_CX,256 ; Length + mov P_ES,cs + mov P_BX,KbdMap + ret +.err: + stc + ret + +; +; INT 22h AX=001Fh Get current working directory +; +comapi_getcwd: + mov P_ES,cs + mov P_BX,CurrentDirName + clc + ret + +; +; INT 22h AX=0020h Open directory +; +%if IS_SYSLINUX +comapi_opendir: + call reset_idle + push ds + mov ds,P_ES + mov si,P_SI + mov di,InitRD + call mangle_name + pop ds + call searchdir + jnz comapi_err ; Didn't find a directory + cmp eax,0 + jz comapi_err ; Found nothing + ;ZF is unset + call alloc_fill_dir + mov P_EAX,eax + mov P_CX,SECTOR_SIZE + mov P_SI,si + clc + ret +%else +comapi_opendir equ comapi_err +%endif + +; +; INT 22h AX=0021h Read directory +; +%if IS_SYSLINUX +comapi_readdir: + call reset_idle + mov es,P_ES + mov di,P_DI + mov si,P_SI + call readdir + mov P_EAX,eax + mov P_DL,dl + mov P_EBX,ebx + mov P_SI,si + ret +%else +comapi_readdir equ comapi_err +%endif + +; +; INT 22h AX=0022h Close directory +; +%if IS_SYSLINUX +comapi_closedir: + mov si,P_SI + call close_dir + clc + ret +%else +comapi_closedir equ comapi_err +%endif + +; +; INT 22h AX=0023h Query shuffler size +; +comapi_shufsize: + mov P_CX,bcopyxx_safe + ret + +; +; INT 22h AX=0024h Cleanup, shuffle and boot raw +; +comapi_shufraw: + call comapi_cleanup + mov edi,P_EDI + mov esi,P_ESI + mov ecx,P_ECX + jmp shuffle_and_boot_raw + section .data -%macro int21 2 +%macro int21 2 db %1 dw %2 %endmacro @@ -757,10 +987,10 @@ int21 0Bh, comboot_checkkey int21 30h, comboot_checkver int21 4Ch, comboot_return - int21 -1, comboot_bogus + int21 -1, comboot_bad_int21 int21_count equ ($-int21_table)/3 - align 2, db 0 + alignz 2 int22_table: dw comapi_err ; 0000 unimplemented syscall dw comapi_get_version ; 0001 get SYSLINUX version @@ -775,16 +1005,30 @@ dw comapi_derinfo ; 000A derivative-specific info dw comapi_serialcfg ; 000B get serial port config dw comapi_cleanup ; 000C perform final cleanup - dw comapi_chainboot ; 000D clean up then bootstrap + dw comapi_err ; 000D clean up then bootstrap dw comapi_configfile ; 000E get name of config file dw comapi_ipappend ; 000F get ipappend strings dw comapi_dnsresolv ; 0010 resolve hostname - dw comapi_maxshuffle ; 0011 maximum shuffle descriptors - dw comapi_shuffle ; 0012 cleanup, shuffle and boot + dw comapi_err ; 0011 maximum shuffle descriptors + dw comapi_err ; 0012 cleanup, shuffle and boot dw comapi_idle ; 0013 idle call dw comapi_localboot ; 0014 local boot dw comapi_features ; 0015 feature flags dw comapi_runkernel ; 0016 run kernel image + dw comapi_usingvga ; 0017 report video mode change + dw comapi_userfont ; 0018 query custom font + dw comapi_readdisk ; 0019 read disk + dw comapi_err ; 001A cleanup, shuffle and boot to pm + dw comapi_err ; 001B cleanup, shuffle and boot to rm + dw comapi_getadv ; 001C get pointer to ADV + dw comapi_writeadv ; 001D write ADV to disk + dw comapi_kbdtable ; 001E keyboard remapping table + dw comapi_getcwd ; 001F get current working directory + dw comapi_opendir ; 0020 open directory + dw comapi_readdir ; 0021 read directory + dw comapi_closedir ; 0022 close directory + dw comapi_shufsize ; 0023 query shuffler size + dw comapi_shufraw ; 0024 cleanup, shuffle and boot raw int22_count equ ($-int22_table)/2 APIKeyWait db 0 @@ -794,12 +1038,19 @@ ; ; This is the feature flag array for INT 22h AX=0015h +; +; Note: PXELINUX clears the idle is noop flag if appropriate +; in pxe_detect_nic_type +; feature_flags: -%if IS_PXELINUX - db 1 ; Have local boot, idle not noop -%elif IS_ISOLINUX - db 3 ; Have local boot, idle is noop -%else - db 2 ; No local boot, idle is noop -%endif + db 1 ; Have local boot, idle is not noop 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 + alignb 4 +DOSErrTramp resd 33 ; Error trampolines +ConfigName resb FILENAME_MAX +CurrentDirName resb FILENAME_MAX