天天看點

centos 自定義核心子產品 編譯運作

簡單記錄一下 centos 自定義核心子產品的一些編譯運作記錄,代碼如下:

主要功能是通過rdtsc 指令直接從 CPU MSR 寄存器中擷取時鐘,嘗試擷取兩次,兩次之間會做一些指派操作什麼的,并記錄一下時差。

#include <linux/hardirq.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/preempt.h>
#include <linux/sched.h>
void inline measured_function(volatile int *var) { (*var) = 1; }

static int __init hello_start(void) {
  unsigned long flags;
  uint64_t start, end;
  int variable = 0;
  unsigned cycles_low, cycles_high, cycles_low1, cycles_high1;
  printk(KERN_INFO "Loading test module...\n");
  preempt_disable();         /*we disable preemption on our CPU*/
  raw_local_irq_save(flags); /*we disable hard interrupts on our CPU*/
  /*at this stage we exclusively own the CPU*/
  asm volatile(
      "RDTSC\n\t"
      "mov %%edx, %0\n\t"
      "mov %%eax, %1\n\t"
      : "=r"(cycles_high), "=r"(cycles_low));
  measured_function(&variable);
  asm volatile(
      "RDTSC\n\t"
      "mov %%edx, %0\n\t"
      "mov %%eax, %1\n\t"
      : "=r"(cycles_high1), "=r"(cycles_low1));
  raw_local_irq_restore(flags);
  /*we enable hard interrupts on our CPU*/
  preempt_enable(); /*we enable preemption*/
  start = (((uint64_t)cycles_high << 32) | cycles_low);
  end = (((uint64_t)cycles_high1 << 32) | cycles_low1);
  printk(KERN_INFO "\n function execution time is %llu clock cycles",
         (end - start));
  return 0;
}

static void __exit hello_end(void) { printk(KERN_INFO "Goodbye Mr.\n"); }
module_init(hello_start);
module_exit(hello_end);      

編譯方式,Makefile

# obj-m 必須存在,後面的 .o 檔案可以是自己的檔案名,其他無需更改
obj-m := rdtsc_mode.o 
KERNELBUILD :=/lib/modules/$(shell uname -r)/build
default:
        make -C $(KERNELBUILD) M=$(shell pwd) modules

clean:
        rm -rf *.o *.ko *.mod.c .*.cmd      

将源代碼檔案和 makefile 放在一個目錄之下,

​​

​sudo make​

​ 執行即可,執行成功之後會在目前目錄下生成一個 rdtsc_mode.ko 檔案。

[Fri Jan 14 16:41:52 2022] Loading test module...
[Fri Jan 14 16:41:52 2022] function execution time is 3504353503 clock cycles
[Fri Jan 14 16:42:11 2022] Goodbye Mr.      

繼續閱讀