static int atag_arm_load(struct kexec_info *info, unsigned long base, const char *command_line, off_t command_line_len, const char *initrd, off_t initrd_len) { struct tag *saved_tags = atag_read_tags(); char *buf, *cmdline_buf; off_t len, cmdline_len = 0; struct tag *params; uint32_t *initrd_start; int i; buf = xmalloc(getpagesize()); if (!buf) { fprintf(stderr, "Compiling ATAGs: out of memory\n"); return -1; } cmdline_buf = xmalloc(COMMAND_LINE_SIZE); if (!cmdline_buf) { fprintf(stderr, "Compiling Command line: out of memory\n"); return -1; } memset(buf, 0xff, getpagesize()); memset((void *)cmdline_buf, 0, COMMAND_LINE_SIZE); params = (struct tag *)buf; if (saved_tags) { // Copy tags saved_tags = (struct tag *) saved_tags; while(byte_size(saved_tags)) { switch (saved_tags->hdr.tag) { case ATAG_INITRD: case ATAG_INITRD2: case ATAG_NONE: // skip these tags break; case ATAG_CMDLINE: cmdline_len = strlen(saved_tags->u.cmdline.cmdline) + 1; if(cmdline_len > COMMAND_LINE_SIZE) die("Command line overflow\n"); strncpy(cmdline_buf, saved_tags->u.cmdline.cmdline, COMMAND_LINE_SIZE); cmdline_buf[COMMAND_LINE_SIZE - 1] = '\0'; break; default: // copy all other tags memcpy(params, saved_tags, byte_size(saved_tags)); params = tag_next(params); } saved_tags = tag_next(saved_tags); } } else { params->hdr.size = 2; params->hdr.tag = ATAG_CORE; params = tag_next(params); } if (initrd) { params->hdr.size = tag_size(tag_initrd); params->hdr.tag = ATAG_INITRD2; initrd_start = ¶ms->u.initrd.start; params->u.initrd.size = initrd_len; params = tag_next(params); } if (command_line) { command_line_len = command_line_len + cmdline_len -1; if(command_line_len > COMMAND_LINE_SIZE) die("Command line overflow\n"); strncat(cmdline_buf, command_line, COMMAND_LINE_SIZE - 1); params->hdr.size = (sizeof(struct tag_header) + command_line_len + 3) >> 2; params->hdr.tag = ATAG_CMDLINE; memcpy(params->u.cmdline.cmdline, cmdline_buf, command_line_len); params->u.cmdline.cmdline[command_line_len - 1] = '\0'; params = tag_next(params); } params->hdr.size = 0; params->hdr.tag = ATAG_NONE; len = ((char *)params - buf) + sizeof(struct tag_header); add_segment(info, buf, len, base, len); if (initrd) { struct memory_range *range; int ranges; get_memory_ranges(&range, &ranges, info->kexec_flags); for (i=0; range[i].start; i++) { printf("Memory Ranges: range[%d].start = 0x%x\n", i, range[i].start); } //*initrd_start = locate_hole(info, initrd_len, getpagesize(), range[0].start + 0x800000, ULONG_MAX, INT_MAX); /* Allocate memory from 0x400000 offset from start of capture kernel*/ if (range[ranges-1].start > 0) *initrd_start = range[ranges-1].start + 0x400000; printf("*initrd_start = %p\n", *initrd_start); if (*initrd_start == ULONG_MAX) return -1; add_segment(info, initrd, initrd_len, *initrd_start, initrd_len); } return 0; }
static int atag_arm_load(struct kexec_info *info, unsigned long base, const char *command_line, off_t command_line_len, const char *initrd, off_t initrd_len, off_t initrd_off) { struct tag *saved_tags = atag_read_tags(); char *buf = NULL; size_t buf_size = 0; struct tag *params, *tag; uint32_t *initrd_start = NULL; params = xmalloc(getpagesize()); if (!params) { fprintf(stderr, "Compiling ATAGs: out of memory\n"); free(saved_tags); return -1; } memset(params, 0xff, getpagesize()); if (saved_tags) { // Copy tags tag = saved_tags; while(byte_size(tag)) { switch (tag->hdr.tag) { case ATAG_INITRD: case ATAG_INITRD2: case ATAG_CMDLINE: case ATAG_NONE: // skip these tags break; default: // copy all other tags tag_buf_add(tag, &buf, &buf_size); break; } tag = tag_next(tag); } free(saved_tags); } else { params->hdr.size = 2; params->hdr.tag = ATAG_CORE; tag_buf_add(params, &buf, &buf_size); memset(params, 0xff, byte_size(params)); } if (initrd) { params->hdr.size = tag_size(tag_initrd); params->hdr.tag = ATAG_INITRD2; params->u.initrd.size = initrd_len; tag_buf_add(params, &buf, &buf_size); memset(params, 0xff, byte_size(params)); } if (command_line) { params->hdr.size = (sizeof(struct tag_header) + command_line_len + 3) >> 2; params->hdr.tag = ATAG_CMDLINE; memcpy(params->u.cmdline.cmdline, command_line, command_line_len); params->u.cmdline.cmdline[command_line_len - 1] = '\0'; tag_buf_add(params, &buf, &buf_size); memset(params, 0xff, byte_size(params)); } params->hdr.size = 0; params->hdr.tag = ATAG_NONE; tag_buf_add(params, &buf, &buf_size); free(params); add_segment(info, buf, buf_size, base, buf_size); if (initrd) { initrd_start = tag_buf_find_initrd_start((struct tag *)buf); if(!initrd_start) { fprintf(stderr, "Failed to find initrd start!\n"); return -1; } *initrd_start = locate_hole(info, initrd_len, getpagesize(), initrd_off, ULONG_MAX, INT_MAX); if (*initrd_start == ULONG_MAX) return -1; add_segment(info, initrd, initrd_len, *initrd_start, initrd_len); } return 0; }
static int atag_arm_load(struct kexec_info *info, unsigned long base, const char *command_line, off_t command_line_len, const char *initrd, off_t initrd_len, off_t initrd_off) { struct tag *saved_tags = atag_read_tags(); char *buf; off_t len; struct tag *params; uint32_t *initrd_start = NULL; buf = xmalloc(getpagesize()); if (!buf) { fprintf(stderr, "Compiling ATAGs: out of memory\n"); return -1; } memset(buf, 0xff, getpagesize()); params = (struct tag *)buf; if (saved_tags) { // Copy tags saved_tags = (struct tag *) saved_tags; while(byte_size(saved_tags)) { switch (saved_tags->hdr.tag) { case ATAG_INITRD: case ATAG_INITRD2: case ATAG_CMDLINE: case ATAG_NONE: // skip these tags break; default: // copy all other tags memcpy(params, saved_tags, byte_size(saved_tags)); params = tag_next(params); } saved_tags = tag_next(saved_tags); } } else { params->hdr.size = 2; params->hdr.tag = ATAG_CORE; params = tag_next(params); } if (initrd) { params->hdr.size = tag_size(tag_initrd); params->hdr.tag = ATAG_INITRD2; initrd_start = ¶ms->u.initrd.start; params->u.initrd.size = initrd_len; params = tag_next(params); } if (command_line) { params->hdr.size = (sizeof(struct tag_header) + command_line_len + 3) >> 2; params->hdr.tag = ATAG_CMDLINE; memcpy(params->u.cmdline.cmdline, command_line, command_line_len); params->u.cmdline.cmdline[command_line_len - 1] = '\0'; params = tag_next(params); } params->hdr.size = 0; params->hdr.tag = ATAG_NONE; len = ((char *)params - buf) + sizeof(struct tag_header); add_segment(info, buf, len, base, len); if (initrd) { *initrd_start = locate_hole(info, initrd_len, getpagesize(), initrd_off, ULONG_MAX, INT_MAX); if (*initrd_start == ULONG_MAX) return -1; add_segment(info, initrd, initrd_len, *initrd_start, initrd_len); } return 0; }