如何在 kext 中获取 OS X 版本号?

3
我有一个需要知道正在运行的OS X版本的kext。CocoaDev有一篇文章,其中描述了如何使用Gestalt()获取OS X版本信息,但该代码需要Cocoa。
我能从kext中调用Gestalt()吗?
如果可以,我应该使用哪个#include来定义它?
如果不行,还有其他解决方案吗?

背景:

我想在所有OS X版本(从10.4到10.7)中使用相同的kexts。

但是:kexts调用cdevsw_add,这在狮子山中以不向后兼容的方式进行了更改。随着(显然)某些调用它的内核程序的更改,这些更改意味着 - 根据例程之前的评论 - 在10.7上应该使用不同的第一个参数调用cdevsw_add,而在OS X 10.0到10.6上则不同。(Lion上为-12,在早期版本上为-1。)

如果kexts可以确定它们正在运行的OS X版本,那很容易。(如果不能,则可能会很麻烦 - 可能像构建两个不同版本的kexts并让kext加载代码选择要加载的版本一样可怕的修补程序。)


出于好奇,你在看哪个驱动程序?我问这个问题是因为我现在正在修复OSS tuntaposx驱动系统中的一个Lion bug - 这就是我来到这个问题的原因!谢谢... - Dave Peck
PPS:我很久以前就看到了bsd_stubs.c中关于向cdevsw_add(...)发送-1的注释。实际上,这个注释已经存在于XNU源代码中很长时间了--比如,在10.6.0版本的源代码中就有它的身影。从代码来看,我认为在Lion中使用-1仍然可以正常工作,即使这不是一个理想的值要发送... - Dave Peck
那些版本范围看起来不对。也许您混淆了 bdev/cdev 或者 isfree/add?这是我得到的,可以自由检查:**10.0.0 - 10.4.11:必须严格传递 -1 来自动插入;任何小于此值都会中止。10.5.0 - 10.7.5**:传递 -1 会从 0 开始搜索,建议使用 -12。(...) - user2975337
10.8.0 - 10.11.6:与之前相同,但测试已移至_isfree,现在建议使用-24 - user2975337
2个回答

3

Kernel.framework提供了<libkern/version.h>。其中声明了一些外部变量,如version_major、version_minor等。据我所知,这些变量是从libkern.kpi中导出的。

希望这有所帮助。


2

您可以使用sysctl获取内核版本(向下滚动到第三种方法)。据称在开发内核模块时有效。

以下是该方法的示例,以防该网站关闭。

#include <sys/param.h>
#include <sys/sysctl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{
    int mib[] = {CTL_KERN, KERN_OSRELEASE};
    size_t len;
    sysctl(mib, sizeof mib / sizeof(int), NULL, &len, NULL, 0);

    char* kernelVersion = malloc(len);
    sysctl(mib, sizeof mib / sizeof(int), kernelVersion, &len, NULL, 0);

    printf("Kernel version is %s\n", kernelVersion);
    free(kernelVersion);
}

当然,您需要找出Snow Leopard和Lion的内核版本,但这不应该很难。(我可以证明当前Lion发布版的内核版本是11.0.0。)

谢谢。看起来可以工作,至少在kext环境之外是这样。我会在下一个kext中尝试它。我确实不得不将“sizeof nib”更改为“sizeof(nib)”,但那很容易/显然只是一个打字错误。 - user532477
@user532477,很高兴这对你有用。但是,你确定sizeof需要括号吗?据我所知,当参数是类型时,需要括号,但当参数是变量时,括号是可选的。 - zneak
抱歉,我不知道它们是可选的。在我的 C 测试中这个很好用,但当我将其放入 C++ kext 代码中时,我遇到了麻烦,因为 sysctl()、CTL_KERN 和 KERN_OSRELEASE 没有定义(即使包括 <sys/sysctl.h>)。我改用 sysctlbyname("kern.osrelease"...),这样就可以正常工作了。供以后参考:Tiger 10.4.11 是内核“8.11.0”,Leopard 10.5.8 是内核“9.8.0”,Snow Leopard 10.6.8 是内核“10.8.0”,正如你所说,Lion 10.7.0 是内核“11.0.0”。再次感谢。 - user532477
@user532477,如果这个解决了你的问题,请不要忘记在答案左边点击勾选标志:这将奖励回答者的声誉,并告诉未来有相同问题的访问者,这对你有效。 - zneak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接