1. 程式人生 > >Linux的 __setup解析 -- 命令列處理

Linux的 __setup解析 -- 命令列處理

__setup這條巨集在Linux Kernel中,使用最多的地方就是定義處理Kernel的啟動引數 的函式及資料結構,巨集定義如下:

#define __setup(str, fn) \
__setup_param(str, fn, fn, 0)

#define __setup_param(str, unique_id, fn, early) \
static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
__used __section(.init.setup) \
__attribute__((aligned((sizeof(long))))) \
= { __setup_str_##unique_id, fn, early }

===================

使用Kernel中的例子分析一下這兩條定義:

__setup("root=", root_dev_setup);

這條語句出現在init/do_mounts.c中,其作用是處理Kernel啟動時的像root=/dev/mtdblock3之類的引數的。

分解一下這條語句,首先變為:

__setup_param("root=",root_dev_setup,root_dev_setup,0);

繼續分解,將得到下面這段代嗎:

static char __setup_str_root_dev_setup_id[] __initdata __aligned(1) = "root=";
static struct obs_kernel_param __setup_root_dev_setup_id
__used __section(.init.setup)
__attribute__((aligned((sizeof(long)))))
= { __setup_str_root_dev_setup_id, root_dev_setup, 0 };

也就是 以下 定義:

static char __setup_str_root_dev_setup_id[]  = "root=";
static struct obs_kernel_param __setup_root_dev_setup_id = { __setup_str_root_dev_setup_id, root_dev_setup, 0 };

這段程式碼定義了兩個變數:字元陣列變數__setup_str_root_dev_setup_id,其初始化內容為"root=",由於該變數用 __initdata修飾,它將被放入.init.data輸入段;另一變數是結構變數__setup_root_dev_setup_id,其型別為 struct obs_kernel_param, 該變理被放入 輸入段.init.setup

中。結構struct struct obs_kernel_param也在該檔案中定義如下:

struct obs_kernel_param {
     const char *str;
     int (*setup_func)(char *);
     int early;
};

變數__setup_root_dev_setup_id的三個成員分別被初始化為:

__setup_str_root_dev_setup_id --> 前面定義的字元陣列變數,初始內容為"root="。

root_dev_setup --> 通過巨集傳過來的處理函式。

0 -->常量0,該成員的作用以後分析。

現在不難想像核心啟動時怎麼處理啟動引數的了:通過__setup巨集定義obs_kernel_param結構變數都被放入.init.setup段中,這樣一來實際是使.init.setup段變成一張表,Kernel在處理每一個啟動引數時,都會來查詢這張表,與每一個數據項中的成員str進行比較,如果完全相同,就會呼叫該資料項的函式指標成員setup_func所指向的函式(該函式是在使用__setup巨集定義該變數時傳入的函式引數),並將啟動引數 如root=後面的內容 傳給該處理函式。

也就是 root_dev_setup 的引數為  /dev/mtdblock3

相關推薦

Linux__setup解析 -- 命令處理

__setup這條巨集在Linux Kernel中,使用最多的地方就是定義處理Kernel的啟動引數 的函式及資料結構,巨集定義如下: #define __setup(str, fn) \ __se

linux解析命令引數(getopt_long用法)

getopt_long支援長選項的命令列解析,使用man getopt_long,得到其宣告如下:   #include <getopt.h>   int getopt_long(int argc, char * const argv[],   const cha

linux】--- 高階命令文字處理工具 sort

二、sort命令  sort 命令對 File 引數指定的檔案中的行排序,並將結果寫到標準輸出。如果 File 引數指定多個檔案,那麼 sort 命令將這些檔案連線起來,並當作一個檔案進行排序。 選項與引數: -f  :忽略大小寫的差異,例如 A 與 a 視為編碼相同

linux】--- 高階命令文字處理工具 cut

第一: cut命令 cut : 可以從一個文字檔案或者文字流中提取文字列 echo $PATH 選項 -b:僅顯示行中指定直接範圍的內容; -c:僅顯示行中指定範圍的字元; -d:指定欄位的分隔符,預設的欄位分隔符為“TAB”; -f:顯示指定欄位的內容; --comple

jq: 在Linux通過命令處理 JSON

因為最近要處理一些 JSON 資料格式,所以在經過一番搜尋後 最終找到了 jq 這個很棒的工具。jq 允許你直接在命令 行下對 JSON 進行操作,包括分片、過濾、轉換等等。 讓我們通過幾個例子來說明 jq 的功能: 漂亮列印 如果我們用文字編輯器開啟 JSON,有時候可能看起來會一團 糟,但是通過

linux中getopt_long解析命令引數(附上windows上的getopt_long原始碼)

     getopt_long支援長選項的命令列解析,使用man getopt_long,得到其宣告如下:       #include <getopt.h>       int getopt_long(int argc, char * const argv[

get_optlong用法(linux解析命令引數)

const char * const shor_options = “ho:v” ;struct option 型別陣列該資料結構中的每個元素對應了一個長選項,並且每個元素是由四個域組成。通常情況下,可以按以下規則使用。第一個元素,描述長選項的名稱;第二個選項,代表該選項是否需要跟著引數,需要引數則為1,反

linux在一行命令上執行多個命令

1. [ ; ]  如果被分號(;)所分隔的命令會連續的執行下去,就算是錯誤的命令也會繼續執行後面的命令。  [[email protected] etc]# lld ; echo “ok” ; lok  -bash: lld: command not fou

FFmpeg 解析命令引數

FFmpeg 命令列基礎語法: ffmpeg [global_options] {[input_file_options] -i input_file}...{[output_file_options] output_file}... global_options:全域性引

Linux終端下命令顏色的設定,三步解決

要實現的效果如下: 步驟: 1,在命令列輸入: vim  ~/ .bashrc 2,進入vim編輯器內容頁,然後在vim的最後一行(正文的最後一行),輸入 PS1='\[\033[1;31;1m\]\[email

nmcli 命令Linux 系統的命令網路管理器

要想在 Linux 命令下對網路進行相關設定,總的來說不外乎兩類方法:其一乃寫配置檔案,如 /etc/network/interfaces 進行網路介面配置,其二直接在終端呼叫 Linux 網路管理命令,在終端間接同文件打交道。 首先為大家所熟知的,ifconfig 命令和 iwconf

mysql 命令處理(六)事務

mysql中,事務是一些資料庫操作語句,有3個特點: 1.只有使用了InnoD引擎的資料庫或者表支援事務 2.事務可以用來維護資料庫完整性,保證成批的sql語句要麼全執行,要麼全不執行,不會出現部分執行失敗導致不一致的情況 3.事務用來管理insert,update,d

[編譯] 5、在Linux下搭建安卓APP的開發燒寫環境(makefile版)—— 在Linux上用命令+VIM開發安卓APP

星期三, 19. 九月 2018 02:19上午 - BEAUTIFULZZZZ 0)前言 本文不討論用IDE和文字編輯器開發的優劣,是基於以下兩點考慮去嘗試用命令列編譯安卓APP的: 瞭解安卓APP的編譯過程,瞭解IDE幹了什麼事; 放在打包伺服器上需要自動化生成APP的指令碼; 1)安裝配置環境

