1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <byteswap.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 7 void xlate( char * inb, char * trb, unsigned len ) 8 { 9 unsigned i; 10 for ( i=0; i<len; ++i ) { 11 char c = *inb++; 12 char c1 = c >> 4; 13 char c2 = c & 0xf; 14 if ( c1 > 9 ) 15 c1 = c1 + 'A' - 10; 16 else 17 c1 = c1 + ''; 18 if ( c2 > 9 ) 19 c2 = c2 + 'A' - 10; 20 else 21 c2 = c2 + ''; 22 *trb++ = c1; 23 *trb++ = c2; 24 } 25 *trb = 0; 26 } 27 28 #define ElfHeaderSize (64 * 1024) 29 #define ElfPages (ElfHeaderSize / 4096) 30 #define KERNELBASE (0xc0000000) 31 32 void get4k( /*istream *inf*/FILE *file, char *buf ) 33 { 34 unsigned j; 35 unsigned num = fread(buf, 1, 4096, file); 36 for ( j=num; j<4096; ++j ) 37 buf[j] = 0; 38 } 39 40 void put4k( /*ostream *outf*/FILE *file, char *buf ) 41 { 42 fwrite(buf, 1, 4096, file); 43 } 44 45 int main(int argc, char **argv) 46 { 47 char inbuf[4096]; 48 FILE *ramDisk = NULL; 49 FILE *inputVmlinux = NULL; 50 FILE *outputVmlinux = NULL; 51 unsigned i = 0; 52 unsigned long ramFileLen = 0; 53 unsigned long ramLen = 0; 54 unsigned long roundR = 0; 55 unsigned long kernelLen = 0; 56 unsigned long actualKernelLen = 0; 57 unsigned long round = 0; 58 unsigned long roundedKernelLen = 0; 59 unsigned long ramStartOffs = 0; 60 unsigned long ramPages = 0; 61 unsigned long roundedKernelPages = 0; 62 if ( argc < 2 ) { 63 printf("Name of System Map file missing.\n"); 64 exit(1); 65 } 66 67 if ( argc < 3 ) { 68 printf("Name of vmlinux file missing.\n"); 69 exit(1); 70 } 71 72 if ( argc < 4 ) { 73 printf("Name of vmlinux output file missing.\n"); 74 exit(1); 75 } 76 77 ramDisk = fopen(argv[1], "r"); 78 if ( ! ramDisk ) { 79 printf("System Map file \"%s\" failed to open.\n", argv[1]); 80 exit(1); 81 } 82 inputVmlinux = fopen(argv[2], "r"); 83 if ( ! inputVmlinux ) { 84 printf("vmlinux file \"%s\" failed to open.\n", argv[2]); 85 exit(1); 86 } 87 outputVmlinux = fopen(argv[3], "w"); 88 if ( ! outputVmlinux ) { 89 printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); 90 exit(1); 91 } 92 fseek(ramDisk, 0, SEEK_END); 93 ramFileLen = ftell(ramDisk); 94 fseek(ramDisk, 0, SEEK_SET); 95 printf("%s file size = %ld\n", argv[1], ramFileLen); 96 97 ramLen = ramFileLen; 98 99 roundR = 4096 - (ramLen % 4096); 100 if ( roundR ) { 101 printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR); 102 ramLen += roundR; 103 } 104 105 printf("Rounded System Map size is %ld\n", ramLen); 106 fseek(inputVmlinux, 0, SEEK_END); 107 kernelLen = ftell(inputVmlinux); 108 fseek(inputVmlinux, 0, SEEK_SET); 109 printf("kernel file size = %ld\n", kernelLen); 110 if ( kernelLen == 0 ) { 111 printf("You must have a linux kernel specified as argv[2]\n"); 112 exit(1); 113 } 114 115 actualKernelLen = kernelLen - ElfHeaderSize; 116 117 printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen); 118 119 round = actualKernelLen % 4096; 120 roundedKernelLen = actualKernelLen; 121 if ( round ) 122 roundedKernelLen += (4096 - round); 123 124 printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen); 125 126 ramStartOffs = roundedKernelLen; 127 ramPages = ramLen / 4096; 128 129 printf("System map pages to copy = %ld\n", ramPages); 130 131 // Copy 64K ELF header 132 for (i=0; i<(ElfPages); ++i) { 133 get4k( inputVmlinux, inbuf ); 134 put4k( outputVmlinux, inbuf ); 135 } 136 137 138 139 roundedKernelPages = roundedKernelLen / 4096; 140 141 fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); 142 143 { 144 for ( i=0; i<roundedKernelPages; ++i ) { 145 get4k( inputVmlinux, inbuf ); 146 if ( i == 0 ) { 147 unsigned long * p; 148 printf("Storing embedded_sysmap_start at 0x3c\n"); 149 p = (unsigned long *)(inbuf + 0x3c); 150 151 #if (BYTE_ORDER == __BIG_ENDIAN) 152 *p = ramStartOffs; 153 #else 154 *p = bswap_32(ramStartOffs); 155 #endif 156 157 printf("Storing embedded_sysmap_end at 0x44\n"); 158 p = (unsigned long *)(inbuf + 0x44); 159 #if (BYTE_ORDER == __BIG_ENDIAN) 160 *p = ramStartOffs + ramFileLen; 161 #else 162 *p = bswap_32(ramStartOffs + ramFileLen); 163 #endif 164 } 165 put4k( outputVmlinux, inbuf ); 166 } 167 } 168 169 { 170 for ( i=0; i<ramPages; ++i ) { 171 get4k( ramDisk, inbuf ); 172 put4k( outputVmlinux, inbuf ); 173 } 174 } 175 176 177 fclose(ramDisk); 178 fclose(inputVmlinux); 179 fclose(outputVmlinux); 180 /* Set permission to executable */ 181 chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); 182 183 return 0; 184 185 } 186 187
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.