發表文章

目前顯示的是有「linux」標籤的文章

IPC: (3) socket

圖片
Socket 為 Linux IPC (Inter-process communication) 的方式之一. process 可藉由 socket 傳遞資料至另一個 process. 以下以 AF_INET 作為範例來介紹 TCP 與 UDP. TCP 與 UDP 皆以講解流程圖與 API 的用法為主. 完整範例 code 請點選 github 連結. TCP 以下為 TCP server 與 client 端的建立通訊流程. 當中的 write 與 read 可以與 send 與 recv 替換 . 範例 code 請參閱 github TCP 流程圖 [1] Server 與 client 透過 socket 來通訊的流程如下. Server 端: 建立 socket 後, 藉由 bind() 綁上 ip 與 port. 執行 listen() 等待 client 的連線要求. 透過 accept() 接受要求後, 便可開始與 client 進行傳輸的動作. Client 端: 建立 socket 後, 在 connect() 綁上 server 的 ip 與 port 進行連線. 當連線要求被接受後, 便可以進行傳輸. TCP APIs socket [2] #include <sys/socket.h> sockfd = socket( int socket_family, int socket_type, int protocol); socket_family: 為所用的 socket domain, 這邊採用網際網路的關係, 故選用 AF_INET. socket_type: 由於選用 TCP, 所以使用 SOCK_STREAM. protocol: 預設數值為 0 bind [3] #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int bind ( int sockfd, const struct sockaddr...

IPC : (2) signal

Signal Signal 為 Linux IPC(Inter-process communication)的方式之一. process 藉由 system call 傳遞特定 signal number 至另一個 process. 當 signal number 被傳遞至目標 process, process 會執行下列其中一項應對[2]: 此 signal number 的配置(disposition) 被設為 SIG_IGN(signal is ignored)[3]. 忽略此 signal number 此 signal number 的配置(disposition) 被設為 SIG_DFL(default signal handling)[3]. default action 會處理此 signal number 此 signal number 的配置(disposition) 對應到一個 function. 呼叫對應的 handler function[3] 並把 signal number 帶入此 function. 注意: SIGKILL 與 SIGSTOP 無法被 略過 以及 攔截 . API 範例 以下針對 signal 與 kill 的 API 說明. 完整的範例程式可於 github 看到 API 說明 signal[2] #include <signal.h> typedef void ( * sighandler_t )( int ); sighandler_t signal ( int signum, sighandler_t handler); 在 signal 函數設置 signum 所要對應的 handler. 其 handler 可以為 SIG_IGN, SIG_DFL 或者自訂的 handler. 其 handler 格式為 void (*sighandler_t)(int);. kill[4] #include <sys/types.h> #include <signal.h> int kill ( pid_t pid, int sig)...

IPC : (1) pipe & fifo

PIPE & FIFO 簡介 Pipe 與 fifo 為 Linux IPC(Inter-process communication)的方式之一. 共同的部分為 (1) 建立一個單向的 data channel. (2) 同樣使用 fd(file descriptor) 作為讀寫的媒介. (3) 預設讀取端(read)沒資料讀取會被鎖住(block), 直到寫入端(write)寫入資料. 相反過來 pipe buffer 滿了, write 會被鎖住(block). 若想改為非鎖住(non-block)則可透過 fcntl 或於 API 設置相關 flag 參數(如果 API 提供) 存取限制的部分 (1) pipe 僅舉限於關聯的 processes. (2) fifo 則是透過 permission mask 來作為限制. 相關的特性如下表所示[1]. 類型 識別名稱 於系統的表示 存取特性 persistence pipe no name fd Only by related processes process FIFO path name fd permission mask process (?) API 範例 以下針對兩個 API 個別進行說明. 其個別完整的範例程式可於 github 看到 Pipe[2] API 說明 #include <unistd.h> int pipe ( int pipefd[ 2 ]); #define _GNU_SOURCE /* See feature_test_macros(7) */ #include <fcntl.h> /* Obtain O_* constant definitions */ #include <unistd.h> int pipe2 ( int pipefd[ 2 ], ...

Linux : ram disk

