void write_sff_read_header(FILE *fp, sff_read_header *rh) { int header_size; char *name; uint16_t header_len = be16toh(rh->header_len); uint16_t name_len = be16toh(rh->name_len); uint32_t nbases = be32toh(rh->nbases); uint16_t clip_qual_left = be16toh(rh->clip_qual_left); uint16_t clip_qual_right = be16toh(rh->clip_qual_right); uint16_t clip_adapter_left = be16toh(rh->clip_adapter_left); uint16_t clip_adapter_right = be16toh(rh->clip_adapter_right); name = rh->name; fwrite(&header_len , sizeof(uint16_t), 1, fp); fwrite(&name_len , sizeof(uint16_t), 1, fp); fwrite(&nbases , sizeof(uint32_t), 1, fp); fwrite(&clip_qual_left , sizeof(uint16_t), 1, fp); fwrite(&clip_qual_right , sizeof(uint16_t), 1, fp); fwrite(&clip_adapter_left , sizeof(uint16_t), 1, fp); fwrite(&clip_adapter_right, sizeof(uint16_t), 1, fp); fwrite(name, sizeof(char), rh->name_len, fp); /* the section should be a multiple of 8-bytes, if not, it is zero-byte padded to make it so */ header_size = sizeof(rh->header_len) + sizeof(rh->name_len) + sizeof(rh->nbases) + sizeof(rh->clip_qual_left) + sizeof(rh->clip_qual_right) + sizeof(rh->clip_adapter_left) + sizeof(rh->clip_adapter_right) + (sizeof(char) * rh->name_len); if ( !(header_size % PADDING_SIZE == 0) ) { write_padding(fp, header_size); } }
static void write_finalize( filter_t *p_filter, uint16_t i_data_type, uint8_t i_length_mul ) { filter_sys_t *p_sys = p_filter->p_sys; assert( p_sys->p_out_buf != NULL ); uint8_t *p_out = p_sys->p_out_buf->p_buffer; /* S/PDIF header */ if( i_data_type != 0 ) { assert( p_sys->i_out_offset > SPDIF_HEADER_SIZE ); assert( i_length_mul == 1 || i_length_mul == 8 ); set_16( p_filter, &p_out[0], 0xf872 ); /* syncword 1 */ set_16( p_filter, &p_out[2], 0x4e1f ); /* syncword 2 */ set_16( p_filter, &p_out[4], i_data_type ); /* data type */ /* length in bits or bytes */ set_16( p_filter, &p_out[6], ( p_sys->i_out_offset - SPDIF_HEADER_SIZE ) * i_length_mul ); } /* 0 padding */ if( p_sys->i_out_offset < p_sys->p_out_buf->i_buffer ) write_padding( p_filter, p_sys->p_out_buf->i_buffer - p_sys->i_out_offset ); }
static ptrdiff_t write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags) { uint8_t *cur = buf; uint32_t iseq_no; cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */ cur += write_padding(cur); switch (flags & DUMP_ENDIAN_NAT) { case DUMP_ENDIAN_BIG: if (bigendian_p()) goto native; for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ } break; case DUMP_ENDIAN_LIL: if (!bigendian_p()) goto native; for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { cur += uint32l_to_bin(irep->iseq[iseq_no], cur); /* opcode */ } break; native: case DUMP_ENDIAN_NAT: memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); cur += irep->ilen * sizeof(mrb_code); break; } return cur - buf; }
int main(int argc, const char* argv[]) { if(argc <= 2) { printf("\nADF trackloader creator\n\n"); printf(" Usage: %s <output adf> <bootblock> [<files>]\n\n", argv[0]); exit(0); } FILE *adf_file = fopen(argv[1], "wb"); if(!adf_file) { fputs("ADF file error", stderr); exit(0); } unsigned int file_size = 0; file_size += write_bootblock(adf_file, argv[2]); for(int i = 3; i < argc; i++) { file_size += write_file(adf_file, argv[i]); } if(file_size < DISK_SIZE) { write_padding(adf_file, file_size); } }
void write_print(michet_t *michet, char *text_to_print, size_t len) { uint8_t instruction; // mov edx, len write_instruction(michet->fp, MOV+EDX); write_instruction(michet->fp, len); write_padding(michet->fp); // mov ecx, 0xA0 write_instruction(michet->fp, MOV+ECX); write_instruction(michet->fp, 0xA0); // 0xA0 is the address where the string starts // Unknown bits write_instruction(michet->fp, 0x90); write_instruction(michet->fp, 0x04); write_instruction(michet->fp, 0x08); // mov ebx, 1 write_instruction(michet->fp, MOV+EBX); write_instruction(michet->fp, 0x01); write_padding(michet->fp); // mov eax, 4 write_instruction(michet->fp, MOV+EAX); write_instruction(michet->fp, 0x04); write_padding(michet->fp); // int 0x80 write_instruction(michet->fp, INT); write_instruction(michet->fp, 0x80); // mov eax, 1 write_instruction(michet->fp, MOV+EAX); write_instruction(michet->fp, 0x01); write_padding(michet->fp); // int 0x80 write_instruction(michet->fp, INT); write_instruction(michet->fp, 0x80); write_padding(michet->fp); fwrite(text_to_print, len, 1, michet->fp); fflush(michet->fp); }
/* Adapted from libavformat/spdifenc.c: */ static int write_buffer_dtshd( filter_t *p_filter, block_t *p_in_buf ) { static const char p_dtshd_start_code[10] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe }; static const size_t i_dtshd_start_code = sizeof( p_dtshd_start_code ); filter_sys_t *p_sys = p_filter->p_sys; vlc_dts_header_t core; if( vlc_dts_header_Parse( &core, p_in_buf->p_buffer, p_in_buf->i_buffer ) != VLC_SUCCESS ) return SPDIF_ERROR; unsigned i_period = p_filter->fmt_out.audio.i_rate * core.i_frame_length / core.i_rate; int i_subtype = dtshd_get_subtype( i_period ); if( i_subtype == -1 ) return SPDIF_ERROR; size_t i_in_size = i_dtshd_start_code + 2 + p_in_buf->i_buffer; size_t i_out_size = i_period * 4; uint16_t i_data_type = IEC61937_DTSHD | i_subtype << 8; if( p_filter->p_sys->dtshd.b_skip || i_in_size + SPDIF_HEADER_SIZE > i_out_size ) { /* The bitrate is too high, pass only the core part */ p_in_buf->i_buffer = core.i_frame_size; i_in_size = i_dtshd_start_code + 2 + p_in_buf->i_buffer; if( i_in_size + SPDIF_HEADER_SIZE > i_out_size ) return SPDIF_ERROR; /* Don't try to send substreams anymore. That way, we avoid to switch * back and forth between DTD and DTS-HD */ p_filter->p_sys->dtshd.b_skip = true; } if( write_init( p_filter, p_in_buf, i_out_size, i_out_size / p_filter->fmt_out.audio.i_bytes_per_frame ) ) return SPDIF_ERROR; write_data( p_filter, p_dtshd_start_code, i_dtshd_start_code, true ); write_16( p_filter, p_in_buf->i_buffer ); write_buffer( p_filter, p_in_buf ); /* Align so that (length_code & 0xf) == 0x8. This is reportedly needed * with some receivers, but the exact requirement is unconfirmed. */ #define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1)) size_t i_align = ALIGN( i_in_size + 0x8, 0x10 ) - 0x8; #undef ALIGN if( i_align > i_in_size && i_align - i_in_size <= p_sys->p_out_buf->i_buffer - p_sys->i_out_offset ) write_padding( p_filter, i_align - i_in_size ); write_finalize( p_filter, i_data_type, 1 /* in bytes */ ); return SPDIF_SUCCESS; }
/* CPIO voodoo. */ static void cpio_append_trailer (void) { struct stat statbuf; memset (&statbuf, 0, sizeof statbuf); statbuf.st_nlink = 1; cpio_append_stat ("TRAILER!!!", &statbuf); /* CPIO seems to pad up to the next block boundary, ie. up to * the next 512 bytes. */ write_padding (((out_offset + 511) & ~511) - out_offset); assert ((out_offset & 511) == 0); }
gboolean ostree_write_variant_with_size (GOutputStream *output, GVariant *variant, guint64 alignment_offset, gsize *out_bytes_written, GChecksum *checksum, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint64 variant_size; guint32 variant_size_u32_be; gsize bytes_written; gsize ret_bytes_written = 0; /* Write variant size */ variant_size = g_variant_get_size (variant); g_assert (variant_size < G_MAXUINT32); variant_size_u32_be = GUINT32_TO_BE((guint32) variant_size); bytes_written = 0; if (!ot_gio_write_update_checksum (output, &variant_size_u32_be, 4, &bytes_written, checksum, cancellable, error)) goto out; ret_bytes_written += bytes_written; alignment_offset += bytes_written; bytes_written = 0; /* Pad to offset of 8, write variant */ if (!write_padding (output, 8, alignment_offset, &bytes_written, checksum, cancellable, error)) goto out; ret_bytes_written += bytes_written; bytes_written = 0; if (!ot_gio_write_update_checksum (output, g_variant_get_data (variant), variant_size, &bytes_written, checksum, cancellable, error)) goto out; ret_bytes_written += bytes_written; ret = TRUE; if (out_bytes_written) *out_bytes_written = ret_bytes_written; out: return ret; }
void write_sff_read_data(FILE *fp, sff_read_data *rd, uint16_t nflows, uint32_t nbases) { int data_size; int i; /* read from the sff file and assign to sff_read_data */ fwrite(rd->flowgram, sizeof(uint16_t), (size_t) nflows, fp); fwrite(rd->flow_index, sizeof(uint8_t), (size_t) nbases, fp); fwrite(rd->bases, sizeof(char), (size_t) nbases, fp); fwrite(rd->quality, sizeof(uint8_t), (size_t) nbases, fp); /* the section should be a multiple of 8-bytes, if not, it is zero-byte padded to make it so */ data_size = (sizeof(uint16_t) * nflows) // flowgram size + (sizeof(uint8_t) * nbases) // flow_index size + (sizeof(char) * nbases) // bases size + (sizeof(uint8_t) * nbases); // quality size if ( !(data_size % PADDING_SIZE == 0) ) { write_padding(fp, data_size); } }
static int init() { struct resource *p; int err = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) resource_size_t p_last = -1; #else __PTRDIFF_TYPE__ p_last = -1; #endif DBG("Initilizing Dump..."); if((err = setup())) { DBG("Setup Error"); cleanup(); return err; } for (p = iomem_resource.child; p ; p = p->sibling) { if (strcmp(p->name, LIME_RAMSTR)) continue; if (mode == LIME_MODE_LIME && (err = write_lime_header(p))) { DBG("Error writing header 0x%lx - 0x%lx", (long) p->start, (long) p->end); break; } else if (mode == LIME_MODE_PADDED && (err = write_padding((size_t) ((p->start - 1) - p_last)))) { DBG("Error writing padding 0x%lx - 0x%lx", (long) p_last, (long) p->start - 1); break; } if ((err = write_range(p))) { DBG("Error writing range 0x%lx - 0x%lx", (long) p->start, (long) p->end); break; } p_last = p->end; } cleanup(); return err; }
/* F U N C T I O N S *********************************************************/ void write_sff_common_header(FILE *fp, sff_common_header *h) { int header_size; uint32_t magic = be32toh(h->magic); uint64_t index_offset = be64toh(h->index_offset); uint32_t index_len = be32toh(h->index_len); uint32_t nreads = be32toh(h->nreads); uint16_t header_len = be16toh(h->header_len); uint16_t key_len = be16toh(h->key_len); uint16_t flow_len = be16toh(h->flow_len); fwrite(&magic , sizeof(uint32_t), 1, fp); fwrite(&(h->version) , sizeof(char) , 4, fp); fwrite(&index_offset , sizeof(uint64_t), 1, fp); fwrite(&index_len , sizeof(uint32_t), 1, fp); fwrite(&nreads , sizeof(uint32_t), 1, fp); fwrite(&header_len , sizeof(uint16_t), 1, fp); fwrite(&key_len , sizeof(uint16_t), 1, fp); fwrite(&flow_len , sizeof(uint16_t), 1, fp); fwrite(&(h->flowgram_format), sizeof(uint8_t) , 1, fp); fwrite(h->flow, sizeof(char), h->flow_len, fp); fwrite(h->key , sizeof(char), h->key_len , fp); /* the common header section should be a multiple of 8-bytes if the header is not, it is zero-byte padded to make it so */ header_size = sizeof(h->magic) + sizeof(*(h->version))*4 + sizeof(h->index_offset) + sizeof(h->index_len) + sizeof(h->nreads) + sizeof(h->header_len) + sizeof(h->key_len) + sizeof(h->flow_len) + sizeof(h->flowgram_format) + (sizeof(char) * h->flow_len) + (sizeof(char) * h->key_len); if ( !(header_size % PADDING_SIZE == 0) ) { write_padding(fp, header_size); } }
static int write_range(struct resource * res) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) resource_size_t i, is; #else __PTRDIFF_TYPE__ i, is; #endif struct page * p; void * v; int s; for (i = res->start; i <= res->end; i += is) { p = pfn_to_page((i) >> PAGE_SHIFT); is = min((size_t) PAGE_SIZE, (size_t) (res->end - i + 1)); if (is < PAGE_SIZE) { // We can't map partial pages and // the linux kernel doesn't use them anyway DBG("Padding partial page: vaddr %p size: %lu", (void *) i, is); write_padding(is); } else { v = kmap(p); s = write_vaddr(v, is); kunmap(p); if (s != is) { DBG("Error writing page: vaddr %p ret: %d", v, s); return (int) s; } } } return 0; }
static void cpio_append_stat (const char *filename, const struct stat *statbuf) { const char *orig_filename = filename; if (*filename == '/') filename++; if (*filename == '\0') filename = "."; if (verbose >= 2) fprintf (stderr, "cpio_append_stat %s 0%o -> %d\n", orig_filename, statbuf->st_mode, out_fd); /* Regular files and symlinks are the only ones that have a "body" * in this cpio entry. */ int has_body = S_ISREG (statbuf->st_mode) || S_ISLNK (statbuf->st_mode); size_t len = strlen (filename) + 1; char header[CPIO_HEADER_LEN + 1]; snprintf (header, sizeof header, "070701" /* magic */ "%08X" /* inode */ "%08X" /* mode */ "%08X" "%08X" /* uid, gid */ "%08X" /* nlink */ "%08X" /* mtime */ "%08X" /* file length */ "%08X" "%08X" /* device holding file major, minor */ "%08X" "%08X" /* for specials, device major, minor */ "%08X" /* name length (including \0 byte) */ "%08X", /* checksum (not used by the kernel) */ (unsigned) statbuf->st_ino, statbuf->st_mode, statbuf->st_uid, statbuf->st_gid, (unsigned) statbuf->st_nlink, (unsigned) statbuf->st_mtime, has_body ? (unsigned) statbuf->st_size : 0, major (statbuf->st_dev), minor (statbuf->st_dev), major (statbuf->st_rdev), minor (statbuf->st_rdev), (unsigned) len, 0); /* Write the header. */ write_to_fd (header, CPIO_HEADER_LEN); /* Follow with the filename, and pad it. */ write_to_fd (filename, len); size_t padding_len = PADDING (CPIO_HEADER_LEN + len); write_padding (padding_len); /* Follow with the file or symlink content, and pad it. */ if (has_body) { if (S_ISREG (statbuf->st_mode)) write_file_len_to_fd (orig_filename, statbuf->st_size); else if (S_ISLNK (statbuf->st_mode)) { char tmp[PATH_MAX]; if (readlink (orig_filename, tmp, sizeof tmp) == -1) error (EXIT_FAILURE, errno, "readlink: %s", orig_filename); write_to_fd (tmp, statbuf->st_size); } padding_len = PADDING (statbuf->st_size); write_padding (padding_len); } }
int main(int argc, char **argv) { boot_img_hdr hdr; char *kernel_fn = 0; void *kernel_data = 0; char *ramdisk_fn = 0; void *ramdisk_data = 0; char *second_fn = 0; void *second_data = 0; char *cmdline = ""; char *bootimg = 0; char *board = ""; unsigned pagesize = 2048; unsigned saddr = 0; int fd; SHA_CTX ctx; uint8_t* sha; argc--; argv++; memset(&hdr, 0, sizeof(hdr)); /* default load addresses */ hdr.kernel_addr = 0x10008000; hdr.ramdisk_addr = 0x11000000; hdr.second_addr = 0x10F00000; hdr.tags_addr = 0x10000100; hdr.page_size = pagesize; while(argc > 0){ char *arg = argv[0]; char *val = argv[1]; if(argc < 2) { return usage(); } argc -= 2; argv += 2; if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { bootimg = val; } else if(!strcmp(arg, "--kernel")) { kernel_fn = val; } else if(!strcmp(arg, "--ramdisk")) { ramdisk_fn = val; } else if(!strcmp(arg, "--second")) { second_fn = val; } else if(!strcmp(arg, "--cmdline")) { cmdline = val; } else if(!strcmp(arg, "--base")) { unsigned base = strtoul(val, 0, 16); hdr.kernel_addr = base + 0x00008000; hdr.ramdisk_addr = base + 0x01000000; hdr.second_addr = base + 0x00F00000; hdr.tags_addr = base + 0x00000100; } else if(!strcmp(arg, "--board")) { board = val; } else { return usage(); } } if(bootimg == 0) { fprintf(stderr,"error: no output filename specified\n"); return usage(); } if(kernel_fn == 0) { fprintf(stderr,"error: no kernel image specified\n"); return usage(); } if(ramdisk_fn == 0) { fprintf(stderr,"error: no ramdisk image specified\n"); return usage(); } if(strlen(board) >= BOOT_NAME_SIZE) { fprintf(stderr,"error: board name too large\n"); return usage(); } strcpy(hdr.name, board); #ifndef GENERIC hdr.kernel_addr = KERNEL_ADDR; hdr.ramdisk_addr = RAMDISK_ADDR; if(saddr) { hdr.second_addr = 0x00300000; } else { hdr.second_addr = SECONDARY_ADDR; } hdr.tags_addr = TAGS_ADDR; hdr.page_size = pagesize; #else hdr.kernel_addr = 0x208000; hdr.ramdisk_addr = 0x1200000; if(saddr) { hdr.second_addr = 0x00300000; } else { hdr.second_addr = 0x1100000; } hdr.tags_addr = 0x10000100; hdr.page_size = pagesize; #endif memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); if(strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) { fprintf(stderr,"error: kernel commandline too large\n"); return 1; } strcpy((char*)hdr.cmdline, cmdline); kernel_data = load_file(kernel_fn, &hdr.kernel_size); if(kernel_data == 0) { fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn); return 1; } if(!strcmp(ramdisk_fn,"NONE")) { ramdisk_data = 0; hdr.ramdisk_size = 0; } else { ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); if(ramdisk_data == 0) { fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn); return 1; } } if(second_fn) { second_data = load_file(second_fn, &hdr.second_size); if(second_data == 0) { fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn); return 1; } } /* put a hash of the contents in the header so boot images can be * differentiated based on their first 2k. */ SHA_init(&ctx); SHA_update(&ctx, kernel_data, hdr.kernel_size); SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size)); SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size); SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size)); SHA_update(&ctx, second_data, hdr.second_size); SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size)); sha = SHA_final(&ctx); memcpy(hdr.id, sha, SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); if(fd < 0) { fprintf(stderr,"error: could not create '%s'\n", bootimg); return 1; } if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; if(write_padding(fd, pagesize, sizeof(hdr))) goto fail; if(write_page_padding(fd, pagesize, sizeof(hdr))) goto fail; if(write(fd, kernel_data, hdr.kernel_size) != hdr.kernel_size) goto fail; if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail; if(write_page_padding(fd, pagesize, hdr.kernel_size)) goto fail; if(write(fd, ramdisk_data, hdr.ramdisk_size) != hdr.ramdisk_size) goto fail; if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; if(write_page_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; if(second_data) { if(write(fd, second_data, hdr.second_size) != hdr.second_size) goto fail; if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; if(write_page_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; } return 0; fail: unlink(bootimg); close(fd); fprintf(stderr,"error: failed writing '%s': %s\n", bootimg, strerror(errno)); return 1; }
int main(int argc, char **argv) { boot_img_hdr hdr; char *kernel_fn = 0; void *kernel_data = 0; char *ramdisk_fn = 0; void *ramdisk_data = 0; char *second_fn = 0; void *second_data = 0; char *cmdline = ""; char *bootimg = 0; char *board = ""; char *dt_fn = 0; void *dt_data = 0; unsigned pagesize = 2048; int fd; SHA_CTX ctx; uint8_t* sha; unsigned base = 0x10000000; unsigned kernel_offset = 0x00008000; unsigned ramdisk_offset = 0x01000000; unsigned second_offset = 0x00f00000; unsigned tags_offset = 0x00000100; argc--; argv++; memset(&hdr, 0, sizeof(hdr)); while(argc > 0){ char *arg = argv[0]; char *val = argv[1]; if(argc < 2) { return usage(); } argc -= 2; argv += 2; if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { bootimg = val; } else if(!strcmp(arg, "--kernel")) { kernel_fn = val; } else if(!strcmp(arg, "--ramdisk")) { ramdisk_fn = val; } else if(!strcmp(arg, "--second")) { second_fn = val; } else if(!strcmp(arg, "--cmdline")) { cmdline = val; } else if(!strcmp(arg, "--base")) { base = strtoul(val, 0, 16); } else if(!strcmp(arg, "--kernel_offset")) { kernel_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--ramdisk_offset")) { ramdisk_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--second_offset")) { second_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--tags_offset")) { tags_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--board")) { board = val; } else if(!strcmp(arg,"--pagesize")) { pagesize = strtoul(val, 0, 10); if ((pagesize != 2048) && (pagesize != 4096) && (pagesize != 8192) && (pagesize != 16384)) { fprintf(stderr,"error: unsupported page size %d\n", pagesize); return -1; } } else if(!strcmp(arg, "--dt")) { dt_fn = val; } else { return usage(); } } hdr.page_size = pagesize; hdr.kernel_addr = base + kernel_offset; hdr.ramdisk_addr = base + ramdisk_offset; hdr.second_addr = base + second_offset; hdr.tags_addr = base + tags_offset; if(bootimg == 0) { fprintf(stderr,"error: no output filename specified\n"); return usage(); } if(kernel_fn == 0) { fprintf(stderr,"error: no kernel image specified\n"); return usage(); } if(ramdisk_fn == 0) { fprintf(stderr,"error: no ramdisk image specified\n"); return usage(); } if(strlen(board) >= BOOT_NAME_SIZE) { fprintf(stderr,"error: board name too large\n"); return usage(); } strcpy(hdr.name, board); memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); if(strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) { fprintf(stderr,"error: kernel commandline too large\n"); return 1; } strcpy((char*)hdr.cmdline, cmdline); kernel_data = load_file(kernel_fn, &hdr.kernel_size); if(kernel_data == 0) { fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn); return 1; } if(!strcmp(ramdisk_fn,"NONE")) { ramdisk_data = 0; hdr.ramdisk_size = 0; } else { ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); if(ramdisk_data == 0) { fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn); return 1; } } if(second_fn) { second_data = load_file(second_fn, &hdr.second_size); if(second_data == 0) { fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn); return 1; } } if(dt_fn) { dt_data = load_file(dt_fn, &hdr.dt_size); if (dt_data == 0) { fprintf(stderr,"error: could not load device tree image '%s'\n", dt_fn); return 1; } } /* put a hash of the contents in the header so boot images can be * differentiated based on their first 2k. */ SHA_init(&ctx); SHA_update(&ctx, kernel_data, hdr.kernel_size); SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size)); SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size); SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size)); SHA_update(&ctx, second_data, hdr.second_size); SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size)); if(dt_data) { SHA_update(&ctx, dt_data, hdr.dt_size); SHA_update(&ctx, &hdr.dt_size, sizeof(hdr.dt_size)); } sha = SHA_final(&ctx); memcpy(hdr.id, sha, SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); if(fd < 0) { fprintf(stderr,"error: could not create '%s'\n", bootimg); return 1; } if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; if(write_padding(fd, pagesize, sizeof(hdr))) goto fail; if(write(fd, kernel_data, hdr.kernel_size) != hdr.kernel_size) goto fail; if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail; if(write(fd, ramdisk_data, hdr.ramdisk_size) != hdr.ramdisk_size) goto fail; if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; if(second_data) { if(write(fd, second_data, hdr.second_size) != hdr.second_size) goto fail; if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; } if(dt_data) { if(write(fd, dt_data, hdr.dt_size) != hdr.dt_size) goto fail; if(write_padding(fd, pagesize, hdr.dt_size)) goto fail; } return 0; fail: unlink(bootimg); close(fd); fprintf(stderr,"error: failed writing '%s': %s\n", bootimg, strerror(errno)); return 1; }
static bool do_join() { int i,bytes_to_skip,bytes_to_xfer; proc_info output_proc; char outfilename[FILENAME_SIZE]; wlong total=0; unsigned char header[CANONICAL_HEADER_SIZE]; FILE *output; wave_info *joined_info; bool success; progress_info proginfo; success = FALSE; create_output_filename("","",outfilename); for (i=0;i<numfiles;i++) total += files[i]->data_size; if (all_files_cd_quality && (total % CD_BLOCK_SIZE) != 0) { pad_bytes = CD_BLOCK_SIZE - (total % CD_BLOCK_SIZE); if (JOIN_NOPAD != pad_type) total += pad_bytes; } if (NULL == (joined_info = new_wave_info(NULL))) { st_error("could not allocate memory for joined file information"); } joined_info->chunk_size = total + CANONICAL_HEADER_SIZE - 8; joined_info->channels = files[0]->channels; joined_info->samples_per_sec = files[0]->samples_per_sec; joined_info->avg_bytes_per_sec = files[0]->avg_bytes_per_sec; joined_info->rate = files[0]->rate; joined_info->block_align = files[0]->block_align; joined_info->bits_per_sample = files[0]->bits_per_sample; joined_info->data_size = total; joined_info->wave_format = files[0]->wave_format; joined_info->problems = (files[0]->problems & PROBLEM_NOT_CD_QUALITY); if (PROB_ODD_SIZED_DATA(joined_info)) joined_info->chunk_size++; joined_info->total_size = joined_info->chunk_size + 8; joined_info->length = joined_info->data_size / joined_info->rate; joined_info->exact_length = (double)joined_info->data_size / (double)joined_info->rate; length_to_str(joined_info); proginfo.initialized = FALSE; proginfo.prefix = "Joining"; proginfo.clause = "-->"; proginfo.filename1 = files[0]->filename; proginfo.filedesc1 = files[0]->m_ss; proginfo.filename2 = outfilename; proginfo.filedesc2 = joined_info->m_ss; proginfo.bytes_total = files[0]->total_size; prog_update(&proginfo); if (NULL == (output = open_output_stream(outfilename,&output_proc))) { st_error("could not open output file"); } make_canonical_header(header,joined_info); if (write_n_bytes(output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) { prog_error(&proginfo); st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE); goto cleanup; } if (all_files_cd_quality && (JOIN_PREPAD == pad_type) && pad_bytes) { if (pad_bytes != write_padding(output,pad_bytes,&proginfo)) { prog_error(&proginfo); st_warning("error while pre-padding with %d zero-bytes",pad_bytes); goto cleanup; } } for (i=0;i<numfiles;i++) { proginfo.bytes_total = files[i]->total_size; proginfo.filename1 = files[i]->filename; proginfo.filedesc1 = files[i]->m_ss; prog_update(&proginfo); if (!open_input_stream(files[i])) { prog_error(&proginfo); st_warning("could not reopen input file"); goto cleanup; } bytes_to_skip = files[i]->header_size; while (bytes_to_skip > 0) { bytes_to_xfer = min(bytes_to_skip,CANONICAL_HEADER_SIZE); if (read_n_bytes(files[i]->input,header,bytes_to_xfer,NULL) != bytes_to_xfer) { prog_error(&proginfo); st_warning("error while reading %d bytes of data",bytes_to_xfer); goto cleanup; } bytes_to_skip -= bytes_to_xfer; } if (transfer_n_bytes(files[i]->input,output,files[i]->data_size,&proginfo) != files[i]->data_size) { prog_error(&proginfo); st_warning("error while transferring %lu bytes of data",files[i]->data_size); goto cleanup; } prog_success(&proginfo); close_input_stream(files[i]); } if (all_files_cd_quality && JOIN_POSTPAD == pad_type && pad_bytes) { if (pad_bytes != write_padding(output,pad_bytes,NULL)) { prog_error(&proginfo); st_warning("error while post-padding with %d zero-bytes",pad_bytes); goto cleanup; } } if ((JOIN_NOPAD == pad_type) && PROB_ODD_SIZED_DATA(joined_info) && (1 != write_padding(output,1,NULL))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } if (all_files_cd_quality) { if (JOIN_NOPAD != pad_type) { if (pad_bytes) st_info("%s-padded output file with %d zero-bytes.\n",((JOIN_PREPAD == pad_type)?"Pre":"Post"),pad_bytes); else st_info("No padding needed.\n"); } else { st_info("Output file was not padded, "); if (pad_bytes) st_info("though it needs %d bytes of padding.\n",pad_bytes); else st_info("nor was it needed.\n"); } } success = TRUE; cleanup: if ((CLOSE_CHILD_ERROR_OUTPUT == close_output(output,output_proc)) || !success) { success = FALSE; remove_file(outfilename); st_error("failed to join files"); } return success; }
int main(int argc, char *argv[]) { /* Any variable that begins with 't' means topocentric */ /* Any variable that begins with 'b' means barycentric */ FILE **outfiles = NULL; float **outdata; double dtmp, *dms, avgdm = 0.0, dsdt = 0, maxdm; double *dispdt, tlotoa = 0.0, blotoa = 0.0, BW_ddelay = 0.0; double max = -9.9E30, min = 9.9E30, var = 0.0, avg = 0.0; double *btoa = NULL, *ttoa = NULL, avgvoverc = 0.0; char obs[3], ephem[10], rastring[50], decstring[50]; long totnumtowrite, totwrote = 0, padwrote = 0, datawrote = 0; int *idispdt, **offsets; int ii, jj, numadded = 0, numremoved = 0, padding = 0, good_inputs = 1; int numbarypts = 0, numread = 0, numtowrite = 0; int padtowrite = 0, statnum = 0; int numdiffbins = 0, *diffbins = NULL, *diffbinptr = NULL, good_padvals = 0; double local_lodm; char *datafilenm, *outpath, *outfilenm, *hostname; struct spectra_info s; infodata idata; mask obsmask; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myid); #ifdef _OPENMP omp_set_num_threads(1); // Explicitly turn off OpenMP #endif set_using_MPI(); { FILE *hostfile; char tmpname[100]; int retval; hostfile = chkfopen("/etc/hostname", "r"); retval = fscanf(hostfile, "%s\n", tmpname); if (retval==0) { printf("Warning: error reading /etc/hostname on proc %d\n", myid); } hostname = (char *) calloc(strlen(tmpname) + 1, 1); memcpy(hostname, tmpname, strlen(tmpname)); fclose(hostfile); } /* Call usage() if we have no command line arguments */ if (argc == 1) { if (myid == 0) { Program = argv[0]; usage(); } MPI_Finalize(); exit(1); } make_maskbase_struct(); make_spectra_info_struct(); /* Parse the command line using the excellent program Clig */ cmd = parseCmdline(argc, argv); spectra_info_set_defaults(&s); // If we are zeroDMing, make sure that clipping is off. if (cmd->zerodmP) cmd->noclipP = 1; s.clip_sigma = cmd->clip; if (cmd->noclipP) { cmd->clip = 0.0; s.clip_sigma = 0.0; } if (cmd->ifsP) { // 0 = default or summed, 1-4 are possible also s.use_poln = cmd->ifs + 1; } if (!cmd->numoutP) cmd->numout = LONG_MAX; #ifdef DEBUG showOptionValues(); #endif if (myid == 0) { /* Master node only */ printf("\n\n"); printf(" Parallel Pulsar Subband De-dispersion Routine\n"); printf(" by Scott M. Ransom\n\n"); s.filenames = cmd->argv; s.num_files = cmd->argc; s.clip_sigma = cmd->clip; // -1 causes the data to determine if we use weights, scales, & // offsets for PSRFITS or flip the band for any data type where // we can figure that out with the data s.apply_flipband = (cmd->invertP) ? 1 : -1; s.apply_weight = (cmd->noweightsP) ? 0 : -1; s.apply_scale = (cmd->noscalesP) ? 0 : -1; s.apply_offset = (cmd->nooffsetsP) ? 0 : -1; s.remove_zerodm = (cmd->zerodmP) ? 1 : 0; if (RAWDATA) { if (cmd->filterbankP) s.datatype = SIGPROCFB; else if (cmd->psrfitsP) s.datatype = PSRFITS; else if (cmd->pkmbP) s.datatype = SCAMP; else if (cmd->bcpmP) s.datatype = BPP; else if (cmd->wappP) s.datatype = WAPP; else if (cmd->spigotP) s.datatype = SPIGOT; } else { // Attempt to auto-identify the data identify_psrdatatype(&s, 1); if (s.datatype==SIGPROCFB) cmd->filterbankP = 1; else if (s.datatype==PSRFITS) cmd->psrfitsP = 1; else if (s.datatype==SCAMP) cmd->pkmbP = 1; else if (s.datatype==BPP) cmd->bcpmP = 1; else if (s.datatype==WAPP) cmd->wappP = 1; else if (s.datatype==SPIGOT) cmd->spigotP = 1; else if (s.datatype==SUBBAND) insubs = 1; else { printf("\nError: Unable to identify input data files. Please specify type.\n\n"); good_inputs = 0; } } // So far we can only handle PSRFITS, filterbank, and subbands if (s.datatype!=PSRFITS && s.datatype!=SIGPROCFB && s.datatype!=SUBBAND) good_inputs = 0; // For subbanded data if (!RAWDATA) s.files = (FILE **)malloc(sizeof(FILE *) * s.num_files); if (good_inputs && (RAWDATA || insubs)) { char description[40]; psrdatatype_description(description, s.datatype); if (s.num_files > 1) printf("Reading %s data from %d files:\n", description, s.num_files); else printf("Reading %s data from 1 file:\n", description); for (ii = 0; ii < s.num_files; ii++) { printf(" '%s'\n", cmd->argv[ii]); if (insubs) s.files[ii] = chkfopen(s.filenames[ii], "rb"); } printf("\n"); if (RAWDATA) { read_rawdata_files(&s); print_spectra_info_summary(&s); spectra_info_to_inf(&s, &idata); } else { // insubs char *root, *suffix; cmd->nsub = s.num_files; s.N = chkfilelen(s.files[0], sizeof(short)); s.start_subint = gen_ivect(1); s.num_subint = gen_ivect(1); s.start_MJD = (long double *)malloc(sizeof(long double)); s.start_spec = (long long *)malloc(sizeof(long long)); s.num_spec = (long long *)malloc(sizeof(long long)); s.num_pad = (long long *)malloc(sizeof(long long)); s.start_spec[0] = 0L; s.start_subint[0] = 0; s.num_spec[0] = s.N; s.num_subint[0] = s.N / SUBSBLOCKLEN; s.num_pad[0] = 0L; s.padvals = gen_fvect(s.num_files); for (ii = 0 ; ii < ii ; ii++) s.padvals[ii] = 0.0; if (split_root_suffix(s.filenames[0], &root, &suffix) == 0) { printf("\nError: The input filename (%s) must have a suffix!\n\n", s.filenames[0]); exit(1); } if (strncmp(suffix, "sub", 3) == 0) { char *tmpname; tmpname = calloc(strlen(root) + 10, 1); sprintf(tmpname, "%s.sub", root); readinf(&idata, tmpname); free(tmpname); strncpy(s.telescope, idata.telescope, 40); strncpy(s.backend, idata.instrument, 40); strncpy(s.observer, idata.observer, 40); strncpy(s.source, idata.object, 40); s.ra2000 = hms2rad(idata.ra_h, idata.ra_m, idata.ra_s) * RADTODEG; s.dec2000 = dms2rad(idata.dec_d, idata.dec_m, idata.dec_s) * RADTODEG; ra_dec_to_string(s.ra_str, idata.ra_h, idata.ra_m, idata.ra_s); ra_dec_to_string(s.dec_str, idata.dec_d, idata.dec_m, idata.dec_s); s.num_channels = idata.num_chan; s.start_MJD[0] = idata.mjd_i + idata.mjd_f; s.dt = idata.dt; s.T = s.N * s.dt; s.lo_freq = idata.freq; s.df = idata.chan_wid; s.hi_freq = s.lo_freq + (s.num_channels - 1.0) * s.df; s.BW = s.num_channels * s.df; s.fctr = s.lo_freq - 0.5 * s.df + 0.5 * s.BW; s.beam_FWHM = idata.fov / 3600.0; s.spectra_per_subint = SUBSBLOCKLEN; print_spectra_info_summary(&s); } else { printf("\nThe input files (%s) must be subbands! (i.e. *.sub##)\n\n", cmd->argv[0]); MPI_Finalize(); exit(1); } free(root); free(suffix); } } } // If we don't have good input data, exit MPI_Bcast(&good_inputs, 1, MPI_INT, 0, MPI_COMM_WORLD); if (!good_inputs) { MPI_Finalize(); exit(1); } MPI_Bcast(&insubs, 1, MPI_INT, 0, MPI_COMM_WORLD); if (insubs) cmd->nsub = cmd->argc; /* Determine the output file names and open them */ local_numdms = cmd->numdms / (numprocs - 1); dms = gen_dvect(local_numdms); if (cmd->numdms % (numprocs - 1)) { if (myid == 0) printf ("\nThe number of DMs must be divisible by (the number of processors - 1).\n\n"); MPI_Finalize(); exit(1); } local_lodm = cmd->lodm + (myid - 1) * local_numdms * cmd->dmstep; split_path_file(cmd->outfile, &outpath, &outfilenm); datafilenm = (char *) calloc(strlen(outfilenm) + 20, 1); if (myid > 0) { if (chdir(outpath) == -1) { printf("\nProcess %d on %s cannot chdir() to '%s'. Exiting.\n\n", myid, hostname, outpath); MPI_Finalize(); exit(1); } outfiles = (FILE **) malloc(local_numdms * sizeof(FILE *)); for (ii = 0; ii < local_numdms; ii++) { dms[ii] = local_lodm + ii * cmd->dmstep; avgdm += dms[ii]; sprintf(datafilenm, "%s_DM%.2f.dat", outfilenm, dms[ii]); outfiles[ii] = chkfopen(datafilenm, "wb"); } avgdm /= local_numdms; } // Broadcast the raw data information broadcast_spectra_info(&s, myid); if (myid > 0) { spectra_info_to_inf(&s, &idata); if (s.datatype==SIGPROCFB) cmd->filterbankP = 1; else if (s.datatype==PSRFITS) cmd->psrfitsP = 1; else if (s.datatype==SCAMP) cmd->pkmbP = 1; else if (s.datatype==BPP) cmd->bcpmP = 1; else if (s.datatype==WAPP) cmd->wappP = 1; else if (s.datatype==SPIGOT) cmd->spigotP = 1; else if (s.datatype==SUBBAND) insubs = 1; } s.filenames = cmd->argv; /* Read an input mask if wanted */ if (myid > 0) { int numpad = s.num_channels; if (insubs) numpad = s.num_files; s.padvals = gen_fvect(numpad); for (ii = 0 ; ii < numpad ; ii++) s.padvals[ii] = 0.0; } if (cmd->maskfileP) { if (myid == 0) { read_mask(cmd->maskfile, &obsmask); printf("Read mask information from '%s'\n\n", cmd->maskfile); good_padvals = determine_padvals(cmd->maskfile, &obsmask, s.padvals); } broadcast_mask(&obsmask, myid); MPI_Bcast(&good_padvals, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(s.padvals, obsmask.numchan, MPI_FLOAT, 0, MPI_COMM_WORLD); } else { obsmask.numchan = obsmask.numint = 0; MPI_Bcast(&good_padvals, 1, MPI_INT, 0, MPI_COMM_WORLD); } // The number of topo to bary time points to generate with TEMPO numbarypts = (int) (s.T * 1.1 / TDT + 5.5) + 1; // Identify the TEMPO observatory code { char *outscope = (char *) calloc(40, sizeof(char)); telescope_to_tempocode(idata.telescope, outscope, obs); free(outscope); } // Broadcast or calculate a few extra important values if (insubs) avgdm = idata.dm; idata.dm = avgdm; dsdt = cmd->downsamp * idata.dt; maxdm = cmd->lodm + cmd->numdms * cmd->dmstep; BW_ddelay = delay_from_dm(maxdm, idata.freq) - delay_from_dm(maxdm, idata.freq + (idata.num_chan-1) * idata.chan_wid); blocksperread = ((int) (BW_ddelay / idata.dt) / s.spectra_per_subint + 1); worklen = s.spectra_per_subint * blocksperread; if (cmd->nsub > s.num_channels) { printf ("Warning: The number of requested subbands (%d) is larger than the number of channels (%d).\n", cmd->nsub, s.num_channels); printf(" Re-setting the number of subbands to %d.\n\n", s.num_channels); cmd->nsub = s.num_channels; } if (s.spectra_per_subint % cmd->downsamp) { if (myid == 0) { printf ("\nError: The downsample factor (%d) must be a factor of the\n", cmd->downsamp); printf(" blocklength (%d). Exiting.\n\n", s.spectra_per_subint); } MPI_Finalize(); exit(1); } tlotoa = idata.mjd_i + idata.mjd_f; /* Topocentric epoch */ if (cmd->numoutP) totnumtowrite = cmd->numout; else totnumtowrite = (long) idata.N / cmd->downsamp; if (cmd->nobaryP) { /* Main loop if we are not barycentering... */ /* Dispersion delays (in bins). The high freq gets no delay */ /* All other delays are positive fractions of bin length (dt) */ dispdt = subband_search_delays(s.num_channels, cmd->nsub, avgdm, idata.freq, idata.chan_wid, 0.0); idispdt = gen_ivect(s.num_channels); for (ii = 0; ii < s.num_channels; ii++) idispdt[ii] = NEAREST_LONG(dispdt[ii] / idata.dt); vect_free(dispdt); /* The subband dispersion delays (see note above) */ offsets = gen_imatrix(local_numdms, cmd->nsub); for (ii = 0; ii < local_numdms; ii++) { double *subdispdt; subdispdt = subband_delays(s.num_channels, cmd->nsub, dms[ii], idata.freq, idata.chan_wid, 0.0); dtmp = subdispdt[cmd->nsub - 1]; for (jj = 0; jj < cmd->nsub; jj++) offsets[ii][jj] = NEAREST_LONG((subdispdt[jj] - dtmp) / dsdt); vect_free(subdispdt); } /* Allocate our data array and start getting data */ if (myid == 0) { printf("De-dispersing using %d subbands.\n", cmd->nsub); if (cmd->downsamp > 1) printf("Downsampling by a factor of %d (new dt = %.10g)\n", cmd->downsamp, dsdt); printf("\n"); } /* Print the nodes and the DMs they are handling */ print_dms(hostname, myid, numprocs, local_numdms, dms); outdata = gen_fmatrix(local_numdms, worklen / cmd->downsamp); numread = get_data(outdata, blocksperread, &s, &obsmask, idispdt, offsets, &padding); while (numread == worklen) { numread /= cmd->downsamp; if (myid == 0) print_percent_complete(totwrote, totnumtowrite); /* Write the latest chunk of data, but don't */ /* write more than cmd->numout points. */ numtowrite = numread; if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout) numtowrite = cmd->numout - totwrote; if (myid > 0) { write_data(outfiles, local_numdms, outdata, 0, numtowrite); /* Update the statistics */ if (!padding) { for (ii = 0; ii < numtowrite; ii++) update_stats(statnum + ii, outdata[0][ii], &min, &max, &avg, &var); statnum += numtowrite; } } totwrote += numtowrite; /* Stop if we have written out all the data we need to */ if (cmd->numoutP && (totwrote == cmd->numout)) break; numread = get_data(outdata, blocksperread, &s, &obsmask, idispdt, offsets, &padding); } datawrote = totwrote; } else { /* Main loop if we are barycentering... */ /* What ephemeris will we use? (Default is DE405) */ strcpy(ephem, "DE405"); /* Define the RA and DEC of the observation */ ra_dec_to_string(rastring, idata.ra_h, idata.ra_m, idata.ra_s); ra_dec_to_string(decstring, idata.dec_d, idata.dec_m, idata.dec_s); /* Allocate some arrays */ btoa = gen_dvect(numbarypts); ttoa = gen_dvect(numbarypts); for (ii = 0; ii < numbarypts; ii++) ttoa[ii] = tlotoa + TDT * ii / SECPERDAY; /* Call TEMPO for the barycentering */ if (myid == 0) { double maxvoverc = -1.0, minvoverc = 1.0, *voverc = NULL; printf("\nGenerating barycentric corrections...\n"); voverc = gen_dvect(numbarypts); barycenter(ttoa, btoa, voverc, numbarypts, rastring, decstring, obs, ephem); for (ii = 0; ii < numbarypts; ii++) { if (voverc[ii] > maxvoverc) maxvoverc = voverc[ii]; if (voverc[ii] < minvoverc) minvoverc = voverc[ii]; avgvoverc += voverc[ii]; } avgvoverc /= numbarypts; vect_free(voverc); printf(" Average topocentric velocity (c) = %.7g\n", avgvoverc); printf(" Maximum topocentric velocity (c) = %.7g\n", maxvoverc); printf(" Minimum topocentric velocity (c) = %.7g\n\n", minvoverc); printf("De-dispersing using %d subbands.\n", cmd->nsub); if (cmd->downsamp > 1) { printf(" Downsample = %d\n", cmd->downsamp); printf(" New sample dt = %.10g\n", dsdt); } printf("\n"); } /* Print the nodes and the DMs they are handling */ print_dms(hostname, myid, numprocs, local_numdms, dms); MPI_Bcast(btoa, numbarypts, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Bcast(&avgvoverc, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); blotoa = btoa[0]; /* Dispersion delays (in bins). The high freq gets no delay */ /* All other delays are positive fractions of bin length (dt) */ dispdt = subband_search_delays(s.num_channels, cmd->nsub, avgdm, idata.freq, idata.chan_wid, avgvoverc); idispdt = gen_ivect(s.num_channels); for (ii = 0; ii < s.num_channels; ii++) idispdt[ii] = NEAREST_LONG(dispdt[ii] / idata.dt); vect_free(dispdt); /* The subband dispersion delays (see note above) */ offsets = gen_imatrix(local_numdms, cmd->nsub); for (ii = 0; ii < local_numdms; ii++) { double *subdispdt; subdispdt = subband_delays(s.num_channels, cmd->nsub, dms[ii], idata.freq, idata.chan_wid, avgvoverc); dtmp = subdispdt[cmd->nsub - 1]; for (jj = 0; jj < cmd->nsub; jj++) offsets[ii][jj] = NEAREST_LONG((subdispdt[jj] - dtmp) / dsdt); vect_free(subdispdt); } /* Convert the bary TOAs to differences from the topo TOAs in */ /* units of bin length (dt) rounded to the nearest integer. */ dtmp = (btoa[0] - ttoa[0]); for (ii = 0; ii < numbarypts; ii++) btoa[ii] = ((btoa[ii] - ttoa[ii]) - dtmp) * SECPERDAY / dsdt; /* Find the points where we need to add or remove bins */ { int oldbin = 0, currentbin; double lobin, hibin, calcpt; numdiffbins = abs(NEAREST_LONG(btoa[numbarypts - 1])) + 1; diffbins = gen_ivect(numdiffbins); diffbinptr = diffbins; for (ii = 1; ii < numbarypts; ii++) { currentbin = NEAREST_LONG(btoa[ii]); if (currentbin != oldbin) { if (currentbin > 0) { calcpt = oldbin + 0.5; lobin = (ii - 1) * TDT / dsdt; hibin = ii * TDT / dsdt; } else { calcpt = oldbin - 0.5; lobin = -((ii - 1) * TDT / dsdt); hibin = -(ii * TDT / dsdt); } while (fabs(calcpt) < fabs(btoa[ii])) { /* Negative bin number means remove that bin */ /* Positive bin number means add a bin there */ *diffbinptr = NEAREST_LONG(LININTERP (calcpt, btoa[ii - 1], btoa[ii], lobin, hibin)); diffbinptr++; calcpt = (currentbin > 0) ? calcpt + 1.0 : calcpt - 1.0; } oldbin = currentbin; } } *diffbinptr = cmd->numout; /* Used as a marker */ } diffbinptr = diffbins; /* Now perform the barycentering */ outdata = gen_fmatrix(local_numdms, worklen / cmd->downsamp); numread = get_data(outdata, blocksperread, &s, &obsmask, idispdt, offsets, &padding); while (numread == worklen) { /* Loop to read and write the data */ int numwritten = 0; double block_avg, block_var; numread /= cmd->downsamp; /* Determine the approximate local average */ avg_var(outdata[0], numread, &block_avg, &block_var); if (myid == 0) print_percent_complete(totwrote, totnumtowrite); /* Simply write the data if we don't have to add or */ /* remove any bins from this batch. */ /* OR write the amount of data up to cmd->numout or */ /* the next bin that will be added or removed. */ numtowrite = abs(*diffbinptr) - datawrote; if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout) numtowrite = cmd->numout - totwrote; if (numtowrite > numread) numtowrite = numread; if (myid > 0) { write_data(outfiles, local_numdms, outdata, 0, numtowrite); /* Update the statistics */ if (!padding) { for (ii = 0; ii < numtowrite; ii++) update_stats(statnum + ii, outdata[0][ii], &min, &max, &avg, &var); statnum += numtowrite; } } datawrote += numtowrite; totwrote += numtowrite; numwritten += numtowrite; if ((datawrote == abs(*diffbinptr)) && (numwritten != numread) && (totwrote < cmd->numout)) { /* Add/remove a bin */ int skip, nextdiffbin; skip = numtowrite; /* Write the rest of the data after adding/removing a bin */ do { if (*diffbinptr > 0) { /* Add a bin */ if (myid > 0) write_padding(outfiles, local_numdms, block_avg, 1); numadded++; totwrote++; } else { /* Remove a bin */ numremoved++; datawrote++; numwritten++; skip++; } diffbinptr++; /* Write the part after the diffbin */ numtowrite = numread - numwritten; if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout) numtowrite = cmd->numout - totwrote; nextdiffbin = abs(*diffbinptr) - datawrote; if (numtowrite > nextdiffbin) numtowrite = nextdiffbin; if (myid > 0) { write_data(outfiles, local_numdms, outdata, skip, numtowrite); /* Update the statistics and counters */ if (!padding) { for (ii = 0; ii < numtowrite; ii++) update_stats(statnum + ii, outdata[0][skip + ii], &min, &max, &avg, &var); statnum += numtowrite; } } numwritten += numtowrite; datawrote += numtowrite; totwrote += numtowrite; skip += numtowrite; /* Stop if we have written out all the data we need to */ if (cmd->numoutP && (totwrote == cmd->numout)) break; } while (numwritten < numread); } /* Stop if we have written out all the data we need to */ if (cmd->numoutP && (totwrote == cmd->numout)) break; numread = get_data(outdata, blocksperread, &s, &obsmask, idispdt, offsets, &padding); } } if (myid > 0) { /* Calculate the amount of padding we need */ if (cmd->numoutP && (cmd->numout > totwrote)) padwrote = padtowrite = cmd->numout - totwrote; /* Write the new info file for the output data */ idata.dt = dsdt; update_infodata(&idata, totwrote, padtowrite, diffbins, numdiffbins, cmd->downsamp); for (ii = 0; ii < local_numdms; ii++) { idata.dm = dms[ii]; if (!cmd->nobaryP) { double baryepoch, barydispdt, baryhifreq; baryhifreq = idata.freq + (s.num_channels - 1) * idata.chan_wid; barydispdt = delay_from_dm(dms[ii], doppler(baryhifreq, avgvoverc)); baryepoch = blotoa - (barydispdt / SECPERDAY); idata.bary = 1; idata.mjd_i = (int) floor(baryepoch); idata.mjd_f = baryepoch - idata.mjd_i; } sprintf(idata.name, "%s_DM%.2f", outfilenm, dms[ii]); writeinf(&idata); } /* Set the padded points equal to the average data point */ if (idata.numonoff >= 1) { int index, startpad, endpad; for (ii = 0; ii < local_numdms; ii++) { fclose(outfiles[ii]); sprintf(datafilenm, "%s_DM%.2f.dat", outfilenm, dms[ii]); outfiles[ii] = chkfopen(datafilenm, "rb+"); } for (ii = 0; ii < idata.numonoff; ii++) { index = 2 * ii; startpad = idata.onoff[index + 1]; if (ii == idata.numonoff - 1) endpad = idata.N - 1; else endpad = idata.onoff[index + 2]; for (jj = 0; jj < local_numdms; jj++) chkfseek(outfiles[jj], (startpad + 1) * sizeof(float), SEEK_SET); padtowrite = endpad - startpad; write_padding(outfiles, local_numdms, avg, padtowrite); } } } /* Print simple stats and results */ var /= (datawrote - 1); if (myid == 0) print_percent_complete(1, 1); if (myid == 1) { printf("\n\nDone.\n\nSimple statistics of the output data:\n"); printf(" Data points written: %ld\n", totwrote); if (padwrote) printf(" Padding points written: %ld\n", padwrote); if (!cmd->nobaryP) { if (numadded) printf(" Bins added for barycentering: %d\n", numadded); if (numremoved) printf(" Bins removed for barycentering: %d\n", numremoved); } printf(" Maximum value of data: %.2f\n", max); printf(" Minimum value of data: %.2f\n", min); printf(" Data average value: %.2f\n", avg); printf(" Data standard deviation: %.2f\n", sqrt(var)); printf("\n"); } /* Close the files and cleanup */ if (cmd->maskfileP) free_mask(obsmask); if (myid > 0) { for (ii = 0; ii < local_numdms; ii++) fclose(outfiles[ii]); free(outfiles); } vect_free(outdata[0]); vect_free(outdata); vect_free(dms); free(hostname); vect_free(idispdt); vect_free(offsets[0]); vect_free(offsets); free(datafilenm); free(outfilenm); free(outpath); if (!cmd->nobaryP) { vect_free(btoa); vect_free(ttoa); vect_free(diffbins); } MPI_Finalize(); return (0); }
int main(int argc, char **argv) { boot_img_hdr hdr; char *kernel_fn = NULL; void *kernel_data = NULL; char *ramdisk_fn = NULL; void *ramdisk_data = NULL; char *second_fn = NULL; void *second_data = NULL; char *cmdline = ""; char *bootimg = NULL; char *board = ""; char *dt_fn = NULL; void *dt_data = NULL; uint32_t pagesize = 2048; int fd; SHA_CTX ctx; const uint8_t* sha; uint32_t base = 0x10000000U; uint32_t kernel_offset = 0xFE208100; uint32_t ramdisk_offset = 0x00200100; uint32_t second_offset = 0xFF100100; uint32_t tags_offset = 0x00000100U; size_t cmdlen; argc--; argv++; memset(&hdr, 0, sizeof(hdr)); bool get_id = false; while(argc > 0){ char *arg = argv[0]; if (!strcmp(arg, "--id")) { get_id = true; argc -= 1; argv += 1; } else if(argc >= 2) { char *val = argv[1]; argc -= 2; argv += 2; if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { bootimg = val; } else if(!strcmp(arg, "--kernel")) { kernel_fn = val; } else if(!strcmp(arg, "--ramdisk")) { ramdisk_fn = val; } else if(!strcmp(arg, "--second")) { second_fn = val; } else if(!strcmp(arg, "--cmdline")) { cmdline = val; } else if(!strcmp(arg, "--base")) { base = strtoul(val, 0, 16); } else if(!strcmp(arg, "--kernel_offset")) { kernel_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--ramdisk_offset")) { ramdisk_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--second_offset")) { second_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--tags_offset")) { tags_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--board")) { board = val; } else if(!strcmp(arg,"--pagesize")) { pagesize = strtoul(val, 0, 10); if ((pagesize != 2048) && (pagesize != 4096) && (pagesize != 8192) && (pagesize != 16384) && (pagesize != 32768) && (pagesize != 65536) && (pagesize != 131072)) { fprintf(stderr,"error: unsupported page size %d\n", pagesize); return -1; } } else if(!strcmp(arg, "--dt")) { dt_fn = val; } else { return usage(); } } else { return usage(); } } hdr.page_size = pagesize; hdr.kernel_addr = base + kernel_offset; hdr.ramdisk_addr = base + ramdisk_offset; hdr.second_addr = base + second_offset; hdr.tags_addr = base + tags_offset; if(bootimg == 0) { fprintf(stderr,"error: no output filename specified\n"); return usage(); } if(kernel_fn == 0) { fprintf(stderr,"error: no kernel image specified\n"); return usage(); } if(ramdisk_fn == 0) { fprintf(stderr,"error: no ramdisk image specified\n"); return usage(); } if(strlen(board) >= BOOT_NAME_SIZE) { fprintf(stderr,"error: board name too large\n"); return usage(); } strcpy((char *) hdr.name, board); memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); cmdlen = strlen(cmdline); if(cmdlen > (BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE - 2)) { fprintf(stderr,"error: kernel commandline too large\n"); return 1; } /* Even if we need to use the supplemental field, ensure we * are still NULL-terminated */ strncpy((char *)hdr.cmdline, cmdline, BOOT_ARGS_SIZE - 1); hdr.cmdline[BOOT_ARGS_SIZE - 1] = '\0'; if (cmdlen >= (BOOT_ARGS_SIZE - 1)) { cmdline += (BOOT_ARGS_SIZE - 1); strncpy((char *)hdr.extra_cmdline, cmdline, BOOT_EXTRA_ARGS_SIZE); } kernel_data = load_file(kernel_fn, &hdr.kernel_size); if(kernel_data == 0) { fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn); return 1; } if(!strcmp(ramdisk_fn,"NONE")) { ramdisk_data = 0; hdr.ramdisk_size = 0; } else { ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); if(ramdisk_data == 0) { fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn); return 1; } } if(second_fn) { second_data = load_file(second_fn, &hdr.second_size); if(second_data == 0) { fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn); return 1; } } if(dt_fn) { dt_data = load_file(dt_fn, &hdr.dt_size); if (dt_data == 0) { fprintf(stderr,"error: could not load device tree image '%s'\n", dt_fn); return 1; } } /* put a hash of the contents in the header so boot images can be * differentiated based on their first 2k. */ SHA_init(&ctx); SHA_update(&ctx, kernel_data, hdr.kernel_size); SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size)); SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size); SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size)); SHA_update(&ctx, second_data, hdr.second_size); SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size)); if(dt_data) { SHA_update(&ctx, dt_data, hdr.dt_size); SHA_update(&ctx, &hdr.dt_size, sizeof(hdr.dt_size)); } sha = SHA_final(&ctx); memcpy(hdr.id, sha, SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); if(fd < 0) { fprintf(stderr,"error: could not create '%s'\n", bootimg); return 1; } if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; if(write_padding(fd, pagesize, sizeof(hdr))) goto fail; if(write(fd, kernel_data, hdr.kernel_size) != (ssize_t) hdr.kernel_size) goto fail; if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail; if(write(fd, ramdisk_data, hdr.ramdisk_size) != (ssize_t) hdr.ramdisk_size) goto fail; if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; if(second_data) { if(write(fd, second_data, hdr.second_size) != (ssize_t) hdr.second_size) goto fail; if(write_padding(fd, pagesize, hdr.second_size)) goto fail; } if(dt_data) { if(write(fd, dt_data, hdr.dt_size) != (ssize_t) hdr.dt_size) goto fail; if(write_padding(fd, pagesize, hdr.dt_size)) goto fail; } if (get_id) { print_id((uint8_t *) hdr.id, sizeof(hdr.id)); } return 0; fail: unlink(bootimg); close(fd); fprintf(stderr,"error: failed writing '%s': %s\n", bootimg, strerror(errno)); return 1; }
int pack_main(char *dir, char *bootimg) { char tmp[PATH_MAX]; char *img_info = 0; char *kernel_fn; void *kernel_data; char *ramdisk_fn; void *ramdisk_data = 0; char *second_fn = 0; void *second_data = 0; FILE *flag_fn = 0; unsigned char *flag_data[512]; char *board = ""; char *dt_fn = 0; void *dt_data = 0; int fd; SHA_CTX ctx; const uint8_t *sha; int _BOOTIMG_MTK = 0; memset(&hdr, 0, sizeof(hdr)); char *__now_path = getcwd(NULL, NULL); hdr.kernel_addr = 0x10008000; hdr.ramdisk_addr = 0x11000000; hdr.second_addr = 0x10F00000; hdr.tags_addr = 0x10000100; chdir(dir); repack_ramdisk_main(dir); sprintf(tmp, "%s/%s", __now_path, bootimg); bootimg = tmp; kernel_fn = "zImage"; ramdisk_fn = "ramdisk-new.cpio.gz"; dt_fn = "dt.img"; img_info = "img_info.txt"; if (exist(kernel_fn)) { fprintf(stderr, "找不到:%s\n", kernel_fn); //exit(-1); } if (exist(ramdisk_fn)) { fprintf(stderr, "找不到:%s\n", ramdisk_fn); //exit(-1); } if (exist(dt_fn)) { //fprintf(stderr, "no dt.img\n", dt_fn); dt_fn = 0; } if (exist(img_info)) { fprintf(stderr, "找不到:%s\n", img_info); //exit(-1); } if(!exist(".mtk_flag")){ _BOOTIMG_MTK = 1; } read_img_info(img_info); if(_BOOTIMG_MTK){ cmdline = ""; } hdr.page_size = pagesize; strcpy((char *)hdr.name, board); memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); if(_BOOTIMG_MTK){ // MTK 需要多写入512字节 char *ram_old = ramdisk_fn; char *ram_new = "ramdisk-new.cpio.gz.revised"; FILE *flag_fn = fopen(".mtk_flag", "rb"); fread(flag_data, 512, 1, flag_fn); FILE *ram_fn = fopen(ram_old, "rb"); fseek(ram_fn, 0, SEEK_END); long ram_size = ftell(ram_fn); fseek(ram_fn, 0, SEEK_SET); unsigned char buf[ram_size]; fread(buf, ram_size, 1, ram_fn); FILE *new_fn = fopen(ram_new, "wb"); fwrite(flag_data, 512, 1, new_fn); fwrite(buf, ram_size, 1, new_fn); fclose(ram_fn); fclose(new_fn); fclose(flag_fn); unlink(ram_old); ramdisk_fn = ram_new; } if (strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) { fprintf(stderr, "error: kernel commandline too large\n"); return 1; } strcpy((char *)hdr.cmdline, cmdline); kernel_data = load_file(kernel_fn, &hdr.kernel_size); if (!strcmp(ramdisk_fn, "NONE")) { ramdisk_data = 0; hdr.ramdisk_size = 0; } else { ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); } if (second_fn) { second_data = load_file(second_fn, &hdr.second_size); if (second_data == 0) { fprintf(stderr, "error: could not load secondstage '%s'\n", second_fn); return 1; } } if (dt_fn) { dt_data = load_file(dt_fn, &hdr.dt_size); if (dt_data == 0) { fprintf(stderr, "error: could not load device tree image '%s'\n", dt_fn); return 1; } } /* put a hash of the contents in the header so boot images can be differentiated based on their first 2k. */ SHA_init(&ctx); SHA_update(&ctx, kernel_data, (int)hdr.kernel_size); SHA_update(&ctx, &hdr.kernel_size, (int)sizeof(hdr.kernel_size)); SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size); SHA_update(&ctx, &hdr.ramdisk_size, (int)sizeof(hdr.ramdisk_size)); SHA_update(&ctx, second_data, (int)hdr.second_size); SHA_update(&ctx, &hdr.second_size, (int)sizeof(hdr.second_size)); if (dt_data) { SHA_update(&ctx, dt_data, hdr.dt_size); SHA_update(&ctx, &hdr.dt_size, sizeof(hdr.dt_size)); } sha = SHA_final(&ctx); memcpy(hdr.id, sha, SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0777); if (fd < 0) { fprintf(stderr, "无法创建:'%s'\n", bootimg); return 1; } if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; if (write_padding(fd, pagesize, sizeof(hdr))) goto fail; if (write(fd, kernel_data, hdr.kernel_size) != (signed)hdr.kernel_size) goto fail; if (write_padding(fd, pagesize, hdr.kernel_size)) goto fail; if (write(fd, ramdisk_data, hdr.ramdisk_size) != (signed)hdr.ramdisk_size) goto fail; if (write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; if (second_data) { if (write(fd, second_data, hdr.second_size) != (signed)hdr.second_size) goto fail; if (write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; } if (dt_data) { if (write(fd, dt_data, hdr.dt_size) != hdr.dt_size) goto fail; if (write_padding(fd, pagesize, hdr.dt_size)) goto fail; } return 0; fail: unlink(bootimg); close(fd); fprintf(stderr, "error: failed writing '%s': %s\n", bootimg, strerror(errno)); return 1; }
int main(int argc, char **argv) { boot_img_hdr_v2 hdr; char *kernel_fn = NULL; void *kernel_data = NULL; char *ramdisk_fn = NULL; void *ramdisk_data = NULL; char *second_fn = NULL; void *second_data = NULL; char *dtb_fn = NULL; void *dtb_data = NULL; char *recovery_dtbo_fn = NULL; void *recovery_dtbo_data = NULL; char *cmdline = ""; char *bootimg = NULL; char *board = ""; int os_version = 0; int os_patch_level = 0; int header_version = 0; char *dt_fn = NULL; void *dt_data = NULL; uint32_t pagesize = 2048; int fd; uint32_t base = 0x10000000U; uint32_t kernel_offset = 0x00008000U; uint32_t ramdisk_offset = 0x01000000U; uint32_t second_offset = 0x00f00000U; uint32_t tags_offset = 0x00000100U; uint32_t kernel_sz = 0; uint32_t ramdisk_sz = 0; uint32_t second_sz = 0; uint32_t dt_sz = 0; uint32_t rec_dtbo_sz = 0; uint64_t rec_dtbo_offset= 0; uint32_t header_sz = 0; uint32_t dtb_sz = 0; uint64_t dtb_offset = 0x01f00000U; size_t cmdlen; enum hash_alg hash_alg = HASH_SHA1; argc--; argv++; memset(&hdr, 0, sizeof(hdr)); bool get_id = false; while(argc > 0){ char *arg = argv[0]; if(!strcmp(arg, "--id")) { get_id = true; argc -= 1; argv += 1; } else if(argc >= 2) { char *val = argv[1]; argc -= 2; argv += 2; if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { bootimg = val; } else if(!strcmp(arg, "--kernel")) { kernel_fn = val; } else if(!strcmp(arg, "--ramdisk")) { ramdisk_fn = val; } else if(!strcmp(arg, "--second")) { second_fn = val; } else if(!strcmp(arg, "--dtb")) { dtb_fn = val; } else if(!strcmp(arg, "--recovery_dtbo") || !strcmp(arg, "--recovery_acpio")) { recovery_dtbo_fn = val; } else if(!strcmp(arg, "--cmdline")) { cmdline = val; } else if(!strcmp(arg, "--base")) { base = strtoul(val, 0, 16); } else if(!strcmp(arg, "--kernel_offset")) { kernel_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--ramdisk_offset")) { ramdisk_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--second_offset")) { second_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--tags_offset")) { tags_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--dtb_offset")) { dtb_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--board")) { board = val; } else if(!strcmp(arg,"--pagesize")) { pagesize = strtoul(val, 0, 10); if((pagesize != 2048) && (pagesize != 4096) && (pagesize != 8192) && (pagesize != 16384) && (pagesize != 32768) && (pagesize != 65536) && (pagesize != 131072)) { fprintf(stderr,"error: unsupported page size %d\n", pagesize); return -1; } } else if(!strcmp(arg, "--dt")) { dt_fn = val; } else if(!strcmp(arg, "--os_version")) { os_version = parse_os_version(val); } else if(!strcmp(arg, "--os_patch_level")) { os_patch_level = parse_os_patch_level(val); } else if(!strcmp(arg, "--header_version")) { header_version = strtoul(val, 0, 10); } else if(!strcmp(arg, "--hash")) { hash_alg = parse_hash_alg(val); if(hash_alg == HASH_UNKNOWN) { fprintf(stderr, "error: unknown hash algorithm '%s'\n", val); return -1; } } else { return usage(); } } else { return usage(); } } hdr.page_size = pagesize; hdr.kernel_addr = base + kernel_offset; hdr.ramdisk_addr = base + ramdisk_offset; hdr.second_addr = base + second_offset; hdr.tags_addr = base + tags_offset; hdr.header_version = header_version; hdr.os_version = (os_version << 11) | os_patch_level; if(bootimg == 0) { fprintf(stderr,"error: no output filename specified\n"); return usage(); } if(kernel_fn == 0) { fprintf(stderr,"error: no kernel image specified\n"); return usage(); } if(strlen(board) >= BOOT_NAME_SIZE) { fprintf(stderr,"error: board name too large\n"); return usage(); } strcpy((char *) hdr.name, board); memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); cmdlen = strlen(cmdline); if(cmdlen <= BOOT_ARGS_SIZE) { strcpy((char *)hdr.cmdline, cmdline); } else if(cmdlen <= BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE) { /* exceeds the limits of the base command-line size, go for the extra */ memcpy(hdr.cmdline, cmdline, BOOT_ARGS_SIZE); strcpy((char *)hdr.extra_cmdline, cmdline+BOOT_ARGS_SIZE); } else { fprintf(stderr,"error: kernel commandline too large\n"); return 1; } kernel_data = load_file(kernel_fn, &kernel_sz); if(kernel_data == 0) { fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn); return 1; } hdr.kernel_size = kernel_sz; if(ramdisk_fn == NULL) { ramdisk_data = 0; } else { ramdisk_data = load_file(ramdisk_fn, &ramdisk_sz); if(ramdisk_data == 0) { fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn); return 1; } } hdr.ramdisk_size = ramdisk_sz; if(second_fn) { second_data = load_file(second_fn, &second_sz); if(second_data == 0) { fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn); return 1; } } hdr.second_size = second_sz; if(header_version == 0) { if(dt_fn) { dt_data = load_file(dt_fn, &dt_sz); if(dt_data == 0) { fprintf(stderr,"error: could not load device tree image '%s'\n", dt_fn); return 1; } } hdr.dt_size = dt_sz; /* overrides hdr.header_version */ } else { if(recovery_dtbo_fn) { recovery_dtbo_data = load_file(recovery_dtbo_fn, &rec_dtbo_sz); if(recovery_dtbo_data == 0) { fprintf(stderr,"error: could not load recovery dtbo image '%s'\n", recovery_dtbo_fn); return 1; } /* header occupies a page */ rec_dtbo_offset = pagesize * (1 + \ (kernel_sz + pagesize - 1) / pagesize + \ (ramdisk_sz + pagesize - 1) / pagesize + \ (second_sz + pagesize - 1) / pagesize); } if(header_version == 1) { header_sz = 1648; } else { header_sz = sizeof(hdr); } if(header_version > 1) { if(dtb_fn) { dtb_data = load_file(dtb_fn, &dtb_sz); if(dtb_data == 0) { fprintf(stderr,"error: could not load recovery dtb image '%s'\n", dtb_fn); return 1; } } } } hdr.recovery_dtbo_size = rec_dtbo_sz; hdr.recovery_dtbo_offset = rec_dtbo_offset; hdr.header_size = header_sz; hdr.dtb_size = dtb_sz; if(header_version > 1) { hdr.dtb_addr = base + dtb_offset; } else { hdr.dtb_addr = 0; } /* put a hash of the contents in the header so boot images can be * differentiated based on their first 2k. */ generate_id(hash_alg, &hdr, kernel_data, ramdisk_data, second_data, dt_data, recovery_dtbo_data, dtb_data); fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); if(fd < 0) { fprintf(stderr,"error: could not create '%s'\n", bootimg); return 1; } if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; if(write_padding(fd, pagesize, sizeof(hdr))) goto fail; if(write(fd, kernel_data, hdr.kernel_size) != (ssize_t) hdr.kernel_size) goto fail; if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail; if(write(fd, ramdisk_data, hdr.ramdisk_size) != (ssize_t) hdr.ramdisk_size) goto fail; if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; if(second_data) { if(write(fd, second_data, hdr.second_size) != (ssize_t) hdr.second_size) goto fail; if(write_padding(fd, pagesize, hdr.second_size)) goto fail; } if(dt_data) { if(write(fd, dt_data, hdr.dt_size) != (ssize_t) hdr.dt_size) goto fail; if(write_padding(fd, pagesize, hdr.dt_size)) goto fail; } else { if(recovery_dtbo_data) { if(write(fd, recovery_dtbo_data, hdr.recovery_dtbo_size) != (ssize_t) hdr.recovery_dtbo_size) goto fail; if(write_padding(fd, pagesize, hdr.recovery_dtbo_size)) goto fail; } if(dtb_data) { if(write(fd, dtb_data, hdr.dtb_size) != (ssize_t) hdr.dtb_size) goto fail; if(write_padding(fd, pagesize, hdr.dtb_size)) goto fail; } } if(get_id) { print_id((uint8_t *) hdr.id, sizeof(hdr.id)); } return 0; fail: unlink(bootimg); close(fd); fprintf(stderr,"error: failed writing '%s': %s\n", bootimg, strerror(errno)); return 1; }
static bool write_fixed_files() { int cur_input,cur_output; unsigned long bytes_have,bytes_needed,bytes_to_xfer; char outfilename[FILENAME_SIZE]; bool success; progress_info proginfo; success = FALSE; cur_input = cur_output = 0; bytes_have = (unsigned long)files[cur_input]->data_size; bytes_needed = (unsigned long)files[cur_output]->new_data_size; proginfo.initialized = FALSE; proginfo.prefix = "Fixing"; proginfo.clause = "-->"; proginfo.filename1 = files[0]->filename; proginfo.filedesc1 = files[0]->m_ss; proginfo.filename2 = NULL; proginfo.filedesc2 = NULL; proginfo.bytes_total = 1; if (!open_this_file(cur_output,outfilename,&proginfo)) goto cleanup; if (!reopen_input_file(cur_input,&proginfo)) goto cleanup; while (cur_input < numfiles && cur_output < numfiles) { bytes_to_xfer = min(bytes_have,bytes_needed); if (transfer_n_bytes(files[cur_input]->input,files[cur_output]->output,bytes_to_xfer,&proginfo) != bytes_to_xfer) { prog_error(&proginfo); st_warning("error while transferring %lu bytes of data",bytes_to_xfer); goto cleanup; } bytes_have -= bytes_to_xfer; bytes_needed -= bytes_to_xfer; if (0 == bytes_have) { close_input_stream(files[cur_input]); files[cur_input]->input = NULL; cur_input++; if (cur_input < numfiles) { bytes_have = (unsigned long)files[cur_input]->data_size; if (!reopen_input_file(cur_input,&proginfo)) goto cleanup; } } if (0 == bytes_needed) { prog_success(&proginfo); if (numfiles - 1 == cur_output) { if (pad) { if (pad_bytes) { if (pad_bytes != write_padding(files[cur_output]->output,pad_bytes,NULL)) { prog_error(&proginfo); st_warning("error while padding with %d zero-bytes",pad_bytes); goto cleanup; } st_info("Padded last file with %d zero-bytes.\n",pad_bytes); } else st_info("No padding needed.\n"); } else { st_info("Last file was not padded, "); if (pad_bytes) st_info("though it needs %d bytes of padding.\n",pad_bytes); else st_info("nor was it needed.\n"); if ((files[cur_output]->new_data_size & 1) && (1 != write_padding(files[cur_output]->output,1,NULL))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } } } close_output_stream(files[cur_output]); files[cur_output]->output = NULL; cur_output++; if (cur_output < numfiles) { bytes_needed = (unsigned long)files[cur_output]->new_data_size; if (!open_this_file(cur_output,outfilename,&proginfo)) goto cleanup; } } } success = TRUE; cleanup: if (!success) { close_output_stream(files[cur_output]); remove_file(outfilename); st_error("failed to fix files"); } return success; }
static bool split_file(wave_info *info) { unsigned char header[CANONICAL_HEADER_SIZE]; char outfilename[FILENAME_SIZE],filenum[FILENAME_SIZE]; int current; wint discard,bytes; bool success; wlong leadin_bytes, leadout_bytes, bytes_to_xfer; progress_info proginfo; // uwe double start_time, end_time, last_end_time; success = FALSE; proginfo.initialized = FALSE; proginfo.prefix = "Splitting"; proginfo.clause = "-->"; proginfo.filename1 = info->filename; proginfo.filedesc1 = info->m_ss; proginfo.filename2 = NULL; proginfo.filedesc2 = NULL; proginfo.bytes_total = 0; if (!open_input_stream(info)) { prog_error(&proginfo); st_error("could not reopen input file: [%s]",info->filename); } discard = info->header_size; while (discard > 0) { bytes = min(discard,CANONICAL_HEADER_SIZE); if (read_n_bytes(info->input,header,bytes,NULL) != bytes) { prog_error(&proginfo); st_error("error while discarding %d-byte WAVE header",info->header_size); } discard -= bytes; } leadin_bytes = (leadin) ? smrt_parse((unsigned char *)leadin,info) : 0; leadout_bytes = (leadout) ? smrt_parse((unsigned char *)leadout,info) : 0; adjust_for_leadinout(leadin_bytes,leadout_bytes); // uwe transcription st_output("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); st_output("<Trans version=\"2\">\n\n"); start_time = end_time = last_end_time = 0; for (current=0;current<numfiles;current++) { if (SPLIT_INPUT_CUE == input_type && cueinfo.format) { create_output_filename(cueinfo.filenames[current],"",outfilename); } else { st_snprintf(filenum,8,num_format,current+offset); create_output_filename(filenum,"",outfilename); } files[current]->chunk_size = files[current]->data_size + CANONICAL_HEADER_SIZE - 8; files[current]->channels = info->channels; files[current]->samples_per_sec = info->samples_per_sec; files[current]->avg_bytes_per_sec = info->avg_bytes_per_sec; files[current]->block_align = info->block_align; files[current]->bits_per_sample = info->bits_per_sample; files[current]->wave_format = info->wave_format; files[current]->rate = info->rate; files[current]->length = files[current]->data_size / (wlong)info->rate; files[current]->exact_length = (double)files[current]->data_size / (double)info->rate; files[current]->total_size = files[current]->chunk_size + 8; length_to_str(files[current]); proginfo.filedesc2 = files[current]->m_ss; proginfo.bytes_total = files[current]->total_size; if (extract_track[current]) { proginfo.prefix = "Splitting"; proginfo.filename2 = outfilename; // uwe transcription start_time += last_end_time; end_time += files[current]->data_size / (wlong)info->rate; last_end_time = end_time; printf("<Turn startTime=\"%.2f\"", start_time); // %.2f st_output(" endTime=\"%.2f\"", end_time); st_output(" splitFilename=\"%s\"", outfilename); st_output(" speaker=\"spk1\">\n"); st_output("<Sync time=\"%.2f\"/>\n", start_time); st_output("***Include transcript words here***\n"); st_output("</Turn>\n"); if (NULL == (files[current]->output = open_output_stream(outfilename,&files[current]->output_proc))) { prog_error(&proginfo); st_error("could not open output file"); } } else { proginfo.prefix = "Skipping "; proginfo.filename2 = NULLDEVICE; if (NULL == (files[current]->output = open_output(NULLDEVICE))) { prog_error(&proginfo); st_error("while skipping track %d: could not open output file: [%s]",current+1,NULLDEVICE); } files[current]->output_proc.pid = NO_CHILD_PID; } if (PROB_ODD_SIZED_DATA(files[current])) files[current]->chunk_size++; make_canonical_header(header,files[current]); // uwe disable //prog_update(&proginfo); if (write_n_bytes(files[current]->output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) { prog_error(&proginfo); st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE); goto cleanup; } /* if this is not the first file, finish up writing previous file, and simultaneously start writing to current file */ if (0 != current) { /* write overlapping lead-in/lead-out data to both previous and current files */ if (transfer_n_bytes2(info->input,files[current]->output,files[current-1]->output,leadin_bytes+leadout_bytes,&proginfo) != leadin_bytes+leadout_bytes) { prog_error(&proginfo); st_warning("error while transferring %ld bytes of lead-in/lead-out",leadin_bytes+leadout_bytes); goto cleanup; } /* pad and close previous file */ if (PROB_ODD_SIZED_DATA(files[current-1]) && (1 != write_padding(files[current-1]->output,1,&proginfo))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } close_output(files[current-1]->output,files[current-1]->output_proc); } /* transfer unique non-overlapping data from input file to current file */ bytes_to_xfer = files[current]->new_data_size; if (0 != current) bytes_to_xfer -= leadout_bytes; if (numfiles - 1 != current) bytes_to_xfer -= leadin_bytes; if (transfer_n_bytes(info->input,files[current]->output,bytes_to_xfer,&proginfo) != bytes_to_xfer) { prog_error(&proginfo); st_warning("error while transferring %ld bytes of data",bytes_to_xfer); goto cleanup; } /* if this is the last file, close it */ if (numfiles - 1 == current) { /* pad and close current file */ if (PROB_ODD_SIZED_DATA(files[current]) && (1 != write_padding(files[current]->output,1,&proginfo))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } close_output(files[current]->output,files[current]->output_proc); // uwe transcription st_output("</Trans>\n"); } // uwe disable // prog_success(&proginfo); } close_input_stream(info); success = TRUE; cleanup: if (!success) { close_output(files[current]->output,files[current]->output_proc); remove_file(outfilename); st_error("failed to split file"); } return success; }
/* Adapted from libavformat/spdifenc.c: * It seems Dolby TrueHD frames have to be encapsulated in MAT frames before * they can be encapsulated in IEC 61937. * Here we encapsulate 24 TrueHD frames in a single MAT frame, padding them * to achieve constant rate. * The actual format of a MAT frame is unknown, but the below seems to work. * However, it seems it is not actually necessary for the 24 TrueHD frames to * be in an exact alignment with the MAT frame */ static int write_buffer_truehd( filter_t *p_filter, block_t *p_in_buf ) { #define TRUEHD_FRAME_OFFSET 2560 filter_sys_t *p_sys = p_filter->p_sys; if( !p_sys->p_out_buf && write_init( p_filter, p_in_buf, 61440, 61440 / 16 ) ) return SPDIF_ERROR; int i_padding = 0; if( p_sys->truehd.i_frame_count == 0 ) { static const char p_mat_start_code[20] = { 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00, 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0 }; write_data( p_filter, p_mat_start_code, 20, true ); /* We need to include the S/PDIF header in the first MAT frame */ i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer - 20 - SPDIF_HEADER_SIZE; } else if( p_sys->truehd.i_frame_count == 11 ) { /* The middle mat code need to be at the ((2560 * 12) - 4) offset */ i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer - 4; } else if( p_sys->truehd.i_frame_count == 12 ) { static const char p_mat_middle_code[12] = { 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA, 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0 }; write_data( p_filter, p_mat_middle_code, 12, true ); i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer - ( 12 - 4 ); } else if( p_sys->truehd.i_frame_count == 23 ) { static const char p_mat_end_code[16] = { 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11 }; /* The end mat code need to be at the ((2560 * 24) - 24) offset */ i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer - 24; if( i_padding < 0 || p_in_buf->i_buffer + i_padding > p_sys->p_out_buf->i_buffer - p_sys->i_out_offset ) return SPDIF_ERROR; write_buffer( p_filter, p_in_buf ); write_padding( p_filter, i_padding ); write_data( p_filter, p_mat_end_code, 16, true ); write_finalize( p_filter, IEC61937_TRUEHD, 1 /* in bytes */ ); p_sys->truehd.i_frame_count = 0; return SPDIF_SUCCESS; } else i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer; if( i_padding < 0 || p_in_buf->i_buffer + i_padding > p_sys->p_out_buf->i_buffer - p_sys->i_out_offset ) return SPDIF_ERROR; write_buffer( p_filter, p_in_buf ); write_padding( p_filter, i_padding ); p_sys->truehd.i_frame_count++; return SPDIF_MORE_DATA; }