WindowsXP上のVMware 4.5 で linux を動かしていると,どんどん時計が遅れる.いや時計はほとんど進まなくなる. vmware-toolbox を起動しておけば時計を合わせてくれるのだけど,vmware-toolbox はX用のアプリなのでコンソールonlyな環境だとそもそも起動できない.そこで,コンソール版の時計あわせプログラムを作成する.
google で検索すると VMware を解析しておられる方がいるようで,以下のようにあるアドレスのIOポート叩けばホストの時計を参照することができるとのこと.と言うわけで早速プログラム作成.
/** * vmware-sync-time.c * */ #include <stdio.h> #include <sys/time.h> #include <errno.h> int get_host_time(long *sec, long *usec) { int eax, ebx, ecx, edx; __asm__ __volatile__ (" mov $0x564D5868, %%eax; /* magic number */ mov $0x00000000, %%ebx; /* ebx will be ignored */ mov $0x00000017, %%ecx; /* command. 17h is for getting time.*/ mov $0x5658, %%edx; /* VMware I/O port */ in %%dx, %%eax; mov %%eax, %0; mov %%ebx, %1; mov %%ecx, %2; mov %%edx, %3; " : "=r"(eax), "=r"(ebx), "=r"(ecx), "=r"(edx) ); *sec = eax; *usec = ebx; return 0; } int main(int argc, char argv[]) { struct timeval tv; get_host_time(&tv.tv_sec, &tv.tv_usec); if (0 != settimeofday(&tv, NULL)){ perror("can not set system time."); } return 0; }
gccのインラインアセンブラには不慣れながら,なんとか完成に至る.
で,このプログラムをcrontabで数分おきに起動すれば万事解決と思いきや…そもそもシステムの時計がほとんど進まないので,crontabの起動も遅れることが発覚.orz
int main(int argc, char argv[]) { while (!0){ struct timeval tv; get_host_time(&tv.tv_sec, &tv.tv_usec); if (0 != settimeofday(&tv, NULL)){ perror("can not set system time."); } usleep(10*1000); } return 0; }
で,こうなった.うーん,ださい.カーネルソースいじったほうがスマートなんだろうなぁ.
VMware徹底入門 (DVD付)
posted with amazlet at 09.01.10
おすすめ度の平均:
実践的なノウハウがよい