android时区的初始化

android时区的初始化是init进程执行init.rc的解析,找到关键字sysclktz ,和参数0,调用settimeofday(NULL, &tz)将时区设置为0时区。参数时间区域为NULL,表示仅仅改变时区。

init.rc
on early-init
# Set init and its forked children's oom_adj.
write /proc/1/oom_adj -16

start ueventd

# create mountpoints
mkdir /mnt 0775 root system

on init

sysclktz 0

loglevel 3

# setup the global environment
export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
export LD_LIBRARY_PATH /vendor/lib:/system/lib
export ANDROID_BOOTLOGO 1



在init.c 执行下面的代码就触发init,执行init action的一系列操作
action_for_each_trigger("init", action_add_queue_tail);

on init
sysclktz 0 的作用是init被触发就设置时区为0
1,
system/core/init/keywords.h
keywords.h
KEYWORD(sysclktz, COMMAND, 1, do_sysclktz)
2,
init_parser.c
int lookup_keyword(const char *s)
{
case 's':
if (!strcmp(s, "ervice")) return K_service;
if (!strcmp(s, "etenv")) return K_setenv;
if (!strcmp(s, "etkey")) return K_setkey;
if (!strcmp(s, "etprop")) return K_setprop;
if (!strcmp(s, "etrlimit")) return K_setrlimit;
if (!strcmp(s, "ocket")) return K_socket;
if (!strcmp(s, "tart")) return K_start;
if (!strcmp(s, "top")) return K_stop;
if (!strcmp(s, "ymlink")) return K_symlink;
;
;
if (!strcmp(s, "ysclktz")) return K_sysclktz;
break;

}

3,
system/core/init/builtins.c
builtins.c 调用系统调用settimeofday设置时区
int do_sysclktz(int nargs, char **args)
{
struct timezone tz;

if (nargs != 2)
return -1;

memset(&tz, 0, sizeof(tz));
tz.tz_minuteswest = atoi(args[1]);
if (settimeofday(NULL, &tz))
return -1;
return 0;
}

4,
kernel/kernel/time.c
/*
* In case for some reason the CMOS clock has not already been running
* in UTC, but in some local time: The first time we set the timezone,
* we will warp the clock so that it is ticking UTC time instead of
* local time. Presumably, if someone is setting the timezone then we
* are running in an environment where the programs understand about
* timezones. This should be done at boot time in the /etc/rc script,
* as soon as possible, so that the clock can be set right. Otherwise,
* various programs will get confused when the clock gets warped.
*/

int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz)
{
static int firsttime = 1;
int error = 0;

if (tv && !timespec_valid(tv))
return -EINVAL;

error = security_settime(tv, tz);
if (error)
return error;

if (tz) {
/* SMP safe, global irq locking makes it work. */
sys_tz = *tz;
update_vsyscall_tz();
if (firsttime) {
firsttime = 0;
if (!tv)
warp_clock();
}
}
if (tv)
{
/* SMP safe, again the code in arch/foo/time.c should
* globally block out interrupts when it runs.
*/
return do_settimeofday(tv);
}
return 0;
}



SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv,
struct timezone __user *, tz)
{
struct timeval user_tv;
struct timespec new_ts;
struct timezone new_tz;

if (tv) {
if (copy_from_user(&user_tv, tv, sizeof(*tv)))
return -EFAULT;
new_ts.tv_sec = user_tv.tv_sec;
new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
}
if (tz) {
if (copy_from_user(&new_tz, tz, sizeof(*tz)))
return -EFAULT;
}

return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
}


/*
* Adjust the time obtained from the CMOS to be UTC time instead of
* local time.
*
* This is ugly, but preferable to the alternatives. Otherwise we
* would either need to write a program to do it in /etc/rc (and risk
* confusion if the program gets run more than once; it would also be
* hard to make the program warp the clock precisely n hours) or
* compile in the timezone information into the kernel. Bad, bad....
*
* - TYT, 1992-01-01
*
* The best thing to do is to keep the CMOS clock in universal time (UTC)
* as real UNIX machines always do it. This avoids all headaches about
* daylight saving times and warping kernel clocks.
*/
static inline void warp_clock(void)
{
struct timespec adjust;

adjust = current_kernel_time();
adjust.tv_sec += sys_tz.tz_minuteswest * 60;
do_settimeofday(&adjust);
}

  
settimeofday 是可以修改系统时间,但是cmos时间改不了
date可以改cmos
由于通过settimeofday()只能设置软件时钟,并不能真正设置cmos时钟,
可以通过system("hwclock --utc -w")来把软件时钟写入到cmos里去。
但是实验发现时间较长,需要1s钟左右。

date.c中有date命令的实现。发现其实现非常简单:
date.c: main()->stime()->settimeofday() 这个settimeofday
kernel/time.c

更多相关文章

  1. Android如何获取APP启动时间
  2. Android中的网络时间同步
  3. android java获取当前时间的总结
  4. 网络时间同步
  5. 关于标准android中视频播放器中的快进和快退的步长时间设置
  6. Android默认时区、语言设置
  7. 修改应用按键无响应的时间
  8. Android显示时间和日期的控件的使用总结
  9. Android 选择器 PickerView实例,时间选择器、地址选择器、单项选

随机推荐

  1. 孙卫琴的《精通JPA与Hibernate》的读书笔
  2. 孙卫琴的《精通JPA与Hibernate》的读书笔
  3. IntelliJ IDEA破解2021.5月亲测实战详细
  4. 大咖访谈 | 李少鹏的网安江湖
  5. 孙卫琴的《精通JPA与Hibernate》的读书笔
  6. 孙卫琴的《精通JPA与Hibernate》的读书笔
  7. 孙卫琴的《精通JPA与Hibernate》的读书笔
  8. Small Methods:精确调控的自模板法合成高
  9. AM:新型“水-醚”电解质基水系锂离子电池
  10. Solar RRL:2D/2D基Z型异质结在光催化应用