RTC系统【转】

http://blog.csdn.net/fanqipin/article/details/8089995

 转自:http://www.cnblogs.com/muhuacat/p/5276306.html

一. RTC及驱动简介

        RTC即real time clock实时时钟,主要用于为操作系统提供可靠的时间;当系统处于断电 的情况下,RTC记录操作系统时间,并可在电池供电情况下继续正常工作,当系统正常启动后,系统可从RTC读取时间信息,来确保断电后时间运行连续性。

        目前,很多CPU中都已集成RTC系统,且有许多独立的外接RTC芯片可用于实现RTC功能;

        在内核中RTC驱动可分为两层,一层为于硬件无关的抽象层,主要用于管理RTC设备、设备节点,属性节点注册及操作;另一层为与硬件相关的RTC低层驱动层;抽象层程序在/drivers/rtc目录下,主要涉及下面几个文件:

class.c   用于管理和注册RTC设备结构、sysfs、procfs及RTC类;

rtc-dev.c 用于注册和管理RTC设备节点,为用户空间提供devfs操作接口,主要操作有rtc_read,rtc_ioctl; 

rtc-proc.c  用于管理rtc的procfs属性节点,提供一些中断状态、标志查询;

rtc-sysfs.c 用于管理rtc设备的sysfs属性,如获取RTC设备名字、日期、时间等属性信息;

interface.c 为rtc-dev.c 和RTC低层驱动提供操作接口;

        RTC系统结构示意图如图1所示;

图1 RTC系统结构图

       如图1所示,RTC 设备驱动通过rtc_device_register接口向linux系统注册RTC设备,并成生proc、sys目录下的属性文件;当用户通过/dev/rtcx设备节点或proc、sysfs接口来操作RTC设备时,都需要先通过interface接口才能访问真实的设备驱动。

二. 部分数据结构分析

1. RTC设备结构

struct rtc_device
{

struct device dev;

struct module *owner;

int id;   设备编号

char name[RTC_DEVICE_NAME_SIZE];

const struct rtc_class_ops *ops;  rtc设备低层操作接口;

struct mutex ops_lock;                     

struct cdev char_dev;    RTC字符型设备结构;

unsigned long flags;

unsigned long irq_data;    中断数据;

spinlock_t irq_lock;                  

wait_queue_head_t irq_queue;   中断数据等待队列;

struct fasync_struct *async_queue;

struct rtc_task *irq_task;

spinlock_t irq_task_lock;

int irq_freq;         中断频率;

int max_user_freq;

struct timerqueue_head timerqueue;

struct rtc_timer aie_timer;                       报警中断定时器;

struct rtc_timer uie_rtctimer;                  更新中断定时器;

struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */     周期中断高精度定时器;

int pie_enabled;             周期中断使能标志;

struct work_struct irqwork;       

#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL    内部仿真update interrupt时所需;

struct work_struct uie_task;

struct timer_list uie_timer;

/* Those fields are protected by rtc->irq_lock */

unsigned int oldsecs;

unsigned int uie_irq_active:1;

unsigned int stop_uie_polling:1;

unsigned int uie_task_active:1;

unsigned int uie_timer_active:1;

#endif
};

2. RTC设备低层操作接口

struct rtc_class_ops {

int (*open)(struct device *);                           打开设备

void (*release)(struct device *);                    释放设备

int (*ioctl)(struct device *, unsigned int, unsigned long);    

int (*read_time)(struct device *, struct rtc_time *);   读取RTC时间;

int (*set_time)(struct device *, struct rtc_time *);    设置RTC时间;

int (*read_alarm)(struct device *, struct rtc_wkalrm *);  读取RTC报警时间;

int (*set_alarm)(struct device *, struct rtc_wkalrm *);   设置RTC报警时间;

int (*proc)(struct device *, struct seq_file *);                    用于提供procfs查询rtc状态接口;

int (*set_mmss)(struct device *, unsigned long secs);   设置以S为单位RTC时间接口;

int (*read_callback)(struct device *, int data);                        

int (*alarm_irq_enable)(struct device *, unsigned int enabled);  中断使能接口;

};

