10 #include <linux/nvram.h>
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
19 unsigned int verbose = 0; // flag controlling verbose debugging messages
23 unsigned short __get_checksum(unsigned char *buffer, int start, int count, int verbose) {
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);
32 unsigned short get_checksum(unsigned char *buffer, int verbose) {
33 return __get_checksum(buffer, 2, 30, verbose);
36 int main(int argc, char **argv) {
38 char *device = "/dev/nvram";
42 unsigned char byte = 0;
43 unsigned short checksum = 0;
44 unsigned char buffer[256];
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);
51 for (arg=1; arg < argc; arg++) {
52 if (argv[arg][0] == '-' && strlen(argv[arg]) > 1) {
53 switch(argv[arg][1]) {
56 VMX_bit = 0; // value of bit
57 printf("Disabling VMX\n");
61 VMX_bit = 1; // value of bit
62 printf("Enabling VMX\n");
66 setVMX = 1; // change the VMX bit
71 verbose = 1; // enable lots of progress messages
72 printf("Verbose messages\n");
83 if ( ret == 1 || showOptions || device == NULL) {
88 fd = open(device, O_RDWR);
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));
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));
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);
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));
125 printf("Finished\n");
128 else perror("Cannot open device");