# 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 三個步驟 :::