| 
				
			 | 
			
			
				
				@@ -144,7 +144,17 @@ _librm_start: 
			 | 
		
		
	
		
			
			| 
				144
			 | 
			
				144
			 | 
			
			
				
				  **************************************************************************** 
			 | 
		
		
	
		
			
			| 
				145
			 | 
			
				145
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				146
			 | 
			
				146
			 | 
			
			
				
				 	.fill FREE_BASEMEM_HEADER_SIZE, 1, 0 
			 | 
		
		
	
		
			
			| 
				147
			 | 
			
				
			 | 
			
			
				
				-	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				147
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				148
			 | 
			
			
				
				+/**************************************************************************** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				149
			 | 
			
			
				
				+ * Record of the current physical location of the installed copy. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				150
			 | 
			
			
				
				+ * Used by prot_call in order to return via the current installed copy 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				151
			 | 
			
			
				
				+ * even if Etherboot has been relocated during the protected-mode 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				152
			 | 
			
			
				
				+ * call. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				153
			 | 
			
			
				
				+ **************************************************************************** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				154
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				155
			 | 
			
			
				
				+EXPORT(librm_base): 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				156
			 | 
			
			
				
				+librm_base:	.long 0 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				157
			 | 
			
			
				
				+		 
			 | 
		
		
	
		
			
			| 
				148
			 | 
			
				158
			 | 
			
			
				
				 /**************************************************************************** 
			 | 
		
		
	
		
			
			| 
				149
			 | 
			
				159
			 | 
			
			
				
				  * GDT for initial transition to protected mode 
			 | 
		
		
	
		
			
			| 
				150
			 | 
			
				160
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -266,6 +276,9 @@ EXPORT(real_to_prot): 
			 | 
		
		
	
		
			
			| 
				266
			 | 
			
				276
			 | 
			
			
				
				 	xorl	%ebx, %ebx 
			 | 
		
		
	
		
			
			| 
				267
			 | 
			
				277
			 | 
			
			
				
				 	movw	%cs, %bx 
			 | 
		
		
	
		
			
			| 
				268
			 | 
			
				278
			 | 
			
			
				
				 	shll	$4, %ebx 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				279
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				280
			 | 
			
			
				
				+	/* Record physical base address of librm */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				281
			 | 
			
			
				
				+	movl	%ebx, %ds:OFFSET(librm_base) 
			 | 
		
		
	
		
			
			| 
				269
			 | 
			
				282
			 | 
			
			
				
				 		 
			 | 
		
		
	
		
			
			| 
				270
			 | 
			
				283
			 | 
			
			
				
				 	/* Check base address of stored protected-mode GDT.  If it's 
			 | 
		
		
	
		
			
			| 
				271
			 | 
			
				284
			 | 
			
			
				
				 	 * zero, set it up to use our internal GDT (with physical 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -360,6 +373,9 @@ EXPORT(prot_to_real): 
			 | 
		
		
	
		
			
			| 
				360
			 | 
			
				373
			 | 
			
			
				
				 	popl	OFFSET(save_ebx)(%ebx) 
			 | 
		
		
	
		
			
			| 
				361
			 | 
			
				374
			 | 
			
			
				
				 	movl	%eax, OFFSET(save_eax)(%ebx) 
			 | 
		
		
	
		
			
			| 
				362
			 | 
			
				375
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				376
			 | 
			
			
				
				+	/* Record physical base address of librm */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				377
			 | 
			
			
				
				+	movl	%ebx, OFFSET(librm_base)(%ebx) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				378
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				363
			 | 
			
				379
			 | 
			
			
				
				 	/* Extract return address from the stack, convert to offset 
			 | 
		
		
	
		
			
			| 
				364
			 | 
			
				380
			 | 
			
			
				
				 	 * within librm and save in save_retaddr 
			 | 
		
		
	
		
			
			| 
				365
			 | 
			
				381
			 | 
			
			
				
				 	 */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -445,22 +461,32 @@ p2r_ljmp: 
			 | 
		
		
	
		
			
			| 
				445
			 | 
			
				461
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				446
			 | 
			
				462
			 | 
			
			
				
				  * Call a specific C function in the protected-mode code.  The 
			 | 
		
		
	
		
			
			| 
				447
			 | 
			
				463
			 | 
			
			
				
				  * prototype of the C function must be 
			 | 
		
		
	
		
			
			| 
				448
			 | 
			
				
			 | 
			
			
				
				- *   void function ( struct real_mode_regs *rm_regs, 
			 | 
		
		
	
		
			
			| 
				449
			 | 
			
				
			 | 
			
			
				
				- *		     void (*retaddr) (void) );  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				464
			 | 
			
			
				
				+ *   void function ( struct real_mode_regs *rm_regs );  
			 | 
		
		
	
		
			
			| 
				450
			 | 
			
				465
			 | 
			
			
				
				  * rm_regs will point to a struct containing the real-mode registers 
			 | 
		
		
	
		
			
			| 
				451
			 | 
			
				
			 | 
			
			
				
				- * at entry to prot_call.  retaddr will point to the (virtual) return 
			 | 
		
		
	
		
			
			| 
				452
			 | 
			
				
			 | 
			
			
				
				- * address from "function".  This return address will point into 
			 | 
		
		
	
		
			
			| 
				453
			 | 
			
				
			 | 
			
			
				
				- * librm.  It is included so that "function" may, if desired, relocate 
			 | 
		
		
	
		
			
			| 
				454
			 | 
			
				
			 | 
			
			
				
				- * librm and return via the new copy.  It must not be directly called 
			 | 
		
		
	
		
			
			| 
				455
			 | 
			
				
			 | 
			
			
				
				- * as a function, i.e. you may not do "*retaddr()"; you must instead 
			 | 
		
		
	
		
			
			| 
				456
			 | 
			
				
			 | 
			
			
				
				- * do something like: 
			 | 
		
		
	
		
			
			| 
				457
			 | 
			
				
			 | 
			
			
				
				- *	*retaddr += ( new_librm_location - old_librm_location ); 
			 | 
		
		
	
		
			
			| 
				458
			 | 
			
				
			 | 
			
			
				
				- *	return; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				466
			 | 
			
			
				
				+ * at entry to prot_call.   
			 | 
		
		
	
		
			
			| 
				459
			 | 
			
				467
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				460
			 | 
			
				468
			 | 
			
			
				
				  * All registers will be preserved across prot_call(), unless the C 
			 | 
		
		
	
		
			
			| 
				461
			 | 
			
				469
			 | 
			
			
				
				  * function explicitly overwrites values in rm_regs.  Interrupt status 
			 | 
		
		
	
		
			
			| 
				462
			 | 
			
				470
			 | 
			
			
				
				  * will also be preserved.  Gate A20 will be enabled. 
			 | 
		
		
	
		
			
			| 
				463
			 | 
			
				471
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				472
			 | 
			
			
				
				+ * The protected-mode code may install librm to a new location.  If it 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				473
			 | 
			
			
				
				+ * does so, it must update librm_base in *this* copy of librm to point 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				474
			 | 
			
			
				
				+ * to the new physical location.  prot_call will then return via the 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				475
			 | 
			
			
				
				+ * newly installed copy. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				476
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				477
			 | 
			
			
				
				+ * Note that when Etherboot performs its initial relocation, "*this*" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				478
			 | 
			
			
				
				+ * copy in the above paragraph will refer to the "master" copy, since 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				479
			 | 
			
			
				
				+ * that is the initial installed copy.  Etherboot will return to 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				480
			 | 
			
			
				
				+ * prot_call using a virtual address, so will return to the master 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				481
			 | 
			
			
				
				+ * copy in high memory (rather than the original copy in base memory). 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				482
			 | 
			
			
				
				+ * The master copy in high memory will have the physical address of 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				483
			 | 
			
			
				
				+ * the newly installed copy in librm_base, since install_librm() 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				484
			 | 
			
			
				
				+ * writes it there.  Thus, Etherboot's initialise() function will 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				485
			 | 
			
			
				
				+ * return to the master copy of prot_call(), which will then jump to 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				486
			 | 
			
			
				
				+ * the installed copy. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				487
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				488
			 | 
			
			
				
				+ * It works, trust me. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				489
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				464
			 | 
			
				490
			 | 
			
			
				
				  * Parameters: 
			 | 
		
		
	
		
			
			| 
				465
			 | 
			
				491
			 | 
			
			
				
				  *   function : virtual address of protected-mode function to call 
			 | 
		
		
	
		
			
			| 
				466
			 | 
			
				492
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -529,14 +555,10 @@ EXPORT(prot_call): 
			 | 
		
		
	
		
			
			| 
				529
			 | 
			
				555
			 | 
			
			
				
				 	popl	%eax	/* discard */ 
			 | 
		
		
	
		
			
			| 
				530
			 | 
			
				556
			 | 
			
			
				
				 	popal 
			 | 
		
		
	
		
			
			| 
				531
			 | 
			
				557
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				532
			 | 
			
				
			 | 
			
			
				
				-	/* Push &rm_regs and &retaddr on the stack, and call function */ 
			 | 
		
		
	
		
			
			| 
				533
			 | 
			
				
			 | 
			
			
				
				-	movl	%esp, %ebp 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				558
			 | 
			
			
				
				+	/* Push &rm_regs on the stack, and call function */ 
			 | 
		
		
	
		
			
			| 
				534
			 | 
			
				559
			 | 
			
			
				
				 	pushl	%esp 
			 | 
		
		
	
		
			
			| 
				535
			 | 
			
				
			 | 
			
			
				
				-	subl	$12, 0(%esp) 
			 | 
		
		
	
		
			
			| 
				536
			 | 
			
				
			 | 
			
			
				
				-	pushl	%ebp 
			 | 
		
		
	
		
			
			| 
				537
			 | 
			
				560
			 | 
			
			
				
				 	call	*%ebx 
			 | 
		
		
	
		
			
			| 
				538
			 | 
			
				561
			 | 
			
			
				
				 	popl	%eax /* discard */ 
			 | 
		
		
	
		
			
			| 
				539
			 | 
			
				
			 | 
			
			
				
				-	popl	%eax /* discard */ 
			 | 
		
		
	
		
			
			| 
				540
			 | 
			
				562
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				541
			 | 
			
				563
			 | 
			
			
				
				 	/* Switch to physical addresses, discard PM register store */ 
			 | 
		
		
	
		
			
			| 
				542
			 | 
			
				564
			 | 
			
			
				
				 	lcall	$VIRTUAL_CS, $_virt_to_phys 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -553,6 +575,22 @@ EXPORT(prot_call): 
			 | 
		
		
	
		
			
			| 
				553
			 | 
			
				575
			 | 
			
			
				
				 	rep movsb 
			 | 
		
		
	
		
			
			| 
				554
			 | 
			
				576
			 | 
			
			
				
				 	movl	%esi, %esp	/* remove rm_regs from PM stack */ 
			 | 
		
		
	
		
			
			| 
				555
			 | 
			
				577
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				578
			 | 
			
			
				
				+	/* Obtain physical base address of installed copy of librm in 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				579
			 | 
			
			
				
				+	 * %ebx.  (It's possible that this *isn't* the physical base 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				580
			 | 
			
			
				
				+	 * address of the copy we're currently executing in, because 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				581
			 | 
			
			
				
				+	 * the protected-mode call could have moved librm.  If it does 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				582
			 | 
			
			
				
				+	 * so, it must update librm_base in our copy to reflect the 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				583
			 | 
			
			
				
				+	 * new location. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				584
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				585
			 | 
			
			
				
				+	call	1f 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				586
			 | 
			
			
				
				+1:	popl	%ebp 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				587
			 | 
			
			
				
				+	movl	OFFSET(librm_base-1b)(%ebp), %ebx 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				588
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				589
			 | 
			
			
				
				+	/* Jump to running in installed copy of librm */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				590
			 | 
			
			
				
				+	addl	$OFFSET(1f), %ebx 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				591
			 | 
			
			
				
				+	jmp	*%ebx 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				592
			 | 
			
			
				
				+1:	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				593
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				556
			 | 
			
				594
			 | 
			
			
				
				 	/* Switch to real mode */ 
			 | 
		
		
	
		
			
			| 
				557
			 | 
			
				595
			 | 
			
			
				
				 	call	prot_to_real 
			 | 
		
		
	
		
			
			| 
				558
			 | 
			
				596
			 | 
			
			
				
				 	.code16 
			 |