---
# System prepended metadata

title: Work learning note

---

# Work learning note
## program loading in linux

1. 使用者在 shell 模式下執行外部程式（stored program）

2. shell 以 fork+exec system call 的方式執行外部程式

3. 透過 0x80H 軟體中斷（x86）叫用 kernel 的 exec（sys_execve）system call service
---
**kernel space Program Loader**

4. Exec system call 呼叫 program loader（ELF loader），將 process image（ELF image）載入

5. Program loader 找到 PT_INTERP segment

6. Program loader 將 PT_LOAD  segment mapping 為新的 text/data segment，text segment 由 vaddr. 0x0804_8000 開始，data segment 緊接其後

7. Program loader 呼叫 interpreter loader 將 program interpreter（ld.so）載入，並 mapping 到 process memory；interpreter 的 text segment 由 vaddr. 0x4000_0000 開始，interpreter 的 data segment 緊接其後

8. Program loader 將 BSS segment 準備好

9. Program loader 將 process 的 register **eip**（user-mode）修改為 program interpreter 的進入點；並將 **sp** 設定為 user mode 的 stack

**所以任何 shared library 的外部程式，一開始都是由 program interpreter 開始執行**

---
**User Space Program Loader / Linker**
10. Program interpreter(/lib/ld-linux.so.2) 會找到 process 所需的 shared library（名稱及其路徑）(lib/libc.so.6)

11. Program interpreter 使用 mmap system call 將 shared library mapping 到 process memory，以完成整個 process image 的建立

12. 更新 shared library 的符號表

13. Program interpreter 'jump' 到 process 的進入點（紀錄在 ELF header 裡的 entry point）

14. program start

![](https://i.imgur.com/L8dp0U5.png)



## compiling process of c in linux
1. pre-processing (source code)
    input: \*.c, \*.h
    ```clike=
    #include
    #indef
    #if
    #endif
    ```
    output: 中間文件\*.i
    command: **gcc -E hello.c -o hello.i**
    
    
2. compile (assembly code)
    input: \*.i
    编译后生成汇编语言文件\*.s
    output: \*.s
    command: **gcc-s hello.i -o hello.s**

3. assembling (machine code)
    input: \*.s
    将输入的汇编文件*.s转换成二进制机器代码*.o
    output: \*.o
    command: **gcc -c hello.s-o hello.o**

4. linking
    input: \*.o, \*.a, \*.so
    在链接阶段，将输入的二进制机器代码文件*.o（与其他机器代码文件和库文件)汇集成一个可执行的二进制代码文件。
    包含static library 
    output: \*executable_file
    command **gcc hello.o -o hello**

## linux device driver
http://stellvia7.pixnet.net/blog/post/72616455-%5B%E8%BD%89%5Dlinux-kernel%EF%BC%8811%EF%BC%89--sysfs-and-device-node
```=
mknod Name { b | c } Major Minor


b: 表示特殊文件是block的device（磁盘、软盘或磁带）。
    所有的block device都可以在/sys/block/*/dev和/sys/block/*/*/dev找到。
c: 表示特殊文件是char的device（其他设备）。
    所有的char device都可以在/sys/bus/*/devices/*/dev和/sys/class/*/*/dev找到。
p: 创建 FIFO（已命名的管道）。

```
:::warning
cat /dev/device_name
等同於call  device_open-> device_read-> device_close
三個步驟
:::
