2038 年嵌入式 Linux(32 位)解决方案? [复制]

Posted

技术标签:

【中文标题】2038 年嵌入式 Linux(32 位)解决方案? [复制]【英文标题】:Year 2038 solution for embedded Linux (32 bit)? [duplicate] 【发布时间】:2016-05-03 03:27:03 【问题描述】:

在 32 位嵌入式 Linux (ARMLinux) 的 C 代码中处理时间的正确方法是什么,以确保代码在 2038 年 1 月 19 日 UTC 03:14:07 之后继续正常工作(当签名的 32 位time_t 溢出)?鉴于 time_t 在我必须使用的系统上是 32 位签名的,有哪些替代方案?

大量的谷歌搜索没有发现任何实际用途。似乎每个人都认为到那时我们都将使用 64 位操作系统,但这显然不适用于嵌入式系统。

在我需要使用的系统上,__kernel_time_t 被定义为long。这大概意味着 64 位时间没有内核设施。 uClibc的版本是0.9.29。

我不敢相信我是唯一一个遇到这个问题的人,而且我不想重新发明***。

【问题讨论】:

虽然我同意这是一个好问题,但对于 SO 来说可能过于宽泛。您是否搜索过 LKML 或发布过请求? @Olaf:我已经阅读了 Linux 内核作者正在做的事情,但这些都是围绕 64 位系统展开的。我不认为这个问题太宽泛。坦率地说,我怀疑是否有这么多不同的方法可以做到这一点,答案很可能是“目前没有针对嵌入式系统的通用解决方案。” @n.m.在嵌入式世界中,20 年一点也不长。我使用的其中一个系统已经超过 35 年了。 @n.m.:令人惊讶的是,有些应用领域每年都不会发布新设备。对于家用电器,请考虑例如洗衣机(当然不是便宜的)等等。 您好,从 2021 年开始! Linux 5.6 及更高版本已准备好在 2038 年之前在 32 位系统上运行:lkml.org/lkml/2020/1/29/355?anz=web 【参考方案1】:

没有灵丹妙药、技巧或聪明的解决方案。要么使用具有 64 位 time_t 的操作系统,要么不使用 time_t 和任何依赖于它的操作系统设施(包括文件系统、计时器、半网络等),或者计划在下一个更新软件20 年。

在 32 位机器上至少有两个具有 64 位 time_t 的类 unix 系统:OpenBSD 和 NetBSD。 OpenBSD 进行了几次会谈,解释了其背后的原因:http://www.openbsd.org/papers/eurobsdcon_2013_time_t/index.html

【讨论】:

我将其标记为答案只是因为我们的最终决定是暂时使用 32 位时间,以后再担心这个问题。 IMO 不是一个很好的解决方案,但我正在研究的组件并不是唯一受影响的组件。 由于 ARMLinux 似乎是基于 NetBSD 的,因此您可以使用 32 位版本。但是在源代码中检查这个。认为 2038 年是遥远的未来并不奇怪。距离现在不到 18 年。 您好,从 2021 年开始! Linux 5.6 及更高版本已准备好在 2038 年之前在 32 位系统上运行:lkml.org/lkml/2020/1/29/355?anz=web【参考方案2】:

如果时间戳低于某个值,时间转换例程将“简单地”使用 2038-01-19:03:14:07Z 作为 Unix 纪元时间的基础。

即如果您的系统在 2010 年 1 月 1 日开始生产,您可以假设没有未溢出的时间戳低于 1262300400(这是该日期的 unix 纪元时间)。

如果遇到较低的时间戳,则认为它已溢出并使用 2038-01-19:03:14:07Z 作为基准时间。比较也必须考虑在内。

不是一个干净的解决方案,但通过适度的努力是可行的。更好地切换到 64 位时间戳(这并不绝对需要 64 位系统,顺便说一句)。

【讨论】:

这是一种可怕的方法。在我的 Linux 系统上,有相当多的文件带有 1999 年左右的时间戳。此外,当您提取从其他地方(例如从包更新)获得的档案时,mtimes 可能全部搞砸了。 @FUZxxl 我同意 ;) 但我们在这里谈论的是嵌入,影响可能是可控的 未来时间戳的影响可能是致命的。例如,它完全抛弃了make 或基于时间戳运行的备份程序。 @FUZxxl:我绝对不想在那一天旅行:飞机、火车和汽车……到那时都可能会自动驾驶,但可能无法免受 Y2G 虫子之母的影响。 这很巧妙,但可能有点太聪明了。对于可能需要在您之后维护系统的任何人来说,这肯定是一个有趣的惊喜。这是否预示着您的继任者将来会发布 SO 帖子?【参考方案3】:

我假设您的嵌入式系统的 ABI 将 long 定义为 32 位。

time_t 类型不需要签名。您能做到unsigned long 并为自己和您的后代多买 68 年的安宁吗?改变这一点需要重新编译内核、C 库和所有使用time_t 的程序和库...不适合胆小的人!您不妨将其定义为long long,但这会改变许多结构布局,并且更具挑战性。

【讨论】:

如果您为重新编译整个系统上的每个二进制文件而烦恼,何不升级!? @cat:好点子!如果 OP 对系统软件堆栈有足够的控制权,那么他有几个选项可以防止问题发生,升级是比使用内核类型打补丁更好的解决方案,如果他没有,则无能为力。跨度>

以上是关于2038 年嵌入式 Linux(32 位)解决方案? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

到2038年1月19日那天,Unix时钟会失效吗?

PHP Y2K38 (2038年) 问题

2038年小行星真的会撞地球吗将会撞哪里

iphone4s上的日历为啥到2038年就没了?为啥日期最多只能改到2038年1月1日?

64位MySQL的PHP​​ 2038年问题无法通过PHPMyAdmin插入日期

PHP & mySQL:2038 年错误:它是啥?如何解决?