aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v10/boot
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v10/boot')
-rw-r--r--arch/cris/arch-v10/boot/Makefile12
-rw-r--r--arch/cris/arch-v10/boot/compressed/Makefile40
-rw-r--r--arch/cris/arch-v10/boot/compressed/README25
-rw-r--r--arch/cris/arch-v10/boot/compressed/decompress.ld29
-rw-r--r--arch/cris/arch-v10/boot/compressed/head.S111
-rw-r--r--arch/cris/arch-v10/boot/compressed/misc.c273
-rw-r--r--arch/cris/arch-v10/boot/rescue/Makefile55
-rw-r--r--arch/cris/arch-v10/boot/rescue/head.S333
-rw-r--r--arch/cris/arch-v10/boot/rescue/kimagerescue.S144
-rw-r--r--arch/cris/arch-v10/boot/rescue/rescue.ld20
-rw-r--r--arch/cris/arch-v10/boot/rescue/testrescue.S26
-rw-r--r--arch/cris/arch-v10/boot/tools/build.c288
12 files changed, 1356 insertions, 0 deletions
diff --git a/arch/cris/arch-v10/boot/Makefile b/arch/cris/arch-v10/boot/Makefile
new file mode 100644
index 00000000000..fe6650368e6
--- /dev/null
+++ b/arch/cris/arch-v10/boot/Makefile
@@ -0,0 +1,12 @@
1#
2# arch/cris/boot/Makefile
3#
4
5zImage: compressed/vmlinuz
6
7compressed/vmlinuz: $(TOPDIR)/vmlinux
8 @$(MAKE) -C compressed vmlinuz
9
10clean:
11 rm -f zImage tools/build compressed/vmlinux.out
12 @$(MAKE) -C compressed clean
diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/arch-v10/boot/compressed/Makefile
new file mode 100644
index 00000000000..5f71c2c819e
--- /dev/null
+++ b/arch/cris/arch-v10/boot/compressed/Makefile
@@ -0,0 +1,40 @@
1#
2# linux/arch/etrax100/boot/compressed/Makefile
3#
4# create a compressed vmlinux image from the original vmlinux files and romfs
5#
6
7CC = gcc-cris -melf -I $(TOPDIR)/include
8CFLAGS = -O2
9LD = ld-cris
10OBJCOPY = objcopy-cris
11OBJCOPYFLAGS = -O binary --remove-section=.bss
12OBJECTS = head.o misc.o
13
14# files to compress
15SYSTEM = $(TOPDIR)/vmlinux.bin
16
17all: vmlinuz
18
19decompress.bin: $(OBJECTS)
20 $(LD) -T decompress.ld -o decompress.o $(OBJECTS)
21 $(OBJCOPY) $(OBJCOPYFLAGS) decompress.o decompress.bin
22# save it for mkprod in the topdir.
23 cp decompress.bin $(TOPDIR)
24
25
26vmlinuz: piggy.img decompress.bin
27 cat decompress.bin piggy.img > vmlinuz
28 rm -f piggy.img
29
30head.o: head.S
31 $(CC) -D__ASSEMBLY__ -traditional -c head.S -o head.o
32
33# gzip the kernel image
34
35piggy.img: $(SYSTEM)
36 cat $(SYSTEM) | gzip -f -9 > piggy.img
37
38clean:
39 rm -f piggy.img vmlinuz vmlinuz.o
40
diff --git a/arch/cris/arch-v10/boot/compressed/README b/arch/cris/arch-v10/boot/compressed/README
new file mode 100644
index 00000000000..48b3db9924b
--- /dev/null
+++ b/arch/cris/arch-v10/boot/compressed/README
@@ -0,0 +1,25 @@
1Creation of the self-extracting compressed kernel image (vmlinuz)
2-----------------------------------------------------------------
3$Id: README,v 1.1 2001/12/17 13:59:27 bjornw Exp $
4
5This can be slightly confusing because it's a process with many steps.
6
7The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
8by that makefile into text and data binary files, vmlinux.text and
9vmlinux.data.
10
11Those files together with a ROM filesystem can be catted together and
12burned into a flash or executed directly at the DRAM origin.
13
14They can also be catted together and compressed with gzip, which is what
15happens in this makefile. Together they make up piggy.img.
16
17The decompressor is built into the file decompress.o. It is turned into
18the binary file decompress.bin, which is catted together with piggy.img
19into the file vmlinuz. It can be executed in an arbitrary place in flash.
20
21Be careful - it assumes some things about free locations in DRAM. It
22assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
23so it puts its code at 0x40700000, and initial stack at 0x40800000.
24
25-Bjorn
diff --git a/arch/cris/arch-v10/boot/compressed/decompress.ld b/arch/cris/arch-v10/boot/compressed/decompress.ld
new file mode 100644
index 00000000000..0b0a14fe617
--- /dev/null
+++ b/arch/cris/arch-v10/boot/compressed/decompress.ld
@@ -0,0 +1,29 @@
1OUTPUT_FORMAT(elf32-us-cris)
2
3MEMORY
4 {
5 dram : ORIGIN = 0x40700000,
6 LENGTH = 0x00100000
7 }
8
9SECTIONS
10{
11 .text :
12 {
13 _stext = . ;
14 *(.text)
15 *(.rodata)
16 *(.rodata.*)
17 _etext = . ;
18 } > dram
19 .data :
20 {
21 *(.data)
22 _edata = . ;
23 } > dram
24 .bss :
25 {
26 *(.bss)
27 _end = ALIGN( 0x10 ) ;
28 } > dram
29}
diff --git a/arch/cris/arch-v10/boot/compressed/head.S b/arch/cris/arch-v10/boot/compressed/head.S
new file mode 100644
index 00000000000..4cbdd4b1d9d
--- /dev/null
+++ b/arch/cris/arch-v10/boot/compressed/head.S
@@ -0,0 +1,111 @@
1/*
2 * arch/cris/boot/compressed/head.S
3 *
4 * Copyright (C) 1999, 2001 Axis Communications AB
5 *
6 * Code that sets up the DRAM registers, calls the
7 * decompressor to unpack the piggybacked kernel, and jumps.
8 *
9 */
10
11#include <linux/config.h>
12#define ASSEMBLER_MACROS_ONLY
13#include <asm/arch/sv_addr_ag.h>
14
15#define RAM_INIT_MAGIC 0x56902387
16
17 ;; Exported symbols
18
19 .globl _input_data
20
21
22 .text
23
24 nop
25 di
26
27;; We need to initialze DRAM registers before we start using the DRAM
28
29 cmp.d RAM_INIT_MAGIC, r8 ; Already initialized?
30 beq dram_init_finished
31 nop
32
33#include "../../lib/dram_init.S"
34
35dram_init_finished:
36
37 ;; Initiate the PA and PB ports
38
39 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
40 move.b r0, [R_PORT_PA_DATA]
41
42 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
43 move.b r0, [R_PORT_PA_DIR]
44
45 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
46 move.b r0, [R_PORT_PB_DATA]
47
48 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
49 move.b r0, [R_PORT_PB_DIR]
50
51 ;; Setup the stack to a suitably high address.
52 ;; We assume 8 MB is the minimum DRAM in an eLinux
53 ;; product and put the sp at the top for now.
54
55 move.d 0x40800000, sp
56
57 ;; Figure out where the compressed piggyback image is
58 ;; in the flash (since we wont try to copy it to DRAM
59 ;; before unpacking). It is at _edata, but in flash.
60 ;; Use (_edata - basse) as offset to the current PC.
61
62basse: move.d pc, r5
63 and.d 0x7fffffff, r5 ; strip any non-cache bit
64 subq 2, r5 ; compensate for the move.d pc instr
65 move.d r5, r0 ; save for later - flash address of 'basse'
66 add.d _edata, r5
67 sub.d basse, r5 ; r5 = flash address of '_edata'
68
69 ;; Copy text+data to DRAM
70
71 move.d basse, r1 ; destination
72 move.d _edata, r2 ; end destination
731: move.w [r0+], r3
74 move.w r3, [r1+]
75 cmp.d r2, r1
76 bcs 1b
77 nop
78
79 move.d r5, [_input_data] ; for the decompressor
80
81
82 ;; Clear the decompressors BSS (between _edata and _end)
83
84 moveq 0, r0
85 move.d _edata, r1
86 move.d _end, r2
871: move.w r0, [r1+]
88 cmp.d r2, r1
89 bcs 1b
90 nop
91
92 ;; Do the decompression and save compressed size in _inptr
93
94 jsr _decompress_kernel
95
96 ;; Put start address of root partition in r9 so the kernel can use it
97 ;; when mounting from flash
98
99 move.d [_input_data], r9 ; flash address of compressed kernel
100 add.d [_inptr], r9 ; size of compressed kernel
101
102 ;; Enter the decompressed kernel
103 move.d RAM_INIT_MAGIC, r8 ; Tell kernel that DRAM is initialized
104 jump 0x40004000 ; kernel is linked to this address
105
106 .data
107
108_input_data:
109 .dword 0 ; used by the decompressor
110
111#include "../../lib/hw_settings.S"
diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c
new file mode 100644
index 00000000000..1b5e83f1f84
--- /dev/null
+++ b/arch/cris/arch-v10/boot/compressed/misc.c
@@ -0,0 +1,273 @@
1/*
2 * misc.c
3 *
4 * $Id: misc.c,v 1.6 2003/10/27 08:04:31 starvik Exp $
5 *
6 * This is a collection of several routines from gzip-1.0.3
7 * adapted for Linux.
8 *
9 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
10 * puts by Nick Holloway 1993, better puts by Martin Mares 1995
11 * adoptation for Linux/CRIS Axis Communications AB, 1999
12 *
13 */
14
15/* where the piggybacked kernel image expects itself to live.
16 * it is the same address we use when we network load an uncompressed
17 * image into DRAM, and it is the address the kernel is linked to live
18 * at by vmlinux.lds.S
19 */
20
21#define KERNEL_LOAD_ADR 0x40004000
22
23#include <linux/config.h>
24
25#include <linux/types.h>
26#include <asm/arch/svinto.h>
27
28/*
29 * gzip declarations
30 */
31
32#define OF(args) args
33#define STATIC static
34
35void* memset(void* s, int c, size_t n);
36void* memcpy(void* __dest, __const void* __src,
37 size_t __n);
38
39#define memzero(s, n) memset ((s), 0, (n))
40
41
42typedef unsigned char uch;
43typedef unsigned short ush;
44typedef unsigned long ulg;
45
46#define WSIZE 0x8000 /* Window size must be at least 32k, */
47 /* and a power of two */
48
49static uch *inbuf; /* input buffer */
50static uch window[WSIZE]; /* Sliding window buffer */
51
52unsigned inptr = 0; /* index of next byte to be processed in inbuf
53 * After decompression it will contain the
54 * compressed size, and head.S will read it.
55 */
56
57static unsigned outcnt = 0; /* bytes in output buffer */
58
59/* gzip flag byte */
60#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
61#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
62#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
63#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
64#define COMMENT 0x10 /* bit 4 set: file comment present */
65#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
66#define RESERVED 0xC0 /* bit 6,7: reserved */
67
68#define get_byte() inbuf[inptr++]
69
70/* Diagnostic functions */
71#ifdef DEBUG
72# define Assert(cond,msg) {if(!(cond)) error(msg);}
73# define Trace(x) fprintf x
74# define Tracev(x) {if (verbose) fprintf x ;}
75# define Tracevv(x) {if (verbose>1) fprintf x ;}
76# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
77# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
78#else
79# define Assert(cond,msg)
80# define Trace(x)
81# define Tracev(x)
82# define Tracevv(x)
83# define Tracec(c,x)
84# define Tracecv(c,x)
85#endif
86
87static int fill_inbuf(void);
88static void flush_window(void);
89static void error(char *m);
90static void gzip_mark(void **);
91static void gzip_release(void **);
92
93extern char *input_data; /* lives in head.S */
94
95static long bytes_out = 0;
96static uch *output_data;
97static unsigned long output_ptr = 0;
98
99static void *malloc(int size);
100static void free(void *where);
101static void error(char *m);
102static void gzip_mark(void **);
103static void gzip_release(void **);
104
105static void puts(const char *);
106
107/* the "heap" is put directly after the BSS ends, at end */
108
109extern int end;
110static long free_mem_ptr = (long)&end;
111
112#include "../../../../../lib/inflate.c"
113
114static void *malloc(int size)
115{
116 void *p;
117
118 if (size <0) error("Malloc error");
119
120 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
121
122 p = (void *)free_mem_ptr;
123 free_mem_ptr += size;
124
125 return p;
126}
127
128static void free(void *where)
129{ /* Don't care */
130}
131
132static void gzip_mark(void **ptr)
133{
134 *ptr = (void *) free_mem_ptr;
135}
136
137static void gzip_release(void **ptr)
138{
139 free_mem_ptr = (long) *ptr;
140}
141
142/* decompressor info and error messages to serial console */
143
144static void
145puts(const char *s)
146{
147#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
148 while(*s) {
149#ifdef CONFIG_ETRAX_DEBUG_PORT0
150 while(!(*R_SERIAL0_STATUS & (1 << 5))) ;
151 *R_SERIAL0_TR_DATA = *s++;
152#endif
153#ifdef CONFIG_ETRAX_DEBUG_PORT1
154 while(!(*R_SERIAL1_STATUS & (1 << 5))) ;
155 *R_SERIAL1_TR_DATA = *s++;
156#endif
157#ifdef CONFIG_ETRAX_DEBUG_PORT2
158 while(!(*R_SERIAL2_STATUS & (1 << 5))) ;
159 *R_SERIAL2_TR_DATA = *s++;
160#endif
161#ifdef CONFIG_ETRAX_DEBUG_PORT3
162 while(!(*R_SERIAL3_STATUS & (1 << 5))) ;
163 *R_SERIAL3_TR_DATA = *s++;
164#endif
165 }
166#endif
167}
168
169void*
170memset(void* s, int c, size_t n)
171{
172 int i;
173 char *ss = (char*)s;
174
175 for (i=0;i<n;i++) ss[i] = c;
176}
177
178void*
179memcpy(void* __dest, __const void* __src,
180 size_t __n)
181{
182 int i;
183 char *d = (char *)__dest, *s = (char *)__src;
184
185 for (i=0;i<__n;i++) d[i] = s[i];
186}
187
188/* ===========================================================================
189 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
190 * (Used for the decompressed data only.)
191 */
192
193static void
194flush_window()
195{
196 ulg c = crc; /* temporary variable */
197 unsigned n;
198 uch *in, *out, ch;
199
200 in = window;
201 out = &output_data[output_ptr];
202 for (n = 0; n < outcnt; n++) {
203 ch = *out++ = *in++;
204 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
205 }
206 crc = c;
207 bytes_out += (ulg)outcnt;
208 output_ptr += (ulg)outcnt;
209 outcnt = 0;
210}
211
212static void
213error(char *x)
214{
215 puts("\n\n");
216 puts(x);
217 puts("\n\n -- System halted\n");
218
219 while(1); /* Halt */
220}
221
222void
223setup_normal_output_buffer()
224{
225 output_data = (char *)KERNEL_LOAD_ADR;
226}
227
228void
229decompress_kernel()
230{
231 char revision;
232
233 /* input_data is set in head.S */
234 inbuf = input_data;
235
236#ifdef CONFIG_ETRAX_DEBUG_PORT0
237 *R_SERIAL0_XOFF = 0;
238 *R_SERIAL0_BAUD = 0x99;
239 *R_SERIAL0_TR_CTRL = 0x40;
240#endif
241#ifdef CONFIG_ETRAX_DEBUG_PORT1
242 *R_SERIAL1_XOFF = 0;
243 *R_SERIAL1_BAUD = 0x99;
244 *R_SERIAL1_TR_CTRL = 0x40;
245#endif
246#ifdef CONFIG_ETRAX_DEBUG_PORT2
247 *R_GEN_CONFIG = 0x08;
248 *R_SERIAL2_XOFF = 0;
249 *R_SERIAL2_BAUD = 0x99;
250 *R_SERIAL2_TR_CTRL = 0x40;
251#endif
252#ifdef CONFIG_ETRAX_DEBUG_PORT3
253 *R_GEN_CONFIG = 0x100;
254 *R_SERIAL3_XOFF = 0;
255 *R_SERIAL3_BAUD = 0x99;
256 *R_SERIAL3_TR_CTRL = 0x40;
257#endif
258
259 setup_normal_output_buffer();
260
261 makecrc();
262
263 __asm__ volatile ("move vr,%0" : "=rm" (revision));
264 if (revision < 10)
265 {
266 puts("You need an ETRAX 100LX to run linux 2.6\n");
267 while(1);
268 }
269
270 puts("Uncompressing Linux...\n");
271 gunzip();
272 puts("Done. Now booting the kernel.\n");
273}
diff --git a/arch/cris/arch-v10/boot/rescue/Makefile b/arch/cris/arch-v10/boot/rescue/Makefile
new file mode 100644
index 00000000000..e9f2ba2ad02
--- /dev/null
+++ b/arch/cris/arch-v10/boot/rescue/Makefile
@@ -0,0 +1,55 @@
1#
2# Makefile for rescue code
3#
4ifndef TOPDIR
5TOPDIR = ../../../..
6endif
7CC = gcc-cris -mlinux -I $(TOPDIR)/include
8CFLAGS = -O2
9LD = gcc-cris -mlinux -nostdlib
10OBJCOPY = objcopy-cris
11OBJCOPYFLAGS = -O binary --remove-section=.bss
12
13all: rescue.bin testrescue.bin kimagerescue.bin
14
15rescue: rescue.bin
16 # do nothing
17
18rescue.bin: head.o
19 $(LD) -T rescue.ld -o rescue.o head.o
20 $(OBJCOPY) $(OBJCOPYFLAGS) rescue.o rescue.bin
21 cp rescue.bin $(TOPDIR)
22
23testrescue.bin: testrescue.o
24 $(OBJCOPY) $(OBJCOPYFLAGS) testrescue.o tr.bin
25# Pad it to 784 bytes
26 dd if=/dev/zero of=tmp2423 bs=1 count=784
27 cat tr.bin tmp2423 >testrescue_tmp.bin
28 dd if=testrescue_tmp.bin of=testrescue.bin bs=1 count=784
29 rm tr.bin tmp2423 testrescue_tmp.bin
30
31kimagerescue.bin: kimagerescue.o
32 $(OBJCOPY) $(OBJCOPYFLAGS) kimagerescue.o ktr.bin
33# Pad it to 784 bytes, that's what the rescue loader expects
34 dd if=/dev/zero of=tmp2423 bs=1 count=784
35 cat ktr.bin tmp2423 >kimagerescue_tmp.bin
36 dd if=kimagerescue_tmp.bin of=kimagerescue.bin bs=1 count=784
37 rm ktr.bin tmp2423 kimagerescue_tmp.bin
38
39head.o: head.S
40 $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
41
42testrescue.o: testrescue.S
43 $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
44
45kimagerescue.o: kimagerescue.S
46 $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
47
48clean:
49 rm -f *.o *.bin
50
51fastdep:
52
53modules:
54
55modules-install:
diff --git a/arch/cris/arch-v10/boot/rescue/head.S b/arch/cris/arch-v10/boot/rescue/head.S
new file mode 100644
index 00000000000..8689ea972c4
--- /dev/null
+++ b/arch/cris/arch-v10/boot/rescue/head.S
@@ -0,0 +1,333 @@
1/* $Id: head.S,v 1.6 2003/04/09 08:12:43 pkj Exp $
2 *
3 * Rescue code, made to reside at the beginning of the
4 * flash-memory. when it starts, it checks a partition
5 * table at the first sector after the rescue sector.
6 * the partition table was generated by the product builder
7 * script and contains offsets, lengths, types and checksums
8 * for each partition that this code should check.
9 *
10 * If any of the checksums fail, we assume the flash is so
11 * corrupt that we cant use it to boot into the ftp flash
12 * loader, and instead we initialize the serial port to
13 * receive a flash-loader and new flash image. we dont include
14 * any flash code here, but just accept a certain amount of
15 * bytes from the serial port and jump into it. the downloaded
16 * code is put in the cache.
17 *
18 * The partitiontable is designed so that it is transparent to
19 * code execution - it has a relative branch opcode in the
20 * beginning that jumps over it. each entry contains extra
21 * data so we can add stuff later.
22 *
23 * Partition table format:
24 *
25 * Code transparency:
26 *
27 * 2 bytes [opcode 'nop']
28 * 2 bytes [opcode 'di']
29 * 4 bytes [opcode 'ba <offset>', 8-bit or 16-bit version]
30 * 2 bytes [opcode 'nop', delay slot]
31 *
32 * Table validation (at +10):
33 *
34 * 2 bytes [magic/version word for partitiontable - 0xef, 0xbe]
35 * 2 bytes [length of all entries plus the end marker]
36 * 4 bytes [checksum for the partitiontable itself]
37 *
38 * Entries, each with the following format, last has offset -1:
39 *
40 * 4 bytes [offset in bytes, from start of flash]
41 * 4 bytes [length in bytes of partition]
42 * 4 bytes [checksum, simple longword sum]
43 * 2 bytes [partition type]
44 * 2 bytes [flags, only bit 0 used, ro/rw = 1/0]
45 * 16 bytes [reserved for future use]
46 *
47 * End marker
48 *
49 * 4 bytes [-1]
50 *
51 * 10 bytes [0, padding]
52 *
53 * Bit 0 in flags signifies RW or RO. The rescue code only bothers
54 * to check the checksum for RO partitions, since the others will
55 * change their data without updating the checksums. A 1 in bit 0
56 * means RO, 0 means RW. That way, it is possible to set a partition
57 * in RO mode initially, and later mark it as RW, since you can always
58 * write 0's to the flash.
59 *
60 * During the wait for serial input, the status LED will flash so the
61 * user knows something went wrong.
62 *
63 * Copyright (C) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
64 */
65
66#include <linux/config.h>
67#define ASSEMBLER_MACROS_ONLY
68#include <asm/arch/sv_addr_ag.h>
69
70 ;; The partitiontable is looked for at the first sector after the boot
71 ;; sector. Sector size is 65536 bytes in all flashes we use.
72
73#define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR
74#define PTABLE_MAGIC 0xbeef
75
76 ;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0.
77 ;; That is not where we put our downloaded serial boot-code. The length is
78 ;; enough for downloading code that loads the rest of itself (after
79 ;; having setup the DRAM etc). It is the same length as the on-chip
80 ;; ROM loads, so the same host loader can be used to load a rescued
81 ;; product as well as one booted through the Etrax serial boot code.
82
83#define CODE_START 0x40000000
84#define CODE_LENGTH 784
85
86#ifdef CONFIG_ETRAX_RESCUE_SER0
87#define SERXOFF R_SERIAL0_XOFF
88#define SERBAUD R_SERIAL0_BAUD
89#define SERRECC R_SERIAL0_REC_CTRL
90#define SERRDAT R_SERIAL0_REC_DATA
91#define SERSTAT R_SERIAL0_STATUS
92#endif
93#ifdef CONFIG_ETRAX_RESCUE_SER1
94#define SERXOFF R_SERIAL1_XOFF
95#define SERBAUD R_SERIAL1_BAUD
96#define SERRECC R_SERIAL1_REC_CTRL
97#define SERRDAT R_SERIAL1_REC_DATA
98#define SERSTAT R_SERIAL1_STATUS
99#endif
100#ifdef CONFIG_ETRAX_RESCUE_SER2
101#define SERXOFF R_SERIAL2_XOFF
102#define SERBAUD R_SERIAL2_BAUD
103#define SERRECC R_SERIAL2_REC_CTRL
104#define SERRDAT R_SERIAL2_REC_DATA
105#define SERSTAT R_SERIAL2_STATUS
106#endif
107#ifdef CONFIG_ETRAX_RESCUE_SER3
108#define SERXOFF R_SERIAL3_XOFF
109#define SERBAUD R_SERIAL3_BAUD
110#define SERRECC R_SERIAL3_REC_CTRL
111#define SERRDAT R_SERIAL3_REC_DATA
112#define SERSTAT R_SERIAL3_STATUS
113#endif
114
115#define NOP_DI 0xf025050f
116#define RAM_INIT_MAGIC 0x56902387
117
118 .text
119
120 ;; This is the entry point of the rescue code
121 ;; 0x80000000 if loaded in flash (as it should be)
122 ;; since etrax actually starts at address 2 when booting from flash, we
123 ;; put a nop (2 bytes) here first so we dont accidentally skip the di
124
125 nop
126 di
127
128 jump in_cache ; enter cached area instead
129in_cache:
130
131 ;; first put a jump test to give a possibility of upgrading the rescue code
132 ;; without erasing/reflashing the sector. we put a longword of -1 here and if
133 ;; it is not -1, we jump using the value as jump target. since we can always
134 ;; change 1's to 0's without erasing the sector, it is possible to add new
135 ;; code after this and altering the jumptarget in an upgrade.
136
137jtcd: move.d [jumptarget], $r0
138 cmp.d 0xffffffff, $r0
139 beq no_newjump
140 nop
141
142 jump [$r0]
143
144jumptarget:
145 .dword 0xffffffff ; can be overwritten later to insert new code
146
147no_newjump:
148#ifdef CONFIG_ETRAX_ETHERNET
149 ;; Start MII clock to make sure it is running when tranceiver is reset
150 move.d 0x3, $r0 ; enable = on, phy = mii_clk
151 move.d $r0, [R_NETWORK_GEN_CONFIG]
152#endif
153
154 ;; We need to setup the bus registers before we start using the DRAM
155#include "../../lib/dram_init.S"
156
157 ;; we now should go through the checksum-table and check the listed
158 ;; partitions for errors.
159
160 move.d PTABLE_START, $r3
161 move.d [$r3], $r0
162 cmp.d NOP_DI, $r0 ; make sure the nop/di is there...
163 bne do_rescue
164 nop
165
166 ;; skip the code transparency block (10 bytes).
167
168 addq 10, $r3
169
170 ;; check for correct magic
171
172 move.w [$r3+], $r0
173 cmp.w PTABLE_MAGIC, $r0
174 bne do_rescue ; didn't recognize - trig rescue
175 nop
176
177 ;; check for correct ptable checksum
178
179 movu.w [$r3+], $r2 ; ptable length
180 move.d $r2, $r8 ; save for later, length of total ptable
181 addq 28, $r8 ; account for the rest
182 move.d [$r3+], $r4 ; ptable checksum
183 move.d $r3, $r1
184 jsr checksum ; r1 source, r2 length, returns in r0
185
186 cmp.d $r0, $r4
187 bne do_rescue ; didn't match - trig rescue
188 nop
189
190 ;; ptable is ok. validate each entry.
191
192 moveq -1, $r7
193
194ploop: move.d [$r3+], $r1 ; partition offset (from ptable start)
195 bne notfirst ; check if it is the partition containing ptable
196 nop ; yes..
197 move.d $r8, $r1 ; for its checksum check, skip the ptable
198 move.d [$r3+], $r2 ; partition length
199 sub.d $r8, $r2 ; minus the ptable length
200 ba bosse
201 nop
202notfirst:
203 cmp.d -1, $r1 ; the end of the ptable ?
204 beq flash_ok ; if so, the flash is validated
205 move.d [$r3+], $r2 ; partition length
206bosse: move.d [$r3+], $r5 ; checksum
207 move.d [$r3+], $r4 ; type and flags
208 addq 16, $r3 ; skip the reserved bytes
209 btstq 16, $r4 ; check ro flag
210 bpl ploop ; rw partition, skip validation
211 nop
212 btstq 17, $r4 ; check bootable flag
213 bpl 1f
214 nop
215 move.d $r1, $r7 ; remember boot partition offset
2161:
217
218 add.d PTABLE_START, $r1
219
220 jsr checksum ; checksum the partition
221
222 cmp.d $r0, $r5
223 beq ploop ; checksums matched, go to next entry
224 nop
225
226 ;; otherwise fall through to the rescue code.
227
228do_rescue:
229 ;; setup port PA and PB default initial directions and data
230 ;; (so we can flash LEDs, and so that DTR and others are set)
231
232 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
233 move.b $r0, [R_PORT_PA_DIR]
234 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
235 move.b $r0, [R_PORT_PA_DATA]
236
237 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
238 move.b $r0, [R_PORT_PB_DIR]
239 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
240 move.b $r0, [R_PORT_PB_DATA]
241
242 ;; setup the serial port at 115200 baud
243
244 moveq 0, $r0
245 move.d $r0, [SERXOFF]
246
247 move.b 0x99, $r0
248 move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit and receive
249
250 move.b 0x40, $r0 ; rec enable
251 move.b $r0, [SERRECC]
252
253 moveq 0, $r1 ; "timer" to clock out a LED red flash
254 move.d CODE_START, $r3 ; destination counter
255 movu.w CODE_LENGTH, $r4; length
256
257wait_ser:
258 addq 1, $r1
259#ifndef CONFIG_ETRAX_NO_LEDS
260#ifdef CONFIG_ETRAX_PA_LEDS
261 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
262#endif
263#ifdef CONFIG_ETRAX_PB_LEDS
264 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
265#endif
266 move.d (1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
267 btstq 16, $r1
268 bpl 1f
269 nop
270 or.d $r0, $r2 ; set bit
271 ba 2f
272 nop
2731: not $r0 ; clear bit
274 and.d $r0, $r2
2752:
276#ifdef CONFIG_ETRAX_PA_LEDS
277 move.b $r2, [R_PORT_PA_DATA]
278#endif
279#ifdef CONFIG_ETRAX_PB_LEDS
280 move.b $r2, [R_PORT_PB_DATA]
281#endif
282#ifdef CONFIG_ETRAX_90000000_LEDS
283 move.b $r2, [0x90000000]
284#endif
285#endif
286
287 ;; check if we got something on the serial port
288
289 move.b [SERSTAT], $r0
290 btstq 0, $r0 ; data_avail
291 bpl wait_ser
292 nop
293
294 ;; got something - copy the byte and loop
295
296 move.b [SERRDAT], $r0
297 move.b $r0, [$r3+]
298
299 subq 1, $r4 ; decrease length
300 bne wait_ser
301 nop
302
303 ;; jump into downloaded code
304
305 move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is initialized
306 jump CODE_START
307
308flash_ok:
309 ;; check r7, which contains either -1 or the partition to boot from
310
311 cmp.d -1, $r7
312 bne 1f
313 nop
314 move.d PTABLE_START, $r7; otherwise use the ptable start
3151:
316 move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is initialized
317 jump $r7 ; boot!
318
319
320 ;; Helper subroutines
321
322 ;; Will checksum by simple addition
323 ;; r1 - source
324 ;; r2 - length in bytes
325 ;; result will be in r0
326checksum:
327 moveq 0, $r0
3281: addu.b [$r1+], $r0
329 subq 1, $r2
330 bne 1b
331 nop
332 ret
333 nop
diff --git a/arch/cris/arch-v10/boot/rescue/kimagerescue.S b/arch/cris/arch-v10/boot/rescue/kimagerescue.S
new file mode 100644
index 00000000000..264bf7afc9a
--- /dev/null
+++ b/arch/cris/arch-v10/boot/rescue/kimagerescue.S
@@ -0,0 +1,144 @@
1/* $Id: kimagerescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
2 *
3 * Rescue code to be prepended on a kimage and copied to the
4 * rescue serial port.
5 * This is called from the rescue code, it will copy received data to
6 * 4004000 and after a timeout jump to it.
7 */
8
9#include <linux/config.h>
10#define ASSEMBLER_MACROS_ONLY
11#include <asm/sv_addr_ag.h>
12
13#define CODE_START 0x40004000
14#define CODE_LENGTH 784
15#define TIMEOUT_VALUE 1000
16
17
18#ifdef CONFIG_ETRAX_RESCUE_SER0
19#define SERXOFF R_SERIAL0_XOFF
20#define SERBAUD R_SERIAL0_BAUD
21#define SERRECC R_SERIAL0_REC_CTRL
22#define SERRDAT R_SERIAL0_REC_DATA
23#define SERSTAT R_SERIAL0_STATUS
24#endif
25#ifdef CONFIG_ETRAX_RESCUE_SER1
26#define SERXOFF R_SERIAL1_XOFF
27#define SERBAUD R_SERIAL1_BAUD
28#define SERRECC R_SERIAL1_REC_CTRL
29#define SERRDAT R_SERIAL1_REC_DATA
30#define SERSTAT R_SERIAL1_STATUS
31#endif
32#ifdef CONFIG_ETRAX_RESCUE_SER2
33#define SERXOFF R_SERIAL2_XOFF
34#define SERBAUD R_SERIAL2_BAUD
35#define SERRECC R_SERIAL2_REC_CTRL
36#define SERRDAT R_SERIAL2_REC_DATA
37#define SERSTAT R_SERIAL2_STATUS
38#endif
39#ifdef CONFIG_ETRAX_RESCUE_SER3
40#define SERXOFF R_SERIAL3_XOFF
41#define SERBAUD R_SERIAL3_BAUD
42#define SERRECC R_SERIAL3_REC_CTRL
43#define SERRDAT R_SERIAL3_REC_DATA
44#define SERSTAT R_SERIAL3_STATUS
45#endif
46
47 .text
48 ;; This is the entry point of the rescue code
49 ;; 0x80000000 if loaded in flash (as it should be)
50 ;; since etrax actually starts at address 2 when booting from flash, we
51 ;; put a nop (2 bytes) here first so we dont accidentally skip the di
52
53 nop
54 di
55#ifndef CONFIG_SVINTO_SIM
56 ;; setup port PA and PB default initial directions and data
57 ;; (so we can flash LEDs, and so that DTR and others are set)
58
59 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
60 move.b $r0, [R_PORT_PA_DIR]
61 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
62 move.b $r0, [R_PORT_PA_DATA]
63
64 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
65 move.b $r0, [R_PORT_PB_DIR]
66 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
67 move.b $r0, [R_PORT_PB_DATA]
68
69 ;; We need to setup the bus registers before we start using the DRAM
70#include "../../lib/dram_init.S"
71
72#endif
73 ;; Setup the stack to a suitably high address.
74 ;; We assume 8 MB is the minimum DRAM in an eLinux
75 ;; product and put the sp at the top for now.
76
77 move.d 0x40800000, $sp
78
79 ;; setup the serial port at 115200 baud
80
81 moveq 0, $r0
82 move.d $r0, [SERXOFF]
83
84 move.b 0x99, $r0
85 move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit and receive
86
87 move.b 0x40, $r0 ; rec enable
88 move.b $r0, [SERRECC]
89
90
91 moveq 0, $r1 ; "timer" to clock out a LED red flash
92 move.d CODE_START, $r3 ; destination counter
93 move.d CODE_LENGTH, $r4 ; length
94 move.d TIMEOUT_VALUE, $r5 ; "timeout" until jump
95
96wait_ser:
97 addq 1, $r1
98 subq 1, $r5 ; decrease timeout
99 beq jump_start ; timed out
100 nop
101#ifndef CONFIG_ETRAX_NO_LEDS
102#ifdef CONFIG_ETRAX_PA_LEDS
103 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
104#endif
105#ifdef CONFIG_ETRAX_PB_LEDS
106 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
107#endif
108 move.d (1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
109 btstq 16, $r1
110 bpl 1f
111 nop
112 or.d $r0, $r2 ; set bit
113 ba 2f
114 nop
1151: not $r0 ; clear bit
116 and.d $r0, $r2
1172:
118#ifdef CONFIG_ETRAX_PA_LEDS
119 move.b $r2, [R_PORT_PA_DATA]
120#endif
121#ifdef CONFIG_ETRAX_PB_LEDS
122 move.b $r2, [R_PORT_PB_DATA]
123#endif
124#endif
125
126 ;; check if we got something on the serial port
127
128 move.b [SERSTAT], $r0
129 btstq 0, $r0 ; data_avail
130 bpl wait_ser
131 nop
132
133 ;; got something - copy the byte and loop
134
135 move.b [SERRDAT], $r0
136 move.b $r0, [$r3+]
137 move.d TIMEOUT_VALUE, $r5 ; reset "timeout"
138 subq 1, $r4 ; decrease length
139 bne wait_ser
140 nop
141jump_start:
142 ;; jump into downloaded code
143
144 jump CODE_START
diff --git a/arch/cris/arch-v10/boot/rescue/rescue.ld b/arch/cris/arch-v10/boot/rescue/rescue.ld
new file mode 100644
index 00000000000..0b52a9490db
--- /dev/null
+++ b/arch/cris/arch-v10/boot/rescue/rescue.ld
@@ -0,0 +1,20 @@
1MEMORY
2 {
3 flash : ORIGIN = 0x00000000,
4 LENGTH = 0x00100000
5 }
6
7SECTIONS
8{
9 .text :
10 {
11 stext = . ;
12 *(.text)
13 etext = . ;
14 } > flash
15 .data :
16 {
17 *(.data)
18 edata = . ;
19 } > flash
20}
diff --git a/arch/cris/arch-v10/boot/rescue/testrescue.S b/arch/cris/arch-v10/boot/rescue/testrescue.S
new file mode 100644
index 00000000000..566a9f34125
--- /dev/null
+++ b/arch/cris/arch-v10/boot/rescue/testrescue.S
@@ -0,0 +1,26 @@
1/* $Id: testrescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
2 *
3 * Simple testcode to download by the rescue block.
4 * Just lits some LEDs to show it was downloaded correctly.
5 *
6 * Copyright (C) 1999 Axis Communications AB
7 */
8
9#define ASSEMBLER_MACROS_ONLY
10#include <asm/sv_addr_ag.h>
11
12 .text
13
14 nop
15 nop
16 moveq -1, $r2
17 move.b $r2, [R_PORT_PA_DIR]
18 moveq 0, $r2
19 move.b $r2, [R_PORT_PA_DATA]
20
21endless:
22 nop
23 ba endless
24 nop
25
26
diff --git a/arch/cris/arch-v10/boot/tools/build.c b/arch/cris/arch-v10/boot/tools/build.c
new file mode 100644
index 00000000000..2f9bbb26d60
--- /dev/null
+++ b/arch/cris/arch-v10/boot/tools/build.c
@@ -0,0 +1,288 @@
1/*
2 * linux/tools/build.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7/*
8 * This file builds a disk-image from three different files:
9 *
10 * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
11 * - setup: 8086 machine code, sets up system parm
12 * - system: 80386 code for actual system
13 *
14 * It does some checking that all files are of the correct type, and
15 * just writes the result to stdout, removing headers and padding to
16 * the right amount. It also writes some system data to stderr.
17 */
18
19/*
20 * Changes by tytso to allow root device specification
21 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
22 * Cross compiling fixes by Gertjan van Wingerde, July 1996
23 */
24
25#include <stdio.h> /* fprintf */
26#include <string.h>
27#include <stdlib.h> /* contains exit */
28#include <sys/types.h> /* unistd.h needs this */
29#include <sys/stat.h>
30#include <sys/sysmacros.h>
31#include <unistd.h> /* contains read/write */
32#include <fcntl.h>
33#include <linux/a.out.h>
34#include <errno.h>
35
36#define MINIX_HEADER 32
37
38#define N_MAGIC_OFFSET 1024
39#ifndef __BFD__
40static int GCC_HEADER = sizeof(struct exec);
41#endif
42
43#ifdef __BIG_KERNEL__
44#define SYS_SIZE 0xffff
45#else
46#define SYS_SIZE DEF_SYSSIZE
47#endif
48
49#define DEFAULT_MAJOR_ROOT 0
50#define DEFAULT_MINOR_ROOT 0
51
52/* max nr of sectors of setup: don't change unless you also change
53 * bootsect etc */
54#define SETUP_SECTS 4
55
56#define STRINGIFY(x) #x
57
58typedef union {
59 int i;
60 long l;
61 short s[2];
62 char b[4];
63} conv;
64
65long intel_long(long l)
66{
67 conv t;
68
69 t.b[0] = l & 0xff; l >>= 8;
70 t.b[1] = l & 0xff; l >>= 8;
71 t.b[2] = l & 0xff; l >>= 8;
72 t.b[3] = l & 0xff; l >>= 8;
73 return t.l;
74}
75
76int intel_int(int i)
77{
78 conv t;
79
80 t.b[0] = i & 0xff; i >>= 8;
81 t.b[1] = i & 0xff; i >>= 8;
82 t.b[2] = i & 0xff; i >>= 8;
83 t.b[3] = i & 0xff; i >>= 8;
84 return t.i;
85}
86
87short intel_short(short l)
88{
89 conv t;
90
91 t.b[0] = l & 0xff; l >>= 8;
92 t.b[1] = l & 0xff; l >>= 8;
93 return t.s[0];
94}
95
96void die(const char * str)
97{
98 fprintf(stderr,"%s\n",str);
99 exit(1);
100}
101
102void usage(void)
103{
104 die("Usage: build bootsect setup system [rootdev] [> image]");
105}
106
107int main(int argc, char ** argv)
108{
109 int i,c,id,sz,tmp_int;
110 unsigned long sys_size, tmp_long;
111 char buf[1024];
112#ifndef __BFD__
113 struct exec *ex = (struct exec *)buf;
114#endif
115 char major_root, minor_root;
116 struct stat sb;
117 unsigned char setup_sectors;
118
119 if ((argc < 4) || (argc > 5))
120 usage();
121 if (argc > 4) {
122 if (!strcmp(argv[4], "CURRENT")) {
123 if (stat("/", &sb)) {
124 perror("/");
125 die("Couldn't stat /");
126 }
127 major_root = major(sb.st_dev);
128 minor_root = minor(sb.st_dev);
129 } else if (strcmp(argv[4], "FLOPPY")) {
130 if (stat(argv[4], &sb)) {
131 perror(argv[4]);
132 die("Couldn't stat root device.");
133 }
134 major_root = major(sb.st_rdev);
135 minor_root = minor(sb.st_rdev);
136 } else {
137 major_root = 0;
138 minor_root = 0;
139 }
140 } else {
141 major_root = DEFAULT_MAJOR_ROOT;
142 minor_root = DEFAULT_MINOR_ROOT;
143 }
144 fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
145 for (i=0;i<sizeof buf; i++) buf[i]=0;
146 if ((id=open(argv[1],O_RDONLY,0))<0)
147 die("Unable to open 'boot'");
148 if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
149 die("Unable to read header of 'boot'");
150 if (((long *) buf)[0]!=intel_long(0x04100301))
151 die("Non-Minix header of 'boot'");
152 if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
153 die("Non-Minix header of 'boot'");
154 if (((long *) buf)[3] != 0)
155 die("Illegal data segment in 'boot'");
156 if (((long *) buf)[4] != 0)
157 die("Illegal bss in 'boot'");
158 if (((long *) buf)[5] != 0)
159 die("Non-Minix header of 'boot'");
160 if (((long *) buf)[7] != 0)
161 die("Illegal symbol table in 'boot'");
162 i=read(id,buf,sizeof buf);
163 fprintf(stderr,"Boot sector %d bytes.\n",i);
164 if (i != 512)
165 die("Boot block must be exactly 512 bytes");
166 if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
167 die("Boot block hasn't got boot flag (0xAA55)");
168 buf[508] = (char) minor_root;
169 buf[509] = (char) major_root;
170 i=write(1,buf,512);
171 if (i!=512)
172 die("Write call failed");
173 close (id);
174
175 if ((id=open(argv[2],O_RDONLY,0))<0)
176 die("Unable to open 'setup'");
177 if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
178 die("Unable to read header of 'setup'");
179 if (((long *) buf)[0]!=intel_long(0x04100301))
180 die("Non-Minix header of 'setup'");
181 if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
182 die("Non-Minix header of 'setup'");
183 if (((long *) buf)[3] != 0)
184 die("Illegal data segment in 'setup'");
185 if (((long *) buf)[4] != 0)
186 die("Illegal bss in 'setup'");
187 if (((long *) buf)[5] != 0)
188 die("Non-Minix header of 'setup'");
189 if (((long *) buf)[7] != 0)
190 die("Illegal symbol table in 'setup'");
191 for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
192#ifdef __BIG_KERNEL__
193 {
194 if (!i) {
195 /* Working with memcpy because of alignment constraints
196 on Sparc - Gertjan */
197 memcpy(&tmp_long, &buf[2], sizeof(long));
198 if (tmp_long != intel_long(0x53726448) )
199 die("Wrong magic in loader header of 'setup'");
200 memcpy(&tmp_int, &buf[6], sizeof(int));
201 if (tmp_int < intel_int(0x200))
202 die("Wrong version of loader header of 'setup'");
203 buf[0x11] = 1; /* LOADED_HIGH */
204 tmp_long = intel_long(0x100000);
205 memcpy(&buf[0x14], &tmp_long, sizeof(long)); /* code32_start */
206 }
207#endif
208 if (write(1,buf,c)!=c)
209 die("Write call failed");
210#ifdef __BIG_KERNEL__
211 }
212#endif
213 if (c != 0)
214 die("read-error on 'setup'");
215 close (id);
216 setup_sectors = (unsigned char)((i + 511) / 512);
217 /* for compatibility with LILO */
218 if (setup_sectors < SETUP_SECTS)
219 setup_sectors = SETUP_SECTS;
220 fprintf(stderr,"Setup is %d bytes.\n",i);
221 for (c=0 ; c<sizeof(buf) ; c++)
222 buf[c] = '\0';
223 while (i < setup_sectors * 512) {
224 c = setup_sectors * 512 - i;
225 if (c > sizeof(buf))
226 c = sizeof(buf);
227 if (write(1,buf,c) != c)
228 die("Write call failed");
229 i += c;
230 }
231
232 if ((id=open(argv[3],O_RDONLY,0))<0)
233 die("Unable to open 'system'");
234#ifndef __BFD__
235 if (read(id,buf,GCC_HEADER) != GCC_HEADER)
236 die("Unable to read header of 'system'");
237 if (N_MAGIC(*ex) == ZMAGIC) {
238 GCC_HEADER = N_MAGIC_OFFSET;
239 lseek(id, GCC_HEADER, SEEK_SET);
240 } else if (N_MAGIC(*ex) != QMAGIC)
241 die("Non-GCC header of 'system'");
242 fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
243 (ex->a_text+ex->a_data+ex->a_bss)/1024,
244 ex->a_text /1024,
245 ex->a_data /1024,
246 ex->a_bss /1024);
247 sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
248#else
249 if (fstat (id, &sb)) {
250 perror ("fstat");
251 die ("Unable to stat 'system'");
252 }
253 sz = sb.st_size;
254 fprintf (stderr, "System is %d kB\n", sz/1024);
255#endif
256 sys_size = (sz + 15) / 16;
257 if (sys_size > SYS_SIZE)
258 die("System is too big");
259 while (sz > 0) {
260 int l, n;
261
262 l = sz;
263 if (l > sizeof(buf))
264 l = sizeof(buf);
265 if ((n=read(id, buf, l)) != l) {
266 if (n == -1)
267 perror(argv[1]);
268 else
269 fprintf(stderr, "Unexpected EOF\n");
270 die("Can't read 'system'");
271 }
272 if (write(1, buf, l) != l)
273 die("Write failed");
274 sz -= l;
275 }
276 close(id);
277 if (lseek(1, 497, 0) == 497) {
278 if (write(1, &setup_sectors, 1) != 1)
279 die("Write of setup sectors failed");
280 }
281 if (lseek(1,500,0) == 500) {
282 buf[0] = (sys_size & 0xff);
283 buf[1] = ((sys_size >> 8) & 0xff);
284 if (write(1, buf, 2) != 2)
285 die("Write failed");
286 }
287 return(0);
288}