mkinitrd.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <stdint.h> 5 6 struct initrd_header { 7 uint32_t nfiles; 8 }; 9 10 struct initrd_file_header { 11 uint8_t magic; 12 char name[64]; 13 uint32_t offset; 14 uint32_t length; 15 }; 16 17 int main(int argc, char** argv) { 18 if (argc < 3) { 19 printf("Usage: %s <output.img> <file1> [file2] ...\n", argv[0]); 20 return 1; 21 } 22 23 int nfiles = argc - 2; 24 struct initrd_header headers; 25 headers.nfiles = nfiles; 26 27 FILE* output = fopen(argv[1], "wb"); 28 if (!output) { 29 printf("Error: Cannot create output file\n"); 30 return 1; 31 } 32 33 // Write header 34 fwrite(&headers, sizeof(struct initrd_header), 1, output); 35 36 // Calculate offsets and write file headers 37 uint32_t offset = sizeof(struct initrd_header) + nfiles * sizeof(struct initrd_file_header); 38 39 for (int i = 0; i < nfiles; i++) { 40 struct initrd_file_header header; 41 memset(&header, 0, sizeof(header)); 42 43 header.magic = 0xBF; 44 45 // Extract just the filename (not the full path) 46 char* filename = argv[i + 2]; 47 char* slash = strrchr(filename, '/'); 48 if (slash) { 49 filename = slash + 1; 50 } 51 52 strncpy(header.name, filename, 63); 53 header.name[63] = 0; 54 55 // Get file size 56 FILE* file = fopen(argv[i + 2], "rb"); 57 if (!file) { 58 printf("Error: Cannot open %s\n", argv[i + 2]); 59 fclose(output); 60 return 1; 61 } 62 63 fseek(file, 0, SEEK_END); 64 header.length = ftell(file); 65 fclose(file); 66 67 header.offset = offset; 68 offset += header.length; 69 70 fwrite(&header, sizeof(struct initrd_file_header), 1, output); 71 } 72 73 // Write file data 74 for (int i = 0; i < nfiles; i++) { 75 FILE* file = fopen(argv[i + 2], "rb"); 76 if (!file) { 77 printf("Error: Cannot open %s\n", argv[i + 2]); 78 fclose(output); 79 return 1; 80 } 81 82 char buffer[1024]; 83 size_t bytes; 84 while ((bytes = fread(buffer, 1, sizeof(buffer), file)) > 0) { 85 fwrite(buffer, 1, bytes, output); 86 } 87 88 fclose(file); 89 } 90 91 fclose(output); 92 printf("Created initrd with %d files\n", nfiles); 93 94 return 0; 95 }