三.RTC低层驱动实现

        RTC低层驱动实现相对比较简单,只需要通过rtc_device_register向系统注册RTC设备,并实现RTC低层操作接口;本文以samsung s3cxx系列中自带的RTC来进行分析,驱动为/drivers/rtc/rtc-s3c.c。

1. 设备驱动注册及卸载

        对于集成在CPU内部的RTC一般可通过注册平台驱动的方式进行注册,如果RTC为外扩芯片,则可以根据相应来的接口来选择注册方式,如I2C接口芯片DS1307通过i2c_add_driver方式进行注册;在S3C6410中RTC为集成在系统内部,所以通过平台方式注册,平台驱动结构及注册卸载函数接口如下所示:

static struct platform_driver s3c_rtc_driver ={

.probe = s3c_rtc_probe,

.remove = s3c_rtc_remove,

.suspend = s3c_rtc_suspend,

.resume = s3c_rtc_resume,

.id_table = s3c_rtc_driver_ids,  用于匹配平台设备

.driver = {

.name = "s3c-rtc",

.owner = THIS_MODULE,

},

}

static int __init s3c_rtc_init(void)

{

return platform_driver_register(&s3c_rtc_driver)

}

static void __exit s3c_rtc_exit(void)

{

platform_drvier_unregister(&s3c_rtc_driver)

}

module_init(s3c_rtc_init);

mosule_exit(s3c_rtc_exit)

        当linux系统启动后会自动将S3C RTC平台设备驱动添加到系统中,然后会遍历platform 总线上的设备通过match_table,id_table或驱动和设备名字来进行匹配设备,如果找到对应的平台设备就会调用平台驱动中的probe函数;S3C RTC平台设备结构如下所示:

static struct resource s3c_rtc_resource[] = {

[0] = {

.start  = S3C_PA_RTC,                                          RTC寄存器起始地址空间;

.end  = S3C_PA_RTC + 0xff,

.flags  = IORESOURCE_MEM,                                resource为内存类型

},

[1] = {

.start  = IRQ_RTC_ALARM,                                    RTC报警中断号

.end  = IRQ_RTC_ALARM,

.flags  = IORESOURCE_IRQ,                                     resource为中断类型

},

[2] = {

.start  = IRQ_RTC_TIC,                                            RTC TICK中断

.end  = IRQ_RTC_TIC,

.flags  = IORESOURCE_IRQ

}

};
struct platform_device s3c_device_rtc = {

.name  = "s3c64xx-rtc",

.id   = -1,

.num_resources = ARRAY_SIZE(s3c_rtc_resource),

.resource = s3c_rtc_resource,

};

通过platform的match函数匹配完后就会调用平台驱动的probe函数,s3c_rtc_probe函数主要部分如下所示:

