# 2019q1 Homework2 (fibdrv) contributed by < `tommywang0tw` > ## Environment ```shell $ uname -r 4.18.0-15-generic ``` ## 自我檢查清單 ### 檔案 `fibdrv.c` 裡頭的 `MODULE_LICENSE`, `MODULE_AUTHOR`, `MODULE_DESCRIPTION`, `MODULE_VERSION` 等巨集做了什麼事,可以讓核心知曉呢? `insmod` 這命令背後,對應 Linux 核心內部有什麼操作呢?請舉出相關 Linux 核心原始碼並解讀 In [include/linux/module.h](https://elixir.bootlin.com/linux/v4.18/source/include/linux/module.h), we can find: ```cpp #define MODULE_LICENSE(_license) MODULE_INFO(license, _license) #define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) #define MODULE_VERSION(_version) MODULE_INFO(version, _version) ``` :::warning I found a werid thing here. In the source code, `_license` is `"Dual MIT/GPL"`, but how would `license` be? :notes:Tommy ::: >`license` is just an argument of macro `MODULE_INFO`, which means that >```C= >MODULE_LICENSE("Dual MIT/GPL") >``` >should be expanded like >```C= >MODULE_INFO(license, "Dual MIT/GPL") >``` >[color=#0ABAB5][name=bauuuu1021] These four macros are all going to be substituted by `MODULE_INFO`. We can also find `MODULE_INFO` in the same file as below: ```css= #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) ``` Then in [include/linux/moduleparam.h](https://elixir.bootlin.com/linux/v4.18/source/include/linux/moduleparam.h), we can find: ```cpp #define __MODULE_INFO(tag, name, info) \ static const char __UNIQUE_ID(name)[] \ __used __attribute__((section(".modinfo"), unused, aligned(1))) \ = __stringify(tag) "=" info ``` Let's find out what `_UNIQUE_ID` do. In [include/linux/compiler.h](https://elixir.bootlin.com/linux/v4.18/source/include/linux/compiler.h#L166), we can find: ```cpp # define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__) ``` And we can find what __PASTE is in [include/linux/compiler_types.h](https://elixir.bootlin.com/linux/v4.18/source/include/linux/compiler_types.h#L53) as below: ```cpp #define ___PASTE(a,b) a##b #define __PASTE(a,b) ___PASTE(a,b) ``` ### 當我們透過 insmod 去載入一個核心模組時,為何 module_init 所設定的函式得以執行呢?Linux 核心做了什麼事呢? :::warning The first thing I want to do here is to find out what does insmod do. From [linux man page](https://linux.die.net/man/8/insmod), it said "insmod is a trivial program to insert a module into the kernel", so I want to find out the program and drill in it. However, I couldn't find it. All I know is `insmod` called `module_init`. :notes: Tommy ::: Let's find out what is `module_init`. In [include/linux/module.h](https://elixir.bootlin.com/linux/v4.18/source/include/linux/module.h#L329), ```cpp #define module_init(x) __initcall(x); ``` So we know `module_init` is a macro which is coresponding to `__initcall`. So let's find out what is `__initcall`. In [include/linux/init.h](https://elixir.bootlin.com/linux/v4.18/source/include/linux/init.h), ```cpp #define __initcall(fn) device_initcall(fn) ``` ###### Reference: [linux驱动 之 module_init解析 (上)](https://blog.csdn.net/richard_liujh/article/details/45669207)