diff --git "a/C/\346\227\240\346\225\214\347\246\273\350\260\261\344\275\215\350\277\220\347\256\227.md" "b/C/\346\227\240\346\225\214\347\246\273\350\260\261\344\275\215\350\277\220\347\256\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..dc78eecf74ea2bb5a1cd71a25670a263c19d2553 --- /dev/null +++ "b/C/\346\227\240\346\225\214\347\246\273\350\260\261\344\275\215\350\277\220\347\256\227.md" @@ -0,0 +1,77 @@ +某科学的玩具操作系统中的一串用来映射到虚拟内存的代码: +```c + +/* map page s (virtual) to d... okay, what am i doing? */ + +void *__mapto(void *s, void *d, int attr) { +#if CONFIG_64BIT + __archptr_t *lvl1, *lvl2, *lvl3, *p; + __archptr_t dest_addr; + + dest_addr = (__archptr_t) d; + + lvl1 = (__archptr_t *) LVL1_PT[(dest_addr >> 39) & 4095]; + + if (!lvl1) { + if (!(lvl1 = early_kmalloc(4096, 4096))) + panic("mapto: Out of memory\n"); + + LVL1_PT[(dest_addr >> 39) & 4095] = (__archptr_t) lvl1 | DEFAULT_PAGE_ATTR; + memset(lvl1, 0, 4096); + } + + p = (__archptr_t *) ((__archptr_t) lvl1 & ~0xfffu); + lvl2 = (__archptr_t *) p[(dest_addr >> 30) & 4095]; + + if (!lvl2) { + if (!(lvl2 = early_kmalloc(4096, 4096))) + panic("mapto: Out of memory\n"); + + p[(dest_addr >> 30) & 4095] = (__archptr_t) lvl2 | DEFAULT_PAGE_ATTR; + memset(lvl2, 0, 4096); + } + + lvl3 = (__archptr_t *) ((__archptr_t) lvl2 & ~0xfffu); + + if (s) + lvl3[(dest_addr >> 21) & 4095] = (__archptr_t) s | attr; + + else + lvl3[(dest_addr >> 21) & 4095] &= ~0xfffu | attr; + + return d; +#else + + __archptr_t dest_addr = (__archptr_t) d; + __archptr_t *lvl1; + __archptr_t *lvl2; + + dest_addr &= ~PAGE_MASK; + + /* 10 lvl1 10 lvl2 12 offset */ + lvl1 = (__archptr_t *) LVL1_PT[dest_addr >> 22]; + + if (!lvl1) { + if (!(lvl1 = early_kmalloc(4096, 4096))) + panic("mapto: Out of memory\n"); + + LVL1_PT[dest_addr >> 22] = (__archptr_t) lvl1 | DEFAULT_PAGE_ATTR; + memset(lvl1, 0, 4096); + } + + lvl2 = (__archptr_t *) ((__archptr_t) lvl1 & ~0xffu); + + if (!s) + /* clear attributes and then set */ + + lvl2[(dest_addr >> 12) & 1023] &= ~0xff | attr; + + else + lvl2[(dest_addr >> 12) & 1023] = (__archptr_t) s | attr; + + + return (void *) dest_addr; +#endif +} + +``` \ No newline at end of file