| 
				
			 | 
			
			
				
				@@ -23,6 +23,7 @@ 
			 | 
		
		
	
		
			
			| 
				23
			 | 
			
				23
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				24
			 | 
			
				24
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				25
			 | 
			
				25
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				26
			 | 
			
			
				
				+#include <stdio.h> 
			 | 
		
		
	
		
			
			| 
				26
			 | 
			
				27
			 | 
			
			
				
				 #include <errno.h> 
			 | 
		
		
	
		
			
			| 
				27
			 | 
			
				28
			 | 
			
			
				
				 #include <assert.h> 
			 | 
		
		
	
		
			
			| 
				28
			 | 
			
				29
			 | 
			
			
				
				 #include <realmode.h> 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -51,6 +52,16 @@ struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT ); 
			 | 
		
		
	
		
			
			| 
				51
			 | 
			
				52
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				52
			 | 
			
				53
			 | 
			
			
				
				 #define MAX_MODULES 8 
			 | 
		
		
	
		
			
			| 
				53
			 | 
			
				54
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				
				+ * Maximum combined length of command lines 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				
				+ * Again; sorry.  Some broken OSes zero out any non-base memory that 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				
				+ * isn't part of the loaded module set, so we can't just use 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				
				+ * virt_to_phys(cmdline) to point to the command lines, even though 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				
				+ * this would comply with the Multiboot spec. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				
				+#define MB_MAX_CMDLINE 512 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				54
			 | 
			
				65
			 | 
			
			
				
				 /** Multiboot flags that we support */ 
			 | 
		
		
	
		
			
			| 
				55
			 | 
			
				66
			 | 
			
			
				
				 #define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \ 
			 | 
		
		
	
		
			
			| 
				56
			 | 
			
				67
			 | 
			
			
				
				 			     MB_FLAG_VIDMODE | MB_FLAG_RAW ) 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -77,6 +88,13 @@ struct multiboot_header_info { 
			 | 
		
		
	
		
			
			| 
				77
			 | 
			
				88
			 | 
			
			
				
				 	size_t offset; 
			 | 
		
		
	
		
			
			| 
				78
			 | 
			
				89
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				79
			 | 
			
				90
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				
				+/** Multiboot module command lines */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				
				+static char __bss16_array ( mb_cmdlines, [MB_MAX_CMDLINE] ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				
				+#define mb_cmdlines __use_data16 ( mb_cmdlines ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				
				+/** Offset within module command lines */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				96
			 | 
			
			
				
				+static unsigned int mb_cmdline_offset; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				97
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				80
			 | 
			
				98
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				81
			 | 
			
				99
			 | 
			
			
				
				  * Build multiboot memory map 
			 | 
		
		
	
		
			
			| 
				82
			 | 
			
				100
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -118,6 +136,32 @@ static void multiboot_build_memmap ( struct image *image, 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				136
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				137
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				120
			 | 
			
				138
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				139
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				140
			 | 
			
			
				
				+ * Add command line in base memory 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				141
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				142
			 | 
			
			
				
				+ * @v cmdline		Command line 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				143
			 | 
			
			
				
				+ * @ret physaddr	Physical address of command line 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				144
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				145
			 | 
			
			
				
				+physaddr_t multiboot_add_cmdline ( const char *cmdline ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				146
			 | 
			
			
				
				+	char *mb_cmdline; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				147
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				148
			 | 
			
			
				
				+	if ( ! cmdline ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				149
			 | 
			
			
				
				+		cmdline = ""; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				150
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				151
			 | 
			
			
				
				+	/* Copy command line to base memory buffer */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				152
			 | 
			
			
				
				+	mb_cmdline = ( mb_cmdlines + mb_cmdline_offset ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				153
			 | 
			
			
				
				+	mb_cmdline_offset += 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				154
			 | 
			
			
				
				+		( snprintf ( mb_cmdline, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				155
			 | 
			
			
				
				+			     ( sizeof ( mb_cmdlines ) - mb_cmdline_offset ), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				156
			 | 
			
			
				
				+			     "%s", cmdline ) + 1 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				157
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				158
			 | 
			
			
				
				+	/* Truncate to terminating NUL in buffer if necessary */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				159
			 | 
			
			
				
				+	if ( mb_cmdline_offset > sizeof ( mb_cmdlines ) ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				160
			 | 
			
			
				
				+		mb_cmdline_offset = ( sizeof ( mb_cmdlines ) - 1 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				161
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				162
			 | 
			
			
				
				+	return virt_to_phys ( mb_cmdline ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				163
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				164
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				165
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				122
			 | 
			
				166
			 | 
			
			
				
				  * Build multiboot module list 
			 | 
		
		
	
		
			
			| 
				123
			 | 
			
				167
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -135,7 +179,6 @@ multiboot_build_module_list ( struct image *image, 
			 | 
		
		
	
		
			
			| 
				135
			 | 
			
				179
			 | 
			
			
				
				 	unsigned int insert; 
			 | 
		
		
	
		
			
			| 
				136
			 | 
			
				180
			 | 
			
			
				
				 	physaddr_t start; 
			 | 
		
		
	
		
			
			| 
				137
			 | 
			
				181
			 | 
			
			
				
				 	physaddr_t end; 
			 | 
		
		
	
		
			
			| 
				138
			 | 
			
				
			 | 
			
			
				
				-	char *cmdline; 
			 | 
		
		
	
		
			
			| 
				139
			 | 
			
				182
			 | 
			
			
				
				 	unsigned int i; 
			 | 
		
		
	
		
			
			| 
				140
			 | 
			
				183
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				141
			 | 
			
				184
			 | 
			
			
				
				 	/* Add each image as a multiboot module */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -151,44 +194,35 @@ multiboot_build_module_list ( struct image *image, 
			 | 
		
		
	
		
			
			| 
				151
			 | 
			
				194
			 | 
			
			
				
				 		if ( module_image == image ) 
			 | 
		
		
	
		
			
			| 
				152
			 | 
			
				195
			 | 
			
			
				
				 			continue; 
			 | 
		
		
	
		
			
			| 
				153
			 | 
			
				196
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				154
			 | 
			
				
			 | 
			
			
				
				-		/* If we don't have a data structure to populate, just count */ 
			 | 
		
		
	
		
			
			| 
				155
			 | 
			
				
			 | 
			
			
				
				-		if ( modules ) { 
			 | 
		
		
	
		
			
			| 
				156
			 | 
			
				
			 | 
			
			
				
				-			 
			 | 
		
		
	
		
			
			| 
				157
			 | 
			
				
			 | 
			
			
				
				-			/* At least some OSes expect the multiboot 
			 | 
		
		
	
		
			
			| 
				158
			 | 
			
				
			 | 
			
			
				
				-			 * modules to be in ascending order, so we 
			 | 
		
		
	
		
			
			| 
				159
			 | 
			
				
			 | 
			
			
				
				-			 * have to support it. 
			 | 
		
		
	
		
			
			| 
				160
			 | 
			
				
			 | 
			
			
				
				-			 */ 
			 | 
		
		
	
		
			
			| 
				161
			 | 
			
				
			 | 
			
			
				
				-			start = user_to_phys ( module_image->data, 0 ); 
			 | 
		
		
	
		
			
			| 
				162
			 | 
			
				
			 | 
			
			
				
				-			end = user_to_phys ( module_image->data, 
			 | 
		
		
	
		
			
			| 
				163
			 | 
			
				
			 | 
			
			
				
				-					     module_image->len ); 
			 | 
		
		
	
		
			
			| 
				164
			 | 
			
				
			 | 
			
			
				
				-			for ( insert = 0 ; insert < count ; insert++ ) { 
			 | 
		
		
	
		
			
			| 
				165
			 | 
			
				
			 | 
			
			
				
				-				if ( start < modules[insert].mod_start ) 
			 | 
		
		
	
		
			
			| 
				166
			 | 
			
				
			 | 
			
			
				
				-					break; 
			 | 
		
		
	
		
			
			| 
				167
			 | 
			
				
			 | 
			
			
				
				-			} 
			 | 
		
		
	
		
			
			| 
				168
			 | 
			
				
			 | 
			
			
				
				-			module = &modules[insert]; 
			 | 
		
		
	
		
			
			| 
				169
			 | 
			
				
			 | 
			
			
				
				-			memmove ( ( module + 1 ), module, 
			 | 
		
		
	
		
			
			| 
				170
			 | 
			
				
			 | 
			
			
				
				-				  ( ( count - insert ) * sizeof ( *module ) )); 
			 | 
		
		
	
		
			
			| 
				171
			 | 
			
				
			 | 
			
			
				
				-			module->mod_start = start; 
			 | 
		
		
	
		
			
			| 
				172
			 | 
			
				
			 | 
			
			
				
				-			module->mod_end = end; 
			 | 
		
		
	
		
			
			| 
				173
			 | 
			
				
			 | 
			
			
				
				-			cmdline = ( module_image->cmdline ? 
			 | 
		
		
	
		
			
			| 
				174
			 | 
			
				
			 | 
			
			
				
				-				    module_image->cmdline : "" ); 
			 | 
		
		
	
		
			
			| 
				175
			 | 
			
				
			 | 
			
			
				
				-			module->string = virt_to_phys ( cmdline ); 
			 | 
		
		
	
		
			
			| 
				176
			 | 
			
				
			 | 
			
			
				
				-			module->reserved = 0; 
			 | 
		
		
	
		
			
			| 
				177
			 | 
			
				
			 | 
			
			
				
				-			 
			 | 
		
		
	
		
			
			| 
				178
			 | 
			
				
			 | 
			
			
				
				-			/* We promise to page-align modules */ 
			 | 
		
		
	
		
			
			| 
				179
			 | 
			
				
			 | 
			
			
				
				-			assert ( ( module->mod_start & 0xfff ) == 0 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				197
			 | 
			
			
				
				+		/* At least some OSes expect the multiboot modules to 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				198
			 | 
			
			
				
				+		 * be in ascending order, so we have to support it. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				199
			 | 
			
			
				
				+		 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				200
			 | 
			
			
				
				+		start = user_to_phys ( module_image->data, 0 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				201
			 | 
			
			
				
				+		end = user_to_phys ( module_image->data, module_image->len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				202
			 | 
			
			
				
				+		for ( insert = 0 ; insert < count ; insert++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				203
			 | 
			
			
				
				+			if ( start < modules[insert].mod_start ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				204
			 | 
			
			
				
				+				break; 
			 | 
		
		
	
		
			
			| 
				180
			 | 
			
				205
			 | 
			
			
				
				 		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				206
			 | 
			
			
				
				+		module = &modules[insert]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				207
			 | 
			
			
				
				+		memmove ( ( module + 1 ), module, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				208
			 | 
			
			
				
				+			  ( ( count - insert ) * sizeof ( *module ) ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				209
			 | 
			
			
				
				+		module->mod_start = start; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				210
			 | 
			
			
				
				+		module->mod_end = end; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				211
			 | 
			
			
				
				+		module->string = 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				212
			 | 
			
			
				
				+			multiboot_add_cmdline ( module_image->cmdline ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				213
			 | 
			
			
				
				+		module->reserved = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				214
			 | 
			
			
				
				+		 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				215
			 | 
			
			
				
				+		/* We promise to page-align modules */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				216
			 | 
			
			
				
				+		assert ( ( module->mod_start & 0xfff ) == 0 ); 
			 | 
		
		
	
		
			
			| 
				181
			 | 
			
				217
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				182
			 | 
			
				218
			 | 
			
			
				
				 		count++; 
			 | 
		
		
	
		
			
			| 
				183
			 | 
			
				219
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				184
			 | 
			
				220
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				185
			 | 
			
				221
			 | 
			
			
				
				 	/* Dump module configuration */ 
			 | 
		
		
	
		
			
			| 
				186
			 | 
			
				
			 | 
			
			
				
				-	if ( modules ) { 
			 | 
		
		
	
		
			
			| 
				187
			 | 
			
				
			 | 
			
			
				
				-		for ( i = 0 ; i < count ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				188
			 | 
			
				
			 | 
			
			
				
				-			DBGC ( image, "MULTIBOOT %p module %d is [%lx,%lx)\n", 
			 | 
		
		
	
		
			
			| 
				189
			 | 
			
				
			 | 
			
			
				
				-			       image, i, modules[i].mod_start, 
			 | 
		
		
	
		
			
			| 
				190
			 | 
			
				
			 | 
			
			
				
				-			       modules[i].mod_end ); 
			 | 
		
		
	
		
			
			| 
				191
			 | 
			
				
			 | 
			
			
				
				-		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				222
			 | 
			
			
				
				+	for ( i = 0 ; i < count ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				223
			 | 
			
			
				
				+		DBGC ( image, "MULTIBOOT %p module %d is [%lx,%lx)\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				224
			 | 
			
			
				
				+		       image, i, modules[i].mod_start, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				225
			 | 
			
			
				
				+		       modules[i].mod_end ); 
			 | 
		
		
	
		
			
			| 
				192
			 | 
			
				226
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				193
			 | 
			
				227
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				194
			 | 
			
				228
			 | 
			
			
				
				 	return count; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -225,7 +259,6 @@ static struct multiboot_module __bss16_array ( mbmodules, [MAX_MODULES] ); 
			 | 
		
		
	
		
			
			| 
				225
			 | 
			
				259
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				226
			 | 
			
				260
			 | 
			
			
				
				 static int multiboot_exec ( struct image *image ) { 
			 | 
		
		
	
		
			
			| 
				227
			 | 
			
				261
			 | 
			
			
				
				 	physaddr_t entry = image->priv.phys; 
			 | 
		
		
	
		
			
			| 
				228
			 | 
			
				
			 | 
			
			
				
				-	char *cmdline; 
			 | 
		
		
	
		
			
			| 
				229
			 | 
			
				262
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				230
			 | 
			
				263
			 | 
			
			
				
				 	/* Populate multiboot information structure */ 
			 | 
		
		
	
		
			
			| 
				231
			 | 
			
				264
			 | 
			
			
				
				 	memset ( &mbinfo, 0, sizeof ( mbinfo ) ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -233,8 +266,8 @@ static int multiboot_exec ( struct image *image ) { 
			 | 
		
		
	
		
			
			| 
				233
			 | 
			
				266
			 | 
			
			
				
				 			 MBI_FLAG_CMDLINE | MBI_FLAG_MODS ); 
			 | 
		
		
	
		
			
			| 
				234
			 | 
			
				267
			 | 
			
			
				
				 	multiboot_build_memmap ( image, &mbinfo, mbmemmap, 
			 | 
		
		
	
		
			
			| 
				235
			 | 
			
				268
			 | 
			
			
				
				 				 ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) ); 
			 | 
		
		
	
		
			
			| 
				236
			 | 
			
				
			 | 
			
			
				
				-	cmdline = ( image->cmdline ? image->cmdline : "" ); 
			 | 
		
		
	
		
			
			| 
				237
			 | 
			
				
			 | 
			
			
				
				-	mbinfo.cmdline = virt_to_phys ( cmdline ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				269
			 | 
			
			
				
				+	mb_cmdline_offset = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				270
			 | 
			
			
				
				+	mbinfo.cmdline = multiboot_add_cmdline ( image->cmdline ); 
			 | 
		
		
	
		
			
			| 
				238
			 | 
			
				271
			 | 
			
			
				
				 	mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules, 
			 | 
		
		
	
		
			
			| 
				239
			 | 
			
				272
			 | 
			
			
				
				 				( sizeof(mbmodules) / sizeof(mbmodules[0]) ) ); 
			 | 
		
		
	
		
			
			| 
				240
			 | 
			
				273
			 | 
			
			
				
				 	mbinfo.mods_addr = virt_to_phys ( mbmodules ); 
			 |