7 * Copyright (C) 2009 Laurent Vivier (Laurent@vivier.eu)
9 * Original XML parser by Blue Swirl <blauwirbel@gmail.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
18 #include "libopenbios/bindings.h"
19 #include "libopenbios/bootinfo_load.h"
20 #include "libopenbios/ofmem.h"
21 #include "libc/vsprintf.h"
23 //#define DEBUG_BOOTINFO
26 #define DPRINTF(fmt, args...) \
27 do { printk("%s: " fmt, __func__ , ##args); } while (0)
29 #define DPRINTF(fmt, args...) \
34 get_device( const char *path
)
37 static char buf
[1024];
39 for (i
= 0; i
< sizeof(buf
) && path
[i
] && path
[i
] != ':'; i
++)
47 get_partition( const char *path
)
54 while ( *path
&& *path
!= ':' )
61 if (path
[0] == ',' || !strchr(path
, ',')) /* if there is not a ',' or no partition id then return */
64 /* Must be a partition id */
71 get_filename( const char * path
, char **dirname
)
73 static char buf
[1024];
76 while ( *path
&& *path
!= ':' )
85 while ( *path
&& isdigit(*path
) )
91 strncpy(buf
, path
, sizeof(buf
));
92 buf
[sizeof(buf
) - 1] = 0;
94 filename
= strrchr(buf
, '\\');
107 is_bootinfo(char *bootinfo
)
109 return (strncasecmp(bootinfo
, "<chrp-boot", 10) ? 0 : -1);
113 bootinfo_load(struct sys_info
*info
, const char *filename
)
115 // Currently not implemented
116 return LOADER_NOT_SUPPORT
;
120 Parse SGML structure like:
122 <description>Debian/GNU Linux Installation on IBM CHRP hardware</description>
123 <os-name>Debian/GNU Linux for PowerPC</os-name>
124 <boot-script>boot &device;:\install\yaboot</boot-script>
125 <icon size=64,64 color-space=3,3,2>
127 CHRP system bindings are described at:
128 http://playground.sun.com/1275/bindings/chrp/chrp1_7a.ps
132 bootinfo_init_program(void)
137 int tag
, taglen
, script
, scriptlen
, scriptvalid
, entity
, chrp
;
139 char *device
, *filename
, *directory
, *partition
;
145 /* Parse the boot script */
147 chosen
= find_dev("/chosen");
148 tmp
= get_property(chosen
, "bootpath", &proplen
);
149 memcpy(bootpath
, tmp
, proplen
);
150 bootpath
[proplen
] = 0;
152 DPRINTF("bootpath %s\n", bootpath
);
154 device
= get_device(bootpath
);
155 partition
= get_partition(bootpath
);
156 filename
= get_filename(bootpath
, &directory
);
159 base
= (char*)cell2pointer(POP());
164 bootscript
= malloc(size
);
165 if (bootscript
== NULL
) {
166 DPRINTF("Can't malloc %d bytes\n", size
);
170 if (!is_bootinfo(base
)) {
171 DPRINTF("Not a valid bootinfo memory image\n");
183 while (current
< size
) {
191 } else if (c
== '>') {
193 tagbuf
[taglen
] = '\0';
194 if (strncasecmp(tagbuf
, "chrp-boot", 9) == 0) {
196 } else if (chrp
== 1) {
197 if (strncasecmp(tagbuf
, "boot-script", 11) == 0) {
200 } else if (strncasecmp(tagbuf
, "/boot-script", 12) == 0) {
203 bootscript
[scriptlen
] = '\0';
205 DPRINTF("got bootscript %s\n",
211 } else if (strncasecmp(tagbuf
, "/chrp-boot", 10) == 0)
214 } else if (tag
&& taglen
< sizeof(tagbuf
)) {
215 tagbuf
[taglen
++] = c
;
216 } else if (script
&& c
== '&') {
219 } else if (entity
&& c
==';') {
221 tagbuf
[taglen
] = '\0';
222 if (strncasecmp(tagbuf
, "lt", 2) == 0) {
223 bootscript
[scriptlen
++] = '<';
224 } else if (strncasecmp(tagbuf
, "gt", 2) == 0) {
225 bootscript
[scriptlen
++] = '>';
226 } else if (strncasecmp(tagbuf
, "device", 6) == 0) {
227 strcpy(bootscript
+ scriptlen
, device
);
228 scriptlen
+= strlen(device
);
229 } else if (strncasecmp(tagbuf
, "partition", 9) == 0) {
230 strcpy(bootscript
+ scriptlen
, partition
);
231 scriptlen
+= strlen(partition
);
232 } else if (strncasecmp(tagbuf
, "directory", 9) == 0) {
233 strcpy(bootscript
+ scriptlen
, directory
);
234 scriptlen
+= strlen(directory
);
235 } else if (strncasecmp(tagbuf
, "filename", 8) == 0) {
236 strcpy(bootscript
+ scriptlen
, filename
);
237 scriptlen
+= strlen(filename
);
238 } else if (strncasecmp(tagbuf
, "full-path", 9) == 0) {
239 strcpy(bootscript
+ scriptlen
, bootpath
);
240 scriptlen
+= strlen(bootpath
);
241 } else { /* unknown, keep it */
242 bootscript
[scriptlen
] = '&';
243 strcpy(bootscript
+ scriptlen
+ 1, tagbuf
);
244 scriptlen
+= taglen
+ 1;
245 bootscript
[scriptlen
] = ';';
248 } else if (entity
&& taglen
< sizeof(tagbuf
)) {
249 tagbuf
[taglen
++] = c
;
250 } else if (script
&& scriptlen
< size
) {
251 bootscript
[scriptlen
++] = c
;
255 /* If the payload is bootinfo then we execute it immediately */
257 DPRINTF("bootscript: %s\n", bootscript
);
261 DPRINTF("Unable to parse bootinfo bootscript\n");