void create_flatten_tree(char **bufp, off_t *sizep, const char *cmdline) { strcpy(pathname, "/proc/device-tree/"); pathstart = pathname + strlen(pathname); dt_cur_size = INIT_TREE_WORDS; dt_base = malloc(dt_cur_size*4); if (!dt_base) { die("Can't malloc %d bytes for dt struct!\n", dt_cur_size*4); } memset(dt_base, 0, dt_cur_size*4); dt = dt_base; if (cmdline) strcpy(local_cmdline, cmdline); putnode(); dt_reserve(&dt, 1); *dt++ = cpu_to_be32(9); add_boot_block(bufp, sizep); free(dt_base); }
void simpleinput(list *head) { list *temp; temp = findtable(head); if (temp != NULL) { temp->current = makevarnode(); putvar(&temp->head, &temp->tail, temp->current, head); temp->current->current = makedatanode(); putnode(&temp->current->head, &temp->current->tail, temp->current->current, head); } }
/* * put a node (directory) in the property structure. first properties * then children. */ static void putnode(void) { char *dn; struct dirent *dp; char *basename; struct dirent **namelist; int numlist, i; struct stat statbuf; int plen; numlist = scandir(pathname, &namelist, 0, comparefunc); if (numlist < 0) die("unrecoverable error: could not scan \"%s\": %s\n", pathname, strerror(errno)); if (numlist == 0) die("unrecoverable error: no directory entries in \"%s\"", pathname); basename = strrchr(pathname,'/') + 1; plen = *basename ? strlen(basename) : 0; /* Reserve space for string packed to words; e.g. string length 10 * occupies 3 words, length 12 occupies 4 (for terminating \0s). * So round up & include the \0: */ dt_reserve(&dt, 1+((plen + 4)/4)); *dt++ = cpu_to_be32(1); strcpy((void *)dt, *basename ? basename : ""); dt += ((plen + 4)/4); strcat(pathname, "/"); dn = pathname + strlen(pathname); putprops(dn, namelist, numlist); /* Add initrd entries to the second kernel */ if (initrd_base && initrd_size && !strcmp(basename,"chosen/")) { int len = 8; uint64_t bevalue; dt_reserve(&dt, 12); /* both props, of 6 words ea. */ *dt++ = cpu_to_be32(3); *dt++ = cpu_to_be32(len); *dt++ = cpu_to_be32(propnum("linux,initrd-start")); pad_structure_block(len); bevalue = cpu_to_be64(initrd_base); memcpy(dt, &bevalue, len); dt += (len + 3)/4; len = 8; *dt++ = cpu_to_be32(3); *dt++ = cpu_to_be32(len); *dt++ = cpu_to_be32(propnum("linux,initrd-end")); bevalue = cpu_to_be64(initrd_base + initrd_size); pad_structure_block(len); memcpy(dt, &bevalue, len); dt += (len + 3)/4; reserve(initrd_base, initrd_size); } /* Add cmdline to the second kernel. Check to see if the new * cmdline has a root=. If not, use the old root= cmdline. */ if (!strcmp(basename,"chosen/")) { size_t result; size_t cmd_len = 0; char *param = NULL; char filename[MAXPATH]; char *buff; int fd; cmd_len = strlen(local_cmdline); if (cmd_len != 0) { param = strstr(local_cmdline, "crashkernel="); if (param) crash_param = 1; /* does the new cmdline have a root= ? ... */ param = strstr(local_cmdline, "root="); } /* ... if not, grab root= from the old command line */ if (!param) { FILE *fp; char *last_cmdline = NULL; char *old_param; strcpy(filename, pathname); strcat(filename, "bootargs"); fp = fopen(filename, "r"); if (fp) { if (getline(&last_cmdline, &cmd_len, fp) == -1) die("unable to read %s\n", filename); param = strstr(last_cmdline, "root="); if (param) { old_param = strtok(param, " "); if (cmd_len != 0) strcat(local_cmdline, " "); strcat(local_cmdline, old_param); } } if (last_cmdline) free(last_cmdline); } strcat(local_cmdline, " "); cmd_len = strlen(local_cmdline); cmd_len = cmd_len + 1; /* add new bootargs */ dt_reserve(&dt, 4+((cmd_len+3)/4)); *dt++ = cpu_to_be32(3); *dt++ = cpu_to_be32(cmd_len); *dt++ = cpu_to_be32(propnum("bootargs")); pad_structure_block(cmd_len); memcpy(dt, local_cmdline,cmd_len); dt += (cmd_len + 3)/4; fprintf(stderr, "Modified cmdline:%s\n", local_cmdline); /* * Determine the platform type/stdout type, so that purgatory * code can print 'I'm in purgatory' message. Currently only * pseries/hvcterminal is supported. */ snprintf(filename, MAXPATH, "%slinux,stdout-path", pathname); fd = open(filename, O_RDONLY); if (fd == -1) { printf("Unable to find %s, printing from purgatory is diabled\n", filename); goto no_debug; } if (fstat(fd, &statbuf)) { printf("Unable to stat %s, printing from purgatory is diabled\n", filename); close(fd); goto no_debug; } buff = malloc(statbuf.st_size); if (!buff) { printf("Can not allocate memory for buff\n"); close(fd); goto no_debug; } result = read(fd, buff, statbuf.st_size); close(fd); if (result <= 0) { printf("Unable to read %s, printing from purgatory is diabled\n", filename); goto no_debug; } snprintf(filename, MAXPATH, "/proc/device-tree/%s/compatible", buff); fd = open(filename, O_RDONLY); if (fd == -1) { printf("Unable to find %s printing from purgatory is diabled\n", filename); goto no_debug; } if (fstat(fd, &statbuf)) { printf("Unable to stat %s printing from purgatory is diabled\n", filename); close(fd); goto no_debug; } buff = realloc(buff, statbuf.st_size); if (!buff) { printf("Can not allocate memory for buff\n"); close(fd); goto no_debug; } result = read(fd, buff, statbuf.st_size); if (result && (!strcmp(buff, "hvterm1") || !strcmp(buff, "hvterm-protocol"))) my_debug = 1; close(fd); free(buff); } no_debug: for (i=0; i < numlist; i++) { dp = namelist[i]; strcpy(dn, dp->d_name); free(namelist[i]); if (!strcmp(dn, ".") || !strcmp(dn, "..")) continue; if (lstat(pathname, &statbuf)) die("unrecoverable error: could not stat \"%s\": %s\n", pathname, strerror(errno)); if (S_ISDIR(statbuf.st_mode)) putnode(); } dt_reserve(&dt, 1); *dt++ = cpu_to_be32(2); dn[-1] = '\0'; free(namelist); }