首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux 內核移植 S3C2440 實戰筆記:從 menuconfig 到驅動匹配的完整流程

     編輯:關於C語言

記錄將 Linux 內核(2.6.x 時代)移植到 S3C2440(SMDK2440 開發板)的關鍵步驟與核心代碼路徑,涵蓋配置、啟動參數解析、內存映射、控制台初始化、MTD 分區、平台驅動模型。

1. 內核配置

make menuconfig
  → System Type → S3C2440 Machines → SMDK2440

生成 .config,關鍵宏:CONFIG_ARCH_S3C2440、CONFIG_MACH_SMDK2440。

2. 機器類型識別:__lookup_machine_type

U-Boot 傳遞 machine_id(r1 寄存器),內核遍歷 __arch_info_begin~__arch_info_end 段查找匹配的 machine_desc 結構:

// arch/arm/mach-s3c2440/mach-smdk2440.c
MACHINE_START(SMDK2440, "SMDK2440")
    .phys_io        = S3C2410_PA_UART,
    .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
    .boot_params    = S3C2410_SDRAM_PA + 0x100,
    .init_irq       = s3c24xx_init_irq,
    .map_io         = smdk2440_map_io,
    .init_machine   = smdk2440_machine_init,
    .timer          = &s3c24xx_timer,
MACHINE_END

3. setup_arch:解析 ATAGs

  • 調用 __lookup_machine_type 獲取 mdesc。
  • parse_tags(tag_ptr) 遍歷 ATAG 列表:
  • 早期參數解析:__early_param("mem=", early_mem)、__early_param("initrd=", early_initrd)。
  • paging_init(&meminfo, mdesc) 建立頁表映射。
  • 調用 mdesc->map_io() → smdk2440_map_io():
  • static void __init smdk2440_map_io(void) {
        s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); // 靜態 IO 映射表
        s3c24xx_init_clocks(16934400);                                 // 外部晶振 16.9344 MHz
        s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
    }

    4. parse_args:後續命令行參數處理

    處理 setup_arch 未覆蓋的參數(如 ttySAC0=...),並進一步規範化已解析參數。

    5. 控制台初始化:console_init

    遍歷 __con_initcall_start~__con_initcall_end 區間的函數指針:

    console_initcall(s3c24xx_serial_initconsole); // 宏註冊
    // drivers/serial/s3c2410.c
    void __init s3c24xx_serial_initconsole(void) {
        register_console(&s3c24xx_serial_console); // 向內核註冊控制台設備
    }

    6. MTD 分區修改

    預設分區定義於 arch/arm/plat-s3c24xx/common-smdk.c 的 smdk_default_nand_part 結構體,按項目需求調整起始地址、大小、名稱(Bootloader/Kernel/Rootfs/Env 等)。

    7. 平台驅動模型:設備與驅動匹配

    // 設備結構
    struct platform_device {
        const char* name;
        u32 id;
        struct device dev;
        u32 num_resources;
        struct resource* resource; // IOMEM, IRQ, DMA 等
    };
    
    // 驅動結構
    struct platform_driver {
        int (*probe)(struct platform_device*);
        int (*remove)(struct platform_device*);
        // ... pm callbacks
        struct device_driver driver; // .name = "xxx" 用於匹配
    };

    內核掃描註冊的 platform_device,與 platform_driver 的 name 字符串匹配,成功則調用 probe。設備資源(resource)通常來自板級文件(如 mach-smdk2440.c)靜態定義或 Device Tree(新內核)。

    關鍵文件路徑速查

    • arch/arm/mach-s3c2440/mach-smdk2440.c:機器描述、IO 映射、時鐘、串口
    • arch/arm/plat-s3c24xx/common-smdk.c:預設 NAND 分區
    • drivers/serial/s3c2410.c:串口驅動、控制台註冊
    • arch/arm/kernel/setup.c:setup_arch、parse_tags、paging_init

    註:現代內核(4.x+)已全面轉向 Device Tree,ATAGs/板級文件機制逐漸淘汰,但理解舊流程有助於閱讀歷史代碼與舊項目維護。

    1. 上一篇文章:
    2. 下一篇文章:
    Copyright © 程式碼之家 All Rights Reserved
    ATAG 類型處理函數作用
    ATAG_MEMparse_tag_mem32填充 meminfo 結構,記錄物理內存區域
    ATAG_CMDLINEparse_tag_cmdline拷貝啟動參數到 default_command_line