//------------------------------------------------------------------- // earlymbr.c // // This module reads the hard disk's Master Boot Record during // its initialization procedure. It uses the kernel functions // 'preempt_disable()' and 'preempt_enable()' in order that it // can circumvent contention with the kernel's own IDE driver. // (Use 'dmesg' command to display output sent to kernel log.) // // NOTE: Developed and tested with Linux kernel version 2.6.10 // // programmer: ALLAN CRUSE // written on: 06 MAR 2005 //------------------------------------------------------------------- #include // for init_module() #include // for ndelay() #include // for preempt_disable() #include // for inb(), outb() #define IDE_DATA 0x1F0 #define IDE_ERROR 0x1F1 #define IDE_FEATURES 0x1F1 #define IDE_SECTOR_COUNT 0x1F2 #define IDE_SECTOR_LOW 0x1F3 #define IDE_SECTOR_MID 0x1F4 #define IDE_SECTOR_HIGH 0x1F5 #define IDE_DEVICE 0x1F6 #define IDE_STATUS 0x1F7 #define IDE_COMMAND 0x1F7 #define IDE_DEVICE_CONTROL 0x3F6 char modname[] = "earlymbr"; // for displaying module's name unsigned short info[ 256 ]; // for holding the MBR sector int init_module( void ) { int i, status, timeout; printk( "<1>\nInstalling \'%s\' module \n", modname ); status = inb( IDE_STATUS ); printk( "1: status=%02X \n", status ); if ( ( status & 0xC8 ) != 0x40 ) return -EBUSY; preempt_disable(); status = inb( IDE_STATUS ); if ( ( status & 0xC8 ) == 0x40 ) { outb( 0xE0, IDE_DEVICE ); ndelay( 400 ); } status = inb( IDE_STATUS ); printk( "2: status=%02X \n", status ); if ( ( status & 0xC8 ) == 0x40 ) { outb( 0x01, IDE_SECTOR_COUNT ); outb( 0x00, IDE_SECTOR_LOW ); outb( 0x00, IDE_SECTOR_MID ); outb( 0x00, IDE_SECTOR_HIGH ); outb( 0xE0, IDE_DEVICE ); outb( 0x20, IDE_COMMAND ); ndelay( 400 ); } status = inb( IDE_STATUS ); printk( "3: status=%02X \n", status ); timeout = 1000000; do { status = inb( IDE_STATUS ); if ( ( status & 0x88 ) == 0x08 ) break; } while ( --timeout ); printk( "4: status=%02X \n", status ); if ( ( status & 0x88 ) == 0x08 ) { int i; for (i = 0; i < 256; i++) info[i] = inw( IDE_DATA ); } ndelay( 400 ); status = inb( IDE_STATUS ); printk( "5: status=%02X \n", status ); preempt_enable(); printk( "\nPartition-Table and Boot-Signature "); for (i = 0; i < 33; i++) { if ( ( i % 8 ) == 0 ) printk( "\n" ); printk( "%04X ", info[223+i] ); } printk( "\n\n" ); return 0; // SUCCESS } void cleanup_module( void ) { printk( "<1>Removing \'%s\' module\n", modname ); } MODULE_LICENSE("GPL");