[syslinux:elflink] core: Delete code that is duplicated in ldlinux

syslinux-bot for Matt Fleming matt.fleming at linux.intel.com
Sat Dec 17 21:19:37 PST 2011


Commit-ID:  14531c47bc9577e56301884a9cd64dc4f651220b
Gitweb:     http://www.syslinux.org/commit/14531c47bc9577e56301884a9cd64dc4f651220b
Author:     Matt Fleming <matt.fleming at linux.intel.com>
AuthorDate: Tue, 24 May 2011 10:45:51 +0100
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Fri, 2 Dec 2011 12:13:30 +0000

core: Delete code that is duplicated in ldlinux

Lots of code that used to be implemented in the core is now
implemented in ldlinux, but code from core was never deleted. Purge
this code.

Also, move all com32 loading to ldlinux since we need to be able to do
various command line things (which are no longer available in the
core).

Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 com32/elflink/ldlinux/execute.c |   58 +---
 core/bootsect.inc               |  239 --------------
 core/cmdline.inc                |  101 ------
 core/com32.inc                  |   83 -----
 core/comboot.inc                |  228 ++-----------
 core/common.inc                 |    5 -
 core/configinit.inc             |   46 ---
 core/conio.c                    |    2 -
 core/diskfs.inc                 |   29 +--
 core/elflink/load_env32.c       |   69 ++++
 core/extern.inc                 |    5 +-
 core/fs/lib/searchconfig.c      |    2 +
 core/fs/newconfig.c             |   41 ---
 core/getc.inc                   |  415 ------------------------
 core/graphics.c                 |    6 -
 core/idle.inc                   |    4 +-
 core/include/core.h             |    1 +
 core/include/ctype.h            |    5 +
 core/init.c                     |    5 +
 core/init.inc                   |   11 -
 core/isolinux.asm               |   18 -
 core/loadhigh.inc               |   60 ----
 core/localboot.c                |   87 +++++
 core/localboot.inc              |   76 +----
 core/parsecmd.inc               |  129 --------
 core/parseconfig.inc            |  474 ---------------------------
 core/pxelinux.asm               |   49 ---
 core/rawcon.c                   |   91 ++++++
 core/runkernel.inc              |  684 ---------------------------------------
 core/ui.inc                     |   32 +-
 30 files changed, 329 insertions(+), 2726 deletions(-)

diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index dff59e6..2b265a1 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -36,6 +36,8 @@ const char *const kernel_types[] = {
     NULL
 };
 
+extern int create_args_and_load(char *);
+
 void execute(const char *cmdline, enum kernel_type type)
 {
 	const char *p, *const *pp;
@@ -79,60 +81,8 @@ void execute(const char *cmdline, enum kernel_type type)
 
 	if (type == KT_COM32) {
 		/* new entry for elf format c32 */
-		char **argv;
-		int i, argc;
-
-		q = args;
-		for (argc = 0; *q; q++) {
-			argc++;
-
-			/* Find the end of this arg */
-			while(*q && !my_isspace(*q))
-				q++;
-
-			/*
-			 * Now skip all whitespace between arguments.
-			 */
-			while (*q && my_isspace(*q))
-				q++;
-		}
-
-		/*
-		 * Generate a copy of argv on the stack as this is
-		 * traditionally where process arguments go.
-		 *
-		 * argv[0] must be the command name, so bump argc to
-		 * include argv[0].
-		 */
-		argc += 1;
-		argv = alloca(argc * sizeof(char *));
-		argv[0] = kernel;
-
-		for (q = args, i = 1; i < argc - 1; i++) {
-			char *start;
-			int len = 0;
-
-			start = q;
-
-			/* Find the end of this arg */
-			while(*q && !my_isspace(*q)) {
-				q++;
-				len++;
-			}
-
-			argv[i] = malloc(len + 1);
-			strncpy(argv[i], start, len);
-			argv[i][len] = '\0';
-
-			/*
-			 * Now skip all whitespace between arguments.
-			 */
-			while (*q && my_isspace(*q))
-				q++;
-		}
-
-		argv[argc] = NULL;
-		spawn_load(kernel, argc, argv);
+		lfree(kernel);
+		create_args_and_load(cmdline);
 	} else if (type == KT_KERNEL) {
 		/* Need add one item for kernel load, as we don't use
 		* the assembly runkernel.inc any more */
diff --git a/core/bootsect.inc b/core/bootsect.inc
deleted file mode 100644
index 6c20409..0000000
--- a/core/bootsect.inc
+++ /dev/null
@@ -1,239 +0,0 @@
-;; -----------------------------------------------------------------------
-;;
-;;   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
-;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;;   Boston MA 02111-1307, USA; either version 2 of the License, or
-;;   (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; bootsect.inc
-;;
-;; Load a boot sector (or other bootstrap program.)
-;;
-;; Unlike previous versions of this software, this doesn't require that
-;; the length is 512 bytes.  This allows PXE bootstraps and WinNT
-;; "CD boot sectors" to be invoked.
-;;
-
-;
-; Load a boot sector
-;
-is_bootsector:
-%if IS_SYSLINUX
-		; Transfer zero bytes
-		push word 0
-		jmp short load_bootsec
-
-is_bss_sector:
-		; Transfer the superblock
-SuperSize	equ $+1
-		push word superblock_len_fat16
-%endif
-load_bootsec:
-		mov edi,free_high_memory
-		mov [trackbuf+4],edi	; Copy from this address
-		xor dx,dx		; No padding
-		mov bx,abort_check	; Don't print dots, but allow abort
-		call load_high
-
-		sub edi,free_high_memory
-		mov [trackbuf+8],edi	; Save length
-
-		mov eax,7C00h		; Entry point
-		mov [trackbuf],eax	; Copy to this address
-
-%if IS_SYSLINUX
-		xor ecx,ecx
-		pop cx
-
-		; For a BSS boot sector we have to patch.
-		mov esi,superblock
-		mov edi,free_high_memory+(superblock-bootsec)
-		call bcopy
-%endif
-		push eax		; Save entry point
-
-		xor edx,edx
-		xor esi,esi
-%if IS_SYSLINUX || IS_EXTLINUX
-		; Restore original FDC table
-		mov eax,[OrigFDCTabPtr]
-		mov [fdctab],eax
-
-		mov dl,[DriveNumber]
-		mov si,PartInfo		; Partition info buffer
-		mov di,800h-18		; Put partition info here
-		push di
-		mov cx,8		; 16 bytes
-		xor ax,ax
-		rep movsw
-		pop si			; DS:SI points to partition info
-		xor bx,bx
-%elif IS_ISOLINUX
-		mov dl,[DriveNumber]
-		xor bx,bx
-%elif IS_PXELINUX
-		mov byte [KeepPXE],03h	; Chainloading + keep PXE
-		pm_call reset_pxe
-		lfs si,[InitStack]
-		; Put restore DS, EDX and ESI to the true initial values
-		mov bx,[fs:si+6]
-		mov edx,[fs:si+28]
-		mov esi,[fs:si+12]
-%endif
-
-;
-; replace_bootstrap for the special case where we have exactly one
-; descriptor, based in low memory.  We will generate a second descriptor
-; to clear remaining FBM.
-;
-
-replace_bootstrap_one:
-		mov eax,[trackbuf]		; Base address
-		add eax,[trackbuf+8]		; Length
-		movzx ecx,word [BIOS_fbm]
-		shl ecx,10			; Free Base Memory
-		sub ecx,eax
-		mov [trackbuf+12],eax
-		or dword [trackbuf+16],-1	; Zero memory
-		mov [trackbuf+20],ecx
-		push word 2			; Length of descriptor list
-		; Fall through
-
-;
-; Entrypoint for "shut down and replace bootstrap" -- also invoked by
-; the COMBOOT API.  This routine expects the entry point (CS, IP) and the
-; count of the descriptor sequence on the stack; the shuffle
-; descriptors start at the first byte of the trackbuf.
-;
-; The registers EDX and ESI are passed on to the called program,
-; and BX is passed on as DS.
-;
-replace_bootstrap:
-		;
-		; Prepare for shutting down
-		;
-		call vgaclearmode
-
-;
-; We jump here when loading a kernel image, so that we don't reset
-; the screen mode in "quiet" mode
-;
-replace_bootstrap_noclearmode:
-		call cleanup_hardware
-
-		;
-		; Set up initial stack frame (not used by PXE if keeppxe is
-		; set - we use the PXE stack then.)
-		;
-		xor ax,ax
-		mov ds,ax
-		mov es,ax
-
-%if IS_PXELINUX
-		cmp byte [KeepPXE],0
-		je .stdstack
-		les di,[InitStack]	; Reset stack to PXE original
-		jmp .stackok
-%endif
-.stdstack:
-		; StackBuf is guaranteed to have 44 bytes free immediately
-		; above it, and it will not interfere with our existing stack.
-		mov di,StackBuf
-		push di
-		mov cx,22		; 44 bytes
-		rep stosw
-		pop di
-.stackok:
-
-		mov [es:di+28],edx	; New EDX
-		mov [es:di+12],esi	; New ESI
-		mov [es:di+6],bx	; New DS
-
-%if IS_PXELINUX == 0
-		; DON'T DO THIS FOR PXELINUX...
-		; For PXE, ES:BX -> PXENV+, and this would corrupt
-		; that use.
-
-		; Restore ES:DI -> $PnP (if we were ourselves called
-		; that way...)
-		mov ax,[OrigESDI]
-		mov bx,[OrigESDI+2]
-
-		mov [es:di+8],ax	; New DI
-		mov [es:di+4],bx	; New ES
-%endif
-		pop ax			; descriptor list entries count
-
-		push di
-		push es
-
-		push ds
-		pop es
-
-		mov ebx,trackbuf
-		imul di,ax,12
-		push di			; length of list
-		add di,bx		; DI <- end of list
-
-		; Terminating entry...
-		lea eax,[replace_stub]	; Entrypoint
-		push ax
-		stosd
-		xor ax,ax		; EAX[31:16] == 0 already
-		stosd			; 16-bit mode
-		stosd			; End of list
-
-		; Copy the stub
-		pop di
-		mov si,__replacestub_lma
-		mov cx,__replacestub_dwords
-		rep movsd
-
-		; ECX <- final list length
-		xor ecx,ecx
-		pop cx			; original length in bytes
-		add cx, 12		; + termination entry size
-
-		pop word [replace_stub.ss]
-		pop word [replace_stub.esp]
-		pop dword [replace_stub.csip]
-
-		cli
-		mov ss,[replace_stub.ss]
-		mov esp,[replace_stub.esp]
-
-		mov edi,trackbuf
-		mov esi,edi
-
-		jmp shuffle_and_boot_raw
-
-		; This stub gets run after the shuffle.  It is copied
-		; below 0x7c00 in order to properly handle the case
-		; of bootstrap replacement.
-		section .replacestub
-replace_stub:
-		mov cr0,eax
-		jmp 0:.next
-.next:
-		mov ax,strict word 0
-.ss		equ $-2
-		mov ss,ax
-		mov esp,strict dword 0
-.esp		equ $-4
-		pop gs
-		pop fs
-		pop es
-		pop ds
-		popad
-		popfd
-		jmp 0:0
-.csip		equ $-4
-
-		section .text16
diff --git a/core/cmdline.inc b/core/cmdline.inc
deleted file mode 100644
index 3e63f9a..0000000
--- a/core/cmdline.inc
+++ /dev/null
@@ -1,101 +0,0 @@
-;; -----------------------------------------------------------------------
-;;
-;;   Copyright 2003-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
-;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;;   Boston MA 02111-1307, USA; either version 2 of the License, or
-;;   (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; cmdline.inc
-;;
-;; Common routine to assemble [null-terminated] command line into
-;; real_mode_seg:cmd_line_here.
-;; Not used by plain kernel due to BOOT_IMAGE= etc.
-;;
-
-		section .text16
-
-;
-; Assumes DS == CS
-;
-make_plain_cmdline:
-		push es
-		; ui.inc has already copied any APPEND options
-		mov ax,real_mode_seg
-		mov es,ax
-
-		mov di,[CmdLinePtr]
-		call do_ip_append
-
-		mov si,[CmdOptPtr]
-
-		call strcpy
-
-		dec di
-		mov [CmdLinePtr],di
-		mov byte [es:di],0		; Null-terminate
-
-		pop es
-		ret
-
-;
-; Actual IPAppend strings...
-;
-%if IS_PXELINUX
-		extern IPOption, BOOTIFStr, SYSUUIDStr
-		global IPAppends, numIPAppends
-
-		section .data16
-		alignz 2
-IPAppends	dw IPOption
-		dw BOOTIFStr
-		dw SYSUUIDStr
-numIPAppends	equ ($-IPAppends)/2
-%else
-IPAppends	equ 0
-numIPAppends	equ 0
-%endif
-
-;
-; Handle "ipappend" strings, if applicable
-;
-; Assumes DS == CS; pushes output to ES:DI
-;
-		section .text16
-
-do_ip_append:
-%ifndef DEPEND
- %if numIPAppends > 0
-		push cx
-		push bx
-		push si
-
-		mov bx,IPAppends
-		mov cx,[IPAppend]
-		and cx,(1 << numIPAppends)-1
-.loop:
-		jcxz .done
-		mov si,[bx]
-		inc bx
-		inc bx
-		test cl,1
-		jz .not_this
-
-		call strcpy
-		mov byte [es:di-1],' '	; Replace final null with space
-.not_this:
-		shr cx,1
-		jmp .loop
-.done:
-		pop si
-		pop bx
-		pop cx
- %endif
-%endif
-		ret
diff --git a/core/com32.inc b/core/com32.inc
index 111590c..929f50e 100644
--- a/core/com32.inc
+++ b/core/com32.inc
@@ -31,91 +31,8 @@
 ;
 com32_entry	equ	free_high_memory
 
-		section .text16
-is_com32_image:
-		push si			; Save file handle
-		push eax		; Save file length
-
-		call make_plain_cmdline
-		; Copy the command line into the low cmdline buffer
-		mov ax,real_mode_seg
-		mov fs,ax
-		mov si,cmd_line_here
-		mov di,command_line
-		mov cx,[CmdLinePtr]
-		inc cx			; Include final null
-		sub cx,si
-		fs rep movsb
-
-		mov si,KernelName
-		mov di,Com32Name
-		call strcpy
-
-		call comboot_setup_api	; Set up the COMBOOT-style API
-
-		mov edi,com32_entry	; Load address
-		pop eax			; File length
-		pop si			; File handle
-		xor dx,dx		; No padding
-		mov bx,abort_check	; Don't print dots, but allow abort
-		call load_high
-
-		mov esi,com32_entry
-		mov edi,trackbuf
-		mov ecx,5
-		call bcopy
-		cmp dword [trackbuf],0xcd4cfeb8
-		jne not_com32r
-		cmp byte [trackbuf+4],0x21
-		jne not_com32r
-
-com32_start:
-		;
-		; Point the stack to the end of (permitted) high memory
-		;
-		mov eax,[HighMemRsvd]
-		xor ax,ax			; Align to a 64K boundary
-		mov [PMESP],eax
-		mov ebx,.pm			; Where to go in PM
-		jmp enter_pm
-
-;
-; This is invoked right before the actually starting the COM32
-; progam, in 32-bit mode...
-;
-		bits 32
-		section .text
-.pm:
-		; Set up the calling stack frame
-
-		push dword pm_api_vector
-		push dword Com32Name		; Module filename
-		push dword [HighMemSize]	; Memory managed by Syslinux
-		push dword core_cfarcall	; Cfarcall entry point
-		push dword core_farcall		; Farcall entry point
-		push dword (1 << 16)		; 64K bounce buffer
-		push dword core_real_mode	; Bounce buffer address
-		push dword core_intcall		; Intcall entry point
-		push dword command_line		; Command line pointer
-		push dword 9			; Argument count
-		sti				; Interrupts OK now
-		call com32_entry		; Run the program...
-		; ... on return, fall through to com32_exit ...
-com32_exit:
-		mov bx,comboot_return
-		jmp enter_rm
-
 		bits 16
-		section .text16
-not_com32r:
-		mov si,KernelName
-		call writestr
-		mov si,not_com32r_msg
-		call writestr
-		jmp enter_command
-
 		section .data16
-not_com32r_msg	db ': not a COM32R image', CR, LF, 0
 
 		; Ersatz com32 invocation structure, to make libcom32
 		; code run the same if linked to the core.  This is in
diff --git a/core/comboot.inc b/core/comboot.inc
index 880f5db..e0ad068 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -16,7 +16,6 @@
 ;;
 ;; Common code for running a COMBOOT image
 ;;
-
 		section .text16
 
 ; Parameter registers definition; this is the definition
@@ -61,83 +60,6 @@
 %define		P_DI		word [bp]
 %define		P_HDI		word [bp+2]
 
-; Looks like a COMBOOT image but too large
-comboot_too_large:
-		pm_call pm_close_file
-		mov si,err_comlarge
-		call writestr
-		jmp enter_command
-
-;
-; Load a COMBOOT image.  A COMBOOT image is basically a DOS .COM file,
-; except that it may, of course, not contain any DOS system calls.  We
-; do, however, allow the execution of INT 20h to return to SYSLINUX.
-;
-is_comboot_image:
-		push si			; Save file handle
-
-		call make_plain_cmdline
-
-		call comboot_setup_api
-
-		mov cx,comboot_seg
-		mov es,cx
-
-		xor di,di
-		mov cx,64		; 256 bytes (size of PSP)
-		xor eax,eax		; Clear PSP
-		rep stosd
-
-		mov word [es:0], 020CDh	; INT 20h instruction
-		; First non-free paragraph
-		; This is valid because comboot_seg == real_mode_seg
-		; == the highest segment used by all derivatives
-		int 12h			; Get DOS memory size
-		shl ax,6		; Kilobytes -> paragraphs
-		mov word [es:02h],ax
-
-%ifndef DEPEND
-%if real_mode_seg != comboot_seg
-%error "This code assumes real_mode_seg == comboot_seg"
-%endif
-%endif
-		; Copy the command line from high memory
-		mov si,cmd_line_here
-		mov cx,125		; Max cmdline len (minus space and CR)
-		mov di,081h		; Offset in PSP for command line
-		mov al,' '		; DOS command lines begin with a space
-		stosb
-
-.loop:		es lodsb
-		and al,al
-		jz .done
-		stosb
-		loop .loop
-.done:
-
-		mov al,0Dh		; CR after last character
-		stosb
-		mov ax,di
-		sub al,82h		; Include space but not CR
-		mov [es:80h],al		; Store command line length
-
-		; Now actually load the file...
-		pop si			; File handle
-		mov bx,100h		; Load at <seg>:0100h
-		mov cx,0FF00h		; Maximum number of bytes
-		pm_call getfsbytes
-		cmp ecx,65536-256-2	; Maximum size
-		ja comboot_too_large
-
-		; And invoke the program...
-		mov ax,es
-		mov ds,ax
-		mov ss,ax
-		xor sp,sp
-		push word 0		; Return to address 0 -> exit
-
-		jmp comboot_seg:100h	; Run it
-
 ;
 ; Set up the COMBOOT API interrupt vectors.  This is now done at
 ; initialization time.
@@ -239,7 +161,7 @@ comboot_int21:	sti
 		mov es,bp
 		mov bp,sp			; Set up stack frame
 
-		call _adjust_screen		; The COMBOOT program might have changed the screen
+		pm_call pm_adjust_screen	; The COMBOOT program might hav changed the screen
 
 		mov cx,int21_count
 		mov si,int21_table
@@ -277,17 +199,17 @@ comboot_bogus:	pop dx			; Interrupt number
 		jmp comboot_exit_msg
 comboot_bogus_tail:
 		xchg ax,dx
-		call writehex2		; Interrupt number
+		pm_call pm_writehex2		; Interrupt number
 		mov al,' '
-		call writechr
+		pm_call pm_writechr
 		xchg ax,dx
-		call writehex4		; Function number (AX)
+		pm_call pm_writehex4		; Function number (AX)
 		mov al,' '
-		call writechr
+		pm_call pm_writechr
 		mov eax,edi
-		call writehex8		; CS:IP of the origin
-		call crlf
-		jmp enter_command
+		pm_call pm_writehex8		; CS:IP of the origin
+		pm_call crlf
+		jmp kaboom
 
 ; Proper return vector
 ; Note: this gets invoked both via INT 21h and directly via INT 20h.
@@ -310,12 +232,12 @@ comboot_exit_msg:
 		pop bx			; Return address
 		RESET_STACK_AND_SEGS si	; Contains sti, cld
 		pm_call comboot_cleanup_lowmem
-		call _adjust_screen	; The COMBOOT program might have changed the screen
+		pm_call pm_adjust_screen; The COMBOOT program might have change the screen
 		jcxz .nomsg
 		mov si,KernelName
-		call writestr
+		pm_call pm_writestr
 		mov si,cx
-		call writestr
+		pm_call pm_writestr
 .nomsg:
 		jmp bx
 
@@ -323,22 +245,22 @@ comboot_exit_msg:
 ; INT 21h system calls
 ;
 comboot_getkey:				; 01 = get key with echo
-		call vgashowcursor
+		pm_call vgashowcursor
 		call comboot_getchar
-		call vgahidecursor
-		call writechr
+		pm_call vgahidecursor
+		pm_call pm_writechr
 		clc
 		ret
 
 comboot_writechr:			; 02 = writechr
 		mov al,P_DL
-		call writechr
+		pm_call pm_writechr
 		clc
 		ret
 
 comboot_writeserial:			; 04 = write serial port
 		mov al,P_DL
-		call write_serial
+		pm_call pm_write_serial
 		clc
 		ret
 
@@ -353,7 +275,7 @@ comboot_writestr:			; 09 = write DOS string
 .loop:		es lodsb
 		cmp al,'$'		; End string with $ - bizarre
 		je .done
-		call writechr
+		pm_call pm_writechr
 		jmp short .loop
 .done:		clc
 		ret
@@ -361,7 +283,7 @@ comboot_writestr:			; 09 = write DOS string
 comboot_checkkey:			; 0B = check keyboard status
 		cmp byte [APIKeyFlag],00h
 		jnz .waiting
-		call pollchar
+		pm_call pm_pollchar
 .waiting:	setz al
 		dec al			; AL = 0FFh if present, 0 if not
 		mov P_AL,al
@@ -380,7 +302,7 @@ comboot_checkver:			; 30 = check DOS version
 comboot_getchar:
 		cmp byte [APIKeyFlag],00h
 		jne .queued
-		call getchar		; If not queued get input
+		pm_call pm_getchar	; If not queued get input
 		and al,al		; Function key?  (CF <- 0)
 		jnz .done
 		mov [APIKeyWait],ah	; High part of key
@@ -406,7 +328,7 @@ comboot_int28:
 comboot_int29:
 		sti
 		cld
-		call writechr			; Preserves registers!
+		pm_call pm_writechr
 		iret
 
 ;
@@ -426,7 +348,7 @@ comboot_int22:
 		mov es,bp
 		mov bp,sp			; Set up stack frame
 
-		call _adjust_screen		; The COMBOOT program might have changed the screen
+		pm_call pm_adjust_screen	; The COMBOOT program might hav changed the screen
 
 		cmp ax,int22_count
 		jb .ok
@@ -475,7 +397,7 @@ comapi_nop:
 comapi_writestr:
 		mov ds,P_ES
 		mov si,P_BX
-		call writestr
+		pm_call pm_writestr
 		clc
 		ret
 
@@ -486,12 +408,10 @@ comapi_writestr:
 ; ES:BX as if it had been entered by the user.
 ;
 comapi_run:
-		mov ds,P_ES
-		mov si,P_BX
-		mov di,command_line
-		call strcpy
-		push load_kernel		; Run a new kernel
-		jmp comboot_exit		; Terminate task, clean up
+		mov es,P_ES
+		mov bx,P_BX
+		pm_call pm_env32_run
+		ret
 
 ;
 ; INT 22h AX=0004h	Run default command
@@ -509,7 +429,7 @@ comapi_run_default:
 ; Puts the video in standard text mode
 ;
 comapi_textmode:
-		call vgaclearmode
+		pm_call vgaclearmode
 		clc
 		ret
 
@@ -615,19 +535,10 @@ comapi_derinfo:
 ; INT 22h AX=000Bh	Get Serial Console Configuration
 ;
 comapi_serialcfg:
-		mov ax,[SerialPort]
+		pm_call pm_serialcfg
 		mov P_DX,ax
-		mov ax,[BaudDivisor]
-		mov P_CX,ax
-		mov ax,[FlowControl]
-		or al,ah
-		mov ah,[FlowIgnore]
-		shr ah,4
-		test byte [DisplayCon],01h
-		jnz .normalconsole
-		or ah,80h
-.normalconsole:
-		mov P_BX,ax
+		mov P_CX,cx
+		mov P_BX,bx
 		clc
 		ret
 
@@ -647,7 +558,7 @@ comapi_cleanup:
 		mov eax,[OrigFDCTabPtr]
 		mov [fdctab],eax
 %endif
-		call cleanup_hardware
+		pm_call cleanup_hardware
 		clc
 		ret
 
@@ -655,18 +566,7 @@ comapi_cleanup:
 ; INT 22h AX=000Dh	Clean up then replace bootstrap
 ;
 comapi_chainboot:
-		call comapi_cleanup
-		mov eax,P_EDI
-		mov [trackbuf+4],eax		; Copy from
-		mov eax,P_ECX
-		mov [trackbuf+8],eax		; Total bytes
-		mov eax,7C00h
-		mov [trackbuf],eax		; Copy to
-		push eax			; Entry point on stack
-		mov esi,P_ESI
-		mov edx,P_EBX
-		mov bx,P_DS
-		jmp replace_bootstrap_one
+		ret
 
 ;
 ; INT 22h AX=000Eh	Get configuration file name
@@ -726,7 +626,8 @@ comapi_idle:
 ;
 comapi_localboot:
 		mov ax,P_DX
-		jmp local_boot
+		pm_call pm_local_boot
+		ret
 
 ;
 ; INT 22h AX=0015h	Feature flags
@@ -742,57 +643,7 @@ comapi_features:
 ; INT 22h AX=0016h	Run kernel image
 ;
 comapi_runkernel:
-		mov al,P_DL
-		cmp al,VK_TYPES-1
-		ja .error
-		mov [KernelType],al
-
-		; It's not just possible, but quite likely, that ES:BX
-		; points into real_mode_seg or xfer_buf_seg, so we
-		; need to exercise some special care here... use
-		; VKernelBuf for temporary storage.
-		push ds
-		mov ds,P_ES
-		mov si,P_BX
-		mov di,VKernelBuf
-		call strcpy
-		pop ds
-
-		push ds
-		mov ds,P_DS
-		mov si,P_SI
-		mov di,KernelName
-		pm_call pm_mangle_name
-		pop ds
-		pm_call pm_searchdir
-		jz comapi_err
-
-		; The kernel image was found, so we can load it...
-		mov [Kernel_SI],si
-		mov [Kernel_EAX],eax
-
-%if IS_PXELINUX
-		mov al,P_CL
-		mov [IPAppend],al
-%endif
-
-		call comboot_exit
-
-.finish:
-		; Copy the command line into its proper place
-		push es
-		mov dx,real_mode_seg
-		mov es,dx
-		mov si,VKernelBuf
-		mov di,cmd_line_here
-		call strcpy
-		mov word [es:di-1],' '	; Simulate APPEND: space plus null
-		pop es
-		mov [CmdLinePtr],di
-		mov word [CmdOptPtr],zero_string
-		jmp kernel_good_saved
-
-.error		equ comapi_usingvga.error
+		ret
 
 ;
 ; INT 22h AX=0017h  Report video mode change
@@ -801,15 +652,9 @@ 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:
+		pm_call pm_usingvga
 		clc
 		ret
 .error:
@@ -828,7 +673,6 @@ comapi_userfont:
 		mov P_BX,aux.fontbuf
 
 .done:		; CF=0 here
-		mov P_AL,al
 		ret
 
 ;
diff --git a/core/common.inc b/core/common.inc
index 1a6840e..65b4ab6 100644
--- a/core/common.inc
+++ b/core/common.inc
@@ -4,13 +4,8 @@
 ; some derivatives.)
 ;
 
-%include "getc.inc"		; getc et al
-%include "configinit.inc"	; Initialize configuration
-%include "parseconfig.inc"	; High-level config file handling
-%include "parsecmd.inc"		; Low-level config file handling
 %include "pm.inc"		; Protected mode
 %include "bcopy32.inc"		; 32-bit bcopy
-%include "loadhigh.inc"		; Load a file into high memory
 %include "strcpy.inc"           ; strcpy()
 %include "idle.inc"		; Idle handling
 %include "adv.inc"		; Auxillary Data Vector
diff --git a/core/configinit.inc b/core/configinit.inc
deleted file mode 100644
index 7386a8c..0000000
--- a/core/configinit.inc
+++ /dev/null
@@ -1,46 +0,0 @@
-;; -----------------------------------------------------------------------
-;;
-;;   Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
-;;   Copyright 2009-2010 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
-;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;;   Boston MA 02111-1307, USA; either version 2 of the License, or
-;;   (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; configinit.inc
-;;
-;; Initialize the configuration section
-;;
-
-		section .text16
-
-reset_config:
-		; Initialize the .config section
-		xor eax,eax
-		mov si,__config_lma
-		mov di,__config_start
-		mov cx,__config_dwords
-		rep movsd
-
-%ifndef DEPEND
-%if NULLFILE != 0
-		mov al,NULLFILE
-		mov di,FKeyName
-		mov cx,MAX_FKEYS*(1 << FILENAME_MAX_LG2)
-		rep stosb
-%endif
-%endif
-
-		mov di,KbdMap			; Default keymap 1:1
-		xor al,al
-		inc ch				; CX <- 256
-mkkeymap:	stosb
-		inc al
-		loop mkkeymap
-
-		ret
diff --git a/core/conio.c b/core/conio.c
index ddccbdb..5ed0b4b 100644
--- a/core/conio.c
+++ b/core/conio.c
@@ -54,8 +54,6 @@ void msg_initvars(void);
 static void msg_setfg(char data);
 static void msg_putchar(char ch);
 
-uint8_t KbdMap[256];	/* Keyboard map */
-
 /*
  * loadkeys:	Load a LILO-style keymap
  *
diff --git a/core/diskfs.inc b/core/diskfs.inc
index 5a029d3..fff0d32 100644
--- a/core/diskfs.inc
+++ b/core/diskfs.inc
@@ -98,15 +98,15 @@ trackbuf	resb trackbufsize	; Track buffer goes here
 
 kaboom2:
 		mov si,err_bootfailed
-		call writestr
+		pm_call pm_writestr
 		cmp byte [kaboom.again+1],18h	; INT 18h version?
 		je .int18
-		call getchar
-		call vgaclearmode
+		pm_call pm_getchar
+		pm_call vgaclearmode
 		int 19h			; And try once more to boot...
 .norge:		jmp short .norge	; If int 19h returned; this is the end
 .int18:
-		call vgaclearmode
+		pm_call vgaclearmode
 		int 18h
 .noreg:		jmp short .noreg	; Nynorsk
 
@@ -115,8 +115,6 @@ kaboom2:
 ; -----------------------------------------------------------------------------
 
 %include "common.inc"		; Universal modules
-%include "writestr.inc"		; String output
-%include "localboot.inc"	; Disk-based local boot
 
 ; -----------------------------------------------------------------------------
 ;  Begin data section
@@ -131,25 +129,6 @@ err_bootfailed	db CR, LF, 'Boot failed: please change disks and press '
 		db 'a key to continue.', CR, LF, 0
 
 ;
-; Config file keyword table
-;
-%include "keywords.inc"
-
-;
-; Extensions to search for (in *forward* order).
-;
-		alignz 4
-exten_table:	db '.cbt'		; COMBOOT (specific)
-%if IS_SYSLINUX
-		db '.bss'		; Boot sector (add superblock)
-%endif
-		db '.bs', 0		; Boot sector
-		db '.com'		; COMBOOT (same as DOS)
-		db '.c32'		; COM32
-exten_table_end:
-		dd 0, 0			; Need 8 null bytes here
-
-;
 ; Misc initialized (data) variables
 ;
 %ifdef debug				; This code for debugging only
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index d7757f3..7ffe185 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -15,6 +15,8 @@
 #include <fcntl.h>
 #include <sys/file.h>
 #include <fs.h>
+#include <ctype.h>
+#include <alloca.h>
 
 #include <sys/exec.h>
 #include <sys/module.h>
@@ -112,3 +114,70 @@ void load_env32(com32sys_t * regs)
 	if (!search_config(&fp->i.fd, search_directories, filenames))
 		spawn_load(LDLINUX, 1, argv);
 }
+
+int create_args_and_load(char *cmdline)
+{
+	char *p, **argv;
+	int argc;
+	int i;
+
+	if (!cmdline)
+		return -1;
+
+	for (argc = 0, p = cmdline; *p; argc++) {
+		/* Find the end of this arg */
+		while(*p && !isspace(*p))
+			p++;
+
+		/*
+		 * Now skip all whitespace between arguments.
+		 */
+		while (*p && isspace(*p))
+			p++;
+	}
+
+	/*
+	 * Generate a copy of argv on the stack as this is
+	 * traditionally where process arguments go.
+	 *
+	 * argv[0] must be the command name.
+	 */
+	argv = alloca(argc * sizeof(char *));
+
+	for (i = 0, p = cmdline; i < argc; i++) {
+		char *start;
+		int len = 0;
+
+		start = p;
+
+		/* Find the end of this arg */
+		while(*p && !isspace(*p)) {
+			p++;
+			len++;
+		}
+
+		argv[i] = malloc(len + 1);
+		strncpy(argv[i], start, len);
+		argv[i][len] = '\0';
+
+		/*
+		 * Now skip all whitespace between arguments.
+		 */
+		while (*p && isspace(*p))
+			p++;
+	}
+
+	/* NUL-terminate */
+	argv[argc] = NULL;
+
+	return spawn_load(argv[0], argc, argv);
+}
+
+void pm_env32_run(com32sys_t *regs)
+{
+	char *cmdline;
+
+	cmdline = MK_PTR(regs->es, regs->ebx.w[0]);
+	if (create_args_and_load(cmdline) < 0)
+		printf("Failed to run com32 module\n");
+}
diff --git a/core/extern.inc b/core/extern.inc
index dea6052..da3d894 100644
--- a/core/extern.inc
+++ b/core/extern.inc
@@ -16,7 +16,7 @@
 	extern abort_load_new
 
 	; elflink/load_env32.c
-	extern load_env32
+	extern load_env32, pm_env32_run
 
 	; memscan.c
 	extern highmem_init
@@ -72,4 +72,7 @@
 	; font.c
 	extern pm_getchar, pm_adjust_screen, pm_usingvga, pm_userfont
 
+	; localboot.c
+	extern pm_local_boot
+
 %endif ; EXTERN_INC
diff --git a/core/fs/lib/searchconfig.c b/core/fs/lib/searchconfig.c
index fb7322b..7fdad18 100644
--- a/core/fs/lib/searchconfig.c
+++ b/core/fs/lib/searchconfig.c
@@ -4,6 +4,8 @@
 #include <core.h>
 #include <fs.h>
 
+char ConfigName[FILENAME_MAX];
+
 /*
  * Common implementation of load_config
  *
diff --git a/core/fs/newconfig.c b/core/fs/newconfig.c
deleted file mode 100644
index 58c47a5..0000000
--- a/core/fs/newconfig.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- *   Copyright 2010 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
- *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- *   Boston MA 02110-1301, USA; either version 2 of the License, or
- *   (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * newconfig.c
- *
- * Load a new configuration file
- */
-
-#include "core.h"
-#include "fs.h"
-
-void pm_is_config_file(com32sys_t *regs)
-{
-    char target_cwd[FILENAME_MAX];
-    const char *p;
-
-    (void)regs;
-
-    /* Save configuration file as an absolute path for posterity */
-    realpath(ConfigName, KernelName, FILENAME_MAX);
-
-    /* If we got anything on the command line, do a chdir */
-    p = cmd_line;
-    while (*p && !not_whitespace(*p))
-	p++;
-
-    if (*p) {
-	mangle_name(target_cwd, p);
-	chdir(target_cwd);
-    }
-}
diff --git a/core/getc.inc b/core/getc.inc
deleted file mode 100644
index 33656b4..0000000
--- a/core/getc.inc
+++ /dev/null
@@ -1,415 +0,0 @@
-;; -----------------------------------------------------------------------
-;;
-;;   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
-;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;;   Boston MA 02111-1307, USA; either version 2 of the License, or
-;;   (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; getc.inc
-;;
-;; Simple file handling library (open, getc, ungetc)
-;;
-;; WARNING: This interface uses the real_mode_seg/comboot_seg.
-;;
-
-MAX_GETC_LG2	equ 4			; Max number of file nesting
-MAX_GETC	equ (1 << MAX_GETC_LG2)
-bytes_per_getc_lg2	equ 16-MAX_GETC_LG2
-bytes_per_getc		equ (1 << bytes_per_getc_lg2)
-MAX_UNGET	equ 9			; Max bytes that can be pushed back
-
-		struc getc_file
-gc_file		resw 1			; File pointer
-gc_bufbytes	resw 1			; Bytes left in buffer
-gc_bufdata	resw 1			; Pointer to data in buffer
-gc_unget_cnt	resb 1			; Character pushed back count
-gc_unget_buf	resb MAX_UNGET		; Character pushed back buffer
-		endstruc
-getc_file_lg2	equ 4			; Size of getc_file as a power of 2
-
-%ifndef DEPEND
-%if (getc_file_size != (1 << getc_file_lg2))
-%error "getc_file_size != (1 << getc_file_lg2)"
-%endif
-%endif
-
-;
-; open,getc:	Load a file a character at a time for parsing in a manner
-;		similar to the C library getc routine.
-;		Up to MAX_GETC files can be open at the same time,
-;		they are accessed in a stack-like fashion.
-;
-;		All routines assume CS == DS.
-;
-;		open:	Input:	mangled filename in DS:DI
-;			Output: ZF set on file not found or zero length
-;
-;		openfd:	Input:	file handle in SI, file size in EAX
-;			Output:	ZF set on getc stack overflow
-;
-;		getc:	Output: CF set on end of file
-;				Character loaded in AL
-;
-;		close:	Output:	CF set if nothing open
-;
-		global core_open
-core_open:
-		pm_call pm_searchdir
-		jz openfd.ret
-openfd:
-		push bx
-
-		mov bx,[CurrentGetC]
-		sub bx,getc_file_size
-		cmp bx,GetCStack
-		jb .stack_full		; Excessive nesting
-		mov [CurrentGetC],bx
-
-		mov [bx+gc_file],si	; File pointer
-		xor ax,ax
-		mov [bx+gc_bufbytes],ax		; Buffer empty
-		mov [bx+gc_unget_cnt],al	; ungetc buffer empty
-
-		inc ax			; ZF <- 0
-		pop bx
-.ret:		ret
-
-.stack_full:
-		pm_call pm_close_file
-		xor ax,ax		; ZF <- 1
-		pop bx
-		ret
-		
-getc:
-		push bx
-		push si
-		push di
-		push es
-
-		mov di,[CurrentGetC]
-		movzx bx,byte [di+gc_unget_cnt]
-		and bx,bx
-		jnz .have_unget
-
-		mov si,real_mode_seg	; Borrow the real_mode_seg
-		mov es,si
-
-.got_data:
-		sub word [di+gc_bufbytes],1
-		jc .get_data		; Was it zero already?
-		mov si,[di+gc_bufdata]
-		mov al,[es:si]
-		inc si
-		mov [di+gc_bufdata],si
-.done:
-		clc
-.ret:
-		pop es
-		pop di
-		pop si
-		pop bx
-		ret
-.have_unget:
-		dec bx
-		mov al,[di+bx+gc_unget_buf]
-		mov [di+gc_unget_cnt],bl
-		jmp .done
-
-.get_data:
-		pushad
-		; Compute start of buffer
-		mov bx,di
-		sub bx,GetCStack
-		shl bx,bytes_per_getc_lg2-getc_file_lg2
-
-		mov [di+gc_bufdata],bx
-		mov si,[di+gc_file]
-		and si,si
-		mov [di+gc_bufbytes],si	; In case SI == 0
-		jz .empty
-		mov cx,bytes_per_getc
-		pm_call getfsbytes
-		mov [di+gc_bufbytes],cx
-		mov [di+gc_file],si
-		jcxz .empty
-		popad
-		TRACER 'd'
-		jmp .got_data
-
-.empty:
-		TRACER 'e'
-		; [di+gc_bufbytes] is zero already, thus we will continue
-		; to get EOF on any further attempts to read the file.
-		popad
-		xor al,al		; Return a predictable zero
-		stc
-		jmp .ret
-
-;
-; This is similar to getc, except that we read up to CX bytes and
-; store them in ES:DI.  Eventually this could get optimized...
-;
-; On return, CX and DI are adjusted by the number of bytes actually read.
-;
-readc:
-		push ax
-.loop:
-		call getc
-		jc .out
-		stosb
-		loop .loop
-.out:
-		pop ax
-		ret
-
-;
-; close: close the top of the getc stack
-;
-close:
-		push bx
-		push si
-		mov bx,[CurrentGetC]
-		mov si,[bx+gc_file]
-		pm_call pm_close_file
-		add bx,getc_file_size
-		mov [CurrentGetC],bx
-		pop si
-		pop bx
-		ret
-
-;
-; ungetc:	Push a character (in AL) back into the getc buffer
-;		Note: if more than MAX_UNGET bytes are pushed back, all
-;		hell will break loose.
-;
-ungetc:
-		push di
-		push bx
-		mov di,[CurrentGetC]
-		movzx bx,[di+gc_unget_cnt]
-		mov [bx+di+gc_unget_buf],al
-		inc bx
-		mov [di+gc_unget_cnt],bl
-		pop bx
-		pop di
-		ret
-
-;
-; skipspace:	Skip leading whitespace using "getc".  If we hit end-of-line
-;		or end-of-file, return with carry set; ZF = true of EOF
-;		ZF = false for EOLN; otherwise CF = ZF = 0.
-;
-;		Otherwise AL = first character after whitespace
-;
-skipspace:
-.loop:		call getc
-		jc .eof
-		cmp al,1Ah			; DOS EOF
-		je .eof
-		cmp al,0Ah
-		je .eoln
-		cmp al,' '
-		jbe .loop
-		ret				; CF = ZF = 0
-.eof:		cmp al,al			; Set ZF
-		stc				; Set CF
-		ret
-.eoln:		add al,0FFh			; Set CF, clear ZF
-		ret
-
-;
-; getint:	Load an integer from the getc file.
-;		Return CF if error; otherwise return integer in EBX
-;
-getint:
-		mov di,NumBuf
-.getnum:	cmp di,NumBufEnd	; Last byte in NumBuf
-		jae .loaded
-		push di
-		call getc
-		pop di
-		jc .loaded
-		stosb
-		cmp al,'-'
-		jnb .getnum
-		call ungetc		; Unget non-numeric
-.loaded:	mov byte [di],0
-		mov si,NumBuf
-		; Fall through to parseint
-;
-; parseint:	Convert an integer to a number in EBX
-;		Get characters from string in DS:SI
-;		Return CF on error
-;		DS:SI points to first character after number
-;
-;               Syntaxes accepted: [-]dec, [-]0+oct, [-]0x+hex, val+[KMG]
-;
-parseint:
-                push eax
-                push ecx
-		push bp
-		xor eax,eax		; Current digit (keep eax == al)
-		mov ebx,eax		; Accumulator
-		mov ecx,ebx		; Base
-                xor bp,bp               ; Used for negative flag
-.begin:		lodsb
-		cmp al,'-'
-		jne .not_minus
-		xor bp,1		; Set unary minus flag
-		jmp short .begin
-.not_minus:
-		cmp al,'0'
-		jb .err
-		je .octhex
-		cmp al,'9'
-		ja .err
-		mov cl,10		; Base = decimal
-		jmp short .foundbase
-.octhex:
-		lodsb
-		cmp al,'0'
-		jb .km		; Value is zero
-		or al,20h		; Downcase
-		cmp al,'x'
-		je .ishex
-		cmp al,'7'
-		ja .err
-		mov cl,8		; Base = octal
-		jmp short .foundbase
-.ishex:
-		mov al,'0'		; No numeric value accrued yet
-		mov cl,16		; Base = hex
-.foundbase:
-                call unhexchar
-                jc .km                ; Not a (hex) digit
-                cmp al,cl
-		jae .km			; Invalid for base
-		imul ebx,ecx		; Multiply accumulated by base
-                add ebx,eax             ; Add current digit
-		lodsb
-		jmp short .foundbase
-.km:
-		dec si			; Back up to last non-numeric
-		lodsb
-		or al,20h
-		cmp al,'k'
-		je .isk
-		cmp al,'m'
-		je .ism
-		cmp al,'g'
-		je .isg
-		dec si			; Back up
-.fini:		and bp,bp
-		jz .ret		; CF=0!
-		neg ebx			; Value was negative
-.done:		clc
-.ret:		pop bp
-                pop ecx
-                pop eax
-		ret
-.err:		stc
-		jmp short .ret
-.isg:		shl ebx,10		; * 2^30
-.ism:		shl ebx,10		; * 2^20
-.isk:		shl ebx,10		; * 2^10
-		jmp .fini
-
-		section .bss16
-		alignb 4
-NumBuf		resb 15			; Buffer to load number
-NumBufEnd	resb 1			; Last byte in NumBuf
-
-GetCStack	resb getc_file_size*MAX_GETC
-.end		equ $
-
-		section .data16
-CurrentGetC	dw GetCStack.end	; GetCStack empty
-
-;
-; unhexchar:    Convert a hexadecimal digit in AL to the equivalent number;
-;               return CF=1 if not a hex digit
-;
-		section .text16
-unhexchar:
-                cmp al,'0'
-		jb .ret			; If failure, CF == 1 already
-                cmp al,'9'
-                ja .notdigit
-		sub al,'0'		; CF <- 0
-		ret
-.notdigit:	or al,20h		; upper case -> lower case
-		cmp al,'a'
-                jb .ret			; If failure, CF == 1 already
-                cmp al,'f'
-                ja .err
-                sub al,'a'-10           ; CF <- 0
-                ret
-.err:		stc
-.ret:		ret
-
-;
-;
-; getline:	Get a command line, converting control characters to spaces
-;               and collapsing streches to one; a space is appended to the
-;               end of the string, unless the line is empty.
-;		The line is terminated by ^J, ^Z or EOF and is written
-;		to ES:DI.  On return, DI points to first char after string.
-;		CF is set if we hit EOF.
-;
-getline:
-		call skipspace
-                mov dl,1                ; Empty line -> empty string.
-                jz .eof               ; eof
-                jc .eoln              ; eoln
-		call ungetc
-.fillloop:	push dx
-		push di
-		call getc
-		pop di
-		pop dx
-		jc .ret		; CF set!
-		cmp al,' '
-		jna .ctrl
-		xor dx,dx
-.store:		stosb
-		jmp short .fillloop
-.ctrl:		cmp al,10
-		je .ret		; CF clear!
-		cmp al,26
-		je .eof
-		and dl,dl
-		jnz .fillloop		; Ignore multiple spaces
-		mov al,' '		; Ctrl -> space
-		inc dx
-		jmp short .store
-.eoln:		clc                     ; End of line is not end of file
-                jmp short .ret
-.eof:		stc
-.ret:		pushf			; We want the last char to be space!
-		and dl,dl
-		jnz .xret
-		mov al,' '
-		stosb
-.xret:		popf
-		ret
-
-;
-; parseint_esdi:
-;		Same as parseint, but takes the input in ES:DI
-;
-parseint_esdi:
-		push ds
-		push es
-		pop ds
-		xchg si,di
-		call parseint
-		xchg si,di
-		pop ds
-		ret
diff --git a/core/graphics.c b/core/graphics.c
index 7ca20ea..864550b 100644
--- a/core/graphics.c
+++ b/core/graphics.c
@@ -363,12 +363,6 @@ void vgashowcursor(void)
 
 void pm_usingvga(com32sys_t *regs)
 {
-	if (regs->eax.w[0] > 0x0F) {
-		/* Unknown flags = failure */
-		set_flags(regs, EFLAGS_CF);
-		return;
-	}
-
 	UsingVGA = regs->eax.b[0];
 	GXPixCols = regs->ecx.w[0];
 	GXPixRows = regs->edx.w[0];
diff --git a/core/idle.inc b/core/idle.inc
index ad26a10..c93d177 100644
--- a/core/idle.inc
+++ b/core/idle.inc
@@ -37,7 +37,7 @@ do_idle:
 		push si
 		push cx
 		mov si,hlt_err
-		call writestr
+		pm_call pm_writestr
 		mov si,sp
 		add si,10
 		mov cx,16
@@ -50,7 +50,7 @@ do_idle:
 		pm_call pm_writechr
 		jmp .errloop
 .endloop:
-		call crlf
+		pm_call crlf
 		pop cx
 		pop si
 		sti
diff --git a/core/include/core.h b/core/include/core.h
index 9fc0ce1..69c16d6 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -25,6 +25,7 @@ extern char syslinux_banner[];
 extern char copyright_str[];
 
 extern char aux_seg[];
+extern uint8_t KbdMap[256];
 
 /* diskstart.inc isolinux.asm*/
 extern void getlinsec(void);
diff --git a/core/include/ctype.h b/core/include/ctype.h
index 5c6d4cb..048a77d 100644
--- a/core/include/ctype.h
+++ b/core/include/ctype.h
@@ -22,4 +22,9 @@ static inline int tolower(int c)
     return c;
 }
 
+static inline int isspace(int c)
+{
+	return c <= ' ';
+}
+
 #endif /* CTYPE_H */
diff --git a/core/init.c b/core/init.c
index 27b9e46..c1ba298 100644
--- a/core/init.c
+++ b/core/init.c
@@ -63,9 +63,14 @@ static inline void bios_timer_init(void)
 
 void init(com32sys_t *regs)
 {
+	int i;
+
 	/* Initialize timer */
 	bios_timer_init();
 
+	for (i = 0; i < 256; i++)
+		KbdMap[i] = i;
+
 	adjust_screen();
 	printf_init();
 
diff --git a/core/init.inc b/core/init.inc
index 83d6fd6..286b380 100644
--- a/core/init.inc
+++ b/core/init.inc
@@ -30,23 +30,12 @@ common_init:
 
 		extern init
 		pm_call init
-;
-; Initialize configuration information
-;
-		call reset_config
 
 ;
 ; Set up the COMBOOT APIs
 ;
 		call comboot_setup_api
 
-;
-; Inite the memmory subsystem
-;
-;		pm_call mem_init
-		mov eax,[HighMemSize]
-		mov [VKernelEnd],eax
-
 		section .text16
 ;
 ; The code to decompress the PM code and initialize other segments.
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 8757c0f..bc6878b 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -1206,8 +1206,6 @@ debug_tracer:	pushad
 ; -----------------------------------------------------------------------------
 
 %include "common.inc"		; Universal modules
-%include "rawcon.inc"		; Console I/O w/o using the console functions
-%include "localboot.inc"	; Disk-based local boot
 
 ; -----------------------------------------------------------------------------
 ;  Begin data section
@@ -1215,19 +1213,3 @@ debug_tracer:	pushad
 
 		section .data16
 err_disk_image	db 'Cannot load disk image (invalid file)?', CR, LF, 0
-
-;
-; Config file keyword table
-;
-%include "keywords.inc"
-
-;
-; Extensions to search for (in *forward* order).
-;
-		alignz 4
-exten_table:	db '.cbt'		; COMBOOT (specific)
-		db '.bin'		; CD boot sector
-		db '.com'		; COMBOOT (same as DOS)
-		db '.c32'		; COM32
-exten_table_end:
-		dd 0, 0			; Need 8 null bytes here
diff --git a/core/loadhigh.inc b/core/loadhigh.inc
deleted file mode 100644
index 89de5e8..0000000
--- a/core/loadhigh.inc
+++ /dev/null
@@ -1,60 +0,0 @@
-;; -----------------------------------------------------------------------
-;;
-;;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-;;   Copyright 2009-2010 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
-;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;;   Boston MA 02111-1307, USA; either version 2 of the License, or
-;;   (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; loadhigh.inc
-;;
-;; Load a file into high memory
-;;
-
-		section .text16
-
-;
-; load_high:	loads (the remainder of) a file into high memory.
-;
-;		Assumes CS == DS.
-;
-; Inputs:	SI  = file handle/cluster pointer
-;		EDI = target address in high memory
-;		EAX = maximum number of bytes to load
-;		DX  = zero-padding mask (e.g. 0003h for pad to dword)
-;		BX  = subroutine to call at the top of each loop
-;                     (to print status and check for abort)
-;		[MyHighMemSize] = maximum load address
-;
-; Outputs:	SI  = file handle/cluster pointer
-;		EBX = first untouched address (not including padding)
-;		EDI = first untouched address (including padding)
-;		CF  = reached EOF
-;
-		extern pm_load_high
-load_high:
-		push ebp
-		mov ebp,[MyHighMemSize]
-		pm_call pm_load_high
-		pop ebp
-		jo .overflow
-		ret
-
-.overflow:	mov si,err_nohighmem
-		jmp abort_load
-
-		section .data16
-err_nohighmem   db CR, LF
-		db 'Not enough memory to load specified image.', CR, LF, 0
-
-		section .bss16
-		alignb 2
-PauseBird	resw 1
-
-		section .text16
diff --git a/core/localboot.c b/core/localboot.c
new file mode 100644
index 0000000..c6993fc
--- /dev/null
+++ b/core/localboot.c
@@ -0,0 +1,87 @@
+/* -----------------------------------------------------------------------
+ *
+ *   Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   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
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * -----------------------------------------------------------------------
+ */
+#include <sys/cpu.h>
+#include <core.h>
+
+/*
+ * localboot.c
+ *
+ * Boot from a local disk, or invoke INT 18h.
+ */
+
+#define LOCALBOOT_MSG	"Booting from local disk..."
+
+#define retry_count	16
+
+extern void local_boot16(void);
+
+/*
+ * Boot a specified local disk.  AX specifies the BIOS disk number; or
+ * -1 in case we should execute INT 18h ("next device.")
+ */
+void local_boot(int16_t ax)
+{
+	com32sys_t ireg, oreg;
+	unsigned long data;
+	int i;
+
+	vgaclearmode();
+
+	writestr(LOCALBOOT_MSG);
+	crlf();
+	cleanup_hardware();
+
+	if (ax == -1) {
+		/* Hope this does the right thing */
+		__intcall(0x18, &zero_regs, NULL);
+
+		/* If we returned, oh boy... */
+		kaboom();
+	}
+
+	/*
+	 * Load boot sector from the specified BIOS device and jump to
+	 * it.
+	 */
+	ireg.edx.b[0] = ax & 0xff;
+	ireg.eax.w[0] = 0;	/* Reset drive */
+	__intcall(0x13, &ireg, NULL);
+
+	ireg.eax.w[0] = 0x0201;	/* Read one sector */
+	ireg.ecx.w[0] = 0x0001;	/* C/H/S = 0/0/1 (first sector) */
+	ireg.ebx.w[0] = OFFS(trackbuf);
+	ireg.es = SEG(trackbuf);
+
+	for (i = 0; i < retry_count; i++) {
+		__intcall(0x13, &ireg, &oreg);
+
+		if (!(oreg.eflags.l & EFLAGS_CF))
+			break;
+	}
+
+	if (i == retry_count)
+		kaboom();
+
+	cli();			/* Abandon hope, ye who enter here */
+	memcpy(0x07C00, trackbuf, 512);
+
+	ireg.esi.w[0] = OFFS(trackbuf);
+	ireg.edi.w[0] = 0x07C00;
+	ireg.edx.w[0] = ax;
+	call16(local_boot16, &ireg, NULL);
+}
+
+void pm_local_boot(com32sys_t *regs)
+{
+	local_boot(regs->eax.w[0]);
+}
diff --git a/core/localboot.inc b/core/localboot.inc
index 1fe3102..ce971ae 100644
--- a/core/localboot.inc
+++ b/core/localboot.inc
@@ -1,73 +1,7 @@
-; -----------------------------------------------------------------------
-;
-;   Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
-;
-;   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
-;   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-;   Boston MA 02110-1301, USA; either version 2 of the License, or
-;   (at your option) any later version; incorporated herein by reference.
-;
-; -----------------------------------------------------------------------
-
-;
-; localboot.inc
-;
-; Boot from a local disk, or invoke INT 18h.
-;
-
-;
-; Boot a specified local disk.  AX specifies the BIOS disk number; or
-; -1 in case we should execute INT 18h ("next device.")
-;
 		section .text16
-
-local_boot:
-		call vgaclearmode
-		RESET_STACK_AND_SEGS dx		; dx <- 0
-		mov fs,dx
-		mov gs,dx
-		mov si,localboot_msg
-		call writestr
-		call cleanup_hardware
-		cmp ax,-1
-		je .int18
-
-		; Load boot sector from the specified BIOS device and jump to it.
-		mov dl,al
-		xor dh,dh
-		push dx
-		xor ax,ax			; Reset drive
-		int 13h
-		mov ax,0201h			; Read one sector
-		mov cx,0001h			; C/H/S = 0/0/1 (first sector)
-		mov bx,trackbuf
-		mov bp,retry_count
-.again:
-		pusha
-		int 13h
-		popa
-		jnc .ok
-		dec bp
-		jnz .again
-		jmp kaboom			; Failure...
-.ok:
-		pop dx
-		cli				; Abandon hope, ye who enter here
-		mov si,trackbuf
-		mov di,07C00h
-		mov cx,512			; Probably overkill, but should be safe
-		rep movsd
-		mov ss,cx			; SS <- 0
+		global local_boot16
+local_boot16:
+		mov cx,0
+		mov ss,cx
 		mov sp,7C00h
-		jmp 0:07C00h			; Jump to new boot sector
-
-.int18:
-		int 18h				; Hope this does the right thing...
-		jmp kaboom			; If we returned, oh boy...
-
-		section .data16
-localboot_msg	db 'Booting from local disk...', CR, LF, 0
-
-		section .text16
-
+		jmp 0:07C00h
diff --git a/core/parsecmd.inc b/core/parsecmd.inc
deleted file mode 100644
index 30cd67f..0000000
--- a/core/parsecmd.inc
+++ /dev/null
@@ -1,129 +0,0 @@
-;; -----------------------------------------------------------------------
-;;
-;;   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
-;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;;   Boston MA 02111-1307, USA; either version 2 of the License, or
-;;   (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; parsecmd.inc
-;;
-;; Command line parser code
-;;
-
-		section .text16
-
-; -------------------------------------------------------------------------
-;  getcommand:	Get a keyword from the current "getc" file and match it
-;		against a list of keywords (keywd_table).  Each entry in
-;		that table should have the following form:
-;		<32 bit hash value> <16 bit handler offset>
-;
-;               The handler is called, and upon return this function
-;               returns with CF = 0.  On EOF, this function returns
-;		with CF = 1.
-; -------------------------------------------------------------------------
-
-getcommand.skipline:
-		call skipline
-
-getcommand:
-.find:
-		call skipspace		; Skip leading whitespace
-		jz .eof			; End of file
-		jc .find		; End of line: try again
-
-		; Do this explicitly so #foo is treated as a comment
-		cmp al,'#'		; Leading hash mark -> comment
-		je .skipline
-
-		; Abuse the trackbuf by putting the keyword there for
-		; possible error messaging...
-		mov di,trackbuf
-		stosb
-		or al,20h		; Convert to lower case
-		movzx ebx,al		; Hash for a one-char keyword
-.read_loop:
-		call getc
-		jc .eof
-		cmp al,' '		; Whitespace
-		jbe .done
-		stosb
-		or al,20h
-		rol ebx,5
-		xor bl,al
-		jmp short .read_loop
-.done:		call ungetc
-		xor ax,ax
-		stosb			; Null-terminate the trackbuf
-		call skipspace
-		jz .eof
-		jc .noparm
-		call ungetc		; Return nonwhitespace char to buf
-		mov si,keywd_table
-		mov cx,keywd_count
-.table_search:
-		lodsd
-		cmp ebx,eax
-		je .found_keywd
-		lodsd			; Skip entrypoint/argument
-		loop .table_search
-
-		; Otherwise unrecognized keyword
-		mov si,err_badcfg
-		call writestr
-		mov si,trackbuf
-		call writestr
-		call crlf
-		jmp .skipline
-
-		; No parameter
-.noparm:
-		mov si,err_noparm
-		call writestr
-		mov si,trackbuf
-		call writestr
-		call crlf
-		jmp .find
-
-.found_keywd:	lodsw			; Load argument into ax
-		call [si]
-		clc
-		ret
-
-.eof:		stc
-		ret
-
-skipline:	cmp al,10		; Search for LF
-		je .end
-		call getc
-		jnc skipline
-.end:		ret
-
-		section .data16
-err_badcfg      db 'Unknown keyword in configuration file: ',0
-err_noparm      db 'Missing parameter in configuration file. Keyword: ',0
-
-		section .uibss
-		alignb 4
-vk_size		equ (vk_end + 3) & ~3
-VKernelBuf:	resb vk_size		; "Current" vkernel
-AppendBuf       resb max_cmd_len+1	; append=
-Ontimeout	resb max_cmd_len+1	; ontimeout
-Onerror		resb max_cmd_len+1	; onerror
-		; This could be in .uibss but that makes PXELINUX overflow
-		section .bss16
-KbdMap		resb 256		; Keyboard map
-FKeyName	resb MAX_FKEYS*FILENAME_MAX	; File names for F-key help
-                global KernelName
-KernelName      resb FILENAME_MAX	; Mangled name for kernel
-MNameBuf        resb FILENAME_MAX
-InitRD          resb FILENAME_MAX
-
-		section .text16
diff --git a/core/parseconfig.inc b/core/parseconfig.inc
deleted file mode 100644
index f24efe4..0000000
--- a/core/parseconfig.inc
+++ /dev/null
@@ -1,474 +0,0 @@
-;; -----------------------------------------------------------------------
-;;
-;;   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
-;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;;   Boston MA 02111-1307, USA; either version 2 of the License, or
-;;   (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; parseconfig.inc
-;;
-;; Configuration file operations
-;;
-
-		section .text16
-;
-; "default" or "ui" command, with level (1 = default, 2 = ui)
-;
-pc_default:	cmp ax,[DefaultLevel]
-		jb skipline			; == call skipline + ret
-		mov [DefaultLevel],ax
-		mov di,default_cmd
-		call getline
-		mov byte [di-1],0		; null-terminate
-		ret
-
-;
-; "ontimeout" command
-;
-pc_ontimeout:	mov di,Ontimeout
-		call getline
-		sub di,Ontimeout+1		; Don't need final space
-		mov [OntimeoutLen],di
-		ret
-
-;
-; "onerror" command
-;
-pc_onerror:	mov di,Onerror
-		call getline
-		sub di,Onerror
-		mov [OnerrorLen],di
-		ret
-
-;
-; "append" command
-;
-pc_append:      cmp byte [VKernel],0
-		ja .vk
-                mov di,AppendBuf
-		call getline
-                sub di,AppendBuf
-.app1:		mov [AppendLen],di
-		ret
-.vk:		mov di,VKernelBuf+vk_append	; "append" command (vkernel)
-		call getline
-		sub di,VKernelBuf+vk_append
-                cmp di,byte 2
-                jne .app2
-                cmp byte [VKernelBuf+vk_append],'-'
-                jne .app2
-                xor di,di			; If "append -" -> null string
-.app2:		mov [VKernelBuf+vk_appendlen],di
-		ret
-
-;
-; "ipappend" command (PXELINUX only)
-;
-%if IS_PXELINUX
-pc_ipappend:	call getint
-		jc .err
-		cmp byte [VKernel],0
-		jne .vk
-		mov [IPAppend],bl
-.err:		ret
-.vk:		mov [VKernelBuf+vk_ipappend],bl
-		ret
-%endif
-
-;
-; "localboot" command
-;
-pc_localboot:	call getint
-		cmp byte [VKernel],0		; ("label" section only)
-		je .err
-		mov [VKernelBuf+vk_rname],bx
-		mov byte [VKernelBuf+vk_type],VK_LOCALBOOT
-.err:		ret
-
-;
-; "kernel", "config", ... command
-;
-pc_kernel:	cmp byte [VKernel],0
-		je .err				; ("label" section only)
-		mov [VKernelBuf+vk_type],al
-		call pc_getline
-		mov di,VKernelBuf+vk_rname
-		pm_call pm_mangle_name
-.err:		ret
-
-;
-; "timeout", "totaltimeout" command
-;
-; N.B. 1/10 s ~ 1.D2162AABh clock ticks
-;
-pc_timeout:	push ax
-		call getint
-		pop si
-		jc .err
-		mov eax,0D2162AABh
-		mul ebx				; clock ticks per 1/10 s
-		add ebx,edx
-		mov [si],ebx
-.err:		ret
-
-
-;
-; "totaltimeout" command
-;
-pc_totaltimeout:
-
-;
-; Generic integer variable setting commands:
-; "prompt", "implicit"
-;
-pc_setint16:
-		push ax
-		call getint
-		pop si
-		jc .err
-		mov [si],bx
-.err:		ret
-
-;
-; Generic file-processing commands:
-; "font", "kbdmap",
-;
-pc_filecmd:	push ax				; Function to tailcall
-		call pc_getline
-		mov di,MNameBuf
-		pm_call pm_mangle_name
-		pm_call pm_searchdir
-		jnz .ok
-		pop ax				; Drop the successor function
-.ok:		ret				; Tailcall if OK, error return
-
-;
-; Commands that expect the file to be opened on top of the getc stack.
-; "display", "include"
-;
-pc_opencmd:	push ax				; Function to tailcall
-		call pc_getline
-		mov di,MNameBuf
-		pm_call pm_mangle_name
-		call core_open
-		jnz .ok
-		pop ax				; Drop the successor function
-.ok:		ret				; Tailcall if OK, error return
-
-;
-; "include" command (invoked from pc_opencmd)
-;
-pc_include:	inc word [IncludeLevel]
-.err:		ret
-
-;
-; "serial" command
-;
-pc_serial:	call getint
-		jc .err
-		push bx				; Serial port #
-		xor eax,eax
-		mov [FlowControl],eax		; Default to no flow control
-		call skipspace
-		jc .nobaud
-		call ungetc
-		call getint
-		jc .nobaud
-.valid_baud:
-		push ebx
-		call skipspace
-		jc .no_flow
-		call ungetc
-		call getint			; Hardware flow control?
-		jnc .valid_flow
-.no_flow:
-		xor bx,bx			; Default -> no flow control
-.valid_flow:
-		and bh,0Fh			; FlowIgnore
-		shl bh,4
-		mov [FlowIgnore],bh
-		mov bh,bl
-		and bx,0F00Bh			; Valid bits
-		mov [FlowControl],bx
-		pop ebx				; Baud rate
-		jmp short .parse_baud
-.nobaud:
-		mov ebx,DEFAULT_BAUD		; No baud rate given
-.parse_baud:
-		pop di				; Serial port #
-		cmp ebx,byte 75
-		jb .err				; < 75 baud == bogus
-		mov eax,BAUD_DIVISOR
-		cdq
-		div ebx
-		mov [BaudDivisor],ax
-		push ax				; Baud rate divisor
-		cmp di,3
-		ja .port_is_io			; If port > 3 then port is I/O addr
-		shl di,1
-		mov di,[di+serial_base]		; Get the I/O port from the BIOS
-.port_is_io:
-		mov [SerialPort],di
-
-		;
-		; Begin code to actually set up the serial port
-		;
-		call sirq_cleanup_nowipe	; Cleanup existing IRQ handler
-
-		lea dx,[di+3]			; DX -> LCR
-		mov al,83h			; Enable DLAB
-		slow_out dx,al
-
-		pop ax				; Divisor
-		mov dx,di			; DX -> LS
-		slow_out dx,al
-
-		inc dx				; DX -> MS
-		mov al,ah
-		slow_out dx,al
-
-		mov al,03h			; Disable DLAB
-		inc dx				; DX -> LCR
-		inc dx
-		slow_out dx,al
-
-		in al,dx		; Read back LCR (detect missing hw)
-		cmp al,03h		; If nothing here we'll read 00 or FF
-		jne .err		; Assume serial port busted
-		dec dx				; DX -> IIR/FCR
-		mov al,01h
-		slow_out dx,al			; Enable FIFOs if present
-		in al,dx
-		cmp al,0C0h			; FIFOs enabled and usable?
-		jae .fifo_ok
-		xor ax,ax			; Disable FIFO if unusable
-		slow_out dx,al
-.fifo_ok:
-
-		inc dx
-		inc dx				; DX -> MCR
-		mov al,[FlowOutput]		; Assert bits
-		slow_out dx,al
-
-		; Enable interrupts if requested
-		test al,8
-		jz .noirq
-		call sirq_install
-.noirq:
-
-		; Show some life
-		cmp byte [SerialNotice],0
-		je .notfirst
-		mov byte [SerialNotice],0
-
-		mov si,syslinux_banner
-		call write_serial_str
-		mov si,copyright_str
-		call write_serial_str
-.notfirst:
-		ret
-
-.err:
-		mov [SerialPort], word 0
-		ret
-
-;
-; Store mangled filename command (F-keys, "initrd")
-;
-pc_filename:	push ax
-		call pc_getline
-		pop di
-		pm_call pm_mangle_name		; Mangle file name
-		ret
-
-;
-; "label" command
-;
-pc_label:	call commit_vk			; Commit any current vkernel
-		mov byte [InitRD+NULLOFFSET],NULLFILE	; No "initrd" statement
-		mov di,VKernelBuf		; Erase the vkernelbuf for better compression
-		mov cx,(vk_size >> 1)
-		xor ax,ax
-		rep stosw
-		call pc_getline
-		mov di,VKernelBuf+vk_vname
-		mov cx,FILENAME_MAX-1
-.loop:
-		lodsb
-		cmp al,' '
-		jna .done
-		stosb
-		loop .loop
-.done:
-		mov byte [VKernel],1		; We've seen a "label" statement
-		mov si,VKernelBuf+vk_vname	; By default, rname == mangled vname
-		mov di,VKernelBuf+vk_rname
-		pm_call pm_mangle_name
-		mov si,AppendBuf		; Default append==global append
-		mov di,VKernelBuf+vk_append
-		mov cx,[AppendLen]
-		mov [VKernelBuf+vk_appendlen],cx
-		rep movsb
-%if IS_PXELINUX					; PXELINUX only
-		mov al,[IPAppend]		; Default ipappend==global ipappend
-		mov [VKernelBuf+vk_ipappend],al
-%endif
-		ret
-
-;
-; "say" command
-;
-pc_say:		call pc_getline			; "say" command
-		call writestr
-		jmp crlf			; tailcall
-
-;
-; "text" command; ignore everything until we get an "endtext" line
-;
-pc_text:	call skipline			; Ignore rest of line
-.loop:
-		call pc_getline
-		jc .eof
-
-		; Leading spaces are already removed...
-		lodsd
-		and eax,0xdfdfdfdf		; Upper case
-		cmp eax,'ENDT'
-		jne .loop
-		lodsd
-		and eax,0x00dfdfdf		; Upper case and mask
-		cmp eax,'EXT'
-		jne .loop
-		; If we get here we hit ENDTEXT
-.eof:
-		ret
-
-;
-; Comment line
-;
-pc_comment:	; Fall into pc_getline
-
-;
-; Common subroutine: load line into trackbuf; returns with SI -> trackbuf
-; CF is set on EOF.
-;
-pc_getline:	mov di,trackbuf
-		push di
-		call getline
-		mov byte [di],0			; Null-terminate
-		pop si
-		ret
-
-;
-; Main loop for configuration file parsing
-;
-parse_config:
-		mov di,VKernelBuf		; Clear VKernelBuf at start
-		xor ax,ax
-		mov cx,vk_size
-		rep stosb
-
-.again:
-		call getcommand			; Parse one command
-                jnc .again			; If not EOF...
-		call close
-		dec word [IncludeLevel]		; Still parsing?
-		jnz .again
-
-		;
-		; The fall through to commit_vk to commit any final
-		; VKernel being read
-		;
-;
-; commit_vk: Store the current VKernelBuf into buffer segment
-;
-commit_vk:
-		cmp byte [VKernel],0
-		jz .nolabel			; Nothing to commit...
-
-		mov di,VKernelBuf+vk_append
-		add di,[VKernelBuf+vk_appendlen]
-
-		; If we have an initrd statement, append it to the
-		; append statement
-		cmp byte [InitRD+NULLOFFSET],NULLFILE
-		je .noinitrd
-
-		mov si,str_initrd
-		mov cx,7	; "initrd="
-		rep movsb
-		mov si,InitRD
-		call strcpy
-		mov byte [es:di-1],' '
-
-		; For better compression, clean up the append field
-.noinitrd:
-		mov ax,di
-		sub ax,VKernelBuf+vk_append
-		mov [VKernelBuf+vk_appendlen],ax
-		mov cx,max_cmd_len+1
-		sub cx,ax
-		xor ax,ax
-		rep stosb
-
-		; Pack into high memory
-		mov esi,VKernelBuf
-		mov edi,[VKernelEnd]
-		mov ecx,vk_size
-		pm_call rllpack
-		mov [VKernelEnd],edi
-.nolabel:
-		ret
-.overflow:
-		mov si,vk_overflow_msg
-		call writestr
-		ret
-
-		section .data16
-		global SerialNotice
-vk_overflow_msg	db 'Out of memory parsing config file', CR, LF, 0
-SerialNotice	db 1			; Only print this once
-
-		section .bss16
-		alignb 4
-VKernelEnd	resd 1			; Lowest high memory address used
-
-		; This symbol should be used by loaders to indicate
-		; the highest address *they* are allowed to use.
-HighMemRsvd	equ VKernelEnd
-					; by vkernels
-		section .config
-		alignz 4
-KbdTimeout      dd 0                    ; Keyboard timeout (if any)
-TotalTimeout	dd 0			; Total timeout (if any)
-AppendLen       dw 0                    ; Bytes in append= command
-OntimeoutLen	dw 0			; Bytes in ontimeout command
-OnerrorLen	dw 0			; Bytes in onerror command
-CmdLinePtr	dw cmd_line_here	; Command line advancing pointer
-ForcePrompt	dw 0			; Force prompt
-NoEscape	dw 0			; No escape
-NoComplete	dw 0			; No label completion on TAB key
-AllowImplicit   dw 1                    ; Allow implicit kernels
-AllowOptions	dw 1			; User-specified options allowed
-IncludeLevel	dw 1			; Nesting level
-DefaultLevel	dw 0			; The current level of default
-		global PXERetry
-PXERetry	dw 0			; Extra PXE retries
-VKernel		db 0			; Have we seen any "label" statements?
-
-%if IS_PXELINUX
-IPAppend	db 0			; Default IPAPPEND option
-%endif
-
-		section .uibss
-                alignb 4		; For the good of REP MOVSD
-command_line	resb max_cmd_len+2	; Command line buffer
-		alignb 4
-default_cmd	resb max_cmd_len+1	; "default" command line
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 178e354..0c0ff38 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -275,37 +275,6 @@ ROOT_FS_OPS:
 %include "ui.inc"
 
 ;
-; Boot to the local disk by returning the appropriate PXE magic.
-; AX contains the appropriate return code.
-;
-local_boot:
-		push cs
-		pop ds
-		mov [LocalBootType],ax
-		call vgaclearmode
-		mov si,localboot_msg
-		call writestr_early
-		; Restore the environment we were called with
-		pm_call reset_pxe
-		call cleanup_hardware
-		lss sp,[InitStack]
-		pop gs
-		pop fs
-		pop es
-		pop ds
-		popad
-		mov ax,[cs:LocalBootType]
-		cmp ax,-1			; localboot -1 == INT 18h
-		je .int18
-		popfd
-		retf				; Return to PXE
-.int18:
-		popfd
-		int 18h
-		jmp 0F000h:0FFF0h
-		hlt
-
-;
 ; kaboom: write a message and bail out.  Wait for quite a while,
 ;	  or a user keypress, then do a hard reboot.
 ;
@@ -519,7 +488,6 @@ pxe_file_exit_hook:
 ; -----------------------------------------------------------------------------
 
 %include "common.inc"		; Universal modules
-%include "rawcon.inc"		; Console I/O w/o using the console functions
 
 ; -----------------------------------------------------------------------------
 ;  Begin data section
@@ -537,23 +505,6 @@ localboot_msg	db 'Booting from local disk...', CR, LF, 0
 syslinux_banner	db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
 
 ;
-; Config file keyword table
-;
-%include "keywords.inc"
-
-;
-; Extensions to search for (in *forward* order).
-; (.bs and .bss16 are disabled for PXELINUX, since they are not supported)
-;
-		alignz 4
-exten_table:	db '.cbt'		; COMBOOT (specific)
-		db '.0', 0, 0		; PXE bootstrap program
-		db '.com'		; COMBOOT (same as DOS)
-		db '.c32'		; COM32
-exten_table_end:
-		dd 0, 0			; Need 8 null bytes here
-
-;
 ; Misc initialized (data) variables
 ;
 		section .data16
diff --git a/core/rawcon.c b/core/rawcon.c
new file mode 100644
index 0000000..d28113b
--- /dev/null
+++ b/core/rawcon.c
@@ -0,0 +1,91 @@
+/*
+ * writechr:	Write a single character in AL to the console without
+ *		mangling any registers.  This does raw console writes,
+ *		since some PXE BIOSes seem to interfere regular console I/O.
+ */
+#include <sys/io.h>
+#include <fs.h>
+#include <com32.h>
+#include "bios.h"
+
+void writechr(char data)
+{
+	if (UsingVGA & 0x08)
+		vgaclearmode();
+
+	write_serial(data);	/* write to serial port if needed */
+
+	/* Write to screen? */
+	if (DisplayCon & 0x01) {
+		com32sys_t ireg, oreg;
+		bool curxyok = false;
+		uint16_t dx;
+
+		ireg.ebx.b[1] = *(uint8_t *)BIOS_page;
+		ireg.eax.b[1] = 0x03; /* Read cursor position */
+		__intcall(0x10, &ireg, &oreg);
+		ireg.edx.l = oreg.edx.l;
+
+		switch (data) {
+		case 8:
+			if (ireg.edx.b[0]--) {
+				curxyok = true;
+				break;
+			}
+
+			ireg.edx.b[0] = VidCols;
+			if (ireg.edx.b[1]--) {
+				curxyok = true;
+				break;
+			}
+
+			ireg.edx.b[1] = 0;
+			curxyok = true;
+			break;
+		case 13:
+			ireg.edx.b[0] = 0;
+			curxyok = true;
+			break;
+		case 10:
+			break;
+		default:
+			dx = ireg.edx.w[0];
+
+			ireg.ebx.b[1] = *(uint8_t *)BIOS_page;
+			ireg.ebx.b[0] = 0x07; /* White on black */
+			ireg.ecx.w[0] = 1;    /* One only */
+			ireg.eax.b[0] = data;
+			ireg.eax.b[1] = 0x09; /* Write char and attribute */
+			__intcall(0x10, &ireg, NULL);
+
+			ireg.edx.w[0] = dx;
+			if (++ireg.edx.b[0] <= VidCols)
+				curxyok = true;
+			else
+				ireg.edx.b[0] = 0;
+		}
+
+		if (!curxyok && ++ireg.edx.b[1] > VidRows) {
+			/* Scroll */
+			ireg.edx.b[1]--;
+			ireg.ebx.b[1] = *(uint8_t *)BIOS_page;
+			ireg.eax.b[1] = 0x02;
+			__intcall(0x10, &ireg, NULL);
+
+			ireg.eax.w[0] = 0x0601; /* Scroll up one line */
+			ireg.ebx.b[1] = ScrollAttribute;
+			ireg.ecx.w[0] = 0;
+			ireg.edx.w[0] = ScreenSize; /* The whole screen */
+			__intcall(0x10, &ireg, NULL);
+		} else {
+			ireg.ebx.b[1] = *(uint8_t *)BIOS_page;
+			ireg.eax.b[1] = 0x02; /* Set cursor position */
+			__intcall(0x10, &ireg, NULL);
+		}
+	}
+}
+
+void pm_writechr(com32sys_t *regs)
+{
+	writechr(regs->eax.b[0]);
+}
diff --git a/core/runkernel.inc b/core/runkernel.inc
deleted file mode 100644
index 2e94346..0000000
--- a/core/runkernel.inc
+++ /dev/null
@@ -1,684 +0,0 @@
-;; -----------------------------------------------------------------------
-;;
-;;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-;;   Copyright 2009-2010 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
-;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;;   Boston MA 02111-1307, USA; either version 2 of the License, or
-;;   (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; runkernel.inc
-;;
-;; Common code for running a Linux kernel
-;;
-
-;
-; Hook macros, that may or may not be defined
-;
-%ifndef HAVE_UNLOAD_PREP
-%macro UNLOAD_PREP 0
-%endmacro
-%endif
-
-;
-; A Linux kernel consists of three parts: boot sector, setup code, and
-; kernel code.	The boot sector is never executed when using an external
-; booting utility, but it contains some status bytes that are necessary.
-;
-; First check that our kernel is at least 1K, or else it isn't long
-; enough to have the appropriate headers.
-;
-; We used to require the kernel to be 64K or larger, but it has gotten
-; popular to use the Linux kernel format for other things, which may
-; not be so large.
-;
-; Additionally, we used to have a test for 8 MB or smaller.  Equally
-; obsolete.
-;
-is_linux_kernel:
-		push si				; <A> file pointer
-
-;
-; Now start transferring the kernel
-;
-		push word real_mode_seg
-		pop es
-
-;
-; Start by loading the bootsector/setup code, to see if we need to
-; do something funky.  It should fit in the first 32K (loading 64K won't
-; work since we might have funny stuff up near the end of memory).
-;
-		call abort_check		; Check for abort key
-		mov cx,8000h			; Half a moby (32K)
-		xor bx,bx
-                pop si                          ; <A> file pointer
-		pm_call getfsbytes
-		cmp cx,1024
-		jb kernel_corrupt
-                cmp word [es:bs_bootsign],0AA55h
-		jne kernel_corrupt		; Boot sec signature missing
-
-;
-; Save the file pointer for later...
-;
-		push si				; <A> file pointer
-
-;
-; Construct the command line (append options have already been copied)
-;
-construct_cmdline:
-		mov di,[CmdLinePtr]
-                mov si,boot_image		; BOOT_IMAGE=
-                mov cx,boot_image_len
-                rep movsb
-                mov si,KernelName		; Unmangled kernel name
-		call strcpy
-		mov byte [es:di-1],' '		; Follow by space
-
-		call do_ip_append		; Handle IPAppend
-
-                mov si,[CmdOptPtr]              ; Options from user input
-		call strcpy
-
-;
-; Scan through the command line for anything that looks like we might be
-; interested in.  The original version of this code automatically assumed
-; the first option was BOOT_IMAGE=, but that is no longer certain.
-;
-parse_cmdline:
-		mov di,cmd_line_here
-.skipspace:	mov al,[es:di]
-		inc di
-.skipspace_loaded:
-		and al,al
-		jz cmdline_end
-		cmp al,' '
-		jbe .skipspace
-		dec di
-
-		; ES:DI now points to the beginning of an option
-		mov si,options_list
-.next_opt:
-		movzx cx,byte [si]
-		jcxz .skip_opt
-		push di
-		inc si
-		repe cmpsb
-		jne .no_match
-
-		; This either needs to have been an option with parameter,
-		; or be followed by EOL/whitespace
-		mov ax,[es:di-1]		; AL = last chr; AH = following
-		cmp al,'='
-		je .is_match
-		cmp ah,' '
-		ja .no_match
-.is_match:
-		pop ax				; Drop option pointer on stack
-		call [si]
-.skip_opt:
-		mov al,[es:di]
-		inc di
-		cmp al,' '
-		ja .skip_opt
-		jmp .skipspace_loaded
-.no_match:
-		pop di
-		add si,cx			; Skip remaining bytes
-		inc si				; Skip function pointer
-		inc si
-		jmp .next_opt
-
-opt_vga:
-		mov ax,[es:di-1]
-		mov bx,-1
-		cmp ax,'=n'			; vga=normal
-		je .vc0
-		dec bx				; bx <- -2
-		cmp ax,'=e'			; vga=ext
-		je .vc0
-		dec bx				; bx <- -3
-		cmp ax,'=a'			; vga=ask
-		je .vc0
-		mov bx,0x0f04			; bx <- 0x0f04 (current mode)
-		cmp ax,'=c'			; vga=current
-		je .vc0
-		call parseint_esdi		; vga=<number>
-		jc .skip			; Not an integer
-.vc0:		mov [es:bs_vidmode],bx		; Set video mode
-.skip:
-		ret
-
-opt_mem:
-		call parseint_esdi
-		jc .skip
-%if HIGHMEM_SLOP != 0
-		sub ebx,HIGHMEM_SLOP
-%endif
-		mov [MyHighMemSize],ebx
-.skip:
-		ret
-
-opt_quiet:
-		mov byte [QuietBoot],QUIET_FLAG
-		ret
-
-%if IS_PXELINUX
-opt_keeppxe:
-		or byte [KeepPXE],1		; KeepPXE set by command line
-		ret
-%endif
-
-opt_initrd:
-		mov ax,di
-		cmp byte [es:di],' '
-		ja .have_initrd
-		xor ax,ax
-.have_initrd:
-		mov [InitRDPtr],ax
-		ret
-
-;
-; After command line parsing...
-;
-cmdline_end:
-		sub di,cmd_line_here
-		mov [CmdLineLen],di		; Length including final null
-
-;
-; Now check if we have a large kernel, which needs to be loaded high
-;
-prepare_header:
-		mov dword [RamdiskMax], HIGHMEM_MAX	; Default initrd limit
-		cmp dword [es:su_header],HEADER_ID	; New setup code ID
-		jne old_kernel			; Old kernel, load low
-		mov ax,[es:su_version]
-		mov [KernelVersion],ax
-		cmp ax,0200h			; Setup code version 2.0
-		jb old_kernel			; Old kernel, load low
-		cmp ax,0201h			; Version 2.01+?
-                jb new_kernel                   ; If 2.00, skip this step
-		; Set up the heap (assuming loading high for now)
-                mov word [es:su_heapend],linux_stack-512
-                or byte [es:su_loadflags],80h	; Let the kernel know we care
-		cmp ax,0203h			; Version 2.03+?
-		jb new_kernel			; Not 2.03+
-		mov eax,[es:su_ramdisk_max]
-		mov [RamdiskMax],eax		; Set the ramdisk limit
-
-;
-; We definitely have a new-style kernel.  Let the kernel know who we are,
-; and that we are clueful
-;
-new_kernel:
-		mov byte [es:su_loader],my_id	; Show some ID
-		xor eax,eax
-		mov [es:su_ramdisklen],eax	; No initrd loaded yet
-
-;
-; About to load the kernel.  This is a modern kernel, so use the boot flags
-; we were provided.
-;
-                mov al,[es:su_loadflags]
-		or al,[QuietBoot]		; Set QUIET_FLAG if needed
-		mov [es:su_loadflags],al
-		mov [LoadFlags],al
-
-any_kernel:
-		mov si,loading_msg
-                call writestr_qchk
-                mov si,KernelName		; Print kernel name part of
-                call writestr_qchk		; "Loading" message
-
-;
-; Load the kernel.  We always load it at 100000h even if we're supposed to
-; load it "low"; for a "low" load we copy it down to low memory right before
-; jumping to it.
-;
-read_kernel:
-		movzx ax,byte [es:bs_setupsecs]	; Setup sectors
-		and ax,ax
-		jnz .sects_ok
-		mov al,4			; 0 = 4 setup sectors
-.sects_ok:
-		inc ax				; Including the boot sector
-		mov [SetupSecs],ax
-
-		call dot_pause
-
-;
-; Move the stuff beyond the setup code to high memory at 100000h
-;
-		movzx esi,word [SetupSecs]	; Setup sectors
-                shl si,9			; Convert to bytes
-                mov ecx,8000h			; 32K
-		sub ecx,esi			; Number of bytes to copy
-		add esi,core_real_mode		; Pointer to source
-                mov edi,free_high_memory	; Copy to free high memory
-
-                call bcopy			; Transfer to high memory
-
-		pop si				; <A> File pointer
-		and si,si			; EOF already?
-		jz high_load_done
-
-		; On exit EDI -> where to load the rest
-
-		mov bx,dot_pause
-		or eax,-1			; Load the whole file
-		mov dx,3			; Pad to dword
-		call load_high
-
-high_load_done:
-		mov [KernelEnd],edi
-                mov ax,real_mode_seg		; Set to real mode seg
-                mov es,ax
-
-                mov si,dot_msg
-                call writestr_qchk
-
-;
-; Some older kernels (1.2 era) would have more than 4 setup sectors, but
-; would not rely on the boot protocol to manage that.  These kernels fail
-; if they see protected-mode kernel data after the setup sectors, so
-; clear that memory.
-;
-		push di
-		mov di,[SetupSecs]
-		shl di,9
-		xor eax,eax
-		mov cx,cmd_line_here
-		sub cx,di
-		shr cx,2
-		rep stosd
-		pop di
-
-;
-; Now see if we have an initial RAMdisk; if so, do requisite computation
-; We know we have a new kernel; the old_kernel code already will have objected
-; if we tried to load initrd using an old kernel
-;
-load_initrd:
-		; Cap the ramdisk memory range if appropriate
-		mov eax,[RamdiskMax]
-		cmp eax,[MyHighMemSize]
-		ja .ok
-		mov [MyHighMemSize],eax
-.ok:
-		xor eax,eax
-                cmp [InitRDPtr],ax
-                jz .noinitrd
-		call parse_load_initrd
-.noinitrd:
-
-;
-; Abandon hope, ye that enter here!  We do no longer permit aborts.
-;
-                call abort_check		; Last chance!!
-
-		mov si,ready_msg
-		call writestr_qchk
-
-		UNLOAD_PREP			; Module-specific hook
-
-;
-; Now, if we were supposed to load "low", copy the kernel down to 10000h
-; and the real mode stuff to 90000h.  We assume that all bzImage kernels are
-; capable of starting their setup from a different address.
-;
-		mov ax,real_mode_seg
-		mov es,ax
-		mov fs,ax
-
-;
-; If the default root device is set to FLOPPY (0000h), change to
-; /dev/fd0 (0200h)
-;
-		cmp word [es:bs_rootdev],byte 0
-		jne root_not_floppy
-		mov word [es:bs_rootdev],0200h
-root_not_floppy:
-
-;
-; Copy command line.  Unfortunately, the old kernel boot protocol requires
-; the command line to exist in the 9xxxxh range even if the rest of the
-; setup doesn't.
-;
-setup_command_line:
-		mov dx,[KernelVersion]
-		test byte [LoadFlags],LOAD_HIGH
-		jz .need_high_cmdline
-		cmp dx,0202h			; Support new cmdline protocol?
-		jb .need_high_cmdline
-		; New cmdline protocol
-		; Store 32-bit (flat) pointer to command line
-		; This is the "high" location, since we have bzImage
-		mov dword [fs:su_cmd_line_ptr],cmd_line
-		mov word [HeapEnd],linux_stack
-		mov word [fs:su_heapend],linux_stack-512
-		jmp .setup_done
-
-.need_high_cmdline:
-;
-; Copy command line down to fit in high conventional memory
-; -- this happens if we have a zImage kernel or the protocol
-; is less than 2.02.
-;
-		mov si,cmd_line_here
-		mov di,old_cmd_line_here
-		mov [fs:kern_cmd_magic],word CMD_MAGIC ; Store magic
-		mov [fs:kern_cmd_offset],di	; Store pointer
-		mov word [HeapEnd],old_linux_stack
-		mov ax,255			; Max cmdline limit
-		cmp dx,0201h
-		jb .adjusted
-		; Protocol 2.01+
-		mov word [fs:su_heapend],old_linux_stack-512
-		jbe .adjusted
-		; Protocol 2.02+
-		; Note that the only reason we would end up here is
-		; because we have a zImage, so we anticipate the move
-		; to 90000h already...
-		mov dword [fs:su_cmd_line_ptr],0x90000+old_cmd_line_here
-		mov ax,old_max_cmd_len		; 2.02+ allow a higher limit
-.adjusted:
-
-		mov cx,[CmdLineLen]
-		cmp cx,ax
-		jna .len_ok
-		mov cx,ax			; Truncate the command line
-.len_ok:
-		fs rep movsb
-		stosb				; Final null, note AL=0 already
-		mov [CmdLineEnd],di
-		cmp dx,0200h
-		jb .nomovesize
-		mov [es:su_movesize],di		; Tell the kernel what to move
-.nomovesize:
-.setup_done:
-
-;
-; Time to start setting up move descriptors
-;
-setup_move:
-		mov di,trackbuf
-		xor cx,cx			; Number of descriptors
-
-		mov bx,es			; real_mode_seg
-		mov fs,bx
-		push ds				; We need DS == ES == CS here
-		pop es
-
-		mov edx,100000h
-		test byte [LoadFlags],LOAD_HIGH
-		jnz .loading_high
-
-; Loading low: move real_mode stuff to 90000h, then move the kernel down
-		mov eax,90000h
-		stosd
-		mov eax,core_real_mode
-		stosd
-		movzx eax,word [CmdLineEnd]
-		stosd
-		inc cx
-		mov edx,10000h			; Revised target address
-		mov bx,9000h			; Revised real mode segment
-
-.loading_high:
-		mov eax,edx			; Target address of kernel
-		stosd
-		mov eax,free_high_memory	; Where currently loaded
-		stosd
-		neg eax
-		add eax,[KernelEnd]
-		stosd
-		inc cx
-
-		cmp word [InitRDPtr],0		; Did we have an initrd?
-		je .no_initrd
-
-		mov eax,[fs:su_ramdiskat]
-		stosd
-		mov eax,[InitRDStart]
-		stosd
-		mov eax,[fs:su_ramdisklen]
-		stosd
-		inc cx
-
-.no_initrd:
-		push dword run_linux_kernel
-		push cx				; descriptor list entries count
-
-		; BX points to the final real mode segment, and will be loaded
-		; into DS.
-
-		test byte [QuietBoot],QUIET_FLAG
-		jz replace_bootstrap
-		jmp replace_bootstrap_noclearmode
-
-run_linux_kernel:
-;
-; Set up segment registers and the Linux real-mode stack
-; Note: ds == the real mode segment
-;
-		cli
-		mov ax,ds
-		mov ss,ax
-		mov sp,strict word linux_stack
-		; Point HeapEnd to the immediate of the instruction above
-HeapEnd		equ $-2			; Self-modifying code!  Fun!
-		mov es,ax
-		mov fs,ax
-		mov gs,ax
-
-;
-; We're done... now RUN THAT KERNEL!!!!
-; Setup segment == real mode segment + 020h; we need to jump to offset
-; zero in the real mode segment.
-;
-		add ax,020h
-		push ax
-		push word 0h
-		retf
-
-;
-; Load an older kernel.  Older kernels always have 4 setup sectors, can't have
-; initrd, and are always loaded low.
-;
-old_kernel:
-		xor ax,ax
-		cmp word [InitRDPtr],ax		; Old kernel can't have initrd
-                je .load
-                mov si,err_oldkernel
-                jmp abort_load
-.load:
-		mov byte [LoadFlags],al		; Always low
-		mov word [KernelVersion],ax	; Version 0.00
-		jmp any_kernel
-
-;
-; parse_load_initrd
-;
-; Parse an initrd= option and load the initrds.  This sets
-; InitRDStart and InitRDEnd with dword padding between; we then
-; do a global memory shuffle to move it to the end of memory.
-;
-; On entry, EDI points to where to start loading.
-;
-parse_load_initrd:
-		push es
-		push ds
-		mov ax,real_mode_seg
-		mov ds,ax
-		push cs
-		pop es			; DS == real_mode_seg, ES == CS
-
-		mov [cs:InitRDStart],edi
-		mov [cs:InitRDEnd],edi
-
-		mov si,[cs:InitRDPtr]
-
-.get_chunk:
-		; DS:SI points to the start of a name
-
-		mov bx,si
-.find_end:
-		lodsb
-		cmp al,','
-		je .got_end
-		cmp al,' '
-		jbe .got_end
-		jmp .find_end
-
-.got_end:
-		push ax			; Terminating character
-		push si			; Next filename (if any)
-		mov byte [si-1],0	; Zero-terminate
-		mov si,bx		; Current filename
-
-		push di
-		mov di,InitRD		; Target buffer for mangled name
-		pm_call pm_mangle_name
-		pop di
-		call loadinitrd
-
-		pop si
-		pop ax
-		mov [si-1],al		; Restore ending byte
-
-		cmp al,','
-		je .get_chunk
-
-		; Compute the initrd target location
-		; Note: we round to a page boundary twice here.  The first
-		; time it is to make sure we don't use any fractional page
-		; which may be valid RAM but which will be ignored by the
-		; kernel (and therefore is inaccessible.)  The second time
-		; it is to make sure we start out on page boundary.
-		mov edx,[cs:InitRDEnd]
-		sub edx,[cs:InitRDStart]
-		mov [su_ramdisklen],edx
-		mov eax,[cs:MyHighMemSize]
-		and ax,0F000h		; Round to a page boundary
-		sub eax,edx
-		and ax,0F000h		; Round to a page boundary
-		mov [su_ramdiskat],eax
-
-		pop ds
-		pop es
-		ret
-
-;
-; Load RAM disk into high memory
-;
-; Input:	InitRD		- set to the mangled name of the initrd
-;		EDI		- location to load
-; Output:	EDI		- location for next initrd
-;		InitRDEnd	- updated
-;
-loadinitrd:
-		push ds
-		push es
-		mov ax,cs			; CS == DS == ES
-		mov ds,ax
-		mov es,ax
-		push edi
-                mov di,InitRD
-                pm_call pm_searchdir                  ; Look for it in directory
-		pop edi
-		jz .notthere
-
-		push si
-		mov si,crlfloading_msg		; Write "Loading "
-		call writestr_qchk
-                mov si,InitRD			; Write ramdisk name
-                call writestr_qchk
-                mov si,dotdot_msg		; Write dots
-                call writestr_qchk
-		pop si
-
-.li_skip_echo:
-		mov dx,3
-		mov bx,dot_pause
-		call load_high
-		mov [InitRDEnd],ebx
-
-		pop es
-		pop ds
-		ret
-
-.notthere:
-                mov si,err_noinitrd
-                call writestr
-                mov si,InitRD
-                call writestr
-                mov si,crlf_msg
-                jmp abort_load
-
-;
-; writestr_qchk: writestr, except allows output to be suppressed
-;		assumes CS == DS
-;
-writestr_qchk:
-		test byte [QuietBoot],QUIET_FLAG
-		jz writestr
-		ret
-
-		section .data16
-crlfloading_msg	db CR, LF
-loading_msg     db 'Loading ', 0
-dotdot_msg      db '.'
-dot_msg         db '.', 0
-ready_msg	db 'ready.', CR, LF, 0
-err_oldkernel   db 'Cannot load a ramdisk with an old kernel image.'
-                db CR, LF, 0
-err_noinitrd    db CR, LF, 'Could not find ramdisk image: ', 0
-
-boot_image      db 'BOOT_IMAGE='
-boot_image_len  equ $-boot_image
-
-;
-; Command line options we'd like to take a look at
-;
-%macro cmd_opt	2
-%strlen cmd_opt_len	%1
-	db cmd_opt_len
-	db %1
-	dw %2
-%endmacro
-options_list:
-		cmd_opt "vga=", opt_vga
-		cmd_opt "mem=", opt_mem
-		cmd_opt "quiet", opt_quiet
-str_initrd	equ $+1			; Pointer to "initrd=" in memory
-		cmd_opt "initrd=", opt_initrd
-%if IS_PXELINUX
-		cmd_opt "keeppxe", opt_keeppxe
-%endif
-		db 0
-
-		section .bss16
-		alignb 4
-MyHighMemSize	resd 1			; Possibly adjusted highmem size
-RamdiskMax	resd 1			; Highest address for ramdisk
-KernelSize	resd 1			; Size of kernel in bytes
-KernelSects	resd 1			; Size of kernel in sectors
-KernelEnd	resd 1			; Ending address of the kernel image
-InitRDStart	resd 1			; Start of initrd (pre-relocation)
-InitRDEnd	resd 1			; End of initrd (pre-relocation)
-CmdLineLen	resw 1			; Length of command line including null
-CmdLineEnd	resw 1			; End of the command line in real_mode_seg
-SetupSecs	resw 1			; Number of setup sectors (+bootsect)
-KernelVersion	resw 1			; Kernel protocol version
-;
-; These are derived from the command-line parser
-;
-InitRDPtr	resw 1			; Pointer to initrd= option in command line
-LoadFlags	resb 1			; Loadflags from kernel
-QuietBoot	resb 1			; Set if a quiet boot is requested
diff --git a/core/ui.inc b/core/ui.inc
index 5dfeec4..e50c7f5 100644
--- a/core/ui.inc
+++ b/core/ui.inc
@@ -668,15 +668,6 @@ is_unknown_filetype:
 		; Otherwise Linux kernel
 		jmp is_linux_kernel
 
-is_config_file:
-		push si
-		call make_plain_cmdline
-		pm_call pm_is_config_file
-		pop si
-		call openfd
-		call reset_config
-		jmp load_config_file
-
 ; This is an image type we can't deal with
 is_bad_image:
 		mov si,err_badimage
@@ -718,11 +709,10 @@ kerneltype_table:
 		dw is_disk_image	; VK_FDIMAGE
 		dw is_comboot_image	; VK_COMBOOT
 		dw is_com32_image	; VK_COM32
-		dw is_config_file	; VK_CONFIG
 %endif
 
 		section .bss16
-		global CmdOptPtr
+		global CmdOptPtr, KbdMap
 		alignb 4
 ThisKbdTo	resd 1			; Temporary holder for KbdTimeout
 ThisTotalTo	resd 1			; Temporary holder for TotalTimeout
@@ -731,6 +721,7 @@ CmdOptPtr       resw 1			; Pointer to first option on cmd line
 KbdFlags	resb 1			; Check for keyboard escapes
 FuncFlag	resb 1			; Escape sequences received from keyboard
 KernelType	resb 1			; Kernel type, from vkernel, if known
+KbdMap		resb 256		; Keyboard map
 		global KernelName
 KernelName	resb FILENAME_MAX	; Mangled name for kernel
 		section .config
@@ -739,24 +730,27 @@ PXERetry	dw 0			; Extra PXE retries
 		section .data16
 		global SerialNotice
 SerialNotice	db 1			; Only print this once
+%if IS_PXELINUX
+		extern IPOption
+		global IPAppends, numIPAppends
+		alignz 2
+IPAppends	dw IPOption
+numIPAppends	equ ($-IPAppends)/2
+%else
+IPAppends	equ 0
+numIPAppends	equ 0
+%endif
 
 		section .text16
 ;
-; Linux kernel loading code is common.
-;
-%include "runkernel.inc"
-
-;
 ; COMBOOT-loading code
 ;
 %include "comboot.inc"
 %include "com32.inc"
-%include "cmdline.inc"
 
 ;
 ; Boot sector loading code
 ;
-%include "bootsect.inc"
 
 ;
 ; Abort loading code
@@ -765,3 +759,5 @@ SerialNotice	db 1			; Only print this once
 ;
 ; Hardware cleanup common code
 ;
+
+%include "localboot.inc"


More information about the Syslinux-commits mailing list