2020#include "boot.h"
2121
2222struct label {
23+ const char * name ;
2324 const char * kernel ;
2425 const char * initramfs ;
2526 const char * dtb ;
@@ -29,6 +30,8 @@ struct label {
2930};
3031
3132enum token {
33+ CMD_LABEL ,
34+ CMD_DEFAULT ,
3235 CMD_KERNEL ,
3336 CMD_APPEND ,
3437 CMD_INITRD ,
@@ -42,6 +45,8 @@ static const struct {
4245 char * command ;
4346 enum token token ;
4447} token_map [] = {
48+ {"label" , CMD_LABEL },
49+ {"default" , CMD_DEFAULT },
4550 {"kernel" , CMD_KERNEL },
4651 {"linux" , CMD_KERNEL },
4752 {"fdtdir" , CMD_FDTDIR },
@@ -169,6 +174,25 @@ static int parse_command(char **data, size_t *size, char **command, char **value
169174 return 0 ;
170175}
171176
177+ /**
178+ * count_lines() - Count the amount of lines in the string.
179+ */
180+ static int count_lines (char * data , size_t size )
181+ {
182+ int acc = 0 ;
183+ size_t i ;
184+
185+ for (i = 0 ; i < size ; ++ i ) {
186+ if (data [i ] == '\n' )
187+ acc ++ ;
188+
189+ if (data [i ] == '\0' )
190+ break ;
191+ }
192+
193+ return acc ;
194+ }
195+
172196/**
173197 * parse_conf() - Extract default label from extlinux.conf
174198 * @data: File contents
@@ -189,44 +213,109 @@ static int parse_conf(char *data, size_t size, struct label *label)
189213 char * command = NULL , * value = NULL ;
190214 char * overlay , * saveptr ;
191215 int cnt = 0 ;
192-
216+ struct {
217+ enum token cmd ;
218+ char * val ;
219+ } * commands ;
220+ int commands_count ;
221+ struct label * labels ;
222+ struct label * default_label = NULL ;
223+ const char * default_name = "" ;
224+ int labels_count = 0 ;
225+ int label_idx ;
226+ int i ;
227+
228+ commands_count = count_lines (data , size );
229+ commands = calloc (commands_count , sizeof (* commands ));
230+
231+ i = 0 ;
193232 while (parse_command (& data , & size , & command , & value ) == 0 ) {
194- switch (cmd_to_tok (command )) {
233+ if (i >= commands_count ) {
234+ dprintf (INFO , "Failed to parse the extlinux.conf\n" );
235+ free (commands );
236+ return -1 ;
237+ }
238+
239+ commands [i ].cmd = cmd_to_tok (command );
240+ commands [i ].val = value ;
241+ i ++ ;
242+ }
243+
244+ commands_count = i ;
245+
246+ i = 0 ;
247+ for (i = 0 ; i < commands_count ; ++ i ) {
248+ if (commands [i ].cmd == CMD_LABEL )
249+ labels_count ++ ;
250+ }
251+
252+ if (labels_count == 0 ) {
253+ dprintf (INFO , "No labels in the extlinux.conf\n" );
254+ free (commands );
255+ return -1 ;
256+ }
257+
258+ labels = calloc (labels_count , sizeof (* labels ));
259+
260+ label_idx = -1 ;
261+ for (i = 0 ; i < commands_count ; ++ i ) {
262+ if (commands [i ].cmd == CMD_DEFAULT ) {
263+ default_name = commands [i ].val ;
264+ } else if (commands [i ].cmd == CMD_LABEL ) {
265+ label_idx ++ ;
266+ labels [label_idx ].name = commands [i ].val ;
267+ } else if (label_idx >= 0 && label_idx < labels_count ) {
268+ switch (commands [i ].cmd ) {
195269 case CMD_KERNEL :
196- label -> kernel = value ;
270+ labels [ label_idx ]. kernel = commands [ i ]. val ;
197271 break ;
198272 case CMD_INITRD :
199- label -> initramfs = value ;
273+ labels [ label_idx ]. initramfs = commands [ i ]. val ;
200274 break ;
201275 case CMD_APPEND :
202- label -> cmdline = value ;
276+ labels [ label_idx ]. cmdline = commands [ i ]. val ;
203277 break ;
204278 case CMD_FDT :
205- label -> dtb = value ;
279+ labels [ label_idx ]. dtb = commands [ i ]. val ;
206280 break ;
207281 case CMD_FDTDIR :
208- label -> dtbdir = value ;
282+ labels [ label_idx ]. dtbdir = commands [ i ]. val ;
209283 break ;
210284 case CMD_FDTOVERLAY :
211- for (char * c = value ; * c ; c ++ )
285+ for (char * c = commands [ i ]. val ; * c ; c ++ )
212286 if (* c == ' ' )
213287 cnt ++ ;
214288
215289 cnt += 2 ;
216290
217- label -> dtboverlays = calloc (cnt , sizeof (* label -> dtboverlays ));
291+ labels [ label_idx ]. dtboverlays = calloc (cnt , sizeof (* labels [ label_idx ]. dtboverlays ));
218292 cnt = 0 ;
219- for (overlay = strtok_r (value , " " , & saveptr ); overlay ;
293+ for (overlay = strtok_r (commands [ i ]. val , " " , & saveptr ); overlay ;
220294 overlay = strtok_r (NULL , " " , & saveptr )) {
221- label -> dtboverlays [cnt ] = overlay ;
295+ labels [ label_idx ]. dtboverlays [cnt ] = overlay ;
222296 cnt ++ ;
223297 }
224298 break ;
225299 default :
226300 break ;
301+ }
227302 }
228303 }
229304
305+ default_label = & labels [0 ];
306+
307+ for (i = 0 ; i < labels_count ; ++ i ) {
308+ if (!strcmp (default_name , labels [i ].name )) {
309+ default_label = & labels [i ];
310+ break ;
311+ }
312+ }
313+
314+ memcpy (label , default_label , sizeof (* label ));
315+
316+ free (labels );
317+ free (commands );
318+
230319 return 0 ;
231320}
232321
@@ -419,6 +508,8 @@ static void lk2nd_boot_label(struct label *label)
419508 void * kernel_scratch ;
420509 int ret , i = 0 ;
421510
511+ dprintf (INFO , "Trying to boot '%s'\n" , label -> name );
512+
422513 ret = fs_load_file (label -> kernel , scratch , scratch_size );
423514 if (ret < 0 ) {
424515 dprintf (INFO , "Failed to load the kernel: %d\n" , ret );
0 commit comments