Przeglądaj źródła

Ensure multiboot modules are in ascending order of memory start

address, to work around OS bugs.
tags/v0.9.3
Michael Brown 18 lat temu
rodzic
commit
0f29e0e46e
1 zmienionych plików z 40 dodań i 15 usunięć
  1. 40
    15
      src/arch/i386/image/multiboot.c

+ 40
- 15
src/arch/i386/image/multiboot.c Wyświetl plik

106
 	struct image *module_image;
106
 	struct image *module_image;
107
 	struct multiboot_module *module;
107
 	struct multiboot_module *module;
108
 	unsigned int count = 0;
108
 	unsigned int count = 0;
109
+	unsigned int insert;
110
+	physaddr_t start;
111
+	physaddr_t end;
112
+	unsigned int i;
109
 
113
 
114
+	/* Add each image as a multiboot module */
110
 	for_each_image ( module_image ) {
115
 	for_each_image ( module_image ) {
111
 
116
 
112
 		/* Do not include kernel image itself as a module */
117
 		/* Do not include kernel image itself as a module */
113
 		if ( module_image == image )
118
 		if ( module_image == image )
114
 			continue;
119
 			continue;
115
-		module = &modules[count++];
116
 
120
 
117
-		/* Populate module data structure, if applicable */
118
-		if ( ! modules )
119
-			continue;
120
-		module->mod_start = user_to_phys ( module_image->data, 0 );
121
-		module->mod_end = user_to_phys ( module_image->data,
122
-						 module_image->len );
123
-		module->string = virt_to_phys ( module_image->cmdline );
124
-		module->reserved = 0;
125
-		DBG ( "Multiboot module %lx is [%lx,%lx)\n",
126
-		      virt_to_phys ( module ),
127
-		      module->mod_start, module->mod_end );
128
-
129
-		/* We promise to page-align modules, so at least check */
130
-		assert ( ( module->mod_start & 0xfff ) == 0 );
121
+		/* If we don't have a data structure to populate, just count */
122
+		if ( modules ) {
123
+			
124
+			/* At least some OSes expect the multiboot
125
+			 * modules to be in ascending order, so we
126
+			 * have to support it.
127
+			 */
128
+			start = user_to_phys ( module_image->data, 0 );
129
+			end = user_to_phys ( module_image->data,
130
+					     module_image->len );
131
+			for ( insert = 0 ; insert < count ; insert++ ) {
132
+				if ( start < modules[insert].mod_start )
133
+					break;
134
+			}
135
+			module = &modules[insert];
136
+			memmove ( ( module + 1 ), module,
137
+				  ( ( count - insert ) * sizeof ( *module ) ));
138
+			module->mod_start = start;
139
+			module->mod_end = end;
140
+			module->string = virt_to_phys ( module_image->cmdline);
141
+			module->reserved = 0;
142
+			
143
+			/* We promise to page-align modules */
144
+			assert ( ( module->mod_start & 0xfff ) == 0 );
145
+		}
146
+
147
+		count++;
148
+	}
149
+
150
+	/* Dump module configuration */
151
+	if ( modules ) {
152
+		for ( i = 0 ; i < count ; i++ ) {
153
+			DBG ( "Multiboot module %d is [%lx,%lx)\n", i,
154
+			      modules[i].mod_start, modules[i].mod_end );
155
+		}
131
 	}
156
 	}
132
 
157
 
133
 	return count;
158
 	return count;

Ładowanie…
Anuluj
Zapisz