.. SPDX-License-Identifier: GPL-2.0 .. include:: ../disclaimer-zh_TW.rst :Original: Documentation/admin-guide/bootconfig.rst :è¯è€…: 峿ƒ³æˆ Wu XiangCheng <bobwxc@email.cn> ======== 引導é…ç½® ======== :作者: Masami Hiramatsu <mhiramat@kernel.org> 概述 ==== 引導é…ç½®æ“´å±•äº†ç¾æœ‰çš„å…§æ ¸å‘½ä»¤è¡Œï¼Œä»¥ä¸€ç¨®æ›´æœ‰æ•ˆçŽ‡çš„æ–¹å¼åœ¨å¼•å°Žå…§æ ¸æ™‚é€²ä¸€æ¥æ”¯æŒ éµå€¼æ•¸æ“šã€‚這å…許管ç†å“¡å‚³éžä¸€ä»½çµæ§‹åŒ–é—œéµå—çš„é…置文件。 é…置文件語法 ============ 引導é…置文件的語法採用éžå¸¸ç°¡å–®çš„éµå€¼çµæ§‹ã€‚æ¯å€‹é—œéµå—由點連接的單詞組æˆï¼Œéµ 和值由 ``=`` 連接。值以分號( ``;`` )或æ›è¡Œç¬¦ï¼ˆ ``\n`` )çµå°¾ã€‚æ•¸çµ„å€¼ä¸æ¯ å€‹å…ƒç´ ç”±é€—è™Ÿï¼ˆ ``,`` )分隔。:: KEY[.WORD[...]] = VALUE[, VALUE2[...]][;] èˆ‡å…§æ ¸å‘½ä»¤è¡Œèªžæ³•ä¸åŒï¼Œé€—號和 ``=`` 周åœå…è¨±æœ‰ç©ºæ ¼ã€‚ é—œéµå—åªå…許包å«å—æ¯ã€æ•¸å—ã€é€£å—符( ``-`` )和下劃線( ``_`` )。值å¯åŒ…å« å¯æ‰“å°å—ç¬¦å’Œç©ºæ ¼ï¼Œä½†åˆ†è™Ÿï¼ˆ ``;`` ï¼‰ã€æ›è¡Œç¬¦ï¼ˆ ``\n`` )ã€é€—號( ``,`` )〠井號( ``#`` )和å³å¤§æ‹¬è™Ÿï¼ˆ ``}`` )ç‰åˆ†éš”符除外。 å¦‚æžœä½ éœ€è¦åœ¨å€¼ä¸ä½¿ç”¨é€™äº›åˆ†éš”符,å¯ä»¥ç”¨é›™å¼•號( ``"VALUE"`` )或單引號 ( ``'VALUE'`` )括起來。注æ„,引號無法轉義。 éµçš„值å¯ä»¥çˆ²ç©ºæˆ–ä¸å˜åœ¨ã€‚這些éµç”¨æ–¼æª¢æŸ¥è©²éµæ˜¯å¦å˜åœ¨ï¼ˆé¡žä¼¼å¸ƒçˆ¾å€¼ï¼‰ã€‚ éµå€¼èªžæ³• -------- 引導é…置文件語法å…許用戶通éŽå¤§æ‹¬è™Ÿåˆä½µéµå部分相åŒçš„é—œéµå—。例如:: foo.bar.baz = value1 foo.bar.qux.quux = value2 也å¯ä»¥å¯«æˆ:: foo.bar { baz = value1 qux.quux = value2 } 或者更緊湊一些,寫æˆ:: foo.bar { baz = value1; qux.quux = value2 } 在這兩種樣å¼ä¸ï¼Œå¼•å°Žè§£æžæ™‚相åŒçš„é—œéµå—都會自動åˆä½µã€‚å› æ¤å¯ä»¥è¿½åŠ é¡žä¼¼çš„æ¨¹æˆ– éµå€¼ã€‚ 相åŒé—œéµå—的值 -------------- ç¦æ¢å…©å€‹æˆ–多個值或數組共享åŒä¸€å€‹é—œéµå—。例如:: foo = bar, baz foo = qux # !錯誤! 我們ä¸å¯ä»¥é‡å®šç¾©ç›¸åŒçš„é—œéµå— å¦‚æžœä½ æƒ³è¦æ›´æ–°å€¼ï¼Œå¿…é ˆé¡¯å¼ä½¿ç”¨è¦†è“‹æ“作符 ``:=`` 。例如:: foo = bar, baz foo := qux 這樣 ``foo`` é—œéµå—的值就變æˆäº† ``qux`` ã€‚é€™å°æ–¼é€šéŽæ·»åŠ ï¼ˆéƒ¨åˆ†ï¼‰è‡ªå®šç¾©å¼•å°Ž é…置來覆蓋默èªå€¼éžå¸¸æœ‰ç”¨ï¼Œå…於解æžé»˜èªå¼•å°Žé…置。 å¦‚æžœä½ æƒ³å°ç¾æœ‰é—œéµå—è¿½åŠ å€¼ä½œçˆ²æ•¸çµ„æˆå“¡ï¼Œå¯ä»¥ä½¿ç”¨ ``+=`` æ“作符。例如:: foo = bar, baz foo += qux 這樣, ``foo`` é—œéµå—å°±åŒæ™‚æ“æœ‰äº† ``bar`` , ``baz`` å’Œ ``qux`` 。 æ¤å¤–,父關éµå—下å¯åŒæ™‚å˜åœ¨å€¼å’Œåé—œéµå—。 例如,下列é…置是å¯è¡Œçš„。:: foo = value1 foo.bar = value2 foo := value3 # 這會更新foo的值。 注æ„,裸值ä¸èƒ½ç›´æŽ¥æ”¾é€²çµæ§‹åŒ–é—œéµå—ä¸ï¼Œå¿…é ˆåœ¨å¤§æ‹¬è™Ÿå¤–å®šç¾©å®ƒã€‚ä¾‹å¦‚:: foo { bar = value1 bar { baz = value2 qux = value3 } } åŒæ™‚,關éµå—ä¸‹å€¼ç¯€é»žçš„é †åºæ˜¯å›ºå®šçš„。如果值和åé—œéµå—åŒæ™‚å˜åœ¨ï¼Œå€¼æ°¸é 是該關 éµå—的第一個åç¯€é»žã€‚å› æ¤å¦‚果用戶先指定åé—œéµå—,如:: foo.bar = value1 foo = value2 則在程åºï¼ˆå’Œ/proc/bootconfig)ä¸ï¼Œå®ƒæœƒæŒ‰å¦‚下顯示:: foo = value2 foo.bar = value1 註釋 ---- é…置語法接å—shellè…³æœ¬é¢¨æ ¼çš„è¨»é‡‹ã€‚è¨»é‡‹ä»¥äº•è™Ÿï¼ˆ ``#`` )開始,到æ›è¡Œç¬¦ ( ``\n`` ï¼‰çµæŸã€‚ :: # comment line foo = value # value is set to foo. bar = 1, # 1st element 2, # 2nd element 3 # 3rd element 會被解æžçˆ²:: foo = value bar = 1, 2, 3 注æ„ä½ ä¸èƒ½æŠŠè¨»é‡‹æ”¾åœ¨å€¼å’Œåˆ†éš”符( ``,`` 或 ``;`` )之間。如下é…置語法是錯誤的:: key = 1 # comment ,2 /proc/bootconfig ================ /proc/bootconfig是引導é…置的用戶空間接å£ã€‚與/proc/cmdlineä¸åŒï¼Œæ¤æ–‡ä»¶å…§å®¹ä»¥ éµå€¼åˆ—表樣å¼é¡¯ç¤ºã€‚ æ¯å€‹éµå€¼å°ä¸€è¡Œï¼Œæ¨£å¼å¦‚下:: KEY[.WORDS...] = "[VALUE]"[,"VALUE2"...] 用引導é…ç½®å¼•å°Žå…§æ ¸ ================== 用引導é…ç½®å¼•å°Žå…§æ ¸æœ‰å…©ç¨®æ–¹æ³•ï¼šå°‡å¼•å°Žé…ç½®é™„åŠ åˆ°initrdé¡åƒæˆ–ç›´æŽ¥åµŒå…¥å…§æ ¸ä¸ã€‚ *initrd: initial RAM disk,åˆå§‹å…§å˜ç£ç›¤* 將引導é…ç½®é™„åŠ åˆ°initrd ---------------------- ç”±æ–¼é»˜èªæƒ…æ³ä¸‹å¼•å°Žé…置文件是用initrdåŠ è¼‰çš„ï¼Œå› æ¤å®ƒå°‡è¢«æ·»åŠ åˆ°initrd(initramfs) é¡åƒæ–‡ä»¶çš„æœ«å°¾ï¼Œå…¶ä¸åŒ…å«å¡«å……ã€å¤§å°ã€æ ¡é©—值和12å—節幻數,如下所示:: [initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n] 大å°å’Œæ ¡é©—值爲å°ç«¯åºå˜æ”¾çš„32ä½ç„¡ç¬¦è™Ÿå€¼ã€‚ 當引導é…ç½®è¢«åŠ åˆ°initrdé¡åƒæ™‚ï¼Œæ•´å€‹æ–‡ä»¶å¤§å°æœƒå°é½Šåˆ°4å—節。空å—符( ``\0`` ) 會填補å°é½Šç©ºéš™ã€‚å› æ¤ ``size`` 就是引導é…置文件的長度+å¡«å……çš„å—節。 Linuxå…§æ ¸åœ¨å…§å˜ä¸è§£ç¢¼initrdé¡åƒçš„æœ€å¾Œéƒ¨åˆ†ä»¥ç²å–引導é…置數據。由於這種“æ¹è² å¼â€ 的方法,åªè¦å¼•å°ŽåŠ è¼‰å™¨å‚³éžäº†æ£ç¢ºçš„initrd文件大å°ï¼Œå°±ç„¡éœ€æ›´æ”¹æˆ–æ›´æ–°å¼•å°ŽåŠ è¼‰å™¨ å’Œå…§æ ¸é¡åƒæœ¬èº«ã€‚å¦‚æžœå¼•å°ŽåŠ è¼‰å™¨æ„外傳éžäº†æ›´é•·çš„大å°ï¼Œå…§æ ¸å°‡ç„¡æ³•找到引導é…置數 據。 Linuxå…§æ ¸åœ¨tools/bootconfig下æä¾›äº† ``bootconfig`` å‘½ä»¤ä¾†å®Œæˆæ¤æ“作,管ç†å“¡ å¯ä»¥ç”¨å®ƒå¾žinitrdé¡åƒä¸åˆªé™¤æˆ–è¿½åŠ é…ç½®æ–‡ä»¶ã€‚ä½ å¯ä»¥ç”¨ä»¥ä¸‹å‘½ä»¤ä¾†æ§‹å»ºå®ƒ:: # make -C tools/bootconfig è¦å‘initrdé¡åƒæ·»åŠ ä½ çš„å¼•å°Žé…置文件,請按如下命令æ“作(舊數據會自動移除):: # tools/bootconfig/bootconfig -a your-config /boot/initrd.img-X.Y.Z è¦å¾žé¡åƒä¸ç§»é™¤é…置,å¯ä»¥ä½¿ç”¨-dé¸é …:: # tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z ç„¶å¾Œåœ¨å…§æ ¸å‘½ä»¤è¡Œä¸Šæ·»åŠ ``bootconfig`` å‘Šè¨´å…§æ ¸åŽ»initrdæ–‡ä»¶æœ«å°¾å°‹æ‰¾å…§æ ¸é…置。 將引導é…ç½®åµŒå…¥å…§æ ¸ ------------------ å¦‚æžœä½ ä¸èƒ½ä½¿ç”¨initrd,也å¯ä»¥é€šéŽKconfigé¸é …將引導é…ç½®æ–‡ä»¶åµŒå…¥å…§æ ¸ä¸ã€‚åœ¨æ¤æƒ… æ³ä¸‹ï¼Œä½ 需è¦ç”¨ä»¥ä¸‹é¸é …釿–°ç·¨è¯å…§æ ¸:: CONFIG_BOOT_CONFIG_EMBED=y CONFIG_BOOT_CONFIG_EMBED_FILE="/引導é…ç½®/文件/çš„/路徑" ``CONFIG_BOOT_CONFIG_EMBED_FILE`` 需è¦å¾žæºç¢¼æ¨¹æˆ–å°è±¡æ¨¹é–‹å§‹çš„引導é…置文件的 絕å°/相å°è·¯å¾‘ã€‚å…§æ ¸æœƒå°‡å…¶åµŒå…¥ä½œçˆ²é»˜èªå¼•å°Žé…置。 與將引導é…ç½®é™„åŠ åˆ°initrdä¸€æ¨£ï¼Œä½ ä¹Ÿéœ€è¦åœ¨å…§æ ¸å‘½ä»¤è¡Œä¸Šæ·»åŠ ``bootconfig`` 告訴 å…§æ ¸åŽ»å•“ç”¨å…§åµŒçš„å¼•å°Žé…置。 注æ„,å³ä½¿ä½ 已經è¨ç½®äº†æ¤é¸é …,ä»å¯ç”¨é™„åŠ åˆ°initrd的其他引導é…置覆蓋內嵌的引導 é…置。 通éŽå¼•å°Žé…置傳éžå…§æ ¸åƒæ•¸ ======================== é™¤äº†å…§æ ¸å‘½ä»¤è¡Œï¼Œå¼•å°Žé…置也å¯ä»¥ç”¨æ–¼å‚³éžå…§æ ¸åƒæ•¸ã€‚所有 ``kernel`` é—œéµå—ä¸‹çš„éµ å€¼å°éƒ½å°‡ç›´æŽ¥å‚³éžçµ¦å…§æ ¸å‘½ä»¤è¡Œã€‚æ¤å¤–, ``init`` 下的éµå€¼å°å°‡é€šéŽå‘½ä»¤è¡Œå‚³éžçµ¦ inité€²ç¨‹ã€‚åƒæ•¸æŒ‰ä»¥ä¸‹é †åºèˆ‡ç”¨æˆ¶çµ¦å®šçš„å…§æ ¸å‘½ä»¤è¡Œå—ç¬¦ä¸²ç›¸é€£ï¼Œå› æ¤å‘½ä»¤è¡Œåƒæ•¸å¯ä»¥ 覆蓋引導é…ç½®åƒæ•¸ï¼ˆé€™å–決於å系統如何處ç†åƒæ•¸ï¼Œä½†é€šå¸¸å‰é¢çš„åƒæ•¸å°‡è¢«å¾Œé¢çš„åƒæ•¸ 覆蓋):: [bootconfig params][cmdline params] -- [bootconfig init params][cmdline init params] 如果引導é…置文件給出的kernel/initåƒæ•¸æ˜¯:: kernel { root = 01234567-89ab-cdef-0123-456789abcd } init { splash } é€™å°‡è¢«è¤‡åˆ¶åˆ°å…§æ ¸å‘½ä»¤è¡Œå—符串ä¸ï¼Œå¦‚下所示:: root="01234567-89ab-cdef-0123-456789abcd" -- splash 如果用戶給出的其他命令行是:: ro bootconfig -- quiet å‰‡æœ€å¾Œçš„å…§æ ¸å‘½ä»¤è¡Œå¦‚ä¸‹:: root="01234567-89ab-cdef-0123-456789abcd" ro bootconfig -- splash quiet é…置文件的é™åˆ¶ ============== ç•¶å‰æœ€å¤§çš„é…ç½®å¤§å°æ˜¯32KB,關éµå—ç¸½æ•¸ï¼ˆä¸æ˜¯éµå€¼æ¢ç›®ï¼‰å¿…é ˆå°‘æ–¼1024個節點。 注æ„ï¼šé€™ä¸æ˜¯æ¢ç›®æ•¸è€Œæ˜¯ç¯€é»žæ•¸ï¼Œæ¢ç›®å¿…é ˆæ¶ˆè€—è¶…éŽ2個節點(一個關éµå—和一個值)。 所以從ç†è«–上講最多512個éµå€¼å°ã€‚如果關éµå—å¹³å‡åŒ…å«3å€‹å–®è©žï¼Œå‰‡å¯æœ‰256個éµå€¼å°ã€‚ 在大多數情æ³ä¸‹ï¼Œé…ç½®é …çš„æ•¸é‡å°‡å°‘æ–¼100個æ¢ç›®ï¼Œå°æ–¼8KBï¼Œå› æ¤é€™æ‡‰è©²è¶³å¤ 了。如果 節點數超éŽ1024,解æžå™¨å°‡è¿”回錯誤,å³ä½¿æ–‡ä»¶å¤§å°å°æ–¼32KB。(請注æ„ï¼Œæ¤æœ€å¤§å°ºå¯¸ ä¸åŒ…括填充的空å—符。) ç„¡è«–å¦‚ä½•ï¼Œå› çˆ² ``bootconfig`` å‘½ä»¤åœ¨é™„åŠ å•“å‹•é…置到initrdæ˜ åƒæ™‚會驗è‰å®ƒï¼Œç”¨æˆ¶ å¯ä»¥åœ¨å¼•å°Žä¹‹å‰æ³¨æ„到它。 引導é…ç½®API =========== 用戶å¯ä»¥æŸ¥è©¢æˆ–éæ·éµå€¼å°ï¼Œä¹Ÿå¯ä»¥æŸ¥æ‰¾ï¼ˆå‰ç¶´ï¼‰æ ¹é—œéµå—節點,並在查找該節點下的 éµå€¼ã€‚ 如果您有一個關éµå—å—符串,則å¯ä»¥ç›´æŽ¥ä½¿ç”¨ xbc_find_value() 查詢該éµçš„值。如果 ä½ æƒ³çŸ¥é“引導é…ç½®è£æœ‰å“ªäº›é—œéµå—,å¯ä»¥ä½¿ç”¨ xbc_for_each_key_value() è¿ä»£éµå€¼å°ã€‚ 請注æ„,您需è¦ä½¿ç”¨ xbc_array_for_each_value() è¨ªå•æ•¸çµ„的值,例如:: vnode = NULL; xbc_find_value("key.word", &vnode); if (vnode && xbc_node_is_array(vnode)) xbc_array_for_each_value(vnode, value) { printk("%s ", value); } 如果您想查找具有å‰ç¶´å—符串的éµï¼Œå¯ä»¥ä½¿ç”¨ xbc_find_node() 通éŽå‰ç¶´å—符串查找 節點,然後用 xbc_node_for_each_key_value() è¿ä»£å‰ç¶´ç¯€é»žä¸‹çš„éµã€‚ 但最典型的用法是ç²å–å‰ç¶´ä¸‹çš„命å值或å‰ç¶´ä¸‹çš„命忕¸çµ„,例如:: root = xbc_find_node("key.prefix"); value = xbc_node_find_value(root, "option", &vnode); ... xbc_node_for_each_array_value(root, "array-option", value, anode) { ... } 這將訪å•值“key.prefix.optionâ€çš„值和“key.prefix.array-optionâ€çš„æ•¸çµ„。 鎖是ä¸éœ€è¦çš„ï¼Œå› çˆ²åœ¨åˆå§‹åŒ–之後é…ç½®åªè®€ã€‚如果需è¦ä¿®æ”¹ï¼Œå¿…é ˆè¤‡è£½æ‰€æœ‰æ•¸æ“šå’Œé—œéµå—。 å‡½æ•¸èˆ‡çµæ§‹é«” ============ 相關定義的kernel-docåƒè¦‹ï¼š - include/linux/bootconfig.h - lib/bootconfig.c