Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.4 169 lines 4.0 kB view raw
1/* 2 * vrl4 format generator 3 * 4 * Copyright (C) 2010 Simon Horman 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11/* 12 * usage: vrl4 < zImage > out 13 * dd if=out of=/dev/sdx bs=512 seek=1 # Write the image to sector 1 14 * 15 * Reads a zImage from stdin and writes a vrl4 image to stdout. 16 * In practice this means writing a padded vrl4 header to stdout followed 17 * by the zImage. 18 * 19 * The padding places the zImage at ALIGN bytes into the output. 20 * The vrl4 uses ALIGN + START_BASE as the start_address. 21 * This is where the mask ROM will jump to after verifying the header. 22 * 23 * The header sets copy_size to min(sizeof(zImage), MAX_BOOT_PROG_LEN) + ALIGN. 24 * That is, the mask ROM will load the padded header (ALIGN bytes) 25 * And then MAX_BOOT_PROG_LEN bytes of the image, or the entire image, 26 * whichever is smaller. 27 * 28 * The zImage is not modified in any way. 29 */ 30 31#define _BSD_SOURCE 32#include <endian.h> 33#include <unistd.h> 34#include <stdint.h> 35#include <stdio.h> 36#include <errno.h> 37 38struct hdr { 39 uint32_t magic1; 40 uint32_t reserved1; 41 uint32_t magic2; 42 uint32_t reserved2; 43 uint16_t copy_size; 44 uint16_t boot_options; 45 uint32_t reserved3; 46 uint32_t start_address; 47 uint32_t reserved4; 48 uint32_t reserved5; 49 char reserved6[308]; 50}; 51 52#define DECLARE_HDR(h) \ 53 struct hdr (h) = { \ 54 .magic1 = htole32(0xea000000), \ 55 .reserved1 = htole32(0x56), \ 56 .magic2 = htole32(0xe59ff008), \ 57 .reserved3 = htole16(0x1) } 58 59/* Align to 512 bytes, the MMCIF sector size */ 60#define ALIGN_BITS 9 61#define ALIGN (1 << ALIGN_BITS) 62 63#define START_BASE 0xe55b0000 64 65/* 66 * With an alignment of 512 the header uses the first sector. 67 * There is a 128 sector (64kbyte) limit on the data loaded by the mask ROM. 68 * So there are 127 sectors left for the boot programme. But in practice 69 * Only a small portion of a zImage is needed, 16 sectors should be more 70 * than enough. 71 * 72 * Note that this sets how much of the zImage is copied by the mask ROM. 73 * The entire zImage is present after the header and is loaded 74 * by the code in the boot program (which is the first portion of the zImage). 75 */ 76#define MAX_BOOT_PROG_LEN (16 * 512) 77 78#define ROUND_UP(x) ((x + ALIGN - 1) & ~(ALIGN - 1)) 79 80ssize_t do_read(int fd, void *buf, size_t count) 81{ 82 size_t offset = 0; 83 ssize_t l; 84 85 while (offset < count) { 86 l = read(fd, buf + offset, count - offset); 87 if (!l) 88 break; 89 if (l < 0) { 90 if (errno == EAGAIN || errno == EWOULDBLOCK) 91 continue; 92 perror("read"); 93 return -1; 94 } 95 offset += l; 96 } 97 98 return offset; 99} 100 101ssize_t do_write(int fd, const void *buf, size_t count) 102{ 103 size_t offset = 0; 104 ssize_t l; 105 106 while (offset < count) { 107 l = write(fd, buf + offset, count - offset); 108 if (l < 0) { 109 if (errno == EAGAIN || errno == EWOULDBLOCK) 110 continue; 111 perror("write"); 112 return -1; 113 } 114 offset += l; 115 } 116 117 return offset; 118} 119 120ssize_t write_zero(int fd, size_t len) 121{ 122 size_t i = len; 123 124 while (i--) { 125 const char x = 0; 126 if (do_write(fd, &x, 1) < 0) 127 return -1; 128 } 129 130 return len; 131} 132 133int main(void) 134{ 135 DECLARE_HDR(hdr); 136 char boot_program[MAX_BOOT_PROG_LEN]; 137 size_t aligned_hdr_len, alligned_prog_len; 138 ssize_t prog_len; 139 140 prog_len = do_read(0, boot_program, sizeof(boot_program)); 141 if (prog_len <= 0) 142 return -1; 143 144 aligned_hdr_len = ROUND_UP(sizeof(hdr)); 145 hdr.start_address = htole32(START_BASE + aligned_hdr_len); 146 alligned_prog_len = ROUND_UP(prog_len); 147 hdr.copy_size = htole16(aligned_hdr_len + alligned_prog_len); 148 149 if (do_write(1, &hdr, sizeof(hdr)) < 0) 150 return -1; 151 if (write_zero(1, aligned_hdr_len - sizeof(hdr)) < 0) 152 return -1; 153 154 if (do_write(1, boot_program, prog_len) < 0) 155 return 1; 156 157 /* Write out the rest of the kernel */ 158 while (1) { 159 prog_len = do_read(0, boot_program, sizeof(boot_program)); 160 if (prog_len < 0) 161 return 1; 162 if (prog_len == 0) 163 break; 164 if (do_write(1, boot_program, prog_len) < 0) 165 return 1; 166 } 167 168 return 0; 169}