Linux(CentOS 7)命令模式安裝VMware Tools 詳解

本篇文章主要介紹瞭如何在Linux(CentOS 7)命令列模式安裝VMware Tools,具有一定的參考價值,感興趣的小夥伴們可以參考一下。 本例中為在Linux(以CentOS 7為例)安裝VMware Tools。 1.首先啟動CentOS 7,在

Linux 下檢視命令歷史

簡介 Linux中,bash輸入的歷史記錄,會存在.bash_history(或者說root/bash_history)。  通過history檢視。  可以看到,不僅可以輸出正確的命令,還可以輸入錯誤的(如abc),而且輸出的是history之前所有的命令(incl

go語言解析命令引數的實現

一、實現程式碼如下 // fffggg project main.go package main import (     "flag"     "fmt" ) func main() {     var num int     var mode string   

linux中yum命令的使用

yum介紹 yum命令是在Fedora和RedHat以及SUSE中基於rpm的軟體包管理器,它可以使系統管理人員互動和自動化地更細與管理RPM軟體包,能夠從指定的伺服器自動下載RPM包並且安裝,可以自動處理依賴性關係,並且一次安裝所有依賴的軟體包,無須繁瑣地一次

Python解析命令引數

使用Python編寫應用程式或是指令碼的時候,經常會用到命令列引數。C語言中有庫函式getopt解析短命令列引數,使用getopt_long解析短命令和長命令的組合。 Python使用getopt模組,同時解析短命令和長命令。看具體使用例子 #!/usr/bin/python import sys

Linux桌面與命令切換

1、首先在安裝Linux的時候是選則Desktop桌面方式安裝 2、切換命令     2.1快捷鍵:Ctrl+Alt+F1    切換到桌面模式                 &nb

linux centos7 cgroup 命令操作

1, lssubsys -am 檢視系統中已經存在的參cgroup子系統以及子系統的掛載點:          cpuset /sys/fs/cgroup/cpuset cpu,cpuacct /sys/fs/cgroup/cpu,cpuacct memory /sys