Path: blob/master/Documentation/arm/SH-Mobile/vrl4.c
10821 views
/*1* vrl4 format generator2*3* Copyright (C) 2010 Simon Horman4*5* This file is subject to the terms and conditions of the GNU General Public6* License. See the file "COPYING" in the main directory of this archive7* for more details.8*/910/*11* usage: vrl4 < zImage > out12* dd if=out of=/dev/sdx bs=512 seek=1 # Write the image to sector 113*14* Reads a zImage from stdin and writes a vrl4 image to stdout.15* In practice this means writing a padded vrl4 header to stdout followed16* by the zImage.17*18* The padding places the zImage at ALIGN bytes into the output.19* The vrl4 uses ALIGN + START_BASE as the start_address.20* This is where the mask ROM will jump to after verifying the header.21*22* The header sets copy_size to min(sizeof(zImage), MAX_BOOT_PROG_LEN) + ALIGN.23* That is, the mask ROM will load the padded header (ALIGN bytes)24* And then MAX_BOOT_PROG_LEN bytes of the image, or the entire image,25* whichever is smaller.26*27* The zImage is not modified in any way.28*/2930#define _BSD_SOURCE31#include <endian.h>32#include <unistd.h>33#include <stdint.h>34#include <stdio.h>35#include <errno.h>3637struct hdr {38uint32_t magic1;39uint32_t reserved1;40uint32_t magic2;41uint32_t reserved2;42uint16_t copy_size;43uint16_t boot_options;44uint32_t reserved3;45uint32_t start_address;46uint32_t reserved4;47uint32_t reserved5;48char reserved6[308];49};5051#define DECLARE_HDR(h) \52struct hdr (h) = { \53.magic1 = htole32(0xea000000), \54.reserved1 = htole32(0x56), \55.magic2 = htole32(0xe59ff008), \56.reserved3 = htole16(0x1) }5758/* Align to 512 bytes, the MMCIF sector size */59#define ALIGN_BITS 960#define ALIGN (1 << ALIGN_BITS)6162#define START_BASE 0xe55b00006364/*65* With an alignment of 512 the header uses the first sector.66* There is a 128 sector (64kbyte) limit on the data loaded by the mask ROM.67* So there are 127 sectors left for the boot programme. But in practice68* Only a small portion of a zImage is needed, 16 sectors should be more69* than enough.70*71* Note that this sets how much of the zImage is copied by the mask ROM.72* The entire zImage is present after the header and is loaded73* by the code in the boot program (which is the first portion of the zImage).74*/75#define MAX_BOOT_PROG_LEN (16 * 512)7677#define ROUND_UP(x) ((x + ALIGN - 1) & ~(ALIGN - 1))7879ssize_t do_read(int fd, void *buf, size_t count)80{81size_t offset = 0;82ssize_t l;8384while (offset < count) {85l = read(fd, buf + offset, count - offset);86if (!l)87break;88if (l < 0) {89if (errno == EAGAIN || errno == EWOULDBLOCK)90continue;91perror("read");92return -1;93}94offset += l;95}9697return offset;98}99100ssize_t do_write(int fd, const void *buf, size_t count)101{102size_t offset = 0;103ssize_t l;104105while (offset < count) {106l = write(fd, buf + offset, count - offset);107if (l < 0) {108if (errno == EAGAIN || errno == EWOULDBLOCK)109continue;110perror("write");111return -1;112}113offset += l;114}115116return offset;117}118119ssize_t write_zero(int fd, size_t len)120{121size_t i = len;122123while (i--) {124const char x = 0;125if (do_write(fd, &x, 1) < 0)126return -1;127}128129return len;130}131132int main(void)133{134DECLARE_HDR(hdr);135char boot_program[MAX_BOOT_PROG_LEN];136size_t aligned_hdr_len, alligned_prog_len;137ssize_t prog_len;138139prog_len = do_read(0, boot_program, sizeof(boot_program));140if (prog_len <= 0)141return -1;142143aligned_hdr_len = ROUND_UP(sizeof(hdr));144hdr.start_address = htole32(START_BASE + aligned_hdr_len);145alligned_prog_len = ROUND_UP(prog_len);146hdr.copy_size = htole16(aligned_hdr_len + alligned_prog_len);147148if (do_write(1, &hdr, sizeof(hdr)) < 0)149return -1;150if (write_zero(1, aligned_hdr_len - sizeof(hdr)) < 0)151return -1;152153if (do_write(1, boot_program, prog_len) < 0)154return 1;155156/* Write out the rest of the kernel */157while (1) {158prog_len = do_read(0, boot_program, sizeof(boot_program));159if (prog_len < 0)160return 1;161if (prog_len == 0)162break;163if (do_write(1, boot_program, prog_len) < 0)164return 1;165}166167return 0;168}169170171