diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-03 11:52:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-03 11:52:26 -0400 |
commit | ccaa36f73544163ef6e15eb29a620130755f6001 (patch) | |
tree | b5cf50592c45e25edbd66fea451e6941e455fa83 /arch/ppc/boot/utils/mkbugboot.c | |
parent | b4a9071af62f95dc6d22040a0b37ac7225ce4d54 (diff) | |
parent | 5e980823581682d1566e7b5089cf827ddd5f3c94 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (29 commits)
[POWERPC] Fix rheap alignment problem
[POWERPC] Use check_legacy_ioport() for ISAPnP
[POWERPC] Avoid NULL pointer in gpio1_interrupt
[POWERPC] Enable generic rtc hook for the MPC8349 mITX
[POWERPC] Add powerpc get/set_rtc_time interface to new generic rtc class
[POWERPC] Create a "wrapper" script and use it in arch/powerpc/boot
[POWERPC] fix spin lock nesting in hvc_iseries
[POWERPC] EEH failure to mark pci slot as frozen.
[POWERPC] update powerpc defconfig files after libata kconfig breakage
[POWERPC] enable sysrq in pmac32_defconfig
[POWERPC] UPIO_TSI cleanup
[POWERPC] rewrite mkprep and mkbugboot in sane C
[POWERPC] maple/pci iomem annotations
[POWERPC] powerpc oprofile __user annotations
[POWERPC] cell spufs iomem annotations
[POWERPC] NULL noise removal: spufs
[POWERPC] ppc math-emu needs -fno-builtin-fabs for math.c and fabs.c
[POWERPC] update mpc8349_itx_defconfig and remove some debug settings
[POWERPC] Always call cede in pseries dedicated idle loop
[POWERPC] Fix loop logic in irq_alloc_virt()
...
Diffstat (limited to 'arch/ppc/boot/utils/mkbugboot.c')
-rw-r--r-- | arch/ppc/boot/utils/mkbugboot.c | 208 |
1 files changed, 85 insertions, 123 deletions
diff --git a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c index 29115e01f60a..1640c4199ca6 100644 --- a/arch/ppc/boot/utils/mkbugboot.c +++ b/arch/ppc/boot/utils/mkbugboot.c | |||
@@ -19,36 +19,13 @@ | |||
19 | #include <stdlib.h> | 19 | #include <stdlib.h> |
20 | #include <errno.h> | 20 | #include <errno.h> |
21 | #include <fcntl.h> | 21 | #include <fcntl.h> |
22 | #include <netinet/in.h> | ||
22 | #ifdef __sun__ | 23 | #ifdef __sun__ |
23 | #include <inttypes.h> | 24 | #include <inttypes.h> |
24 | #else | 25 | #else |
25 | #include <stdint.h> | 26 | #include <stdint.h> |
26 | #endif | 27 | #endif |
27 | 28 | ||
28 | #ifdef __i386__ | ||
29 | #define cpu_to_be32(x) le32_to_cpu(x) | ||
30 | #define cpu_to_be16(x) le16_to_cpu(x) | ||
31 | #else | ||
32 | #define cpu_to_be32(x) (x) | ||
33 | #define cpu_to_be16(x) (x) | ||
34 | #endif | ||
35 | |||
36 | #define cpu_to_le32(x) le32_to_cpu((x)) | ||
37 | unsigned long le32_to_cpu(unsigned long x) | ||
38 | { | ||
39 | return (((x & 0x000000ffU) << 24) | | ||
40 | ((x & 0x0000ff00U) << 8) | | ||
41 | ((x & 0x00ff0000U) >> 8) | | ||
42 | ((x & 0xff000000U) >> 24)); | ||
43 | } | ||
44 | |||
45 | #define cpu_to_le16(x) le16_to_cpu((x)) | ||
46 | unsigned short le16_to_cpu(unsigned short x) | ||
47 | { | ||
48 | return (((x & 0x00ff) << 8) | | ||
49 | ((x & 0xff00) >> 8)); | ||
50 | } | ||
51 | |||
52 | /* size of read buffer */ | 29 | /* size of read buffer */ |
53 | #define SIZE 0x1000 | 30 | #define SIZE 0x1000 |
54 | 31 | ||
@@ -62,124 +39,109 @@ typedef struct bug_boot_header { | |||
62 | 39 | ||
63 | #define HEADER_SIZE sizeof(bug_boot_header_t) | 40 | #define HEADER_SIZE sizeof(bug_boot_header_t) |
64 | 41 | ||
65 | uint32_t copy_image(int32_t in_fd, int32_t out_fd) | 42 | void update_checksum(void *buf, size_t size, uint16_t *sum) |
66 | { | 43 | { |
67 | uint8_t buf[SIZE]; | 44 | uint32_t csum = *sum; |
68 | int n; | 45 | |
69 | uint32_t image_size = 0; | 46 | while (size) { |
70 | uint8_t zero = 0; | 47 | csum += *(uint16_t *)buf; |
71 | 48 | if (csum > 0xffff) | |
72 | lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); | 49 | csum -= 0xffff; |
73 | 50 | buf = (uint16_t *)buf + 1; | |
74 | /* Copy an image while recording its size */ | 51 | size -= 2; |
75 | while ( (n = read(in_fd, buf, SIZE)) > 0 ) | 52 | } |
76 | { | 53 | *sum = csum; |
77 | image_size = image_size + n; | ||
78 | write(out_fd, buf, n); | ||
79 | } | ||
80 | |||
81 | /* BUG romboot requires that our size is divisible by 2 */ | ||
82 | /* align image to 2 byte boundary */ | ||
83 | if (image_size % 2) | ||
84 | { | ||
85 | image_size++; | ||
86 | write(out_fd, &zero, 1); | ||
87 | } | ||
88 | |||
89 | return image_size; | ||
90 | } | 54 | } |
91 | 55 | ||
92 | void write_bugboot_header(int32_t out_fd, uint32_t boot_size) | 56 | uint32_t copy_image(int in_fd, int out_fd, uint16_t *sum) |
93 | { | 57 | { |
94 | uint8_t header_block[HEADER_SIZE]; | 58 | uint8_t buf[SIZE]; |
95 | bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0]; | 59 | int offset = 0; |
96 | 60 | int n; | |
97 | memset(header_block, 0, HEADER_SIZE); | 61 | uint32_t image_size = 0; |
98 | 62 | ||
99 | /* Fill in the PPCBUG ROM boot header */ | 63 | lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); |
100 | strncpy(bbh->magic_word, "BOOT", 4); /* PPCBUG magic word */ | 64 | |
101 | bbh->entry_offset = cpu_to_be32(HEADER_SIZE); /* Entry address */ | 65 | /* Copy an image while recording its size */ |
102 | bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2); /* Routine length */ | 66 | while ( (n = read(in_fd, buf + offset, SIZE - offset)) > 0 ) { |
103 | strncpy(bbh->routine_name, "LINUXROM", 8); /* Routine name */ | 67 | n += offset; |
104 | 68 | offset = n & 1; | |
105 | /* Output the header and bootloader to the file */ | 69 | n -= offset; |
106 | write(out_fd, header_block, HEADER_SIZE); | 70 | image_size = image_size + n; |
71 | /* who's going to deal with short writes? */ | ||
72 | write(out_fd, buf, n); | ||
73 | update_checksum(buf, n, sum); | ||
74 | if (offset) | ||
75 | buf[0] = buf[n]; | ||
76 | } | ||
77 | |||
78 | /* BUG romboot requires that our size is divisible by 2 */ | ||
79 | /* align image to 2 byte boundary */ | ||
80 | if (offset) { | ||
81 | image_size += 2; | ||
82 | buf[1] = '\0'; | ||
83 | write(out_fd, buf, 2); | ||
84 | update_checksum(buf, 2, sum); | ||
85 | } | ||
86 | return image_size; | ||
107 | } | 87 | } |
108 | 88 | ||
109 | uint16_t calc_checksum(int32_t bug_fd) | 89 | void write_bugboot_header(int out_fd, uint32_t boot_size, uint16_t *sum) |
110 | { | 90 | { |
111 | uint32_t checksum_var = 0; | 91 | static bug_boot_header_t bbh = { |
112 | uint8_t buf[2]; | 92 | .magic_word = "BOOT", |
113 | int n; | 93 | .routine_name = "LINUXROM" |
114 | 94 | }; | |
115 | /* Checksum loop */ | 95 | |
116 | while ( (n = read(bug_fd, buf, 2) ) ) | 96 | /* Fill in the PPCBUG ROM boot header */ |
117 | { | 97 | bbh.entry_offset = htonl(HEADER_SIZE); /* Entry address */ |
118 | checksum_var = checksum_var + *(uint16_t *)buf; | 98 | bbh.routine_length= htonl(HEADER_SIZE+boot_size+2); /* Routine length */ |
119 | 99 | ||
120 | /* If we carry out, mask it and add one to the checksum */ | 100 | /* Output the header and bootloader to the file */ |
121 | if (checksum_var >> 16) | 101 | write(out_fd, &bbh, sizeof(bug_boot_header_t)); |
122 | checksum_var = (checksum_var & 0x0000ffff) + 1; | 102 | update_checksum(&bbh, sizeof(bug_boot_header_t), sum); |
123 | } | ||
124 | |||
125 | return checksum_var; | ||
126 | } | 103 | } |
127 | 104 | ||
128 | int main(int argc, char *argv[]) | 105 | int main(int argc, char *argv[]) |
129 | { | 106 | { |
130 | int32_t image_fd, bugboot_fd; | 107 | int image_fd, bugboot_fd; |
131 | int argptr = 1; | 108 | uint32_t kernel_size = 0; |
132 | uint32_t kernel_size = 0; | 109 | uint16_t checksum = 0; |
133 | uint16_t checksum = 0; | ||
134 | uint8_t bugbootname[256]; | ||
135 | |||
136 | if ( (argc != 3) ) | ||
137 | { | ||
138 | fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]); | ||
139 | exit(-1); | ||
140 | } | ||
141 | |||
142 | /* Get file args */ | ||
143 | |||
144 | /* kernel image file */ | ||
145 | if ((image_fd = open( argv[argptr] , 0)) < 0) | ||
146 | exit(-1); | ||
147 | argptr++; | ||
148 | 110 | ||
149 | /* bugboot file */ | 111 | if (argc != 3) { |
150 | if ( !strcmp( argv[argptr], "-" ) ) | 112 | fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]); |
151 | bugboot_fd = 1; /* stdout */ | 113 | exit(-1); |
152 | else | 114 | } |
153 | if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0) | ||
154 | exit(-1); | ||
155 | else | ||
156 | strcpy(bugbootname, argv[argptr]); | ||
157 | argptr++; | ||
158 | 115 | ||
159 | /* Set file position after ROM header block where zImage will be written */ | 116 | /* Get file args */ |
160 | lseek(bugboot_fd, HEADER_SIZE, SEEK_SET); | ||
161 | 117 | ||
162 | /* Copy kernel image into bugboot image */ | 118 | /* kernel image file */ |
163 | kernel_size = copy_image(image_fd, bugboot_fd); | 119 | if ((image_fd = open(argv[1] , 0)) < 0) |
164 | close(image_fd); | 120 | exit(-1); |
165 | 121 | ||
166 | /* Set file position to beginning where header/romboot will be written */ | 122 | /* bugboot file */ |
167 | lseek(bugboot_fd, 0, SEEK_SET); | 123 | if (!strcmp(argv[2], "-")) |
124 | bugboot_fd = 1; /* stdout */ | ||
125 | else if ((bugboot_fd = creat(argv[2] , 0755)) < 0) | ||
126 | exit(-1); | ||
168 | 127 | ||
169 | /* Write out BUG header/romboot */ | 128 | /* Set file position after ROM header block where zImage will be written */ |
170 | write_bugboot_header(bugboot_fd, kernel_size); | 129 | lseek(bugboot_fd, HEADER_SIZE, SEEK_SET); |
171 | 130 | ||
172 | /* Close bugboot file */ | 131 | /* Copy kernel image into bugboot image */ |
173 | close(bugboot_fd); | 132 | kernel_size = copy_image(image_fd, bugboot_fd, &checksum); |
174 | 133 | ||
175 | /* Reopen it as read/write */ | 134 | /* Set file position to beginning where header/romboot will be written */ |
176 | bugboot_fd = open(bugbootname, O_RDWR); | 135 | lseek(bugboot_fd, 0, SEEK_SET); |
177 | 136 | ||
178 | /* Calculate checksum */ | 137 | /* Write out BUG header/romboot */ |
179 | checksum = calc_checksum(bugboot_fd); | 138 | write_bugboot_header(bugboot_fd, kernel_size, &checksum); |
180 | 139 | ||
181 | /* Write out the calculated checksum */ | 140 | /* Write out the calculated checksum */ |
182 | write(bugboot_fd, &checksum, 2); | 141 | lseek(bugboot_fd, 0, SEEK_END); |
142 | write(bugboot_fd, &checksum, 2); | ||
183 | 143 | ||
184 | return 0; | 144 | /* Close bugboot file */ |
145 | close(bugboot_fd); | ||
146 | return 0; | ||
185 | } | 147 | } |