About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / arm / SH-Mobile / vrl4.c




Custom Search

Based on kernel version 3.13. Page generated on 2014-01-20 22:00 EST.

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	
38	struct 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	
80	ssize_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	
101	ssize_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	
120	ssize_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	
133	int 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	}
Hide Line Numbers
About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Information is copyright its respective author. All material is available from the Linux Kernel Source distributed under a GPL License. This page is provided as a free service by mjmwired.net.