/* include\asm-i386\page.h */
#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
#define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
#define __PAGE_OFFSET (0xC0000000)
#define __VMALLOC_RESERVE (128 << 20)
VMALLOC_RESERVE : 0x08000000
PAGE_OFFSET : 0xc0000000
VMALLOC_RESERVE + PAGE_OFFSET = 0xc8000000 :-) foo
再求个负数嘛(等价于 取反加1) 0x38000000 (3*256 + 8 * 16 ) M = 896M zone_normal
===========================================================================================
static void __init print_memory_map(char *who)
{
int i;
for (i = 0; i < e820.nr_map; i++) {
printk(" %s: %016Lx - %016Lx ", who,
e820.map[i].addr,
e820.map[i].addr + e820.map[i].size);
switch (e820.map[i].type) {
case E820_RAM: printk("(usable)\n");
break;
case E820_RESERVED:
printk("(reserved)\n");
break;
case E820_ACPI:
printk("(ACPI data)\n");
break;
case E820_NVS:
printk("(ACPI NVS)\n");
break;
default: printk("type %lu\n", e820.map[i].type);
break;
}
}
}
switch (e820.map[i].type) {
case E820_RAM: res->name = "System RAM"; break;
case E820_ACPI: res->name = "ACPI Tables"; break;
case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
default: res->name = "reserved";
}
==========================================================
test_and_set_bit
@nr: Bit to set
@addr: Address to count from
注意 .This operation is atomic and cannot be reordered.It may be reordered on other architectures than x86.It also implies a memory barrier.
====> 所以要用锁LOCK_PREFIX
static inline int test_and_set_bit(int nr, volatile unsigned long * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr)
:"memory");
return oldbit;
}
分析:
bts 测试位并置位,被测试位送CF并且被测试位置1 与btr相对。
sbbl %0,%0 将 ”-CF“ 给%0
本文深入探讨了Linux内核中用于管理内存映射和位操作的机制,包括内存区域的划分、内存映射的打印及内核中使用的原子操作。通过解析关键代码段,解释了如何高效地管理和利用内存资源,以及如何实现原子操作以确保数据的一致性和可靠性。
2017

被折叠的 条评论
为什么被折叠?