static int __devinit s3c_rtc_probe(struct platform_device *pdev)
{

struct rtc_device *rtc;

struct rtc_time rtc_tm;

struct resource *res;

int ret;

 

pr_debug("%s: probe=%p\n", __func__, pdev);

/* 从平台设备中获取相关的设备资源*/

s3c_rtc_tickno = platform_get_irq(pdev, 1);                         

if (s3c_rtc_tickno < 0) {

dev_err(&pdev->dev, "no irq for rtc tick\n");

return -ENOENT;

}

s3c_rtc_alarmno = platform_get_irq(pdev, 0);

if (s3c_rtc_alarmno < 0) {

dev_err(&pdev->dev, "no irq for alarm\n");

return -ENOENT;

}

/*内核中,在对内存进行操作前得先申请内存空间,通过ioremap映射完后才能使用*/

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

if (res == NULL) {

dev_err(&pdev->dev, "failed to get memory region resource\n");

return -ENOENT;

}

s3c_rtc_mem = request_mem_region(res->start, resource_size(res), pdev->name);

if (s3c_rtc_mem == NULL) {

dev_err(&pdev->dev, "failed to reserve memory region\n");

ret = -ENOENT;

goto err_nores;

}

 

s3c_rtc_base = ioremap(res->start, resource_size(res));

if (s3c_rtc_base == NULL) {

dev_err(&pdev->dev, "failed ioremap()\n");

ret = -EINVAL;

goto err_nomap;

}

/*获取并使能RTC 系统时钟信号*/

rtc_clk = clk_get(&pdev->dev, "rtc");

if (IS_ERR(rtc_clk)) {

dev_err(&pdev->dev, "failed to find rtc clock source\n");

ret = PTR_ERR(rtc_clk);

rtc_clk = NULL;

goto err_clk;

}

clk_enable(rtc_clk);

/* 配置S3C RTC 控制寄存器,使能RTCEN,只有当RTCEN有效时才能配置BCD等寄存器,当系统断电前得清除RTCEN,防止对BCD寄存器进行写操作; */

s3c_rtc_enable(pdev, 1);

device_init_wakeup(&pdev->dev, 1);

/*注册RTC设备,s3c_rtcops为需要实现的低层操作接口*/

rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,THIS_MODULE);

if (IS_ERR(rtc)) {

dev_err(&pdev->dev, "cannot attach rtc\n");

ret = PTR_ERR(rtc);

goto err_nortc;

}

s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;

 

/* Check RTC Time */

s3c_rtc_gettime(NULL, &rtc_tm);

if (rtc_valid_tm(&rtc_tm)) {

rtc_tm.tm_year = 100;

rtc_tm.tm_mon = 0;

rtc_tm.tm_mday = 1;

rtc_tm.tm_hour = 0;

rtc_tm.tm_min = 0;

rtc_tm.tm_sec = 0;

s3c_rtc_settime(NULL, &rtc_tm);

dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");

}

if (s3c_rtc_cpu_type == TYPE_S3C64XX)

rtc->max_user_freq = 32768;

else

rtc->max_user_freq = 128;

platform_set_drvdata(pdev, rtc);

/*设置时钟频率为1HZ*/

s3c_rtc_setfreq(&pdev->dev, 1);

clk_disable(rtc_clk);

return 0;

 err_nortc:

s3c_rtc_enable(pdev, 0);

clk_disable(rtc_clk);

clk_put(rtc_clk);

 err_clk:

iounmap(s3c_rtc_base);

 err_nomap:

release_resource(s3c_rtc_mem);

 err_nores:

return ret;

}

2. RTC低层操作函数接口

static const struct rtc_class_ops s3c_rtcops = {

.open  = s3c_rtc_open,

.release  = s3c_rtc_release,

.read_time = s3c_rtc_gettime,

.set_time = s3c_rtc_settime,

.read_alarm = s3c_rtc_getalarm,

.set_alarm = s3c_rtc_setalarm,

.proc  = s3c_rtc_proc,

.alarm_irq_enable = s3c_rtc_setaie,

};

 

static int s3c_rtc_open(struct device *dev)
{

struct platform_device *pdev = to_platform_device(dev);

struct rtc_device *rtc_dev = platform_get_drvdata(pdev);

int ret;

 

ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq,IRQF_DISABLED,  "s3c2410-rtc alarm", rtc_dev);

if (ret) {

dev_err(dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret);

return ret;

}

ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, IRQF_DISABLED,  "s3c2410-rtc tick", rtc_dev);

if (ret) {

dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);

goto tick_err;

}

return ret;

 tick_err:

free_irq(s3c_rtc_alarmno, rtc_dev);

return ret;

}

static void s3c_rtc_release(struct device *dev)
{

struct platform_device *pdev = to_platform_device(dev);

struct rtc_device *rtc_dev = platform_get_drvdata(pdev);

 

free_irq(s3c_rtc_alarmno, rtc_dev);

free_irq(s3c_rtc_tickno, rtc_dev);

}

 

       在s3c_rtc_open()和s3c_rtc_release()用于申请和释放s3c rtc 的报警和TICK中断资源;因为中断信号线资源有限,所以最好在打开设备时申请,关闭设备时释放;

 

