1 #include <stdio.h> 2 #include <string.h> 3 #include "finstext2.h" 4 #include "ext2.h" // #defines ext2_data 5 #include <linux/hdreg.h> 6 #include <linux/ext3_fs.h> 7 #include <sys/ioctl.h> 8 #include <sys/types.h> 9 #include <sys/stat.h> 10 #include <fcntl.h> 11 #include <unistd.h> 12 13 #define MAJOR_VERSION 1 14 #define MINOR_VERSION 0 15 16 PEXT2_BOOTCODE Ext2BootCode = (PEXT2_BOOTCODE)ext2_data; 17 struct ext3_super_block Ext2SuperBlock; 18 struct hd_geometry Ext2DriveGeometry; 19 unsigned char Ext2ExistingBootCode[1024]; 20 21 char BlockDevice[260]; 22 int BlockDeviceSpecified = 0; 23 int BlockDeviceFileDescriptor; 24 25 int main(int argc, char *argv[]) 26 { 27 int Index; 28 char ch; 29 30 // Verify that we got enough command line parameters 31 if (argc < 2) 32 { 33 printf("finstext2 block_device [-v]\n\n"); 34 printf("block_device Specifies the ext2/3 volume to install to (i.e. /dev/hda1)\n"); 35 printf("-v Displays the version\n\n"); 36 } 37 38 // Parse the command line parameters 39 for (Index=1; Index<argc; Index++) 40 { 41 if (strcmp(argv[Index], "-v") == 0) 42 { 43 printf("FreeLoader Ext2/3 Installer v%d.%d\n", MAJOR_VERSION, MINOR_VERSION); 44 } 45 else 46 { 47 strcpy(BlockDevice, argv[Index]); 48 BlockDeviceSpecified = 1; 49 } 50 } 51 52 if (BlockDeviceSpecified) 53 { 54 BlockDeviceFileDescriptor = open(BlockDevice, O_RDWR|O_SYNC); 55 56 if (BlockDeviceFileDescriptor == -1) 57 { 58 printf("Couldn't open block device %s\n", BlockDevice); 59 return 1; 60 } 61 62 if (read(BlockDeviceFileDescriptor, Ext2ExistingBootCode, (size_t)1024) != (ssize_t)1024) 63 { 64 close(BlockDeviceFileDescriptor); 65 printf("Couldn't read existing boot code from %s\n", BlockDevice); 66 return 1; 67 } 68 69 for (Index=0; Index<1024; Index++) 70 { 71 if (Ext2ExistingBootCode[Index] != 0x00) 72 { 73 printf("This EXT2/3 volume has existing boot code.\n"); 74 printf("Do you want to overwrite it? [y/n] "); 75 scanf("%c", &ch); 76 77 if (ch == 'n' || ch == 'N') 78 { 79 close(BlockDeviceFileDescriptor); 80 printf("Cancelled.\n"); 81 return 0; 82 } 83 84 break; 85 } 86 } 87 88 if (read(BlockDeviceFileDescriptor, &Ext2SuperBlock, (size_t)1024) != (ssize_t)1024) 89 { 90 close(BlockDeviceFileDescriptor); 91 printf("Couldn't read super block from %s\n", BlockDevice); 92 return 1; 93 } 94 95 if (Ext2SuperBlock.s_magic != EXT3_SUPER_MAGIC) 96 { 97 close(BlockDeviceFileDescriptor); 98 printf("Block device %s is not a EXT2/3 volume or has an invalid super block.\n", BlockDevice); 99 return 1; 100 } 101 102 if (ioctl(BlockDeviceFileDescriptor, HDIO_GETGEO, &Ext2DriveGeometry) != 0) 103 { 104 close(BlockDeviceFileDescriptor); 105 printf("Couldn't get drive geometry from block device %s\n", BlockDevice); 106 return 1; 107 } 108 109 printf("Heads: %d\n", Ext2DriveGeometry.heads); 110 printf("Sectors: %d\n", Ext2DriveGeometry.sectors); 111 printf("Cylinders: %d\n", Ext2DriveGeometry.cylinders); 112 printf("Start: %d\n", Ext2DriveGeometry.start); 113 114 Ext2BootCode->BootDrive = 0xff; 115 Ext2BootCode->BootPartition = 0x00; 116 //Ext2BootCode->SectorsPerTrack = Ext2DriveGeometry.sectors; 117 //Ext2BootCode->NumberOfHeads = Ext2DriveGeometry.heads; 118 Ext2BootCode->Ext2VolumeStartSector = Ext2DriveGeometry.start; 119 Ext2BootCode->Ext2BlockSizeInBytes = 1024 << Ext2SuperBlock.s_log_block_size; 120 Ext2BootCode->Ext2BlockSize = Ext2BootCode->Ext2BlockSizeInBytes / 512; 121 Ext2BootCode->Ext2PointersPerBlock = Ext2BootCode->Ext2BlockSizeInBytes / 4; 122 Ext2BootCode->Ext2GroupDescPerBlock = Ext2BootCode->Ext2BlockSizeInBytes / 32; 123 Ext2BootCode->Ext2FirstDataBlock = Ext2SuperBlock.s_first_data_block; 124 Ext2BootCode->Ext2InodesPerGroup = Ext2SuperBlock.s_inodes_per_group; 125 Ext2BootCode->Ext2InodesPerBlock = Ext2BootCode->Ext2BlockSizeInBytes / 128; 126 127 if (lseek(BlockDeviceFileDescriptor, (off_t)0, SEEK_SET) == (off_t)-1) 128 { 129 close(BlockDeviceFileDescriptor); 130 printf("Couldn't write boot code on %s\n", BlockDevice); 131 return 1; 132 } 133 134 if (write(BlockDeviceFileDescriptor, Ext2BootCode, (size_t)1024) != (ssize_t)1024) 135 { 136 close(BlockDeviceFileDescriptor); 137 printf("Couldn't write boot code on %s\n", BlockDevice); 138 return 1; 139 } 140 141 close(BlockDeviceFileDescriptor); 142 143 printf("Boot code written successfully!\n"); 144 } 145 146 return 0; 147 }