Linux:从32位用户模式程序中检测64位内核(长模式)

时间:2011-05-10 14:26:39

标签: linux kernel 32-bit mode

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

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

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

3 个答案:

答案 0 :(得分:6)

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

扭转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的效果。

Reference

答案 1 :(得分: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);
}

答案 2 :(得分:0)

如果为其配置了内核,则可以从/proc/config.gz

中读取内核配置
zcat /proc/config.gz | grep CONFIG_64BIT
# CONFIG_64BIT is not set

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