Posted  by  admin

Accessing Kernel Headers

Accessing Kernel Headers

Accessing Kernel Memory on the x86 Version of Mac OS X © Amit Singh. All Rights Reserved. Written in May 2006 Introduction Beginning with the x86 version of Mac OS X, Apple removed the /dev/mem and /dev/kmem devices from the system—for reasons that might include interface cleanliness, portability across system versions, security, and perhaps even a bit of obscurity. Consequently, programs that use these devices for directly accessing kernel memory will not work.

Similarly, libraries (most notably libkvm) that use these devices will also not work. Memory devices are sometimes convenient while debugging or analyzing the system, especially in the academic context. My book has a small number of examples that involve directly reading kernel memory from user space to illustrate certain concepts, say, by showing the contents of certain kernel data structures.

Kernel

In some examples, it is especially convenient to use the dd command to read from /dev/kmem. I promised in the book (in the footnote on page 560, Chapter 6, The xnu Kernel, and also in Appendix A) that the accompanying web site will provide information about implementing your own /dev/kmem. Although there are other ways besides these devices to read kernel memory, they are often more involved and less convenient.

In this discussion, we will see how to implement your own /dev/kmem. As a trivial alternative to the kernel extension described in this document, you can try using the kmem=1 boot-time argument. If your kernel supports this argument (the Apple kernels at the time of this writing do), setting it will reenable the kernel memory device. The source code in this discussion is useful for several reasons such as the following:. It is an example of the implementation of a not-too-complex loadable kernel extension that does something useful.

It uses bits from both BSD (mostly) and Mach. It shows how to implement Unix-style devices on Mac OS X. It gives developers and other students of the system the option of using /dev/kmem, along with libkvm and such, for debugging and analysis on the x86 version of Mac OS X. The Memory Devices: Looking Back In the earliest versions of UNIX, the mem device mapped the computer's physical memory in the /dev/mem special file, which provided byte-oriented read/write access to the memory—that is, byte offsets in /dev/mem corresponded to physical memory addresses. A common use of /dev/mem was to debug the system. In particular, the running kernel could be patched through /dev/mem using a debugger. Accessing invalid offsets (memory addresses that did not exist) resulted in a kernel panic.

# ls -l /unix # 5th Edition UNIX -rwxr-xr-x 1 bin 25802 Mar 21 12:07 /unix # 25KB! # ls -l /dev total 0 cr-r-r- 1 bin 1, 0 Nov 26 18:13 mem crw-rw-rw- 1 bin 1, 2 Nov 26 18:13 null crw-w-w- 1 root 0, 0 Mar 21 12:08 tty8 # Since there was no virtual memory in early UNIX, there was no /dev/kmem. Most Unix systems implement the /dev/mem and /dev/kmem character devices. As in early UNIX, mem maps the system's physical memory into a file, whereas kmem maps the kernel's virtual memory into a file. There also exist variations on this theme: for example, the /dev/port device on Linux maps the I/O ports into a file. Moreover, some systems allow physical memory region attributes (such as cacheability and write-protection) to be manipulated through ioctl calls on /dev/mem.

The KVM Library Although /dev/kmem makes it rather easy to read kernel virtual memory, it is excruciating to read structured information this way, especially if the data structures in question involve pointers. Besides, the programmer has to somehow determine which addresses to read from, so there is the additional issue of symbol lookup.

The kvm library, first introduced in SunOS, provides a uniform interface for accessing kernel memory corresponding to live or dead (crashed) kernels. It also allows symbols to be looked up by name.

Kernel Headers Cannot Be Found

There also exist less generic, system-specific kvm library functions such as kvmgetprocs, kvmgetargv, kvmgetenvv, and kvmgetloadavg. The kvm library needs the memory devices for its operation. Therefore, it is obsoleted in the x86 version of Mac OS X. Note, however, that the library itself is implemented within the system library, and is still present. The kernel virtual address of mymmread is 0x3bd0214f. (1) The address of the cdevsw array in the kernel can be looked up by using nm on the /mach file. $ nm /mach grep cdevsw 00441720 A cdevsw.

Determining the kernel virtual address of the cdevsw array We can now retrieve 4 bytes from the kernel virtual address 0x441720 + 624, which is 0x441990 (or 4462992 decimal). # Read 4 bytes from the address 0x441990 (4462992 decimal) $ sudo dd if=/dev/kmem of=/dev/stdout bs=1 iseek=4462992 count=4 od -X 0000000 3bd0214f 0000004 Figure 10. Reading from /dev/kmem.

I am a newbie to kernel programming and I want to modify a header file in arch/x86/include/asm/tlbflush.h so that my kernel module can use one of the functions exported by this header file. I have the source code for 3.2.59 kernel and made changes to tlbflush.h.

I included the header file tlbflush.h. When i compile the module i get a warning saying the function that I am using is not found and as a result I am not able to insmod my kernel module. I went through the following and tried the following steps to install the modified kernel header:. make. sudo make modulesinstall. sudo make headersinstall INSTALLHDRPATH=/usr/include. sudo make install.

sudo update-initramfs -c -k 3.2.59 The link mentioned talks about installing kernel headers to /usr/include for access to user space processes I want to mention that I have so many headers installed due to the upgrades done on my ubuntu machine. Also all of them have extensions like 3.2.0-59, 3.2.0-xx I considered 3.2.0-59 to be same as 3.2.59 though I am not sure. Please correct me in case this is wrong. Edit: I am sorry, I got confused with the headers in /usr/src/. Folder versus the headers in the source code of kernel that is being modified. I made a change in the headers of the kernel source that i downloaded and after that there is no warning now.

Accessing

But the question still remains that why are the kernel headers in /usr/src/ used? I am sorry for the waste of time, if you spent on this. But the question still remains that why are the kernel headers in /usr/src/ used? Actually, nobody forces that. If you're using standard Makefile for building your module, it is a place that states it. Mine contains the following line: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules If you examine what /lib/modules/$(shell uname -r)/build really is, you will find that this is a symlink to folder where kernel source is located. $ ls -l /lib/modules/$(uname -r)/build lrwxrwxrwx 1 root root 32 Jun 9 04:46 /lib/modules/3.12.21-gentoo-r1/build - /usr/src/linux-3.12.21-gentoo-r1 For ubuntu, linux-headers contains only minimum kernel part necessary to build your own module (not only headers).