Linux PM domain framework(1)_概述和使用流程
1. 前言
在複雜的片上系統(SOC)中,設計者一般會將系統的供電分為多個獨立的block,這稱作電源域(Power Domain),這樣做有很多好處,例如:
1)將不同功能模組的供電分開,減小相互之間的干擾(如模擬和數字分開)。
2)不同功能所需的電壓大小不同:小電壓能量損耗低,但對訊號質量的要求較高;大電壓能量損耗高,對訊號質量的要求較低。因此可以根據實際情況,使用不同的電壓供電,例如CPU core只需1.2v左右即可,而大部分的I/O則需要3.3v左右。
3)系統執行的大部分時間,並不需要所有模組都處於power on狀態,因此可以通過關閉不工作模組的供電,將它們的耗電降為最低。
4)等等
雖然電源域的好處多多,卻不是越多越好,因為劃分電源域是需要成本的(需要在PMU中使用類比電路完成,包括金錢成本和空間成本)。因此,大多數系統會根據功能,設定有限的幾個電源域,例如:CPU core(1、2、3…);GPU;NAND;DDR;USB;Display;Codec;等等。
這種設計引出一個問題:存在多個模組共用一個電源域的情況。因而要求在對模組power on/off的時候,考慮power共用的情況:只要一個模組工作,就要power on;直到所有模組停止工作,才能power off。
Kernel的PM domain framework(位於drivers/base/power/domain.c中),提供了管理和使用系統power domain的統一方法,在解決上面提到的問題的同時,結合kernel的
同樣,作為一個framework,我們可以從三個角度分析:使用者(consumer)的角度;提供者(provider)的角度;內部實現。具體如下。
注:本文的linux kernel版本為3.18-rc4。一般情況下,對於那些相對穩定的framework,蝸蝸不會說明文章所使用的kernel版本,但本文是個例外,因為PM domain很多方便、易用的patch,只能在最新版本(當前為3.18-rc4)kernel上才能看到。
2. 怎麼使用(從consumer的角度看)
藉助device tree,pm domain的使用很簡單(非常類似clock的使用,詳見“clock framework的分析文章”),步驟如下:
1)檢查pm domain provider提供的DTS的node名(下面的紅色字型):
powergate: [email protected] {
compatible = "xxx,xxx-pm-domains";
reg = <0 0xe012e000 0 0x1000>;
#power-domain-cells = <1>;
};
各個欄位和clock framework類似,也可參考“Documentation/devicetree/bindings/power/power_domain.txt”,這裡不再詳細描述。
2)大部分情況下,power-domain-cells為1,因此需要得到所需使用的power domain的編號(可能會在include/dt-bindings/*中定義),如POWER_DOMAIN_USB。
3)在模組自己的DTS中,新增對power domian的引用描述,如下面紅色字型:
compatible = "xxx,xxx-dummy";
reg = <0 0xe0280000 0 0x1000>;
power-domains = <&powergate POWER_DOMAIN_USB>;
};
其中:“power-domains”為pm domain framework的關鍵字,由framework core負責解析(由名稱可知,可以指定多個power domain);“&powergate”為provider提供的DTS node名;“POWER_DOMAIN_USB”具體的domain標識,也是由provider提供。
4)藉助runtime pm,在需要使用模組時,增加引用計數(可呼叫pm_runtime_get),不需要使用時,減少引用計數(可呼叫pm_runtime_put)。剩下的事情,就交給PM core了。
注2:PM core會在裝置的引用計數為0時,自動呼叫PM domain的介面,嘗試power off裝置。同理,會在引用計數從0到1時,嘗試power on裝置。整個過程不需要裝置的driver關心任何細節。同時,runtime pm也會處理idle、suspend、resume等相關的電源狀態切換,如果driver只想使用PM domain功能,可以在probe中get一次,在remove中put一次,其效果和常規的power on/power off類似。
3. 怎麼編寫PM domain驅動(從provider的角度看)
從介面層面看,編寫PM domain driver相當簡單,只需要三個步驟:
1)將所有的domain,以struct generic_pm_domain(PM domain framework提供的)形式抽象出來,並填充資料結構中需要由provider提供的內容。
2)呼叫pm_genpd_init,初始化struct generic_pm_domain變數中其餘的內容。
3)呼叫__of_genpd_add_provider介面,將所有的domain(由struct generic_pm_domain變數抽象)新增到kernel中,同時提供一個根據DTS node獲得對應的domain指標的回撥函式(類似clock framework)。
很顯然,這三個步驟對我們編寫pm domain driver沒有任何幫助,因為其複雜度都被掩蓋在struct generic_pm_domain結構體中了。讓我們分析完內部邏輯後,再回來。
4. 基本流程分析
4.1 一些資料結構
1)我們先回到“Linux裝置模型(5)_device和device driver”中,那篇文章我們留下了很多“未解之謎”,其中之一就是pm_domain指標,如下:
1:
2: struct device {
3: ...
4: struct dev_pm_domain *pm_domain;
5: ...
6: };
struct dev_pm_domain結構很簡單,只有一個struct dev_pm_ops型別的變數,該結構在“Linux電源管理(4)_Power Management Interface”中已有詳細描述,是裝置電源管理相關的操作函式集,包括idle、suspend/resume、runtime pm等有關的回撥函式。
那這個結構和PM domain有什麼關係呢?不著急,先看看struct generic_pm_domain結構。
2)struct generic_pm_domain
struct generic_pm_domain結構用於抽象PM domain,在include/linux/pm_domain.h中定義,如下:
1: /* include/linux/pm_domain.h */
2: struct generic_pm_domain {
3: struct dev_pm_domain domain; /* PM domain operations */
4: struct list_head gpd_list_node; /* Node in the global PM domains list */
5: struct list_head master_links; /* Links with PM domain as a master */
6: struct list_head slave_links; /* Links with PM domain as a slave */
7: struct list_head dev_list; /* List of devices */
8: struct mutex lock;
9: struct dev_power_governor *gov;
10: struct work_struct power_off_work;
11: const char *name;
12: unsigned int in_progress; /* Number of devices being suspended now */
13: atomic_t sd_count; /* Number of subdomains with power "on" */
14: enum gpd_status status; /* Current state of the domain */
15: wait_queue_head_t status_wait_queue;
16: struct task_struct *poweroff_task; /* Powering off task */
17: unsigned int resume_count; /* Number of devices being resumed */
18: unsigned int device_count; /* Number of devices */
19: unsigned int suspended_count; /* System suspend device counter */
20: unsigned int prepared_count; /* Suspend counter of prepared devices */
21: bool suspend_power_off; /* Power status before system suspend */
22: int (*power_off)(struct generic_pm_domain *domain);
23: s64 power_off_latency_ns;
24: int (*power_on)(struct generic_pm_domain *domain);
25: s64 power_on_latency_ns;
26: struct gpd_dev_ops dev_ops;
27: s64 max_off_time_ns; /* Maximum allowed "suspended" time. */
28: bool max_off_time_changed;
29: bool cached_power_down_ok;
30: struct gpd_cpuidle_data *cpuidle_data;
31: void (*attach_dev)(struct device *dev);
32: void (*detach_dev)(struct device *dev);
33: };
這個結構很複雜,包括很多引數,不過:對consumer來說,不需要關心該結構;對provider而言,只需要關心有限的引數;大部分引數,framework內部使用。
對provider來說,需要為每個power domain定義一個struct generic_pm_domain變數,並至少提供如下欄位:
name,該power domain的名稱;
power_off/power_on,該power domain的on/off介面;
其它的欄位,這裡做一個大概的介紹(後續程式碼邏輯分析時會更為細緻的說明):
domain,struct dev_pm_domain型別的變數,再回憶一下struct device中的pm_domain指標,這二者一定有些關係,後面再詳細描述;
gpd_list_node,用於將該domain新增到一個全域性的domain連結串列(gpd_list)中;
master_links/slave_links,power domain可以有從屬關係,例如一個power domain,通過一些器件,分出另外幾個power domain,那麼這個domain稱作master domain,分出來的domain稱作slave domain(也成subdomain)。這兩個list用於組成master link和slave link,後面再詳細描述;
dev_list,該domain下所有device的列表;
gov,struct dev_power_governor指標,後面再解釋;
power_off_work,用於執行power off的wrok queue;
in_progress,該domain下正在suspend的device個數;
sd_count,記錄處於power on狀態的subdomain的個數;
status/status_wait_queue,power domain的狀態,以及用於等待狀態切換的wait queue;
power_off_task,
resume_count/device_count/suspended_count/prepared_count,
suspend_power_off,一個struct task_struct指標,記錄正在執行power off操作的任務;
power_on_latency_ns/power_off_latency_ns,執行power on和power off操作時需要等待的時間,一般由provider提供;
dev_ops,struct gpd_dev_ops型別的變數,提供一些回撥函式,後面再詳細解釋;
max_off_time_ns/max_off_timer_changed,和PM domain governor有關的變數,後面再詳細解釋;
cached_power_down_ok,同上;
cpuidle_data,可以把cpuidle和PM domain連線起來,這個指標用於儲存CPU idle相關的資料;
attach_dev/detach_dev,當device和pm domain關聯/去關聯時,呼叫這兩個回撥函式。如果provider需要做一些處理,可以提供。
我相信讀者一定被這個資料結構搞暈了,不要著急,太複雜的話,我們先放一下,去看一些簡單的。下面一節我們先從整體流程上,看一下power domain framework怎麼工作的(最簡單的case),然後再回到這些細節上。
4.2 PM domain的工作流程
結合第二章、第三章的說明,PM domain的工作流程包括:
1)Provider在DTS中定義power domain有關的device tree node,並在provider的初始化介面(可以是一個platform driver的probe,也可以是其它形式)中,定義、初始化並註冊所有的power domain。
2)PM domain的初始化和註冊
provider需要為每個domain定義一個struct generic_pm_domain變數,並初始化必要的欄位和回撥函式,然後呼叫pm_genpd_init介面,初始化其餘的欄位,如下:
1: /**
2: * pm_genpd_init - Initialize a generic I/O PM domain object.
3: * @genpd: PM domain object to initialize.
4: * @gov: PM domain governor to associate with the domain (may be NULL).
5: * @is_off: Initial value of the domain's power_is_off field.
6: */
7: void pm_genpd_init(struct generic_pm_domain *genpd,
8: struct dev_power_governor *gov, bool is_off)
9: {
10: if (IS_ERR_OR_NULL(genpd))
11: return;
12:
13: INIT_LIST_HEAD(&genpd->master_links);
14: INIT_LIST_HEAD(&genpd->slave_links);
15: INIT_LIST_HEAD(&genpd->dev_list);
16: mutex_init(&genpd->lock);
17: genpd->gov = gov;
18: INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
19: genpd->in_progress = 0;
20: atomic_set(&genpd->sd_count, 0);
21: genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE;
22: init_waitqueue_head(&genpd->status_wait_queue);
23: genpd->poweroff_task = NULL;
24: genpd->resume_count = 0;
25: genpd->device_count = 0;
26: genpd->max_off_time_ns = -1;
27: genpd->max_off_time_changed = true;
28: genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
29: genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
30: genpd->domain.ops.prepare = pm_genpd_prepare;
31: genpd->domain.ops.suspend = pm_genpd_suspend;
32: genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
33: genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq;
34: genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
35: genpd->domain.ops.resume_early = pm_genpd_resume_early;
36: genpd->domain.ops.resume = pm_genpd_resume;
37: genpd->domain.ops.freeze = pm_genpd_freeze;
38: genpd->domain.ops.freeze_late = pm_genpd_freeze_late;
39: genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
40: genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
41: genpd->domain.ops.thaw_early = pm_genpd_thaw_early;
42: genpd->domain.ops.thaw = pm_genpd_thaw;
43: genpd->domain.ops.poweroff = pm_genpd_suspend;
44: genpd->domain.ops.poweroff_late = pm_genpd_suspend_late;
45: genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq;
46: genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
47: genpd->domain.ops.restore_early = pm_genpd_resume_early;
48: genpd->domain.ops.restore = pm_genpd_resume;
49: genpd->domain.ops.complete = pm_genpd_complete;
50: genpd->dev_ops.save_state = pm_genpd_default_save_state;
51: genpd->dev_ops.restore_state = pm_genpd_default_restore_state;
52: mutex_lock(&gpd_list_lock);
53: list_add(&genpd->gpd_list_node, &gpd_list);
54: mutex_unlock(&gpd_list_lock);
55: }
該介面可接受三個引數:genpd為需要初始化的power domain指標;gov為governor,可以留空,我們先不考慮它;is_off,指明該power domain在註冊時的狀態,是on還是off,以便framework正確設定該domain的status欄位。
它的邏輯比較簡單,值得注意的是genpd->domain.ops中各個回撥函式的初始化,這些以”pm_genqd_”為字首的函式,都是pm domain framework提供的幫助函式,用於power domain級別的電源管理,包括power on/off、suspend/resume、runtime pm等。
回憶一下“Linux電源管理(4)_Power Management Interface”中有關struct dev_pm_ops的描述,bus_type、device_driver、class、device_type、device等結構,都可以包括dev pm ops,而PM core進行相關的電源狀態切換時,只會呼叫其中的一個。選擇哪個,是有優先順序的,其中優先順序最高的,就是device結構中pm_domain指標的。
那麼,我們再思考一下,device中可是一個指標哦,具體的變數哪來的?你一定猜到了,來自struct generic_pm_domain變數,就是這個函式初始化的內容。後面再詳細介紹。
3)完成所有domain的初始化後,呼叫__of_genpd_add_provider介面,將它們新增到kernel中。從該介面的命名上,我們可以猜到,它和DTS有關(of是Open Firmware的縮寫),定義如下:
1: /**
2: * __of_genpd_add_provider() - Register a PM domain provider for a node
3: * @np: Device node pointer associated with the PM domain provider.
4: * @xlate: Callback for decoding PM domain from phandle arguments.
5: * @data: Context pointer for @xlate callback.
6: */
7: int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
8: void *data)
9: {
10: struct of_genpd_provider *cp;
11:
12: cp = kzalloc(sizeof(*cp), GFP_KERNEL);
13: if (!cp)
14: return -ENOMEM;
15:
16: cp->node = of_node_get(np);
17: cp->data = data;
18: cp->xlate = xlate;
19:
20: mutex_lock(&of_genpd_mutex);
21: list_add(&cp->link, &of_genpd_providers);
22: mutex_unlock(&of_genpd_mutex);
23: pr_debug("Added domain provider from %s\n", np->full_name);
24:
25: return 0;
26: }
也許您會奇怪,該介面的三個引數沒有一個和struct generic_pm_domain所代表的power domain有關啊!不著急,我們慢慢分析。
引數1,np,是一個device node指標,哪來的?想一下第2章pm domain provider提供的DTS,就是它生成的指標;
引數2,xlate,一個用於解析power domain的回撥函式,定義如下:
typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args, void *data);
該回調函式的第二個引數,就是__of_genpd_add_provider介面的引數3。它會返回一個power domain指標;
引數3,data,一個包含了所有power domain資訊的指標,具體的形式,由provider自行定義,反正最終會傳給同樣由provider提供的回撥函式中,provider根據實際情況,獲得對應的power domain指標,並返回給呼叫者。
注3:這是device tree的慣用伎倆,consumer在DTS中對所使用的資源(這裡為power domain,如power-domains = <&powergate POWER_DOMAIN_USB>;)的宣告,最終會由對應的framework(這裡為pm domain framework)解析,並呼叫provider提供的回撥函式,最終返回給consumer該資源的控制代碼(這裡為一個struct generic_pm_domain指標)。所有的framework都是這樣做的,包括前面所講的clock framework,這裡的pm domain framework,等等。具體的解析過程,後面會詳細描述。
4)pm domain framework對consumer DTS中的power domain的解析
先把第2章的例子搬過來:
…
power-domains = <&powergate POWER_DOMAIN_USB>;
};
怎麼解析呢?讓我們從裝置模型的platform_drv_probe介面開始。
由Linux裝置模型相關的文章可知,platform裝置的列舉從platform_drv_probe開始。而所有在DTS中描述的裝置,最終會生成一個platform裝置,這個裝置的driver的執行,也會從platform_drv_probe開始,該介面進而會呼叫platform driver的probe。如下:
1: static int platform_drv_probe(struct device *_dev)
2: {
3: struct platform_driver *drv = to_platform_driver(_dev->driver);
4: struct platform_device *dev = to_platform_device(_dev);
5: int ret;
6:
7: ret = of_clk_set_defaults(_dev->of_node, false);
8: if (ret < 0)
9: return ret;
10:
11: ret = dev_pm_domain_attach(_dev, true);
12: if (ret != -EPROBE_DEFER) {
13: ret = drv->probe(dev);
14: if (ret)
15: dev_pm_domain_detach(_dev, true);
16: }
17:
18: if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
19: dev_warn(_dev, "probe deferral not supported\n");
20: ret = -ENXIO;
21: }
22:
23: return ret;
24: }
在執行driver的probe之前,會先呼叫dev_pm_domain_attach介面,將該裝置attach到指定的power domain上(如果有的話)。該介面位於drivers/base/power/common.c中,實現如下:
1: int dev_pm_domain_attach(struct device *dev, bool power_on)
2: {
3: int ret;
4:
5: ret = acpi_dev_pm_attach(dev, power_on);
6: if (ret)
7: ret = genpd_dev_pm_attach(dev);
8:
9: return ret;
10: }
11: EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
先不考慮ACPI裝置,會直接呼叫genpd_dev_pm_attach介面(呵呵,回到pm domain framework了),該介面位於drivers/base/power/domain.c,如下:
1: /**
2: * genpd_dev_pm_attach - Attach a device to its PM domain using DT.
3: * @dev: Device to attach.
4: *
相關推薦
Linux PM domain framework(1)_概述和使用流程
1. 前言 在複雜的片上系統(SOC)中,設計者一般會將系統的供電分為多個獨立的block,這稱作電源域(Power Domain),這樣做有很多好處,例如: 1)將不同功能模組的供電分開,減小相互之間的干擾(如模擬和數字分開)。 2)不同功能所需的電壓大小不同:小電壓能量損耗低,
Linux學習筆記之1——文件和目錄管理(硬連接和軟連接)(連結檔,相當於快捷方式)
class 學習linux lock 訪問 接下來 所有 sdn ext test 在這節將要學習linux的連接檔,在之前用"ls -l" 查看文件屬性的命令時, 其中第二個屬性是連接數。那麽這個連接數是幹什麽的?這就要理解inode。 先說一下文件是怎麽存儲的。
從零開始之驅動發開、linux驅動(四十、Linux common clock framework(5)_使用舉例)
前面三節分析的3.16.57核心中,三星的驅動中,恰好S5PV210的CPU沒有使用Linux common clock framework來處理clk。所以,本文采用4.9.92的核心來分析S5PV210對前面第三節中時鐘註冊部分的使用。對於老的時鐘框架,後面章節可能會用1到2部分說明一下。
從零開始之驅動發開、linux驅動(三十九、Linux common clock framework(4)_總結)
前面三節參考蝸窩大神的文章分析了Linux common clock framework的主要實現細節,本篇則是對前三篇從全域性的一個整合說明。 common clock framework主要維護著四條連結串列 static HLIST_HEAD(clk_root_l
從零開始之驅動發開、linux驅動(三十八、Linux common clock framework(3)_實現邏輯分析)
1. 前言 前面兩篇clock framework的分析文章,分別從clock consumer和clock provider的角度,介紹了Linux kernel怎麼管理系統的clock資源,以及device driver怎麼使用clock資源。本文將深入到clock framework的
1.1 html概述和基本結構
1.1.1 HTML是什麼? HTML是 HyperText Mark-up Language 的首字母簡寫,意思是超文字標記語言,超文字指的是超連結,標記指的是標籤,是一種用來製作網頁的語言,這種語言由一個個的標籤組成,用這種語言製作的檔案儲存的是一個文字檔案,檔案的
三、Django概述和流程
分享 一起 有一個 視圖 請求轉發 最終 請求 模型 view(視圖) 一、MVC模式 MVC(Model-View-Controller),中文名“模型-視圖-控制器”,是一個好的Web應用開發所遵循的模式,它有利於把Web應用的代碼分解為易於管
Robot Framework之案例層和流程層分離
案例層和流程層分離的意思就是將指令碼內容進行關鍵字封裝,使得執行指令碼時只需要傳入相應的引數即可進行,此例中需先建立測試用例,建立的過程不再說明,編輯一個簡單的測試指令碼,開啟百度頁面,指令碼內容如(1)步驟中的截圖所示 (1)選中test case中的所有指令碼內容,右鍵
linux文件系統1基本文件類型和inode
文件類型、索引節點基本文件類型 普通文件:文件中包含信息是用戶、系統或應用程序輸入生成,在文件系統中不加任何內部修飾,把它們看做純粹的字節流。 目錄:包含文件名列表和指向與之相關聯的的索引節點的指針。目錄文件時特殊寫保護權限的普通文件,只有文件系統才能進行寫操作。特殊文件:不含數據內容,提供一個映射物理設備到
1.NoSQL入門和概述
第三方 推薦 自然 穩定 外部 計算 grid 日誌 數據庫 入門概述: 1.為什麽要用到NoSQL a) 單機MySQL的美好年代,在90年代,一個網站的訪問量一般都不大,用單個數據庫完全可以輕松應付。在那個時候,更多的都是靜態網頁,動態交互類型的網站不多。 上
Linux鞏固記錄(1) java項目的編譯和執行
mce frame cati readfile 知識 4.3 sse apach ast 由於要近期使用hadoop等進行相關任務執行,操作linux時候就多了 以前只在linux上配置J2EE項目執行環境,無非配置下jdk,部署tomcat,再通過docker或者jenk
Linux九陰真經之九陰白骨爪殘卷1(加密和安全)
con touch 接收 sock 就是 any bss pan 字節數 CA和證書 1、KPI :公共秘鑰體系 簽證機構:CA 註冊機構:RA 證書吊銷列表:CRL 證書存取庫 509
Linux學習筆記之1——檔案和目錄管理(硬連線和軟連線)(連結檔,相當於快捷方式)
在這節將要學習linux的連線檔,在之前用"ls -l" 檢視檔案屬性的命令時, 其中第二個屬性是連線數。那麼這個連線數是幹什麼的?這就要理解inode。 先說一下檔案是怎麼儲存的。檔案儲存在硬碟上,硬碟的最小儲存單位叫做"扇區"(Sector),每個扇區儲存512位元
《compass-reference》翻譯計劃之:1.1概述和1.2所涉及技術(續)
1.2.2. 領域模型 Compass的一個主要特性就是OSEM(物件/搜尋引擎對映)。可以採用annotation或者xml定義(或聯合使用),把豐富的領域模型對映到搜尋引擎中。想了解更多的內容,請閱讀第6章:OSEM-物件/搜尋引擎對映。 1.
Linux從0到1⑥使用者管理(新建刪除組使用者_更改使用者)
使用者和組 **小述:在進行使用者和組的管理之前,我們必須要知道何為使用者,何為組,它們究竟有什麼作用呢,又有何種關聯。 關於使用者那些事 系統上的每個程序(執行的程式)都是作為特定使用者執行的 每個檔案是由一個特定的使用者擁有 訪問檔案和目錄受到使用者的限
1.linux服務之spoon書寫的tr和tjob的驗證
1. 使用rz進行檔案上傳,進行從本地檔案往linux伺服器上面的上傳以及下載,,過程如下所示: 將本地檔案上傳到伺服器上,使用命令為rz, 執行rz命令如下所示: 選擇相應檔案如下所示: 點解add 再如下圖所示:
Linux學習筆記1——命令列和終端常用快捷鍵
命令引數 引數有短引數和長引數之分 短引數(-+一個字母)如:-p -a -T -c 區分大小寫,短引數可合併寫,如-paTc 長引數(–+多個字母)如:–all 給引數賦值: 短引數:command -p 10 長引數:command --paramet
Linux-ftp伺服器 檔案的上傳和下載總結(1-實名登入)
1.安裝和配置vsftpd 不然會這樣 2.重啟伺服器 3.實名登入 4.上傳檔案 4.1建立檔案—再開一個終端,在home/ftptest目錄下建立檔案haha 4.2 命令:put filename 成功上傳到伺服器zy的home目錄下 附:
Redis 1.NoSql入門和概述
Redis @Author:hanguixian @Email:[email protected] 一 NoSql入門和概述 1 . 入門概述 1.1 網際網路時代背景下大機遇,為什麼用nosql 1.1.1 單機mysql 在90年代,一個
Linux系統使用入門進階總結(1)——概述
Linux系統使用入門進階總結(1) 本文轉自:https://blog.csdn.net/VennyJin/article/details/84998926 Linux與Windows的區別 相對較少的資源佔用(同樣的執行效率需要更少的硬體資源成本!)