1212#include <linux/init.h> // Macros used to mark up functions e.g., __init __exit
1313#include <linux/module.h> // Core header for loading LKMs into the kernel
1414#include <linux/kernel.h> // Contains types, macros, functions for the kernel
15+ #include <linux/page-flags.h>
16+ #include <asm/cacheflush.h>
1517
1618MODULE_LICENSE ("GPL" ); ///< The license type -- this affects runtime behavior
1719MODULE_AUTHOR ("Derek Molloy" ); ///< The author -- visible when you use modinfo
@@ -22,6 +24,63 @@ static char *name = "world"; ///< An example LKM argument -- default valu
2224module_param (name , charp , S_IRUGO ); ///< Param desc. charp = char ptr, S_IRUGO can be read/not changed
2325MODULE_PARM_DESC (name , "The name to display in /var/log/kern.log" ); ///< parameter description
2426
27+ #if 0
28+ // x86 only ?
29+ #define alloc_gatt_pages (order ) \
30+ ((char *)__get_free_pages(GFP_KERNEL, (order)))
31+ #define free_gatt_pages (table , order ) \
32+ free_pages((unsigned long)(table), (order))
33+ #endif
34+
35+ // use vmalloc()
36+
37+ static int page_order = 10 ; // we allocate (1<<page_order) pages
38+ static char * table = 0 ;
39+
40+ static void
41+ hello_alloc_pages (void )
42+ {
43+ struct page * page ;
44+ char * table_end ;
45+
46+ table = (char * ) __get_free_pages (GFP_KERNEL , page_order );
47+ if (!table ) { printk (KERN_WARNING "Could not allocate pages\n" ); return ; }
48+
49+ printk (KERN_WARNING "sizeof(phys_addr_t): %i\n" , sizeof (phys_addr_t ));
50+ if (sizeof (phys_addr_t ) == 8 )
51+ printk (KERN_WARNING "Allocated %li bytes (%i pages) at 0x%llx\n" ,
52+ (1 << page_order ) * PAGE_SIZE , 1 << page_order , virt_to_phys (table ));
53+
54+ table_end = table + ((PAGE_SIZE * (1 << page_order )) - 1 );
55+
56+ for (page = virt_to_page (table ); page <= virt_to_page (table_end ); page ++ )
57+ SetPageReserved (page );
58+
59+ * ((int * )table ) = 0xdeadbeaf ;
60+
61+ if (set_memory_uc ((unsigned long )table , 1 << page_order ))
62+ printk (KERN_WARNING "Could not set pages to UC!\n" );
63+ else
64+ printk (KERN_WARNING "Success !\n" );
65+ }
66+
67+ static void
68+ hello_free_pages (void )
69+ {
70+ char * table_end = table + ((PAGE_SIZE * (1 << page_order )) - 1 );
71+ struct page * page ;
72+
73+ printk (KERN_WARNING "Freeing pages\n" );
74+
75+ set_memory_wb ((unsigned long )table , 1 << page_order );
76+
77+ for (page = virt_to_page (table ); page <= virt_to_page (table_end ); page ++ )
78+ ClearPageReserved (page );
79+
80+ free_pages ((unsigned long )(table ), (page_order ));
81+ }
82+
83+
2584/** @brief The LKM initialization function
2685 * The static keyword restricts the visibility of the function to within this C file. The __init
2786 * macro means that for a built-in driver (not a LKM) the function is only used at initialization
@@ -30,6 +89,7 @@ MODULE_PARM_DESC(name, "The name to display in /var/log/kern.log"); ///< parame
3089 */
3190static int __init helloBBB_init (void ){
3291 printk (KERN_INFO "EBB: Hello %s from the BBB LKM!\n" , name );
92+ hello_alloc_pages ();
3393 return 0 ;
3494}
3595
@@ -38,6 +98,8 @@ static int __init helloBBB_init(void){
3898 * code is used for a built-in driver (not a LKM) that this function is not required.
3999 */
40100static void __exit helloBBB_exit (void ){
101+ if (table )
102+ hello_free_pages ();
41103 printk (KERN_INFO "EBB: Goodbye %s from the BBB LKM!\n" , name );
42104}
43105
0 commit comments