【问题标题】:64-bit time_t in Linux KernelLinux 内核中的 64 位 time_t
【发布时间】:2015-05-19 01:22:20
【问题描述】:

我已经编译了内核 3.19.1,但time_t 仍然存在问题。只是一个带有cout << sizeof (time_t); 的简单程序就给出了 4 个字节的大小,而不是我的意图的 8 个字节。

我应该在 make menuconfig 期间打开特定选项吗?

【问题讨论】:

    标签: linux kernel 64-bit time-t year2038


    【解决方案1】:

    目前time_t 在内核中只是long:参见__kernel_time_t 类型定义。所以如果你的 CPU 上的 long 类型是 32 位长,time_t 也是 32 位长。基本上,如果您有 32 位 CPU——您系统上的 long 类型也是 32 位长的。如果您有 64 位 CPU -- long 类型将是 64 位长。

    如果您需要自己的 64 位类型 - 只需使用 long long。如果您希望内核时间 API 与 time_t 一样的 64 位长类型工作 - 这有点困难(意味着更改内核源代码)。例如看看here。您也可能有兴趣阅读下一个链接:

    [1]patchset: "Change time_t and clock_t to 64 bit"

    [2]Is there any way to get 64-bit time_t in 32-bit program in Linux

    [3]What is ultimately a time_t typedef to?


    更新

    关于将time_t 更改为long long 后的构建问题(__divdi3 等)。

    既然您已将 time_t 的大小更改为 64 位,任何使用 time_t 的代码都将尝试使用 64 位操作。 __divdi3 表示:divdouble i整数的ision 操作。 3 代表操作数的数量(如1 = 2 / 3)。有关详细信息,请参阅this。所以这个操作显然没有为你的平台实现。您应该自己实现它(在内核代码中)或以某种方式使用来自gcc 的实现。下一个链接应该对您有所帮助:

    [1]__udivdi3 undefined. Howto find code?

    [2]divdi3 division used for long long by gcc on x86

    [3]Where to find udivdi3 and umoddi3 in gcc?

    【讨论】:

    • 我宁愿使用int64_t,因为我知道它会一直是 64 位,甚至不用考虑它。不过,它仅在 C99 之后可用。
    • 据我了解,您正在开发内核。在内核中,你总是在include/linux/types.h 中定义了int64_t,所以你不必使用C99+。只需使用#include <linux/types.h>,或者甚至可以通过其他标头隐式包含(通常这样做)。
    • 我可以在 do_div() 或类似的宏上更改 % 或 / 等运算符,但我不确定该任务是否值得做。让我们来看第一个有构建错误的函数 - time_to_tm() - 里面有很多长类型(不是 long long),它需要静态 long math_div(long a, long b) (再次不是 long long)。所以应该重建很多其他功能。来自 glibc 的函数也应该重新构建 - time()、ctime()、mktime() 等。最后但同样重要的是 - 系统 ABI 会受到影响。根据lwn.net/Articles/607741,我们需要耐心:)
    • 您不应替换(或更改)代码中的运算符。您只需要实现一些操作,例如__divdi3。但是您是对的,它仍然意味着更改用户空间中的所有相关代码。所以最好的选择是现在使用可用的 32 位实现(它仍然有效到 2038 年)并等待内核开发人员在将来的某个时候对其进行更改。
    【解决方案2】:

    32 位 Linux 上的 64 位时间支持是 first introduced in the 5.1 kernel,所以如果您比这更老,对不起。因为更改旧系统调用的返回类型会破坏旧应用程序,所以必须添加新的*time64 syscalls。检查this table,您会发现这些系统调用仅在 32 位平台上可用。

    现在,如果您正在为 32 位系统编写代码,您可以直接调用 clock_gettime64(从内联汇编,或从带有 syscall() 函数的 C 语言)获取当前时间。然而,在那之后你就完全靠自己了。要获得完整的用户空间支持,您必须使用 Linux 5.6 或更高版本以及 musl 1.2+ 或 glibc 2.32+。只需重建您的代码,time_t 将变为 64 位长

    • 所有用户空间都必须使用 64 位 time_t 编译,即将推出的 musl-1.2 和 glibc-2.32 版本以及已安装的 linux-5.6 或更高版本的内核头文件都将支持该文件。

    • 直接使用系统调用接口的应用程序需要移植到使用 linux-5.1 中添加的time64 系统调用来代替现有的系统调用。这会影响futex()seccomp() 的大多数用户以及拥有自己的运行时环境而不基于libc 的编程语言。

    https://lkml.org/lkml/2020/1/29/355?anz=web

    更多信息请阅读

    【讨论】:

      猜你喜欢
      • 2017-05-30
      • 1970-01-01
      • 1970-01-01
      • 2012-06-28
      • 1970-01-01
      • 2012-12-30
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多