Openwrt系统初始时间

一般Openwrt系统较多用于网络方面的产品,比如路由器,但路由器几乎都没有硬件RTC,因此系统初始时间不准.

在Openwrt系统中,初始时间可以认为有2个, 固件编译时间和文件系统加载后的初始时间

关于固件编译时间,即为Linux kernel 编译时间, 即是/proc/version内容,比如:

root@UVCOSS:~# cat /proc/version
Linux version 4.14.221 (xxxx) (gcc version 7.5.0 (OpenWrt GCC 7.5.0 r11063-85e04e9f46)) #0 Tue Aug 31 06:45:02 2021

 kernel 编译时间通过宏KBUILD_BUILD_TIMESTAMP来传入

宏初始化, 从SOURCE_DATE_EPOCH获取时间

SOURCE_DATE_EPOCH 由脚本生成

 

脚本get_source_date_epoch.sh如下:

分别从version.date文件,git,hg来进行初始化

version.date文件存储的即为编译时的UTC时间

# cat version.date
1630392302

#!/usr/bin/env bash
export LANG=C
export LC_ALL=C
[ -n "$TOPDIR" ] && cd $TOPDIRtry_version() {[ -f version.date ] || return 1SOURCE_DATE_EPOCH="$(cat version.date)"[ -n "$SOURCE_DATE_EPOCH" ]
}try_git() {[ -e .git ] || return 1SOURCE_DATE_EPOCH="$(git log -1 --format=format:%ct)"[ -n "$SOURCE_DATE_EPOCH" ]
}try_hg() {[ -d .hg ] || return 1SOURCE_DATE_EPOCH="$(hg log --template '{date}' -l 1 | cut -d. -f1)"[ -n "$SOURCE_DATE_EPOCH" ]
}try_mtime() {perl -e 'print((stat $ARGV[0])[9])' "$0"[ -n "$SOURCE_DATE_EPOCH" ]
}try_version || try_git || try_hg || try_mtime || SOURCE_DATE_EPOCH=""
echo "$SOURCE_DATE_EPOCH"

宏传入:

宏使用 scripts/mkcompile_h 脚本:

#!/bin/sh
# SPDX-License-Identifier: GPL-2.0TARGET=$1
ARCH=$2
SMP=$3
PREEMPT=$4
CC=$5vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; }# If compile.h exists already and we don't own autoconf.h
# (i.e. we're not the same user who did make *config), don't
# modify compile.h
# So "sudo make install" won't change the "compiled by "
# do "compiled by root"if [ -r $TARGET -a ! -O include/generated/autoconf.h ]; thenvecho "  SKIPPED $TARGET"exit 0
fi# Do not expand names
set -f# Fix the language to get consistent output
LC_ALL=C
export LC_ALLif [ -z "$KBUILD_BUILD_VERSION" ]; thenif [ -r .version ]; thenVERSION=`cat .version`elseVERSION=0echo 0 > .versionfi
elseVERSION=$KBUILD_BUILD_VERSION
fi#### 获取外部定义,没有则自动生成,以当前时间为主
if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; thenTIMESTAMP=`date`
elseTIMESTAMP=$KBUILD_BUILD_TIMESTAMP
fi
if test -z "$KBUILD_BUILD_USER"; thenLINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
elseLINUX_COMPILE_BY=$KBUILD_BUILD_USER
fi
if test -z "$KBUILD_BUILD_HOST"; thenLINUX_COMPILE_HOST=`hostname`
elseLINUX_COMPILE_HOST=$KBUILD_BUILD_HOST
fiUTS_VERSION="#$VERSION"
CONFIG_FLAGS=""
if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi
if [ -n "$PREEMPT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"; fi
UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP"# Truncate to maximum lengthUTS_LEN=64
UTS_TRUNCATE="cut -b -$UTS_LEN"# Generate a temporary compile.h( echo /\* This file is auto generated, version $VERSION \*/if [ -n "$CONFIG_FLAGS" ] ; then echo "/* $CONFIG_FLAGS */"; fiecho \#define UTS_MACHINE \"$ARCH\"echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\"echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\"echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\"echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//'`\"
) > .tmpcompile# Only replace the real compile.h if the new one is different,
# in order to preserve the timestamp and avoid unnecessary
# recompilations.
# We don't consider the file changed if only the date/time changed.
# A kernel config change will increase the generation number, thus
# causing compile.h to be updated (including date/time) due to the
# changed comment in the
# first line.if [ -r $TARGET ] && \grep -v 'UTS_VERSION' $TARGET > .tmpver.1 && \grep -v 'UTS_VERSION' .tmpcompile > .tmpver.2 && \cmp -s .tmpver.1 .tmpver.2; thenrm -f .tmpcompile
elsevecho "  UPD     $TARGET"mv -f .tmpcompile $TARGET
fi
rm -f .tmpver.1 .tmpver.2

最终生成在文件include/generated/compile.h

/* This file is auto generated, version 0 */

#define UTS_MACHINE "mips"

#define UTS_VERSION "#0 Tue Aug 31 06:45:02 2021"

#define LINUX_COMPILE_BY "gwind"

#define LINUX_COMPILE_HOST "gwind-XX"

#define LINUX_COMPILER "gcc version 7.5.0 (OpenWrt GCC 7.5.0 r11063-85e04e9f46)"

关于 文件系统加载后的初始时间, 可以理解为用户应用起来后的系统时间

Openwrt系统启动过程中会进行系统文件更新时间判断,以最新的文件更新时间设置为当前系统时间

实现在脚本package/base-files/files/etc/init.d/sysfixtime

#!/bin/sh /etc/rc.common
# Copyright (C) 2013-2014 OpenWrt.org### 00,最先运行
START=00
STOP=90RTC_DEV=/dev/rtc0
HWCLOCK=/sbin/hwclockboot() {start && exit 0local maxtime="$(maxtime)"local curtime="$(date +%s)"[ $curtime -lt $maxtime ] && date -s @$maxtime
}start() {[ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -s -u -f $RTC_DEV
}stop() {[ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -w -u -f $RTC_DEV && \logger -t sysfixtime "saved '$(date)' to $RTC_DEV"
}maxtime() {local file newest#### 搜索/etc下最新的文件for file in $( find /etc -type f ) ; do[ -z "$newest" -o "$newest" -ot "$file" ] && newest=$filedone### 以最新的文件时间设置为系统时间[ "$newest" ] && date -r "$newest" +%s
}

最终系统运行日志:

root@UVCOSS:~# logread |head
Tue Aug 31 14:45:10 2021 kern.notice kernel: [    0.000000] Linux version 4.14.221  (gcc version 7.5.0 (OpenWrt GCC 7.5.0 r11063-85e04e9f46)) #0 Tue Aug 31 06:45:02 2021

====Kernel时间为6:45编译时间, 标准UTC时间

=== 系统时间为14:45,  因为当前时区是CST-8
Tue Aug 31 14:45:10 2021 kern.info kernel: [    0.000000] Board has DDR2
Tue Aug 31 14:45:10 2021 kern.info kernel: [    0.000000] Analog PMU set to hw control
Tue Aug 31 14:45:10 2021 kern.info kernel: [    0.000000] Digital PMU set to hw control
Tue Aug 31 14:45:10 2021 kern.info kernel: [    0.000000] SoC Type: MediaTek MT7688 ver:1 eco:2
Tue Aug 31 14:45:10 2021 kern.info kernel: [    0.000000] bootconsole [early0] enabled
Tue Aug 31 14:45:10 2021 kern.info kernel: [    0.000000] CPU0 revision is: 00019655 (MIPS 24KEc)


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部