# 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)