1 /* kbootcfg.c - kboot.cfg parsing
3 Copyright (C) 2010-2011 Hector Martin "marcan" <hector@marcansoft.com>
5 This code is licensed to you under the terms of the GNU GPL, version 2;
6 see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
9 /* See http://www.kernel.org/pub/linux/kernel/people/geoff/cell/ps3-linux-docs/ps3-linux-docs-08.06.09/mini-boot-conf.txt */
13 #include "kbootconf.h"
16 char conf_buf
[MAX_KBOOTCONF_SIZE
];
18 struct kbootconf conf
;
20 char *strip(char *buf
)
22 while (*buf
== ' ' || *buf
== '\t')
24 char *end
= buf
+ strlen(buf
) - 1;
25 while (*end
== ' ' || *end
== '\t')
31 void split(char *buf
, char **left
, char **right
, char delim
)
33 char *p
= strchr(buf
, delim
);
45 int kbootconf_parse(void)
51 char tmpbuf
[MAX_CMDLINE_SIZE
];
55 memset(&conf
, 0, sizeof(conf
));
60 char *newline
= strchr(lp
, '\n');
75 split(lp
, &left
, &right
, '=');
77 printf("kboot.conf: parse error (line %d)\n", lineno
);
81 while(*right
== '"' || *right
== '\'')
83 char *rend
= right
+ strlen(right
) - 1;
84 while(*rend
== '"' || *rend
== '\'')
87 if (!strcmp(left
, "timeout")) {
88 conf
.timeout
= my_atoi(right
);
89 } else if (!strcmp(left
, "default")) {
91 } else if (!strcmp(left
, "message")) {
93 } else if (!strcmp(left
, "initrd")) {
95 } else if (!strcmp(left
, "root")) {
97 } else if (!strcmp(left
, "video")) {
100 if (strlen(right
) > MAX_CMDLINE_SIZE
) {
101 printf("kboot.conf: maximum length exceeded (line %d)\n", lineno
);
104 conf
.kernels
[conf
.num_kernels
].label
= left
;
105 conf
.kernels
[conf
.num_kernels
].kernel
= right
;
106 char *p
= strchr(right
, ' ');
108 // kernel, no arguments
117 /* split commandline arguments and extract the useful bits */
119 char *spc
= strchr(p
, ' ');
130 split(p
, &arg
, &val
, '=');
132 strlcat(tmpbuf
, arg
, sizeof(tmpbuf
));
133 strlcat(tmpbuf
, " ", sizeof(tmpbuf
));
134 } else if (!strcmp(arg
, "root")) {
136 } else if (!strcmp(arg
, "initrd")) {
139 strlcat(tmpbuf
, arg
, sizeof(tmpbuf
));
140 strlcat(tmpbuf
, "=", sizeof(tmpbuf
));
141 strlcat(tmpbuf
, val
, sizeof(tmpbuf
));
142 strlcat(tmpbuf
, " ", sizeof(tmpbuf
));
148 int len
= strlen(tmpbuf
);
149 if (len
&& tmpbuf
[len
-1] == ' ')
153 // UGLY: tack on initrd and root onto tmpbuf, then copy it entirely
154 // on top of the original buffer (avoids having to deal with malloc)
155 conf
.kernels
[conf
.num_kernels
].parameters
= buf
;
157 strlcpy(tmpbuf
+len
, initrd
, sizeof(tmpbuf
)-len
);
158 conf
.kernels
[conf
.num_kernels
].initrd
= buf
+ len
;
159 len
+= strlen(initrd
)+1;
162 strlcpy(tmpbuf
+len
, root
, sizeof(tmpbuf
)-len
);
163 conf
.kernels
[conf
.num_kernels
].root
= buf
+ len
;
164 len
+= strlen(root
)+1;
166 memcpy(buf
, tmpbuf
, len
);
175 conf
.default_idx
= 0;
176 for (i
=0; i
<conf
.num_kernels
; i
++) {
177 if (dflt
&& !strcmp(conf
.kernels
[i
].label
, dflt
))
178 conf
.default_idx
= i
;
179 if (!conf
.kernels
[i
].initrd
&& dinitrd
)
180 conf
.kernels
[i
].initrd
= dinitrd
;
181 if (!conf
.kernels
[i
].root
&& droot
)
182 conf
.kernels
[i
].root
= droot
;
183 if (conf
.kernels
[i
].initrd
&& !conf
.kernels
[i
].root
)
184 conf
.kernels
[i
].root
= "/dev/ram0";
187 printf("==== kboot.conf dump ====\n");
188 if (conf
.timeout
!= -1)
189 printf("Timeout: %d\n", conf
.timeout
);
191 printf("Message: %s\n", conf
.msgfile
);
193 for (i
=0; i
<conf
.num_kernels
; i
++) {
194 printf("Entry #%d '%s'", i
, conf
.kernels
[i
].label
);
195 if (conf
.default_idx
== i
)
196 printf(" (default):\n");
199 printf(" Kernel: %s\n", conf
.kernels
[i
].kernel
);
200 if (conf
.kernels
[i
].initrd
)
201 printf(" Initrd: %s\n", conf
.kernels
[i
].initrd
);
202 if (conf
.kernels
[i
].root
)
203 printf(" Root: %s\n", conf
.kernels
[i
].root
);
204 if (conf
.kernels
[i
].parameters
)
205 printf(" Parameters: %s\n", conf
.kernels
[i
].parameters
);
208 printf("=========================\n");
209 return conf
.num_kernels
;