首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Linux 2.6 內核模塊編譯報錯:cli/sti/xtime/proc_root 過時 API 遷移指南

     編輯:程式設計疑難解答

錯誤信息分析

/root/clock.c:20: error: implicit declaration of function 'cli'
/root/clock.c:21: error: 'xtime' undeclared
/root/clock.c:22: error: implicit declaration of function 'sti'
/root/clock.c:36: error: unknown field 'owner' specified in initializer
/root/clock.c:50: error: 'proc_root' undeclared

API 遷移對照表(2.4 → 2.6+)

2.4 內核2.6+ 內核說明
cli() / sti()local_irq_save() / local_irq_restore()中斷控制,支持嵌套、多 CPU
xtimektime_get_real() / getnstimeofday()高精度時間,納秒級
proc_root移除,使用 proc_mkdir() 創建目錄/proc 根目錄不再導出符號
struct proc_dir_entry 靜態初始化proc_create() / proc_create_data()動態創建,自動管理字段
owner 字段自動設置為 THIS_MODULE無需手動指定

修正後的 clock.c 完整代碼

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/time.h>
#include <linux/ktime.h>

#define PROC_NAME "clock"

static struct proc_dir_entry *proc_entry;

static ssize_t clock_read(struct file *file, char __user *buf, 
                          size_t count, loff_t *ppos) {
    struct timespec64 ts;
    ktime_get_real_ts64(&ts);  // 獲取當前時間 (秒 + 納秒)
    
    char kbuf[64];
    int len = snprintf(kbuf, sizeof(kbuf), "%lld %ld\n", 
                       (long long)ts.tv_sec, ts.tv_nsec / 1000); // 微秒
    
    return simple_read_from_buffer(buf, count, ppos, kbuf, len);
}

static const struct proc_ops clock_proc_ops = {
    .proc_read = clock_read,
};

static int __init clock_init(void) {
    // 動態創建 /proc/clock
    proc_entry = proc_create(PROC_NAME, 0444, NULL, &clock_proc_ops);
    if (!proc_entry) {
        pr_err("Failed to create /proc/%s\n", PROC_NAME);
        return -ENOMEM;
    }
    pr_info("/proc/%s created\n", PROC_NAME);
    return 0;
}

static void __exit clock_exit(void) {
    proc_remove(proc_entry);
    pr_info("/proc/%s removed\n", PROC_NAME);
}

module_init(clock_init);
module_exit(clock_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Developer");
MODULE_DESCRIPTION("Simple /proc clock module for Linux 2.6+");

Makefile 現代化

obj-m += clock.o

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean

install:
	insmod clock.ko

uninstall:
	rmmod clock

編譯與測試

# 編譯
make

# 加載
sudo insmod clock.ko
dmesg | tail  # 查看內核日誌

# 測試
cat /proc/clock
# 輸出示例:1701234567 123456

# 卸載
sudo rmmod clock

關鍵遷移要點總結

  1. 中斷控制:local_irq_save(flags) 返回保存的標誌,local_irq_restore(flags) 恢復,必須成對使用
  2. 時間獲取:ktime_get_real_ts64() 替代 xtime,提供 64 位秒 + 納秒
  3. /proc 文件系統:使用 proc_create() + proc_ops (2.6.30+) 或 file_operations (舊版)
  4. 模塊導出符號:避免依賴內核未導出符號(如 proc_root)
  5. 內核版本宏:#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) 做版本兼容

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved