|  | @@ -6,6 +6,10 @@
 | 
		
	
		
			
			| 6 | 6 |   * table so using a noticeable amount of stack space is a no-no.
 | 
		
	
		
			
			| 7 | 7 |   */
 | 
		
	
		
			
			| 8 | 8 |  
 | 
		
	
		
			
			|  | 9 | +#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
 | 
		
	
		
			
			|  | 10 | +#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) )
 | 
		
	
		
			
			|  | 11 | +#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
 | 
		
	
		
			
			|  | 12 | +
 | 
		
	
		
			
			| 9 | 13 |  	.text
 | 
		
	
		
			
			| 10 | 14 |  	.code16
 | 
		
	
		
			
			| 11 | 15 |  	.arch i386
 | 
		
	
	
		
			
			|  | @@ -15,7 +19,9 @@
 | 
		
	
		
			
			| 15 | 19 |  romheader:
 | 
		
	
		
			
			| 16 | 20 |  	.word	0xAA55			/* BIOS extension signature */
 | 
		
	
		
			
			| 17 | 21 |  romheader_size:	.byte _load_size_sect	/* Size in 512-byte blocks */
 | 
		
	
		
			
			| 18 |  | -	jmp	init_vector		/* Initialisation vector */
 | 
		
	
		
			
			|  | 22 | +	jmp	init			/* Initialisation vector */
 | 
		
	
		
			
			|  | 23 | +checksum:
 | 
		
	
		
			
			|  | 24 | +	.byte	0
 | 
		
	
		
			
			| 19 | 25 |  	.org	0x16
 | 
		
	
		
			
			| 20 | 26 |  	.word	undiheader
 | 
		
	
		
			
			| 21 | 27 |  	.org	0x18
 | 
		
	
	
		
			
			|  | @@ -72,7 +78,7 @@ pnpheader:
 | 
		
	
		
			
			| 72 | 78 |  	.byte	0x54			/* Device indicator */
 | 
		
	
		
			
			| 73 | 79 |  	.word	0x0000			/* Boot connection vector */
 | 
		
	
		
			
			| 74 | 80 |  	.word	0x0000			/* Disconnect vector */
 | 
		
	
		
			
			| 75 |  | -	.word	exec_vector		/* Boot execution vector */
 | 
		
	
		
			
			|  | 81 | +	.word	bev_entry		/* Boot execution vector */
 | 
		
	
		
			
			| 76 | 82 |  	.word	0x0000			/* Reserved */
 | 
		
	
		
			
			| 77 | 83 |  	.word	0x0000			/* Static resource information vector*/
 | 
		
	
		
			
			| 78 | 84 |  	.equ pnpheader_len, . - pnpheader
 | 
		
	
	
		
			
			|  | @@ -98,60 +104,180 @@ undiheader:
 | 
		
	
		
			
			| 98 | 104 |  	.equ undiheader_len, . - undiheader
 | 
		
	
		
			
			| 99 | 105 |  	.size undiheader, . - undiheader
 | 
		
	
		
			
			| 100 | 106 |  
 | 
		
	
		
			
			| 101 |  | -/* Initialisation vector
 | 
		
	
		
			
			|  | 107 | +/* Initialisation (called once during POST)
 | 
		
	
		
			
			| 102 | 108 |   *
 | 
		
	
		
			
			| 103 | 109 |   * Determine whether or not this is a PnP system via a signature
 | 
		
	
		
			
			| 104 | 110 |   * check.  If it is PnP, return to the PnP BIOS indicating that we are
 | 
		
	
		
			
			| 105 | 111 |   * a boot-capable device; the BIOS will call our boot execution vector
 | 
		
	
		
			
			| 106 | 112 |   * if it wants to boot us.  If it is not PnP, hook INT 19.
 | 
		
	
		
			
			| 107 | 113 |   */
 | 
		
	
		
			
			| 108 |  | -init_vector:
 | 
		
	
		
			
			| 109 |  | -	pushw	%si
 | 
		
	
		
			
			| 110 |  | -	cmpw	$'$'+'P'*256, %es:0(%di)
 | 
		
	
		
			
			| 111 |  | -	jne	notpnp
 | 
		
	
		
			
			| 112 |  | -	cmpw	$'n'+'P'*256, %es:2(%di)
 | 
		
	
		
			
			| 113 |  | -	jne	notpnp
 | 
		
	
		
			
			| 114 |  | -ispnp:
 | 
		
	
		
			
			| 115 |  | -	movw	$ispnp_message, %si
 | 
		
	
		
			
			| 116 |  | -	jmp	99f
 | 
		
	
		
			
			| 117 |  | -notpnp:
 | 
		
	
		
			
			|  | 114 | +init:
 | 
		
	
		
			
			|  | 115 | +	/* Preserve registers, clear direction flag, set %ds=%cs */
 | 
		
	
		
			
			|  | 116 | +	pushaw
 | 
		
	
		
			
			| 118 | 117 |  	pushw	%ds
 | 
		
	
		
			
			| 119 |  | -	pushw	$0
 | 
		
	
		
			
			| 120 |  | -	popw	%ds
 | 
		
	
		
			
			|  | 118 | +	pushw	%es
 | 
		
	
		
			
			|  | 119 | +	cld
 | 
		
	
		
			
			| 121 | 120 |  	pushw	%cs
 | 
		
	
		
			
			| 122 |  | -	pushw	$exec_vector
 | 
		
	
		
			
			| 123 |  | -	popl	( 0x19 * 4 )
 | 
		
	
		
			
			| 124 | 121 |  	popw	%ds
 | 
		
	
		
			
			| 125 |  | -	movw	$notpnp_message, %si
 | 
		
	
		
			
			|  | 122 | +	/* Print message as early as possible */
 | 
		
	
		
			
			|  | 123 | +	movw	$init_message, %si
 | 
		
	
		
			
			|  | 124 | +	call	print_message
 | 
		
	
		
			
			|  | 125 | +	/* Check for PnP BIOS */
 | 
		
	
		
			
			|  | 126 | +	cmpl	$PNP_SIGNATURE, %es:0(%di)
 | 
		
	
		
			
			|  | 127 | +	je	ispnp
 | 
		
	
		
			
			|  | 128 | +notpnp:	/* Not PnP: hook INT19 */
 | 
		
	
		
			
			|  | 129 | +	xorw	%ax, %ax
 | 
		
	
		
			
			|  | 130 | +	movw	%ax, %es
 | 
		
	
		
			
			|  | 131 | +	pushw	%cs
 | 
		
	
		
			
			|  | 132 | +	pushw	$int19_entry
 | 
		
	
		
			
			|  | 133 | +	popl	%es:( 0x19 * 4 )
 | 
		
	
		
			
			|  | 134 | +	jmp	99f
 | 
		
	
		
			
			|  | 135 | +ispnp:	/* Is PnP: print PnP message */
 | 
		
	
		
			
			|  | 136 | +	movw	$init_message_pnp, %si
 | 
		
	
		
			
			|  | 137 | +	call	print_message
 | 
		
	
		
			
			|  | 138 | +	/* Check for PMM */
 | 
		
	
		
			
			|  | 139 | +	movw	$( 0xe000 - 1 ), %di
 | 
		
	
		
			
			|  | 140 | +pmm_scan:
 | 
		
	
		
			
			|  | 141 | +	incw	%di
 | 
		
	
		
			
			|  | 142 | +	jz	99f
 | 
		
	
		
			
			|  | 143 | +	movw	%di, %es
 | 
		
	
		
			
			|  | 144 | +	cmpl	$PMM_SIGNATURE, %es:0
 | 
		
	
		
			
			|  | 145 | +	jne	pmm_scan
 | 
		
	
		
			
			|  | 146 | +	xorw	%bx, %bx
 | 
		
	
		
			
			|  | 147 | +	xorw	%si, %si
 | 
		
	
		
			
			|  | 148 | +	movzbw	%es:5, %cx
 | 
		
	
		
			
			|  | 149 | +1:	es lodsb
 | 
		
	
		
			
			|  | 150 | +	addb	%al, %bl
 | 
		
	
		
			
			|  | 151 | +	loop	1b
 | 
		
	
		
			
			|  | 152 | +	jnz	pmm_scan
 | 
		
	
		
			
			|  | 153 | +	/* PMM found: print PMM message */
 | 
		
	
		
			
			|  | 154 | +	movw	$init_message_pmm, %si
 | 
		
	
		
			
			|  | 155 | +	call	print_message
 | 
		
	
		
			
			|  | 156 | +	/* Try to allocate 2MB block via PMM */
 | 
		
	
		
			
			|  | 157 | +	pushw	$0x0006		/* Aligned, extended memory */
 | 
		
	
		
			
			|  | 158 | +	pushl	$0xffffffff	/* No handle */
 | 
		
	
		
			
			|  | 159 | +	pushl	$( 0x00200000 / 16 ) /* 2MB in paragraphs */
 | 
		
	
		
			
			|  | 160 | +	pushw	$0x0000		/* pmmAllocate */
 | 
		
	
		
			
			|  | 161 | +	lcall	%es:*(7)
 | 
		
	
		
			
			|  | 162 | +	addw	$12, %sp
 | 
		
	
		
			
			|  | 163 | +	testw	%dx, %dx	/* %ax==0 even on success, since align=2MB */
 | 
		
	
		
			
			|  | 164 | +	jnz	gotpmm
 | 
		
	
		
			
			|  | 165 | +	movw	$init_message_pmm_failed, %si
 | 
		
	
		
			
			|  | 166 | +	call	print_message
 | 
		
	
		
			
			|  | 167 | +	jmp	99f
 | 
		
	
		
			
			|  | 168 | +gotpmm:	/* PMM allocation succeeded: copy ROM to PMM block */
 | 
		
	
		
			
			|  | 169 | +	pushal			/* PMM presence implies 1kB stack */
 | 
		
	
		
			
			|  | 170 | +	movw	%ax, %es	/* %ax=0 already - see above */
 | 
		
	
		
			
			|  | 171 | +	pushw	%dx
 | 
		
	
		
			
			|  | 172 | +	pushw	%ax
 | 
		
	
		
			
			|  | 173 | +	popl	%edi
 | 
		
	
		
			
			|  | 174 | +	movl	%edi, image_source
 | 
		
	
		
			
			|  | 175 | +	xorl	%esi, %esi
 | 
		
	
		
			
			|  | 176 | +	movzbl	romheader_size, %ecx
 | 
		
	
		
			
			|  | 177 | +	shll	$9, %ecx
 | 
		
	
		
			
			|  | 178 | +	addr32 rep movsb	/* PMM presence implies flat real mode */
 | 
		
	
		
			
			|  | 179 | +	movl	%edi, decompress_to
 | 
		
	
		
			
			|  | 180 | +	/* Shrink ROM and update checksum */
 | 
		
	
		
			
			|  | 181 | +	xorw	%bx, %bx
 | 
		
	
		
			
			|  | 182 | +	xorw	%si, %si
 | 
		
	
		
			
			|  | 183 | +	movb	$_prefix_size_sect, romheader_size
 | 
		
	
		
			
			|  | 184 | +	shlw	$9, %cx
 | 
		
	
		
			
			|  | 185 | +1:	lodsb
 | 
		
	
		
			
			|  | 186 | +	addb	%al, %bl
 | 
		
	
		
			
			|  | 187 | +	loop	1b
 | 
		
	
		
			
			|  | 188 | +	subb	%bl, checksum
 | 
		
	
		
			
			|  | 189 | +	popal
 | 
		
	
		
			
			| 126 | 190 |  99:
 | 
		
	
		
			
			|  | 191 | +	/* Print CRLF to terminate messages */
 | 
		
	
		
			
			|  | 192 | +	movw	$init_message_crlf, %si
 | 
		
	
		
			
			| 127 | 193 |  	call	print_message
 | 
		
	
		
			
			|  | 194 | +	/* Restore registers */
 | 
		
	
		
			
			|  | 195 | +	popw	%es
 | 
		
	
		
			
			|  | 196 | +	popw	%ds
 | 
		
	
		
			
			|  | 197 | +	popaw
 | 
		
	
		
			
			|  | 198 | +	/* Indicate boot capability to PnP BIOS, if present */
 | 
		
	
		
			
			| 128 | 199 |  	movw	$0x20, %ax
 | 
		
	
		
			
			| 129 |  | -	popw	%si
 | 
		
	
		
			
			| 130 | 200 |  	lret
 | 
		
	
		
			
			| 131 |  | -	.size init_vector, . - init_vector
 | 
		
	
		
			
			| 132 |  | -
 | 
		
	
		
			
			| 133 |  | -ispnp_message:
 | 
		
	
		
			
			| 134 |  | -	.asciz	"gPXE detected PnP BIOS\r\n"
 | 
		
	
		
			
			| 135 |  | -	.size ispnp_message, . - ispnp_message
 | 
		
	
		
			
			| 136 |  | -notpnp_message:
 | 
		
	
		
			
			| 137 |  | -	.asciz	"gPXE detected non-PnP BIOS\r\n"
 | 
		
	
		
			
			| 138 |  | -	.size notpnp_message, . - notpnp_message
 | 
		
	
		
			
			| 139 |  | -
 | 
		
	
		
			
			| 140 |  | -/* Boot execution vector
 | 
		
	
		
			
			| 141 |  | - *pciheader_size
 | 
		
	
		
			
			| 142 |  | - * Called by the PnP BIOS when it wants to boot us, or via the hooked
 | 
		
	
		
			
			| 143 |  | - * INT 19 if we detected a non-PnP BIOS.
 | 
		
	
		
			
			| 144 |  | - */	
 | 
		
	
		
			
			| 145 |  | -exec_vector:
 | 
		
	
		
			
			| 146 |  | -	/* Obtain a reasonably-sized stack */
 | 
		
	
		
			
			|  | 201 | +	.size init, . - init
 | 
		
	
		
			
			|  | 202 | +
 | 
		
	
		
			
			|  | 203 | +init_message:
 | 
		
	
		
			
			|  | 204 | +	.asciz	"gPXE (http://etherboot.org)"
 | 
		
	
		
			
			|  | 205 | +	.size	init_message, . - init_message
 | 
		
	
		
			
			|  | 206 | +init_message_pnp:
 | 
		
	
		
			
			|  | 207 | +	.asciz	" - PnP BIOS detected"
 | 
		
	
		
			
			|  | 208 | +	.size init_message_pnp, . - init_message_pnp
 | 
		
	
		
			
			|  | 209 | +init_message_pmm:
 | 
		
	
		
			
			|  | 210 | +	.asciz	", using PMM"
 | 
		
	
		
			
			|  | 211 | +	.size init_message_pmm, . - init_message_pmm
 | 
		
	
		
			
			|  | 212 | +init_message_pmm_failed:
 | 
		
	
		
			
			|  | 213 | +	.asciz	" (failed)"
 | 
		
	
		
			
			|  | 214 | +	.size init_message_pmm_failed, . - init_message_pmm_failed
 | 
		
	
		
			
			|  | 215 | +init_message_crlf:
 | 
		
	
		
			
			|  | 216 | +	.asciz	"\r\n"
 | 
		
	
		
			
			|  | 217 | +	.size	init_message_crlf, . - init_message_crlf
 | 
		
	
		
			
			|  | 218 | +
 | 
		
	
		
			
			|  | 219 | +/* ROM image location
 | 
		
	
		
			
			|  | 220 | + *
 | 
		
	
		
			
			|  | 221 | + * May be either within option ROM space, or within PMM-allocated block.
 | 
		
	
		
			
			|  | 222 | + */
 | 
		
	
		
			
			|  | 223 | +image_source:
 | 
		
	
		
			
			|  | 224 | +	.long	0
 | 
		
	
		
			
			|  | 225 | +	.size	image_source, . - image_source
 | 
		
	
		
			
			|  | 226 | +/* Temporary decompression area
 | 
		
	
		
			
			|  | 227 | + *
 | 
		
	
		
			
			|  | 228 | + * May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.
 | 
		
	
		
			
			|  | 229 | + */
 | 
		
	
		
			
			|  | 230 | +decompress_to:
 | 
		
	
		
			
			|  | 231 | +	.long	HIGHMEM_LOADPOINT
 | 
		
	
		
			
			|  | 232 | +	.size	decompress_to, . - decompress_to
 | 
		
	
		
			
			|  | 233 | +
 | 
		
	
		
			
			|  | 234 | +/* Boot Execution Vector entry point
 | 
		
	
		
			
			|  | 235 | + *
 | 
		
	
		
			
			|  | 236 | + * Called by the PnP BIOS when it wants to boot us.
 | 
		
	
		
			
			|  | 237 | + */
 | 
		
	
		
			
			|  | 238 | +bev_entry:
 | 
		
	
		
			
			|  | 239 | +	pushw	%cs
 | 
		
	
		
			
			|  | 240 | +	call	exec
 | 
		
	
		
			
			|  | 241 | +	lret
 | 
		
	
		
			
			|  | 242 | +	.size	bev_entry, . - bev_entry
 | 
		
	
		
			
			|  | 243 | +
 | 
		
	
		
			
			|  | 244 | +/* INT19 entry point
 | 
		
	
		
			
			|  | 245 | + *
 | 
		
	
		
			
			|  | 246 | + * Called via the hooked INT 19 if we detected a non-PnP BIOS.
 | 
		
	
		
			
			|  | 247 | + */
 | 
		
	
		
			
			|  | 248 | +int19_entry:
 | 
		
	
		
			
			|  | 249 | +	pushw	%cs
 | 
		
	
		
			
			|  | 250 | +	call	exec
 | 
		
	
		
			
			|  | 251 | +	/* No real way to return from INT19 */
 | 
		
	
		
			
			|  | 252 | +	int	$0x18
 | 
		
	
		
			
			|  | 253 | +	.size	int19_entry, . - int19_entry
 | 
		
	
		
			
			|  | 254 | +
 | 
		
	
		
			
			|  | 255 | +/* Execute as a boot device
 | 
		
	
		
			
			|  | 256 | + *
 | 
		
	
		
			
			|  | 257 | + */
 | 
		
	
		
			
			|  | 258 | +exec:	/* Set %ds = %cs */
 | 
		
	
		
			
			|  | 259 | +	pushw	%cs
 | 
		
	
		
			
			|  | 260 | +	popw	%ds
 | 
		
	
		
			
			|  | 261 | +
 | 
		
	
		
			
			|  | 262 | +	/* Print message as soon as possible */
 | 
		
	
		
			
			|  | 263 | +	movw	$exec_message, %si
 | 
		
	
		
			
			|  | 264 | +	call	print_message
 | 
		
	
		
			
			|  | 265 | +
 | 
		
	
		
			
			|  | 266 | +	/* Store magic word on BIOS stack and remember BIOS %ss:sp */
 | 
		
	
		
			
			|  | 267 | +	pushl	$STACK_MAGIC
 | 
		
	
		
			
			|  | 268 | +	movw	%ss, %dx
 | 
		
	
		
			
			|  | 269 | +	movw	%sp, %bp
 | 
		
	
		
			
			|  | 270 | +
 | 
		
	
		
			
			|  | 271 | +	/* Obtain a reasonably-sized temporary stack */
 | 
		
	
		
			
			| 147 | 272 |  	xorw	%ax, %ax
 | 
		
	
		
			
			| 148 | 273 |  	movw	%ax, %ss
 | 
		
	
		
			
			| 149 | 274 |  	movw	$0x7c00, %sp
 | 
		
	
		
			
			| 150 |  | -	
 | 
		
	
		
			
			| 151 |  | -	movw	$exec_message, %si
 | 
		
	
		
			
			| 152 |  | -	call	print_message
 | 
		
	
		
			
			| 153 | 275 |  
 | 
		
	
		
			
			| 154 |  | -	call	install
 | 
		
	
		
			
			|  | 276 | +	/* Install gPXE */
 | 
		
	
		
			
			|  | 277 | +	movl	image_source, %esi
 | 
		
	
		
			
			|  | 278 | +	movl	decompress_to, %edi
 | 
		
	
		
			
			|  | 279 | +	call	alloc_basemem
 | 
		
	
		
			
			|  | 280 | +	call	install_prealloc
 | 
		
	
		
			
			| 155 | 281 |  
 | 
		
	
		
			
			| 156 | 282 |  	/* Set up real-mode stack */
 | 
		
	
		
			
			| 157 | 283 |  	movw	%bx, %ss
 | 
		
	
	
		
			
			|  | @@ -162,13 +288,23 @@ exec_vector:
 | 
		
	
		
			
			| 162 | 288 |  	pushw	$1f
 | 
		
	
		
			
			| 163 | 289 |  	lret
 | 
		
	
		
			
			| 164 | 290 |  	.section ".text16", "awx", @progbits
 | 
		
	
		
			
			| 165 |  | -1:
 | 
		
	
		
			
			|  | 291 | +1:	/* Call main() */
 | 
		
	
		
			
			| 166 | 292 |  	pushl	$main
 | 
		
	
		
			
			| 167 | 293 |  	pushw	%cs
 | 
		
	
		
			
			| 168 | 294 |  	call	prot_call
 | 
		
	
		
			
			| 169 |  | -	popl	%eax /* discard */
 | 
		
	
		
			
			|  | 295 | +	/* No need to clean up stack; we are about to reload %ss:sp */
 | 
		
	
		
			
			|  | 296 | +	
 | 
		
	
		
			
			|  | 297 | +	/* Restore BIOS stack */
 | 
		
	
		
			
			|  | 298 | +	movw	%dx, %ss
 | 
		
	
		
			
			|  | 299 | +	movw	%bp, %sp
 | 
		
	
		
			
			| 170 | 300 |  
 | 
		
	
		
			
			| 171 |  | -	/* Boot next device */
 | 
		
	
		
			
			|  | 301 | +	/* Check magic word on BIOS stack */
 | 
		
	
		
			
			|  | 302 | +	popl	%eax
 | 
		
	
		
			
			|  | 303 | +	cmpl	$STACK_MAGIC, %eax
 | 
		
	
		
			
			|  | 304 | +	jne	1f
 | 
		
	
		
			
			|  | 305 | +	/* BIOS stack OK: return to caller */
 | 
		
	
		
			
			|  | 306 | +	lret
 | 
		
	
		
			
			|  | 307 | +1:	/* BIOS stack corrupt: use INT 18 */
 | 
		
	
		
			
			| 172 | 308 |  	int	$0x18
 | 
		
	
		
			
			| 173 | 309 |  	.previous
 | 
		
	
		
			
			| 174 | 310 |  
 | 
		
	
	
		
			
			|  | @@ -182,6 +318,7 @@ exec_message:
 | 
		
	
		
			
			| 182 | 318 |   */
 | 
		
	
		
			
			| 183 | 319 |  undiloader:
 | 
		
	
		
			
			| 184 | 320 |  	/* Save registers */
 | 
		
	
		
			
			|  | 321 | +	pushl	%esi
 | 
		
	
		
			
			| 185 | 322 |  	pushl	%edi
 | 
		
	
		
			
			| 186 | 323 |  	pushw	%es
 | 
		
	
		
			
			| 187 | 324 |  	pushw	%bx
 | 
		
	
	
		
			
			|  | @@ -193,6 +330,8 @@ undiloader:
 | 
		
	
		
			
			| 193 | 330 |  	pushw	%di
 | 
		
	
		
			
			| 194 | 331 |  	movw	%es:12(%di), %bx
 | 
		
	
		
			
			| 195 | 332 |  	movw	%es:14(%di), %ax
 | 
		
	
		
			
			|  | 333 | +	movl	%cs:image_source, %esi
 | 
		
	
		
			
			|  | 334 | +	movl	%cs:decompress_to, %edi
 | 
		
	
		
			
			| 196 | 335 |  	call	install_prealloc
 | 
		
	
		
			
			| 197 | 336 |  	popw	%di
 | 
		
	
		
			
			| 198 | 337 |  	/* Call UNDI loader C code */
 | 
		
	
	
		
			
			|  | @@ -208,6 +347,7 @@ undiloader:
 | 
		
	
		
			
			| 208 | 347 |  	popw	%bx
 | 
		
	
		
			
			| 209 | 348 |  	popw	%es
 | 
		
	
		
			
			| 210 | 349 |  	popl	%edi
 | 
		
	
		
			
			|  | 350 | +	popl	%esi
 | 
		
	
		
			
			| 211 | 351 |  	lret
 | 
		
	
		
			
			| 212 | 352 |  	.size undiloader, . - undiloader
 | 
		
	
		
			
			| 213 | 353 |  				
 | 
		
	
	
		
			
			|  | @@ -218,7 +358,7 @@ print_message:
 | 
		
	
		
			
			| 218 | 358 |  	pushw	%bx
 | 
		
	
		
			
			| 219 | 359 |  	pushw	%bp
 | 
		
	
		
			
			| 220 | 360 |  	movw    $0x0007, %bx
 | 
		
	
		
			
			| 221 |  | -1:	cs lodsb
 | 
		
	
		
			
			|  | 361 | +1:	lodsb
 | 
		
	
		
			
			| 222 | 362 |  	testb	%al, %al
 | 
		
	
		
			
			| 223 | 363 |  	je	2f
 | 
		
	
		
			
			| 224 | 364 |  	movb    $0x0e, %ah              /* write char, tty mode */
 |