linux支援以memory做作為disk方法,來提升存取效率. 但也意味著資料會隨著電源關閉而消失. 以下為常見的方法列表與特性. tmpfs ramfs ramdisk Write out of limitation Error keep writing Error Fixed Size Y N Y Uses Swap Y N N Volatile Storage Y Y Y format before use N N Y 以下為各種ram disk的相關指令 tmpfs root@~# mkdir tmpfs root@~# mount -t tmpfs -o size=20m tmpfs tmpfs/ ramfs root@~# mkdir ramfs root@~# mount -t ramfs -o size=20m ramfs tmpfs/ ramdisk root@~# mkdir ramdisk root@~# mkfs.ext3 /dev/ram9 mke2fs 1.42.13 (17-May-2015) Discarding device blocks: done Creating filesystem with 65536 1k blocks and 16384 inodes Filesystem UUID: df58a293-4574-4e95-bde5-e60618eee94b Superblock backups stored on blocks: 8193, 24577, 40961, 57345 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accoun...

linux : kernel modules 簡介

Linux modules 基本上linux modules在編譯時候可以分為builtin modules與external modules. builtin module: 在make mennuconfig把要builtin的module設置為y. 編譯的時候就會在對應目錄產生built-in.o的檔案. 這些檔案便會被包入在image裡面. external module: 在make mennuconfig把要builtin的module設置為m. 編譯的時候就會在對應目錄產生kernel/time/test_udelay.ko的檔案. 這些檔案便會被放置在/lib/modules/$(uname -r) Modules 操作指令 顯示已安裝模組列表 root@yijyun-server:~# lsmod | head Module Size Used by usbhid 49152 0 usb_storage 69632 0 crct10dif_pclmul 16384 0 ppdev 20480 0 單一模組安裝&移除 藉由insmod與rmmod去針對單一模組進行安裝與移除 insmod [filename] [module options...] insmod /lib/modules/4.4.0-64-generic/kernel/drivers/hid/usbhid/usbhid.ko rmmod [modulename] rmmod usbhid 相依性的模組安裝&移除 藉由modprode去針對此模組進行安裝與移除. 安裝與刪除中會去移除相依性的模組 modprobe [modulename] [module parameters...] root@yijyun-server:~# modprobe cfg80211 modprobe -r [modulename...] root@yijyun-server:~# modprobe -r cfg80211 modules相關資訊 module是否為builtin 透...

linux : firmware 簡介

我以為device要可以運作, 只要在linux安裝相關的driver即可 最近看到原來device除了driver之外, 還是需要firmware這東西才可以運作... 稍微做個筆記.... Firmware 基本上device要可以正常運作是需要driver和firmware. driver可以看成是系統跟device溝通的橋樑. firmware則是執行在device上面的程式. Firmware除了可以預先寫死在device上外,另一方式就是driver初始化device的時候. 從系統讀取firmware, 在寫入到device. Firmware讀取流程 linux放置firmware的地方為/lib/firmware. 讀取firmware的時候就是透過此. (1) 流程參考[2] Driver跟kernel要求 "ar9170.fw" kernel傳遞event給udev來要求firmware udev執行對應的script,把firmware傳送至kernel所創建的一個特殊檔案 kernel從此特殊檔案讀取firmware, 再把資料傳送給driver driver再把資料傳給device (2) 流程參考[3][5] 1), kernel(driver): - calls request_firmware(&fw_entry, $FIRMWARE, device) - kernel searchs the fimware image with name $FIRMWARE directly in the below search path of root filesystem: User customized search path by module parameter 'path'[1] "/lib/firmware/updates/" UTS_RELEASE, "/lib/firmware/updates", "/lib/firmware/" UTS_RELEASE, ...

Linux: udev 介紹

