差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

cpp:linux_kernel:show_physical_address [2017/10/14 16:38]
tony [Introduction]
cpp:linux_kernel:show_physical_address [2023/06/25 09:48]
行 1: 行 1:
-====== Show Physical Memory Address of the kernel module ====== 
-===== Introduction ===== 
-我希望透過寫一個kernel module,透過user space的操作,去顯示某個變數值的實體記憶體位置與數值。 
-\\ 
-Note: 由於這程式僅用於測試,因此不會特別去考慮更好的寫法;會補充這點是由於看書有看到更好的寫法。 
-===== How to? ===== 
-==== Source Code ==== 
-包含以下內容:​ 
-  - 在init時,我建立一個字元裝置用以接受user space的操作,並初始hello_buf。 
-  - 當使用者執行cat /​dev/​hello時,會觸發file_operations的open與release,這裡我只實做open的對應行為:​ dump_physical_address。 
-  - dump_physical_address則是取得hello_buf的實體記憶體位置並dump出來。 
-  - exit就是釋放所有用到的資源。 
-<code cpp> 
-#include <​linux/​init.h>​ 
-#include <​linux/​module.h>​ 
-#include <​linux/​slab.h>​ 
-#include <​linux/​string.h>​ 
-#include <​asm/​io.h>​ 
-#include <​linux/​fs.h>​ 
- 
-MODULE_LICENSE("​Dual BSD/​GPL"​);​ 
- 
-static char* hello_buf; 
- 
-static int dump_physical_address(struct file *filp, struct vm_area_struct *vma) 
-{  
- unsigned long virt_addr; 
- phys_addr_t phy_addr; 
- printk("​damn\n"​);​  
- virt_addr = (unsigned long)hello_buf;​ 
- printk("​Hello kernel: %lx, value: %c\n", virt_addr, hello_buf[0]);​ 
- phy_addr = virt_to_phys((void*)virt_addr);​ 
- printk("​PA:​ 0x%lx\n",​ phy_addr); 
- pr_info("​PA:​ %pa for VA: 0x%lx\n",​ &​phy_addr,​ virt_addr); 
- return 0; 
-} 
- 
-static struct file_operations hello_fops = { 
- open: dump_physical_address,​  
-};  
- 
-static int hello_init(void) 
-{  
- 
- int ret = register_chrdev(187,​ "​hello",​ &​hello_fops);​ 
- if(ret<​0) { 
- printk("​Unsable to register char device %d\n", ret); 
- return ret; 
- } 
- 
- hello_buf = kmalloc(256,​ GFP_KERNEL);​ 
- memset(hello_buf,'​*',​256);​ 
- printk("​Hello kernel: %c\n", hello_buf[0]);​ 
- return 0; 
-} 
-static void hello_exit(void) 
-{ 
- if(hello_buf) { 
-   printk("​Goodbyte kernel: %c\n", hello_buf[0]);​ 
-   kfree(hello_buf);​ 
- } 
- unregister_chrdev(187,"​hello"​);​ 
- printk(KERN_INFO "​Goodbye\n"​);​ 
-} 
- 
-module_init(hello_init);​ 
-module_exit(hello_exit);​ 
-</​code>​ 
-==== Makefile ==== 
-<​code>​ 
-# 
-## Makefile for kernel test 
-# 
-#PWD         := $(shell pwd)  
-KVERSION ​   := $(shell uname -r) 
-KERNEL_DIR ​  = /​usr/​src/​kernels/​$(KVERSION)/​ 
-MODULE_NAME ​ = hello 
-obj-m       := $(MODULE_NAME).o ​   
-all: 
- make -C $(KERNEL_DIR) M=$(PWD) modules 
-clean: 
- make -C $(KERNEL_DIR) M=$(PWD) clean 
-</​code>​ 
-==== Test Script ==== 
-<code bash> 
-#!/bin/bash 
- 
-#mknod /dev/hello c 187 0 
- 
-rmmod hello 
-insmod hello.ko 
-cat /dev/hello 
-dmesg | tail 
-</​code>​ 
-===== Reference ===== 
-  * [[https://​wwssllabcd.github.io/​blog/​2012/​11/​13/​how-to-make-linux-module/​|一個簡單的 Linux Kernel Module]] 
-  * [[https://​github.com/​torvalds/​linux/​blob/​master/​lib/​test_debug_virtual.c|virt_to_phys sample]] 
-  * [[http://​blog.csdn.net/​freenaut/​article/​details/​4298174|字符设备 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()]] 
-