5

检测 32 位用户模式程序是否在 64 位内核上运行(即系统是否处于“长模式”)的最佳和最可靠的方法是什么?如果可能的话,我宁愿不调用外部程序(或者必须加载任何内核模块)。

注意:我想检测是否正在使用 64 位内核(或者实际上,CPU 是否处于长模式),而不仅仅是是否存在支持 64 位的处理器(/proc/cpuinfo告诉我,但不是 64 位正在使用能力)。

uname如果编译为 32 位或使用了,内核会伪造 32 位处理器setarch i686

4

3 回答 3

6

调用该uname()函数并检查返回的machine字符串,该字符串x86_64适用于 64 位 Intel 平台。

扭转使用效果的一种方法setarch是重置个性:

#include <stdio.h>
#include <sys/utsname.h>
#include <sys/personality.h>

int main()
{
    struct utsname u;

    personality(PER_LINUX);

    uname(&u);
    puts(u.machine);
    return 0;
}

这显示了在 32 位模式下编译并在 64 位系统上运行时的正确结果:

$ gcc -m32 -o u u.c
$ ./u
x86_64
$ setarch i686 ./u
x86_64

编辑:修复代码以反转setarch.

参考

于 2011-05-10T14:28:23.447 回答
1

假设 uname() 是作弊,仍然有几种机制。一种方法是检查任何内核符号的地址宽度。

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  char *inputline = malloc(1024);
  char *oinputline = inputline;
  int fd = open("/proc/kallsyms", O_RDONLY);
  int numnibbles = 0;
  if (fd == -1) {
      perror("open");
      free(inputline);
      exit(1);
  }
  read(fd, inputline, 1024);
  close(fd);
  while(!isspace(*inputline)) {
      numnibbles++;
      inputline++;
  }
  printf("%dbit\n", numnibbles*4);
  free(oinputline);
  exit (0);
}
于 2011-05-10T14:52:57.307 回答
0

如果为它配置了内核,您可以从 /proc/config.gz 读取内核配置

zcat /proc/config.gz | grep CONFIG_64BIT
# CONFIG_64BIT is not set

我不确定您需要它的便携性 - 它似乎不是一个超级常见的配置选项。

于 2011-05-10T14:50:28.937 回答