在談論udev之前,先要知道/dev這目錄. /dev在linux用途是存放device node(file-like device nodes). 程式可以透過device node來與系統上的裝置溝通. e.g. /dev/input/mice 為滑鼠 那誰負責管理/dev底下的device node? 沒錯,那就是udev最主要的工作. kernel會把裝置相關的events(add/remove/etc.)傳送至udev(藉由netlink). udev根據寫好的rules,在/dev底下建立對應的device node. 而這些rules會根據裝置的屬性去撰寫相關設定條件. 針對符合規則的裝置做對應的處理 到這時候應該會好奇要怎麼去得知道裝置的屬性呢? 而這邊就要談到 /sys (file type: sysfs), 這個是由kernel所維護的device資訊, kernel會把連接上的裝置資訊給放在這邊. udev在建立device node的時候也會參考這邊相關的屬性 e.g. udevadm info -a --name /dev/input/mice or udevadm info -a --path $(udevadm info --query=path --name=/dev/input/mice) 接下來談的部分是udev rules. 基本上rule是由 match keys 和 assignment keys 這兩個部分構成. match key主要是作為條件判斷用. assignment keys則是用來設定數值與執行相關操作. 每一條rule至少都要有一個 match key 和 assignment key. 在 rule 中的這些keys則使用逗號(,)來做隔離, 並不允許由多行的keys來成一條rule. 這意味著udev rule file中的每一行就是一條rule . KERNEL=="sda", ATTR{size}=="234441648", NAME="sda", SYMLINK+=disk/by-id/ata-VBOX_HARDDISK_VBa2440069-7fdbc2ad 這一個例子是判斷KERNEL是否符合...

PC Booting 簡介

基於 BIOS 的開機流程簡介 描述基於 linux 的開機流程步驟, 適用於有 BIOS 的機器 開機的時候會執行 BIOS, BIOS 先對硬體做檢測. 在根據設定所指定的開機 device 去讀取 MBR(Master Boot Record). MBR 處於 device 的第一個 sector, 裡面包含了基本的 boot loader 與 partition table 資訊. 礙於 MBR 大小的限制(512 bytes = 446(basic boot loader code, e.g. boot.img) + 64(partition table)), boot loader 的會再去其他 sector 讀取完整的 boot loader 程式(e.g. core.img). 程式依據 MBR 或 GPT 來判斷放 boot loader 的位置[3][4]. (1) 為MBR時候, 通常 boot loader 安裝於 MBR 與第一個 partition 之間. (2) 當為GPT, 則使用一個 Boot Partition 來存放 boot loader 當 boot loader 被執行後, 會去讀取 /boot/grub 裡面的設定來決定所要讀取的 OS 核心檔案 (kernel.img 和 initrd.img) initrd.img 裡面包含 kernel 所需的基本模組(mod), 當被掛載後 kernel 便可以去讀取外接裝置, 並視設定來決定是否有需要重掛載檔案系統 接著就執行第一支程式 e.g. initd or systemd 範例 範例1 [6] Stage 1 : boot.img is stored in the master boot record (MBR) or optionally in any of the volume boot records (VBRs), and addresses the next stage by an LBA48 address (thus, the 1024-cylinder limitation of GRUB legacy is avoided); at installation time it is ...

pkg-config

編譯package的時候, 總是會看到--pkg-config=PKGCONFIG相關的選項。這邊就稍微研究一下pkg-config。 pkg-config這指令主要是用來搜尋安裝在系統上的libs,透過此指令列出lib的相關訊息。而libs的相關資訊則被記錄在.pc的檔案裡面。 附註: 在cross-compile的時候,編譯好的packages通常不會安裝在系統的預設目錄底下。通常都會放置在我們自訂的目錄。若是想讓pkg-config去搜尋我們放置的目錄,而不是預設的路徑。僅僅只需要修改PKG_CONFIG_PATH即可。 e.g. PKG_CONFIG_PATH=$PKG_CONFIG_PATH : /cross/x64/usr/lib/pkg 這邊以一個foo.pc作為例子,其內容如下: foo.pc: prefix=/usr/local exec_prefix=${prefix} includedir=${prefix}/include libdir=${exec_prefix}/lib Name: foo Description: The foo library Version: 1.0.0 Cflags: -I${includedir}/foo Libs: -L${libdir} -lfoo 相關指令用法如下: # 列出 cflag 以及所需的libs (prefix=/usr 輸出則為-I/usr/include/foo -lfoo) /usr/lib/pkgconfig$ pkg-config --cflags --libs foo -I/usr/local/include/foo -L/usr/local/lib -lfoo # 檢查lib版本 /usr/lib/pkgconfig$ pkg-config --libs "foo >= 1.9" Requested 'foo >= 1.9' but version of foo is 1.0.0 # 測試lib是否存在 (0表示存在;) /usr/lib/pkgconfig$ pkg-config --exists foo; echo $? 0 # 測試lib是否存在,並顯示錯誤訊息 (這對有編譯packa...