======================== Linking ======================== Linking is rarely discussed in OS courses, but this is what makes loadable modules (read: drivers that can be loaded on demand into a running system; of course, you can compile all the drivers into the kernel and load them at boot time, but this is lame and unscalable) work. Also, page sharing, one of the major functions of the VM systems, is made worthwhile by dynamic libraries; they probably get shared the most on a typical system (that is not a database server.) Dynamic libraries are made possible by having a standard for linking code into a running process. Hence we look at dynamic libraries, and, specifically, at the ELF standard features they depend on. Microsoft's PE format is ELF's close cousin (they are both the sons of COFF): http://www.iecc.com/linker/linker10.html Suggestion: read the Symbol Table section of the ELF specification: http://www.muppetlabs.com/~breadbox/software/ELF.txt Compile a C program into an object file ("gcc -c some.c") and use readelf, nm, and objdump to examine the symbol tables. Also notice the associated relocation tables (see the "Relocation Types". This is what the compiler toolchain linker ("ld") will go by. Then compile the program into a dynamic executable and examine the "dynsym" section (this is what the dynamic linker will go by), and repeat the examination. Driver modules for the kernel will look like .o object files. ================= Per-page hash table ============ The kernel maintans a "struct page" page_t data structure for every physical page, explained in the beginning of Chapter 10. This is the heart of mmap-ed file sharing (libraries, in particular) and file I/O caching: it associates a physical page is associated with a piece of a file/device, i.e. maps --> an instance of page_t <--> phys. page page_t defined at: http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/page.h#463 Multiple kernel functions using this table means multiple locks protecting its different members. The comment at lines 118--385 of page.h tells the whole story. The story, especially the "locking protocol", is a perfect example of OS programming optimizations. Lookup in the pagetable: page_find http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/vm_page.c#1011 Note that most of the standard hash table work is done in macros: PAGE_HASH_SEARCH line 297 and PAGE_HASH_FUNC, http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/page.h#567 The hash table itself is page_hash, defined in http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/i86pc/os/startup.c#282 next to other globals that enable other traversals of phys memory pages. We've seen similar code in /proc traversal. The linking of page structs is discussed in Ch. 10.1--10.3. Observe placement of page structs on the freelist in page_free: http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/vm_page.c#2617 This is one of the points where "page coloring" (explained in the textbook) comes in. Observe the calls to page_list_add in page_free: http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/vm_pagelist.c#page_list_add There is a reason why the heads of the lists are obtained through macros, PAGE_{CACHE,FREE}LISTS: they are 4-LEVEL POINTER ARRAYS: http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/i86pc/vm/vm_dep.h#105 The last level of pointer translation is "coloring". Read the coloring theory in Chapter 10, and observe its setup in http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/i86pc/vm/vm_machdep.c#1640 ***** We stopped here in class ***** ======================== Segment Drivers ======================== Named in Table 9.4 (p. 479), code in http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/ Primary example: "seg_vn": http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/seg_vn.c Observe *static* methods of this driver being packed into a "struct seg_ops", called segvn_ops, actually assigned at http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/seg_vn.c#780 Note that "struct seg"'s s_data member in segments created by segvn driver (http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/vm/seg.h#111) will be pointing to an segvn_data (p. 482 explains it), and thus through it to the mapped file's vnode ("vp" member) and offset ("offset" member). The same driver also handles anonymous mappings. In that case, the segvn_data's "amp" member will be used instead (shown in Fig. 9.11) When faulting in a file-backed page: trap() -> pagefault() -> as_fault() -> segvn_fault() -> _getpage() Observe the "dives" from abstraction layers to specific systems' implementation workhorse methods and back: mmap() -> _map() -> segvn_create() -> hat_map() ufs_map zfs_map ... ======================== Misc ======================== What is XHAT? According to this posting, its existence was a reluctant compromise for supporting a particular special device: http://archive.netbsd.se/?ml=opensolaris-code&a=2006-03&t=1864384 As such, it is not of interest to us, other than as an example of "giant kludges" that OS kernel developers can be forced into implementing.