Annotation of qemu/roms/openbios/libopenbios/bootinfo_load.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *
                      3:  *       <bootinfo_load.c>
                      4:  *
                      5:  *       bootinfo file loader
                      6:  *
                      7:  *   Copyright (C) 2009 Laurent Vivier ([email protected])
                      8:  *
                      9:  *   Original XML parser by Blue Swirl <[email protected]>
                     10:  *
                     11:  *   This program is free software; you can redistribute it and/or
                     12:  *   modify it under the terms of the GNU General Public License
                     13:  *   version 2
                     14:  *
                     15:  */
                     16: 
                     17: #include "config.h"
                     18: #include "libopenbios/bindings.h"
                     19: #include "libopenbios/bootinfo_load.h"
                     20: #include "libopenbios/ofmem.h"
                     21: #include "libc/vsprintf.h"
                     22: 
                     23: //#define DEBUG_BOOTINFO
                     24: 
                     25: #ifdef DEBUG_BOOTINFO
                     26: #define DPRINTF(fmt, args...) \
                     27:     do { printk("%s: " fmt, __func__ , ##args); } while (0)
                     28: #else
                     29: #define DPRINTF(fmt, args...) \
                     30:     do { } while (0)
                     31: #endif
                     32: 
                     33: static char *
                     34: get_device( const char *path )
                     35: {
                     36:        int i;
                     37:        static char buf[1024];
                     38: 
                     39:        for (i = 0; i < sizeof(buf) && path[i] && path[i] != ':'; i++)
                     40:                buf[i] = path[i];
                     41:        buf[i] = 0;
                     42: 
                     43:        return buf;
                     44: }
                     45: 
                     46: static char *
                     47: get_partition( const char *path )
                     48: {
                     49:        static char buf[2];
                     50: 
                     51:        buf[0] = '\0';
                     52:        buf[1] = '\0';
                     53: 
                     54:        while ( *path && *path != ':' )
                     55:                path++;
                     56: 
                     57:        if (!*path)
                     58:                return buf;
                     59:        path++;
                     60: 
                     61:        if (path[0] == ',' || !strchr(path, ',')) /* if there is not a ',' or no partition id then return */
                     62:                return buf;
                     63: 
                     64:        /* Must be a partition id */
                     65:        buf[0] = path[0];
                     66: 
                     67:        return buf;
                     68: }
                     69: 
                     70: static char *
                     71: get_filename( const char * path , char **dirname)
                     72: {
                     73:         static char buf[1024];
                     74:         char *filename;
                     75: 
                     76:         while ( *path && *path != ':' )
                     77:                 path++;
                     78: 
                     79:         if (!*path) {
                     80:                 *dirname = NULL;
                     81:                 return NULL;
                     82:         }
                     83:         path++;
                     84: 
                     85:         while ( *path && isdigit(*path) )
                     86:                 path++;
                     87: 
                     88:         if (*path == ',')
                     89:                 path++;
                     90: 
                     91:         strncpy(buf, path, sizeof(buf));
                     92:         buf[sizeof(buf) - 1] = 0;
                     93: 
                     94:         filename = strrchr(buf, '\\');
                     95:         if (filename) {
                     96:                 *dirname = buf;
                     97:                 (*filename++) = 0;
                     98:         } else {
                     99:                 *dirname = NULL;
                    100:                 filename = buf;
                    101:         }
                    102: 
                    103:         return filename;
                    104: }
                    105: 
                    106: int
                    107: is_bootinfo(char *bootinfo)
                    108: {
                    109:        return (strncasecmp(bootinfo, "<chrp-boot", 10) ? 0 : -1);
                    110: }
                    111: 
                    112: int 
                    113: bootinfo_load(struct sys_info *info, const char *filename)
                    114: {
                    115:        // Currently not implemented
                    116:        return LOADER_NOT_SUPPORT;
                    117: }
                    118: 
                    119: /*
                    120:   Parse SGML structure like:
                    121:   <chrp-boot>
                    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>
                    126: 
                    127:   CHRP system bindings are described at:
                    128:   http://playground.sun.com/1275/bindings/chrp/chrp1_7a.ps
                    129: */
                    130: 
                    131: void
                    132: bootinfo_init_program(void)
                    133: {
                    134:        char *base;
                    135:        int proplen;
                    136:        phandle_t chosen;
                    137:        int tag, taglen, script, scriptlen, scriptvalid, entity, chrp;
                    138:        char tagbuf[128], c;
                    139:        char *device, *filename, *directory, *partition;
                    140:        int current, size;
                    141:        char *bootscript;
                    142:         char *tmp;
                    143:        char bootpath[1024];
                    144: 
                    145:        /* Parse the boot script */
                    146: 
                    147:        chosen = find_dev("/chosen");
                    148:        tmp = get_property(chosen, "bootpath", &proplen);
                    149:        memcpy(bootpath, tmp, proplen);
                    150:        bootpath[proplen] = 0;
                    151: 
                    152:        DPRINTF("bootpath %s\n", bootpath);
                    153: 
                    154:        device = get_device(bootpath);
                    155:        partition = get_partition(bootpath);
                    156:        filename = get_filename(bootpath, &directory);
                    157: 
                    158:        feval("load-base");
                    159:        base = (char*)cell2pointer(POP());
                    160: 
                    161:        feval("load-size");
                    162:        size = POP();
                    163: 
                    164:        bootscript = malloc(size);
                    165:        if (bootscript == NULL) {
                    166:                DPRINTF("Can't malloc %d bytes\n", size);
                    167:                return;
                    168:        }
                    169: 
                    170:        if (!is_bootinfo(base)) {
                    171:                DPRINTF("Not a valid bootinfo memory image\n");
                    172:                 free(bootscript);
                    173:                return;
                    174:        }
                    175: 
                    176:        chrp = 0;
                    177:        tag = 0;
                    178:        taglen = 0;
                    179:        script = 0;
                    180:        scriptvalid = 0;
                    181:        scriptlen = 0;
                    182:        entity = 0;
                    183:        current = 0;
                    184:        while (current < size) {
                    185: 
                    186:                c = base[current++];
                    187: 
                    188:                if (c == '<') {
                    189:                        script = 0;
                    190:                        tag = 1;
                    191:                        taglen = 0;
                    192:                } else if (c == '>') {
                    193:                        tag = 0;
                    194:                        tagbuf[taglen] = '\0';
                    195:                        if (strncasecmp(tagbuf, "chrp-boot", 9) == 0) {
                    196:                                chrp = 1;
                    197:                        } else if (chrp == 1) {
                    198:                                if (strncasecmp(tagbuf, "boot-script", 11) == 0) {
                    199:                                        script = 1;
                    200:                                        scriptlen = 0;
                    201:                                } else if (strncasecmp(tagbuf, "/boot-script", 12) == 0) {
                    202: 
                    203:                                        script = 0;
                    204:                                        bootscript[scriptlen] = '\0';
                    205: 
                    206:                                        DPRINTF("got bootscript %s\n",
                    207:                                                bootscript);
                    208: 
                    209:                                        scriptvalid = -1;
                    210: 
                    211:                                        break;
                    212:                                } else if (strncasecmp(tagbuf, "/chrp-boot", 10) == 0)
                    213:                                        break;
                    214:                        }
                    215:                } else if (tag && taglen < sizeof(tagbuf)) {
                    216:                        tagbuf[taglen++] = c;
                    217:                } else if (script && c == '&') {
                    218:                        entity = 1;
                    219:                        taglen = 0;
                    220:                } else if (entity && c ==';') {
                    221:                        entity = 0;
                    222:                        tagbuf[taglen] = '\0';
                    223:                        if (strncasecmp(tagbuf, "lt", 2) == 0) {
                    224:                                bootscript[scriptlen++] = '<';
                    225:                        } else if (strncasecmp(tagbuf, "gt", 2) == 0) {
                    226:                                bootscript[scriptlen++] = '>';
                    227:                        } else if (strncasecmp(tagbuf, "device", 6) == 0) {
                    228:                                strcpy(bootscript + scriptlen, device);
                    229:                                scriptlen += strlen(device);
                    230:                        } else if (strncasecmp(tagbuf, "partition", 9) == 0) {
                    231:                                strcpy(bootscript + scriptlen, partition);
                    232:                                scriptlen += strlen(partition);
                    233:                        } else if (strncasecmp(tagbuf, "directory", 9) == 0) {
                    234:                                strcpy(bootscript + scriptlen, directory);
                    235:                                scriptlen += strlen(directory);
                    236:                        } else if (strncasecmp(tagbuf, "filename", 8) == 0) {
                    237:                                strcpy(bootscript + scriptlen, filename);
                    238:                                scriptlen += strlen(filename);
                    239:                        } else if (strncasecmp(tagbuf, "full-path", 9) == 0) {
                    240:                                strcpy(bootscript + scriptlen, bootpath);
                    241:                                scriptlen += strlen(bootpath);
                    242:                        } else { /* unknown, keep it */
                    243:                                bootscript[scriptlen] = '&';
                    244:                                strcpy(bootscript + scriptlen + 1, tagbuf);
                    245:                                scriptlen += taglen + 1;
                    246:                                bootscript[scriptlen] = ';';
                    247:                                scriptlen++;
                    248:                        }
                    249:                } else if (entity && taglen < sizeof(tagbuf)) {
                    250:                        tagbuf[taglen++] = c;
                    251:                } else if (script && scriptlen < size) {
                    252:                        bootscript[scriptlen++] = c;
                    253:                }
                    254:        }
                    255: 
                    256:        /* If the payload is bootinfo then we execute it immediately */
                    257:        if (scriptvalid) {
                    258:                DPRINTF("bootscript: %s\n", bootscript);
                    259:                feval(bootscript);
                    260:        }
                    261:        else
                    262:                DPRINTF("Unable to parse bootinfo bootscript\n");
                    263: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.