static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
{

unsigned int have_retried = 0;

void __iomem *base = s3c_rtc_base;

 

clk_enable(rtc_clk);

 retry_get_time:

/*读取年、月、日、天、小时、分、秒数据*/

rtc_tm->tm_min  = readb(base + S3C2410_RTCMIN);

rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR);

rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE);

rtc_tm->tm_mon  = readb(base + S3C2410_RTCMON);

rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);

rtc_tm->tm_sec  = readb(base + S3C2410_RTCSEC);

if (rtc_tm->tm_sec == 0 && !have_retried) {

have_retried = 1;

goto retry_get_time;

}

/*将读取出来的数据进行BCD转二进制操作*/

rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);

rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);

rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);

rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);

rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);

rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);

 

rtc_tm->tm_year += 100;

rtc_tm->tm_mon -= 1;

 

clk_disable(rtc_clk);

return rtc_valid_tm(rtc_tm);

}

s3c_rtc_gettime用于从S3C RTC里读出RTC 日期和时间,RTC时间1S更新一次,在读时间的过程中如果秒为0,表示从秒从59到0跳变,则需要重新读取时间,S3C RTC的时候为BCD码形式,需要进行简单的转换才能得到正确时间信息。

static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
{

void __iomem *base = s3c_rtc_base;

int year = tm->tm_year - 100;

 

clk_enable(rtc_clk);

/* we get around y2k by simply not supporting it */

if (year < 0 || year >= 100) {

dev_err(dev, "rtc only supports 100 years\n");

return -EINVAL;

}

/*将时间数据转成BCD码形式后存入到相应寄存器*/

writeb(bin2bcd(tm->tm_sec),  base + S3C2410_RTCSEC);

writeb(bin2bcd(tm->tm_min),  base + S3C2410_RTCMIN);

writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR);

writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE);

writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON);

writeb(bin2bcd(year), base + S3C2410_RTCYEAR);

clk_disable(rtc_clk);

 

return 0;

}

s3c_rtc_settime()设置RTC时间,在应用层用hwclock -w来进行同步系统和RTC时间时会调用该函数。 

static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
{

struct rtc_time *alm_tm = &alrm->time;

void __iomem *base = s3c_rtc_base;

unsigned int alm_en;

 

clk_enable(rtc_clk);

alm_tm->tm_sec  = readb(base + S3C2410_ALMSEC);

alm_tm->tm_min  = readb(base + S3C2410_ALMMIN);

alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR);

alm_tm->tm_mon  = readb(base + S3C2410_ALMMON);

alm_tm->tm_mday = readb(base + S3C2410_ALMDATE);

alm_tm->tm_year = readb(base + S3C2410_ALMYEAR);

alm_en = readb(base + S3C2410_RTCALM);

alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;

/* decode the alarm enable field */

if (alm_en & S3C2410_RTCALM_SECEN)

alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);

else

alm_tm->tm_sec = -1;

 

if (alm_en & S3C2410_RTCALM_MINEN)

alm_tm->tm_min = bcd2bin(alm_tm->tm_min);

else

alm_tm->tm_min = -1;

if (alm_en & S3C2410_RTCALM_HOUREN)

alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);

else

alm_tm->tm_hour = -1;

if (alm_en & S3C2410_RTCALM_DAYEN)

alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday);

else

alm_tm->tm_mday = -1;

if (alm_en & S3C2410_RTCALM_MONEN) {

alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon);

alm_tm->tm_mon -= 1;

} else {

alm_tm->tm_mon = -1;

}

if (alm_en & S3C2410_RTCALM_YEAREN)

alm_tm->tm_year = bcd2bin(alm_tm->tm_year);

else

alm_tm->tm_year = -1;

clk_disable(rtc_clk);

