C 来自Linux内核的源代码做什么?
我对这个代码段的实际功能感到困惑。我知道它与内存分配有关,但如果有人能向我解释这段代码中发生了什么,我将不胜感激 系统调用使用各种系统信息填充结构。它由SYSCALL\u DEFINE1sysinfo、struct sysinfo\u user*、info定义 COMPAT_SYSCALL_DEFINE1变量用于与64位内核交互的32位代码。返回结构由长值定义,即64位程序为64位,32位程序为32位。报告的内存大小是mem_单元的倍数。如果totalram或totalswap不适合32位值,并且mem_单元小于PAGE_大小,则它将mem_单元按2的幂放大到PAGESIZE,并按相同的因子缩小其余内存值。理想情况下,它们现在适合32位值,通过这种方式缩放,32位程序仍然可以获得相当准确的系统信息视图。如果没有,就没有通过32位API返回好值的好方法,太糟糕了C 来自Linux内核的源代码做什么?,c,linux,linux-kernel,kernel,C,Linux,Linux Kernel,Kernel,我对这个代码段的实际功能感到困惑。我知道它与内存分配有关,但如果有人能向我解释这段代码中发生了什么,我将不胜感激 系统调用使用各种系统信息填充结构。它由SYSCALL\u DEFINE1sysinfo、struct sysinfo\u user*、info定义 COMPAT_SYSCALL_DEFINE1变量用于与64位内核交互的32位代码。返回结构由长值定义,即64位程序为64位,32位程序为32位。报告的内存大小是mem_单元的倍数。如果totalram或totalswap不适合32位值,并
注意,此时我认为mem_单元是PAGESIZE,所以这段代码可能没有任何作用。。。。它会缩放这些值,直到它们适合32位。这实际上与内存分配无关。它是sysinfo系统调用的实现,它只返回内存和交换使用情况等。在上述结构中,内存和交换字段的大小以mem_单位字节的倍数给出。
COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info){
struct sysinfo s;
do_sysinfo(&s);
/* Check to see if any memory value is too large for 32-bit and scale
* down if needed
*/
if (upper_32_bits(s.totalram) || upper_32_bits(s.totalswap)) {
int bitcount = 0;
while (s.mem_unit < PAGE_SIZE) {
s.mem_unit <<= 1;
bitcount++;
}
s.totalram >>= bitcount;
s.freeram >>= bitcount;
s.sharedram >>= bitcount;
s.bufferram >>= bitcount;
s.totalswap >>= bitcount;
s.freeswap >>= bitcount;
s.totalhigh >>= bitcount;
s.freehigh >>= bitcount;
}
if (!access_ok(VERIFY_WRITE, info, sizeof(struct compat_sysinfo)) ||
__put_user(s.uptime, &info->uptime) ||
__put_user(s.loads[0], &info->loads[0]) ||
__put_user(s.loads[1], &info->loads[1]) ||
__put_user(s.loads[2], &info->loads[2]) ||
__put_user(s.totalram, &info->totalram) ||
__put_user(s.freeram, &info->freeram) ||
__put_user(s.sharedram, &info->sharedram) ||
__put_user(s.bufferram, &info->bufferram) ||
__put_user(s.totalswap, &info->totalswap) ||
__put_user(s.freeswap, &info->freeswap) ||
__put_user(s.procs, &info->procs) ||
__put_user(s.totalhigh, &info->totalhigh) ||
__put_user(s.freehigh, &info->freehigh) ||
__put_user(s.mem_unit, &info->mem_unit))
return -EFAULT;
return 0;
}
#endif /* CONFIG_COMPAT */