64bit time_t в ядре Linux
Я скомпилировал ядро 3.19.1, но все еще проблема с time_t. Просто простая программа с cout << sizeof (time_t); дает размер 4 байта, а не 8 байтов, как было мое намерение. Должен ли я включить конкретную опцию во время make menuconfig?
2 ответа
Поддержка 64-битного времени в 32-битном Linux была впервые представлена в ядре 5.1, так что, если вы старше этого, извините. Поскольку изменение типа возврата старых системных вызовов ломает старые приложения, новые *time64
Вместо этого пришлось добавить системные вызовы. Посмотрите эту таблицу, и вы увидите, что эти системные вызовы доступны только на 32-битных платформах.
Теперь, если вы пишете код для 32-битных систем, вы можете вызвать
clock_gettime64
напрямую (из встроенной сборки или из C с syscall()
функция), чтобы получить текущее время. Однако после этого вы полностью предоставлены сами себе. Для полной поддержки пользовательского пространства вы должны быть на Linux 5.6 или выше вместе с musl 1.2+ или glibc 2.32+. Просто перестройте свой код и
time_t
станет 64-битным
Все пользовательское пространство должно быть скомпилировано с 64-битной
time_t
, который будет поддерживаться в следующих выпусках musl-1.2 и glibc-2.32 вместе с установленными заголовками ядра из linux-5.6 или выше.Приложения, которые напрямую используют интерфейсы системных вызовов, необходимо портировать для использования
time64
системные вызовы добавлены в linux-5.1 вместо существующих системных вызовов. Это влияет на большинство пользователейfutex()
иseccomp()
а также языки программирования, у которых есть собственная среда выполнения, не основанная на libc.
Для получения дополнительной информации прочтите
В настоящее время time_t
просто long
в ядре: см. определение типа __kernel_time_t. Так что если long
тип на вашем процессоре 32-битный, time_t
также является 32-битным В основном, если у вас 32-битный процессор - long
тип в вашей системе также 32-битный. Если у вас 64-битный процессор - long
тип будет 64-битным
Если вам нужен собственный 64-битный тип - просто используйте long long
, Если вы хотите, чтобы API времени ядра работал с 64-битным длинным типом как time_t
- это немного сложнее (подразумевает изменение исходных текстов ядра). Например, посмотрите здесь. Также вас может заинтересовать чтение следующих ссылок:
[1] набор патчей: "Измените time_t и clock_t на 64 бит"
[2] Есть ли способ получить 64-битный time_t в 32-битной программе в Linux
[3] К чему в конечном счете относится type_t?
ОБНОВИТЬ
По вопросам строительства (с __divdi3
и т. д.) после смены time_t
в long long
,
Теперь, когда вы изменились time_t
размер до 64 бит, любой код, который использует time_t
постараюсь использовать 64-битные операции. __divdi3
означает: операция деления на двойных целых. 3 означает количество операндов (например, 1 = 2 / 3
). Смотрите это для деталей. Так что эта операция явно не реализована для вашей платформы. Вы должны либо реализовать это самостоятельно (в коде ядра), либо использовать реализацию из gcc
как-то. Следующие ссылки должны помочь вам:
[1] __udivdi3 не определено. Как найти код?
Спасибо за ответы! Я изменил include/uapi/asm-generic/posix_types.h (длинные длинные __kernel_time_t и __kernel_clock_t)
К сожалению, ядро не правильно собрано, это вывод:
LD init / built-in.o ядро /built-in.o: в функции time_to_tm':
/root/linux-3.19.1/kernel/time/timeconv.c:82: undefined reference to
__divdi3'
/root/linux-3.19.1/kernel/time/timeconv.c:83: неопределенная ссылка на __moddi3'
security/built-in.o: In function
tomoyo_convert_time':
/root/linux-3.19.1/security/tomoyo/util.c:99: неопределенная ссылка на __moddi3'
/root/linux-3.19.1/security/tomoyo/util.c:100: undefined reference to
__divdi3'
/root/linux-3.19.1/security/tomoyo/util.c:101: неопределенная ссылка на __moddi3'
/root/linux-3.19.1/security/tomoyo/util.c:102: undefined reference to
__divdi3'
/root/linux-3.19.1/security/tomoyo/util.c:103: неопределенная ссылка на __moddi3'
/root/linux-3.19.1/security/tomoyo/util.c:104: undefined reference to
__divdi3 'net / встроенный. o: в функции ip_options_compile':
/root/linux-3.19.1/net/ipv4/ip_options.c:421: undefined reference to
__moddi3 'net / встроенный. o: в функции ip_options_build':
/root/linux-3.19.1/net/ipv4/ip_options.c:64: undefined reference to
__moddi3 'net / встроенный. o: в функции icmp_timestamp':
/root/linux-3.19.1/net/ipv4/icmp.c:922: undefined reference to
__moddi3'
make: *** [vmlinux] Ошибка 1