return 0;

}

       s3c_rtc_getalarm()函数读 ALARM 中BCD码时间信息,并根据ALARM控制寄存器的值来进行BCD转二进制,如果ALARM控制寄存器中使能相应位,则进行BCD转换,否则相应数据填-1处理;

 

static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{

struct rtc_time *tm = &alrm->time;

void __iomem *base = s3c_rtc_base;

unsigned int alrm_en;

 

clk_enable(rtc_clk);

alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;

writeb(0x00, base + S3C2410_RTCALM);

if (tm->tm_sec < 60 && tm->tm_sec >= 0) {

alrm_en |= S3C2410_RTCALM_SECEN;

writeb(bin2bcd(tm->tm_sec), base + S3C2410_ALMSEC);

}

if (tm->tm_min < 60 && tm->tm_min >= 0) {

alrm_en |= S3C2410_RTCALM_MINEN;

writeb(bin2bcd(tm->tm_min), base + S3C2410_ALMMIN);

}

if (tm->tm_hour < 24 && tm->tm_hour >= 0) {

alrm_en |= S3C2410_RTCALM_HOUREN;

writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR);

}

writeb(alrm_en, base + S3C2410_RTCALM);

s3c_rtc_setaie(dev, alrm->enabled);

clk_disable(rtc_clk);

return 0;

}

 

s3c_rtc_setalarm()检查填入的报警时间是否合法,如果合法则将时间信息存入ALARM时间寄存器,并使能小时、分、秒相应ALARM使能位;当正常BCD寄存器里的时间和ALARM寄存器里的时间相等时,发生报警中断 ;中断发生后就会调用在s3c_rtc_open函数中申请alarm中断服务程序s3c_rtc_alarmirq();

static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
{

struct rtc_device *rdev = id;

 

clk_enable(rtc_clk);

rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);

 

if (s3c_rtc_cpu_type == TYPE_S3C64XX)

writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP);

 

clk_disable(rtc_clk);

return IRQ_HANDLED;

}

s3c_rtc_alarmirq()中断服务程序主要通过rtc_update_irq来更新中断数据;

3. 使用过程中出现问题及解决方法

       在使用hwclock命令进行同步系统和硬件时间时,调试口输出“select() to /dev/rtc0 to wait for clock tick timed out.”;后来跟踪hwclock源码发现,原来在用hwclock进行显示,设置RTC硬件时间之前都会先通过进行时钟tick同步,同步方法是开启1S 一次update interrupt,每过1S RTC都会产生一次报警中断,并更新相应的中断数据,在应用层通过select来监控是否有RTC数据可读,如果有数据则会继续显示或设置硬件时间操作,否则输出

“select() to /dev/rtc0 to wait for clock tick timed out.”

linux系统中/proc/interrupt可以用来查询中断号,中断使用次数等信息,由于S3C RTC中的中断申请是在s3c_rtc_open中,所以每次使用完就会在s3c_rtc_release中释放,所以无法在/proc/interrupt中查询到rtc相应信息,为了确定是否有中断产生,把中断申请和释放移到s3c_rtc_probe和s3c_rtc_remove函数中。更新程序后发现S3C RTC中的alarm 和tick中断相应的次数都为0,说明根本就没有产生中断。后来经过测试和分析发现,原来S3C RTC中的低层操作接口在每次设置完相应的寄存器后都会关闭RTC时钟,即clk_disable(rtc_clk);而没有RTC时钟就不会产生相应ALARM 和TICK中断,所以解决的方法就是使能RTC时钟;解决方法是在打开 RTC设备时,就一直使能时钟直到关闭设备;

        后来在看源码修改历史时,发现源码中已经解决并更新了这个BUG,有兴趣的可以去看源码修改记录;

时间: 2024-09-10 21:04:27

RTC系统【转】的相关文章

戴文的Linux内核专题:21 配置内核 (17)

你好!这篇文章会覆盖不同的驱动. 首先"virtio console"是一种用于hypervisors的虚拟控制台驱动. "IPMI top-level message handler"是用于IPMI系统的消息管理器.IPMI代表的是"Intelligent Platform Management Interface"(智能平台管理系统).IPMI是一种不需要shell通过网络管理系统的接口. "/dev/nvram support&q

