Original code from 2007
[vt-enable.git] / src / vmx-enable.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/stat.h>
4 #include <sys/types.h>
5 #include <sys/ioctl.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <string.h>
10 #include <linux/nvram.h>
11
12 // program version
13 #define VER "0.1"
14 // offset in accessible CMOS NVRAM of byte containing VMX bit (CMOS byte 0x11, bit 6)
15 #define CMOS_VMX_BYTE 3
16 #define CMOS_VMX_BIT 6
17 #define CMOS_VMX_MASK (unsigned char)0x01 << CMOS_VMX_BIT
18
19 unsigned int verbose = 0; // flag controlling verbose debugging messages
20 int size = 0;
21
22
23 unsigned short __get_checksum(unsigned char *buffer, int start, int count, int verbose) {
24  int i;
25  unsigned short checksum = 0;
26  for (i=start; i < start+count && i < size; i++) {
27   checksum += buffer[i];
28   if(verbose) printf("0x%0.2X = 0x%0.2X (0x%0.4X)\n", i, buffer[i], checksum);
29  }
30  return checksum;
31 }
32 unsigned short get_checksum(unsigned char *buffer, int verbose) {
33  return __get_checksum(buffer, 2, 30, verbose);
34 }
35
36 int main(int argc, char **argv) {
37  int arg, ret = 0;
38  char *device = "/dev/nvram";
39  int showOptions=0;
40  int setVMX=0;
41  int VMX_bit=0;
42  unsigned char byte = 0;
43  unsigned short checksum = 0;
44  unsigned char buffer[256];
45  
46  printf("\n"
47         "VMX-enable version %s © 2007 TJ http://intuitivenipple.net\n"
48         "Licensed on the terms of GPL version 3\n\n"
49         "Enables VMX (for supported BIOS's only).\n\n", VER);
50    
51  for (arg=1; arg < argc; arg++) {
52   if (argv[arg][0] == '-' && strlen(argv[arg]) > 1) {
53    switch(argv[arg][1]) {
54
55     case 'd': // disable
56      VMX_bit = 0; // value of bit
57      printf("Disabling VMX\n");
58      break;
59      
60     case 'e': // enable
61      VMX_bit = 1; // value of bit
62      printf("Enabling VMX\n");
63      break;
64      
65     case 's': // set
66      setVMX = 1; // change the VMX bit
67      printf("Set VMX\n");
68      break;
69      
70     case 'v': // verbose
71      verbose = 1; // enable lots of progress messages
72      printf("Verbose messages\n");
73      break;
74      
75     case 'h': // help
76     default:
77      showOptions=1;
78      break;
79    } // end switch
80   }
81  }
82
83  if ( ret == 1 || showOptions || device == NULL) {
84   printf("Options\n" );  
85  }
86  else if (ret == 0) {
87   int fd;
88   fd = open(device, O_RDWR);
89   if (fd > 0) {
90    if((size = read(fd, &buffer, 256)) > 0) {
91     printf("%d bytes read\n", size);
92     printf("\nCMOS VMX flag: %d (%sabled)\n", (buffer[CMOS_VMX_BYTE] & CMOS_VMX_MASK ? 1 : 0),
93             (buffer[CMOS_VMX_BYTE] & CMOS_VMX_MASK ? "en" : "dis"));
94     printf("CMOS Checksum (calculated): 0x%0.4X\n", get_checksum(buffer, 0));
95     printf("CMOS Checksum (stored): 0x%0.4X\n", buffer[33] + (buffer[32] << 8));
96
97     // __get_checksum(buffer, 34, size-34, 0);
98     if(!setVMX) printf("\n**Simulation only**\n");
99     printf("\nDoing VMX %sable with mask 0x%0.2X\n", VMX_bit ? "en" : "dis", CMOS_VMX_MASK);
100     printf("Byte %d (before updating flag): 0x%0.2X\n", CMOS_VMX_BYTE, buffer[CMOS_VMX_BYTE]);
101     printf("Change mask 0x%0.2X\n", VMX_bit ? CMOS_VMX_MASK : 0);
102             buffer[CMOS_VMX_BYTE] |= VMX_bit ? CMOS_VMX_MASK : 0;
103     printf("Byte %d ( after updating flag): 0x%0.2X\n", CMOS_VMX_BYTE, buffer[CMOS_VMX_BYTE]);
104     printf("CMOS VMX flag: %d (%sabled)\n", (buffer[CMOS_VMX_BYTE] & CMOS_VMX_MASK ? 1 : 0),
105             (buffer[CMOS_VMX_BYTE] & CMOS_VMX_MASK ? "en" : "dis"));
106     printf("Checksum (calculated): 0x%0.4X\n", get_checksum(buffer, 0));
107
108     if (setVMX) {
109      printf("\nWriting VMX bit\n");
110      lseek(fd, CMOS_VMX_BYTE, SEEK_SET); // VMX_bit is bit-6 of byte 17 (0x11)
111      write(fd, &buffer[CMOS_VMX_BYTE], 1);
112      printf("Setting CMOS Checksum\n");
113      checksum = get_checksum(buffer, 0);
114      lseek(fd, 32, SEEK_SET);
115      write(fd, &checksum, 2);
116
117      printf("\nChecking NVRAM...\n");
118      lseek(fd, 0, SEEK_SET);
119      read(fd, &buffer, 128);
120      printf("Checksum (calculated): 0x%0.4X\n", get_checksum(buffer, 0));
121      printf("Checksum (stored): 0x%0.4X\n", buffer[33] + (buffer[32] << 8));      
122     }
123    }
124
125    printf("Finished\n");
126    close(fd);
127   }
128   else perror("Cannot open device");
129  } 
130  return ret;
131 }
132