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 v2.6.12-rc4 203 lines 5.8 kB view raw
1#include <stdio.h> 2#include <stdlib.h> 3#include <netinet/in.h> 4#include <unistd.h> 5#include <sys/types.h> 6#include <sys/stat.h> 7#include <string.h> 8 9#define ElfHeaderSize (64 * 1024) 10#define ElfPages (ElfHeaderSize / 4096) 11#define KERNELBASE (0xc0000000) 12 13void get4k(FILE *file, char *buf ) 14{ 15 unsigned j; 16 unsigned num = fread(buf, 1, 4096, file); 17 for ( j=num; j<4096; ++j ) 18 buf[j] = 0; 19} 20 21void put4k(FILE *file, char *buf ) 22{ 23 fwrite(buf, 1, 4096, file); 24} 25 26void death(const char *msg, FILE *fdesc, const char *fname) 27{ 28 printf(msg); 29 fclose(fdesc); 30 unlink(fname); 31 exit(1); 32} 33 34int main(int argc, char **argv) 35{ 36 char inbuf[4096]; 37 FILE *ramDisk = NULL; 38 FILE *inputVmlinux = NULL; 39 FILE *outputVmlinux = NULL; 40 unsigned i = 0; 41 u_int32_t ramFileLen = 0; 42 u_int32_t ramLen = 0; 43 u_int32_t roundR = 0; 44 u_int32_t kernelLen = 0; 45 u_int32_t actualKernelLen = 0; 46 u_int32_t round = 0; 47 u_int32_t roundedKernelLen = 0; 48 u_int32_t ramStartOffs = 0; 49 u_int32_t ramPages = 0; 50 u_int32_t roundedKernelPages = 0; 51 u_int32_t hvReleaseData = 0; 52 u_int32_t eyeCatcher = 0xc8a5d9c4; 53 u_int32_t naca = 0; 54 u_int32_t xRamDisk = 0; 55 u_int32_t xRamDiskSize = 0; 56 if ( argc < 2 ) { 57 printf("Name of RAM disk file missing.\n"); 58 exit(1); 59 } 60 61 if ( argc < 3 ) { 62 printf("Name of vmlinux file missing.\n"); 63 exit(1); 64 } 65 66 if ( argc < 4 ) { 67 printf("Name of vmlinux output file missing.\n"); 68 exit(1); 69 } 70 71 ramDisk = fopen(argv[1], "r"); 72 if ( ! ramDisk ) { 73 printf("RAM disk file \"%s\" failed to open.\n", argv[1]); 74 exit(1); 75 } 76 inputVmlinux = fopen(argv[2], "r"); 77 if ( ! inputVmlinux ) { 78 printf("vmlinux file \"%s\" failed to open.\n", argv[2]); 79 exit(1); 80 } 81 outputVmlinux = fopen(argv[3], "w+"); 82 if ( ! outputVmlinux ) { 83 printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); 84 exit(1); 85 } 86 fseek(ramDisk, 0, SEEK_END); 87 ramFileLen = ftell(ramDisk); 88 fseek(ramDisk, 0, SEEK_SET); 89 printf("%s file size = %d\n", argv[1], ramFileLen); 90 91 ramLen = ramFileLen; 92 93 roundR = 4096 - (ramLen % 4096); 94 if ( roundR ) { 95 printf("Rounding RAM disk file up to a multiple of 4096, adding %d\n", roundR); 96 ramLen += roundR; 97 } 98 99 printf("Rounded RAM disk size is %d\n", ramLen); 100 fseek(inputVmlinux, 0, SEEK_END); 101 kernelLen = ftell(inputVmlinux); 102 fseek(inputVmlinux, 0, SEEK_SET); 103 printf("kernel file size = %d\n", kernelLen); 104 if ( kernelLen == 0 ) { 105 printf("You must have a linux kernel specified as argv[2]\n"); 106 exit(1); 107 } 108 109 actualKernelLen = kernelLen - ElfHeaderSize; 110 111 printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); 112 113 round = actualKernelLen % 4096; 114 roundedKernelLen = actualKernelLen; 115 if ( round ) 116 roundedKernelLen += (4096 - round); 117 118 printf("actual kernel length rounded up to a 4k multiple = %d\n", roundedKernelLen); 119 120 ramStartOffs = roundedKernelLen; 121 ramPages = ramLen / 4096; 122 123 printf("RAM disk pages to copy = %d\n", ramPages); 124 125 // Copy 64K ELF header 126 for (i=0; i<(ElfPages); ++i) { 127 get4k( inputVmlinux, inbuf ); 128 put4k( outputVmlinux, inbuf ); 129 } 130 131 roundedKernelPages = roundedKernelLen / 4096; 132 133 fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); 134 135 for ( i=0; i<roundedKernelPages; ++i ) { 136 get4k( inputVmlinux, inbuf ); 137 put4k( outputVmlinux, inbuf ); 138 } 139 140 for ( i=0; i<ramPages; ++i ) { 141 get4k( ramDisk, inbuf ); 142 put4k( outputVmlinux, inbuf ); 143 } 144 145 /* Close the input files */ 146 fclose(ramDisk); 147 fclose(inputVmlinux); 148 /* And flush the written output file */ 149 fflush(outputVmlinux); 150 151 /* fseek to the hvReleaseData pointer */ 152 fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); 153 if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { 154 death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[3]); 155 } 156 hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ 157 printf("hvReleaseData is at %08x\n", hvReleaseData); 158 159 /* fseek to the hvReleaseData */ 160 fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); 161 if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { 162 death("Could not read hvReleaseData\n", outputVmlinux, argv[3]); 163 } 164 /* Check hvReleaseData sanity */ 165 if (memcmp(inbuf, &eyeCatcher, 4) != 0) { 166 death("hvReleaseData is invalid\n", outputVmlinux, argv[3]); 167 } 168 /* Get the naca pointer */ 169 naca = ntohl(*((u_int32_t *) &inbuf[0x0c])) - KERNELBASE; 170 printf("naca is at %08x\n", naca); 171 172 /* fseek to the naca */ 173 fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); 174 if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { 175 death("Could not read naca\n", outputVmlinux, argv[3]); 176 } 177 xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); 178 xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); 179 /* Make sure a RAM disk isn't already present */ 180 if ((xRamDisk != 0) || (xRamDiskSize != 0)) { 181 death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[3]); 182 } 183 /* Fill in the values */ 184 *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); 185 *((u_int32_t *) &inbuf[0x14]) = htonl(ramPages); 186 187 /* Write out the new naca */ 188 fflush(outputVmlinux); 189 fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); 190 if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { 191 death("Could not write naca\n", outputVmlinux, argv[3]); 192 } 193 printf("RAM Disk of 0x%x pages size is attached to the kernel at offset 0x%08x\n", 194 ramPages, ramStartOffs); 195 196 /* Done */ 197 fclose(outputVmlinux); 198 /* Set permission to executable */ 199 chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); 200 201 return 0; 202} 203