23
23
#define ACRN_DBG_BOOT 6U
24
24
25
25
#define MAX_BOOT_PARAMS_LEN 64U
26
+ #define INVALID_MOD_IDX 0xFFFFU
27
+
28
+ /**
29
+ * @pre vm != NULL && mbi != NULL
30
+ */
31
+ static void init_vm_ramdisk_info (struct acrn_vm * vm , struct multiboot_module * mod )
32
+ {
33
+ void * mod_addr = hpa2hva ((uint64_t )mod -> mm_mod_start );
34
+ uint32_t mod_size = mod -> mm_mod_end - mod -> mm_mod_start ;
35
+
36
+ vm -> sw .ramdisk_info .src_addr = mod_addr ;
37
+ vm -> sw .ramdisk_info .load_addr = vm -> sw .kernel_info .kernel_load_addr + vm -> sw .kernel_info .kernel_size ;
38
+ vm -> sw .ramdisk_info .load_addr = (void * )round_page_up ((uint64_t )vm -> sw .ramdisk_info .load_addr );
39
+ vm -> sw .ramdisk_info .size = mod_size ;
40
+ }
26
41
27
42
/* There are two sources for sos_vm kernel cmdline:
28
43
* - cmdline from direct boot mbi->cmdline
31
46
*/
32
47
static char kernel_cmdline [MAX_BOOTARGS_SIZE + 1U ];
33
48
34
- /* now modules support: FIRMWARE & RAMDISK & SeedList */
35
- static void parse_other_modules (struct acrn_vm * vm , const struct multiboot_module * mods , uint32_t mods_count )
36
- {
37
- uint32_t i ;
38
-
39
- for (i = 0U ; i < mods_count ; i ++ ) {
40
- uint32_t type_len ;
41
- const char * start = (char * )hpa2hva ((uint64_t )mods [i ].mm_string );
42
- const char * end ;
43
- void * mod_addr = hpa2hva ((uint64_t )mods [i ].mm_mod_start );
44
- uint32_t mod_size = mods [i ].mm_mod_end - mods [i ].mm_mod_start ;
45
-
46
- dev_dbg (ACRN_DBG_BOOT , "other mod-%d start=0x%x, end=0x%x" ,
47
- i , mods [i ].mm_mod_start , mods [i ].mm_mod_end );
48
- dev_dbg (ACRN_DBG_BOOT , "cmd addr=0x%x, str=%s" ,
49
- mods [i ].mm_string , start );
50
-
51
- while (* start == ' ' ) {
52
- start ++ ;
53
- }
54
-
55
- end = start ;
56
- while (((* end ) != ' ' ) && ((* end ) != '\0' )) {
57
- end ++ ;
58
- }
59
-
60
- type_len = end - start ;
61
- if (strncmp ("FIRMWARE" , start , type_len ) == 0 ) {
62
- char dyn_bootargs [100 ] = {'\0' };
63
- void * load_addr = gpa2hva (vm , (uint64_t )vm -> sw .bootargs_info .load_addr );
64
- uint32_t args_size = vm -> sw .bootargs_info .size ;
65
- static int32_t copy_once = 1 ;
66
-
67
- start = end + 1 ; /*it is fw name for boot args */
68
- snprintf (dyn_bootargs , 100U , " %s=0x%x@0x%x " , start , mod_size , mod_addr );
69
- dev_dbg (ACRN_DBG_BOOT , "fw-%d: %s" , i , dyn_bootargs );
70
-
71
- /*copy boot args to load addr, set src=load addr*/
72
- if (copy_once != 0 ) {
73
- copy_once = 0 ;
74
- (void )strncpy_s (load_addr , MAX_BOOTARGS_SIZE + 1U ,
75
- (const char * )vm -> sw .bootargs_info .src_addr ,
76
- vm -> sw .bootargs_info .size );
77
- vm -> sw .bootargs_info .src_addr = load_addr ;
78
- }
79
-
80
- (void )strncpy_s (load_addr + args_size , 100U , dyn_bootargs , 100U );
81
- vm -> sw .bootargs_info .size = strnlen_s (load_addr , MAX_BOOTARGS_SIZE );
82
-
83
- } else if (strncmp ("RAMDISK" , start , type_len ) == 0 ) {
84
- vm -> sw .ramdisk_info .src_addr = mod_addr ;
85
- vm -> sw .ramdisk_info .load_addr = vm -> sw .kernel_info .kernel_load_addr +
86
- vm -> sw .kernel_info .kernel_size ;
87
- vm -> sw .ramdisk_info .load_addr =
88
- (void * )round_page_up ((uint64_t )vm -> sw .ramdisk_info .load_addr );
89
- vm -> sw .ramdisk_info .size = mod_size ;
90
- } else {
91
- pr_warn ("not support mod, cmd: %s" , start );
92
- }
93
- }
94
- }
95
-
96
49
/**
97
50
* @pre vm != NULL && cmdline != NULL && cmdstr != NULL
98
51
*/
@@ -167,11 +120,117 @@ static void *get_kernel_load_addr(struct acrn_vm *vm)
167
120
return load_addr ;
168
121
}
169
122
123
+ /**
124
+ * @pre vm != NULL && mbi != NULL
125
+ */
126
+ static int32_t init_vm_kernel_info (struct acrn_vm * vm , struct multiboot_module * mod )
127
+ {
128
+ struct acrn_vm_config * vm_config = get_vm_config (vm -> vm_id );
129
+
130
+ dev_dbg (ACRN_DBG_BOOT , "kernel mod start=0x%x, end=0x%x" ,
131
+ mod -> mm_mod_start , mod -> mm_mod_end );
132
+
133
+ vm -> sw .kernel_type = vm_config -> os_config .kernel_type ;
134
+ vm -> sw .kernel_info .kernel_src_addr = hpa2hva ((uint64_t )mod -> mm_mod_start );
135
+ vm -> sw .kernel_info .kernel_size = mod -> mm_mod_end - mod -> mm_mod_start ;
136
+ vm -> sw .kernel_info .kernel_load_addr = get_kernel_load_addr (vm );
137
+
138
+ return (vm -> sw .kernel_info .kernel_load_addr == NULL ) ? (- EINVAL ) : 0 ;
139
+ }
140
+
141
+ /**
142
+ * @pre vm != NULL && mbi != NULL
143
+ */
144
+ static void init_vm_bootargs_info (struct acrn_vm * vm , struct multiboot_info * mbi )
145
+ {
146
+ struct acrn_vm_config * vm_config = get_vm_config (vm -> vm_id );
147
+ char * bootargs = vm_config -> os_config .bootargs ;
148
+
149
+ if (vm_config -> load_order == PRE_LAUNCHED_VM ) {
150
+ vm -> sw .bootargs_info .src_addr = bootargs ;
151
+ vm -> sw .bootargs_info .size = strnlen_s (bootargs , MAX_BOOTARGS_SIZE );
152
+ } else {
153
+ /* vm_config->load_order == SOS_VM */
154
+ if ((mbi -> mi_flags & MULTIBOOT_INFO_HAS_CMDLINE ) != 0U ) {
155
+ /*
156
+ * If there is cmdline from mbi->mi_cmdline, merge it with
157
+ * vm_config->os_config.bootargs
158
+ */
159
+ merge_cmdline (vm , hpa2hva ((uint64_t )mbi -> mi_cmdline ), bootargs );
160
+
161
+ vm -> sw .bootargs_info .src_addr = kernel_cmdline ;
162
+ vm -> sw .bootargs_info .size = strnlen_s (kernel_cmdline , MAX_BOOTARGS_SIZE );
163
+ } else {
164
+ vm -> sw .bootargs_info .src_addr = bootargs ;
165
+ vm -> sw .bootargs_info .size = strnlen_s (bootargs , MAX_BOOTARGS_SIZE );
166
+ }
167
+ }
168
+
169
+ /* Kernel bootarg and zero page are right before the kernel image */
170
+ if (vm -> sw .bootargs_info .size > 0 ) {
171
+ vm -> sw .bootargs_info .load_addr = vm -> sw .kernel_info .kernel_load_addr - (MEM_1K * 8U );
172
+ } else {
173
+ vm -> sw .bootargs_info .load_addr = NULL ;
174
+ }
175
+ }
176
+
177
+ static uint32_t get_mod_idx_by_tag (struct multiboot_module * mods , uint32_t mods_count , const char * tag )
178
+ {
179
+ uint32_t i , ret = INVALID_MOD_IDX ;
180
+ uint32_t tag_len = strnlen_s (tag , MAX_MOD_TAG_LEN );
181
+
182
+ for (i = 0 ; i < mods_count ; i ++ ) {
183
+ const char * mm_string = (char * )hpa2hva ((uint64_t )mods [i ].mm_string );
184
+ uint32_t mm_str_len = strnlen_s (mm_string , MAX_MOD_TAG_LEN );
185
+
186
+ /* when do file stitch by tool, the tag in mm_string might be followed with 0x0d or 0x0a */
187
+ if ((mm_str_len >= tag_len ) && (strncmp (mm_string , tag , tag_len ) == 0 )
188
+ && ((mm_string [tag_len ] == 0x0d )
189
+ || (mm_string [tag_len ] == 0x0a )
190
+ || (mm_string [tag_len ] == 0 ))){
191
+ ret = i ;
192
+ break ;
193
+ }
194
+ }
195
+ return ret ;
196
+ }
197
+
198
+ /* @pre vm != NULL && mbi != NULL
199
+ */
200
+ static int32_t init_vm_sw_load (struct acrn_vm * vm , struct multiboot_info * mbi )
201
+ {
202
+ struct acrn_vm_config * vm_config = get_vm_config (vm -> vm_id );
203
+ struct multiboot_module * mods = (struct multiboot_module * )hpa2hva ((uint64_t )mbi -> mi_mods_addr );
204
+ uint32_t mod_idx ;
205
+ int32_t ret = - EINVAL ;
206
+
207
+ dev_dbg (ACRN_DBG_BOOT , "mod counts=%d\n" , mbi -> mi_mods_count );
208
+
209
+ mod_idx = get_mod_idx_by_tag (mods , mbi -> mi_mods_count , vm_config -> os_config .kernel_mod_tag );
210
+ if (mod_idx != INVALID_MOD_IDX ) {
211
+ ret = init_vm_kernel_info (vm , & mods [mod_idx ]);
212
+ }
213
+
214
+ if (ret == 0 ) {
215
+ init_vm_bootargs_info (vm , mbi );
216
+ /* check whether there is a ramdisk module */
217
+ mod_idx = get_mod_idx_by_tag (mods , mbi -> mi_mods_count , vm_config -> os_config .ramdisk_mod_tag );
218
+ if (mod_idx != INVALID_MOD_IDX ) {
219
+ init_vm_ramdisk_info (vm , & mods [mod_idx ]);
220
+ /* TODO: prepare other modules like firmware, seedlist */
221
+ }
222
+ } else {
223
+ pr_err ("failed to load VM %d kernel module" , vm -> vm_id );
224
+ }
225
+ return ret ;
226
+ }
227
+
228
+ /**
229
+ * @pre vm != NULL
230
+ */
170
231
static int32_t init_general_vm_boot_info (struct acrn_vm * vm )
171
232
{
172
- struct multiboot_module * mods = NULL ;
173
233
struct multiboot_info * mbi = NULL ;
174
- struct acrn_vm_config * vm_config = get_vm_config (vm -> vm_id );
175
234
int32_t ret = - EINVAL ;
176
235
177
236
if (boot_regs [0 ] != MULTIBOOT_INFO_MAGIC ) {
@@ -183,59 +242,11 @@ static int32_t init_general_vm_boot_info(struct acrn_vm *vm)
183
242
stac ();
184
243
dev_dbg (ACRN_DBG_BOOT , "Multiboot detected, flag=0x%x" , mbi -> mi_flags );
185
244
if ((mbi -> mi_flags & MULTIBOOT_INFO_HAS_MODS ) == 0U ) {
186
- panic ("no sos kernel info found" );
187
- clac ();
245
+ panic ("no multiboot module info found" );
188
246
} else {
189
-
190
- dev_dbg (ACRN_DBG_BOOT , "mod counts=%d\n" , mbi -> mi_mods_count );
191
-
192
- /* mod[0] is for kernel, other mod for ramdisk/firmware info*/
193
- mods = (struct multiboot_module * )hpa2hva ((uint64_t )mbi -> mi_mods_addr );
194
-
195
- dev_dbg (ACRN_DBG_BOOT , "mod0 start=0x%x, end=0x%x" ,
196
- mods [0 ].mm_mod_start , mods [0 ].mm_mod_end );
197
-
198
- vm -> sw .kernel_type = vm_config -> os_config .kernel_type ;
199
- vm -> sw .kernel_info .kernel_src_addr = hpa2hva ((uint64_t )mods [0 ].mm_mod_start );
200
- vm -> sw .kernel_info .kernel_size = mods [0 ].mm_mod_end - mods [0 ].mm_mod_start ;
201
- vm -> sw .kernel_info .kernel_load_addr = get_kernel_load_addr (vm );
202
-
203
- if (vm_config -> load_order == PRE_LAUNCHED_VM ) {
204
- vm -> sw .bootargs_info .src_addr = (void * )vm_config -> os_config .bootargs ;
205
- vm -> sw .bootargs_info .size =
206
- strnlen_s (vm_config -> os_config .bootargs , MAX_BOOTARGS_SIZE );
207
- } else {
208
- if ((mbi -> mi_flags & MULTIBOOT_INFO_HAS_CMDLINE ) != 0U ) {
209
- /*
210
- * If there is cmdline from mbi->mi_cmdline, merge it with
211
- * vm_config->os_config.bootargs
212
- */
213
- merge_cmdline (vm , hpa2hva ((uint64_t )mbi -> mi_cmdline ),
214
- vm_config -> os_config .bootargs );
215
-
216
- vm -> sw .bootargs_info .src_addr = kernel_cmdline ;
217
- vm -> sw .bootargs_info .size =
218
- strnlen_s (kernel_cmdline , MAX_BOOTARGS_SIZE );
219
- } else {
220
- vm -> sw .bootargs_info .src_addr = vm_config -> os_config .bootargs ;
221
- vm -> sw .bootargs_info .size =
222
- strnlen_s (vm_config -> os_config .bootargs , MAX_BOOTARGS_SIZE );
223
- }
224
- }
225
-
226
- /* Kernel bootarg and zero page are right before the kernel image */
227
- vm -> sw .bootargs_info .load_addr =
228
- vm -> sw .kernel_info .kernel_load_addr - (MEM_1K * 8U );
229
-
230
- if (mbi -> mi_mods_count > 1U ) {
231
- /*parse other modules, like firmware /ramdisk */
232
- parse_other_modules (vm , mods + 1 , mbi -> mi_mods_count - 1 );
233
- }
234
- clac ();
235
- if (vm -> sw .kernel_info .kernel_load_addr != NULL ) {
236
- ret = 0 ;
237
- }
247
+ ret = init_vm_sw_load (vm , mbi );
238
248
}
249
+ clac ();
239
250
}
240
251
}
241
252
return ret ;
0 commit comments