/* Set the MC146818 CMOS clock to local time from the current software clock. I'm *sure* something like this exists already but I can't find it. Build with: gcc -O -o setclock setclock.c N.B. the -O is necessary so that outb_p will be expanded in-line, it doesn't really exist in the libraries so you'll get an undefined external otherwise. By John Wilson . 01/16/2000 JMBW Created. */ #include #include #include /* write a BCD value to an RTC register */ /* called with interrupts off so that nothing will write port 70h and change */ /* the register selection while we're doing this -- could get burned on SMP! */ wcmos(int reg,int val) { outb_p(reg,0x70); /* select reg # */ outb_p(((val/10)<<4)|(val%10),0x71); /* write value in BCD */ } main() { time_t now; struct tm *t; /* get access to (all) I/O ports and the CLI/STI instructions */ /* (must be root) */ if(iopl(3)<0) { perror("iopl"); exit(1); } tzset(); /* probably not really needed */ /* get current time */ if((now=time(NULL))==(time_t)-1) { perror("time"); exit(1); } /* split out individual fields according to time zone */ t=localtime(&now); /* write them all out */ __asm__ __volatile__ ("cli"); /* don't interrupt RTC use */ wcmos(0,t->tm_sec); /* write time out */ wcmos(2,t->tm_min); wcmos(4,t->tm_hour); wcmos(6,t->tm_wday+1); wcmos(7,t->tm_mday); wcmos(8,t->tm_mon+1); wcmos(9,t->tm_year%100); /* set year within century */ wcmos(0x32,t->tm_year/100+19); /* set epoch */ __asm__ __volatile__ ("sti"); /* thanks, carry on */ }