Linux系统时间与RTC时间【转】

http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3637782   Linux的RTC驱动相对还是比较简单的,可以将它作为一个普通的字符型设备,或者一个misc设备,也可以是一个平台设备,这都没有关系,主要还是对rtc_ops这个文件操作结构体中的成员填充,这里主要涉及到两个方面比较重要: 1. 在Linux中有硬件时钟与系统时钟等两种时钟.硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟.系统时钟则是指kernel

电源管理ACPI、及APM、GNU/Linux系统下的对应命令使用

rtc: The Real Time Clock (RTC) unit can be operated by the backup battery when the system power is off. The data include the time by second, minute, hour, date, day, month, and year. The RTC unit works with an external 32.768 KHz crystal and can perf

Linux中解决系统时钟和硬件时钟不一致的问题

在使用linux的过程中,可能遇到系统时候和硬件时钟不一致,即date,hwclock --show看到的时钟不一致. Linux时钟分为系统时钟(System Clock)和硬件(Real Time Clock,简称RTC)时钟.系统时钟是指当前Linux Kernel中的时钟,而硬件时钟则是主板上由电池供电的时钟,这个硬件时钟可以在BIOS中进行设置.当Linux启动时,硬件时钟会去读取系统时钟的设置,然后系统时钟就会独立于硬件运作. Linux中的所有命令(包括函数)都是采用的系统时钟设置

Linux系统platform设备驱动全透析

1.1 platform总线.设备与驱动 在Linux 2.6的设备驱动模型中,关心总线.设备和驱动这3个实体,总线将设备和驱动绑定.在系统每注册一个设备的时候,会寻找与之匹配的驱动:相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成. 一个现实的Linux设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI.USB.I2C.SPI等的设备而言,这自然不是问题,但是在嵌入式系统里面,SoC系统中集成的独立的外设控制器.挂接在SoC内存空间的外设等确不依附于此类总线.

观察Linux系统时钟的指令

Hertz: Linux核心每隔固定周期会发出timer interrupt (IRQ 0),HZ是用来定义每一秒有几次timer interrupts.用这个指令可以查看(可能需要root权限,或有版本要求): # cat /boot/config-`uname -r` | grep '^CONFIG_HZ=' 如果上述指令不能用,可用下面这个来观察: #cat /proc/interrupts | grep timer && sleep 1 && cat /proc/i

win7系统关闭“交互式服务检测”提示窗口的方法

win7系统关闭"交互式服务检测"提示窗口的方法   win7系统 win7定时开机的设置步骤: 此功能需要在BIOS中设置: 步骤一: 启动系统按DEL,进入BIOS设置界面,然后选中 "POWER MANAGEMENT FEATURES" (电源管理设置),按回车.在电源窗口中找到"RESTORE ON AC/POWER LOSS"项,按回车进入 ,然后通过方向键设置其值为"POWER ON". 步骤二: 选中"

双系统间的时间同步

一.首先要弄清几个概念: 1. "系统时间"与"硬件时间" 系统时间: 一般说来就是我们执行 date 命令看到的时间,linux系统下所有的时间调用(除了直接访问硬件时间的命令)都是使用的这个时间. 硬件时间: 主板上BIOS中的时间,由主板电池供电来维持运行,系统开机时要读取这个时间,并根据它来设定系统时间(注意:系统启动时根据硬件时间设定系统时间的过程可能存在时区换算,这要视具体的系统及相关设置而定). 2. "UTC时间"与"本

linux修改系统时间的详细方法介绍

  两步 (1)date 042612492005 (2)hwclock -w 第一步的意思是设置时间,设置完了可以用date命令查看对不对...注意是月日时分年 第二步的意思是写入主板的rtc芯片.. ======================================= su -c 'date -s 月/日/年' su -c 'date -s 时:分:秒' ======================================= 了解Linux的时钟 由于Linux时钟和Win