概念
如果是一台筆電, 你可能會很明確知道我可以把筆電蓋起來讓他休眠, 我可以按下power button讓他power on/off, 有時候程式卡住了我想要強制關機, 我會長按power button然後筆電就會關掉了。同樣的這些功能, 在server上面也有, 不僅有還更加複雜。我嘗試用比喻的方式, 來跟大家介紹OpenBMC裡面的電源控制, 當然…在此之前要提醒大家兩件事情:
- 每個專案的規範不同, 沒有所謂power control的正確或標準答案
- 我用比喻的方式讓大家快速對整件事情有一個概念在腦海, 但精確度顯然不足, 如果你腦中開始有了畫面, 你想更深入去了解細節, 也許後續的文章我會再更近一步地提到, 或者你可以開code去詳細的trace一下完整的流程, 但不要把我說的這些比喻就當成正確答案背下來。(嵌入式的領域裡有著各式各樣的可能, 沒有可以背的正確答案, 請看code, 請實際執行….這件事情我大概會提醒一百萬遍!希望你們覺得我煩, 那表示我達到了提醒的效果。 哈~)
phosphor-state-manager 是 OpenBMC 中負責管理與追蹤 server電源狀態的核心Repo, 透過 systemd target 的啟動與設定, 搭配D-Bus Interface協調電源流程的狀態轉換與回報。(這邊我還來不及跟大家介紹道D-Bus, 他很重要!但是沒有關係, 你先想像system target就像你家牆壁上有開關, 可以透過他來開關不同的電, 可能有房間燈的開關, 廚房燈的開關或是客廳燈的開關。D-Bus Interface就是告訴你目前電是開還是關?那server需要有哪些電源開關呢?從D-bus的interface可以看到他有:
xyz.openbmc_project.State.ChassisD-Bus interfacexyz.openbmc_project.State.HostD-Bus interfacexyz.openbmc_project.State.BMCD-Bus interface
- BMC(Baseboard Management Controller):即我們執行 OpenBMC 的本體, 是整台系統的管理控制器。BMC chip 要能正常上電並且完成開機, 所有BMC的service要能正常的運行, 才表示BMC啟動完成。
- Chassis:代表整個物理機箱的供電狀態, 通常與電源供應器、風扇、電壓模組等有關。當我們執行
chassis power on時, 表示要讓這些基本硬體系統進入通電狀態, 為 Host 上電做好準備。(通常這時候BMC就已經上電了!) - Host:代表主機系統本身(包含 CPU、RAM、BIOS/UEFI 等)。只有在 Chassis 已經 power on 的情況下, Host 才能進一步 power on, 啟動 BIOS 並載入作業系統。
同樣的, 我們也可以對這些實體去進行有別於on/off這兩種最基本的電源控制行為, 不同的專案設計不同, 有些會有reset, cycle….etc更多不同的控制行為。(這邊不多做介紹, 如果你已經在工作中遇到, 請詳細閱讀你的客人以及EE給你的SPEC和線路圖, 積極與你的客戶溝通, 確保你的實作和控制方式符合他們的期待)
流程走一遍
實際上, 當我們執行如 Chassis Power Off 的動作時, 系統會透過類似 systemctl 的方式去啟動對應的 power off target。你會在 phosphor-state-manager 這個 repo 中看到一個名為 target-files 的目錄, 裡面包含許多像 power on、off、reset 等對應的 target 檔案。這些 target 是用來響應從 IPMI 或 Redfish 接收到的使用者電源控制指令, 並藉由觸發對應的 unit file 完成控制流程。
不同系統對於電源控制的實作方式可能有所不同。舉例來說, 某些伺服器的 power on/off 控制訊號是直接接給 BMC, 這時 BMC 只需在 target 被啟動後呼叫對應的 service, 而該 service 可能僅僅是一支 script。這支 script 裡面會控制一根 GPIO 腳位來讓實際的電源切換發生。
但也有可能你的平台是透過 CPLD 來控制電源, 這時候 script 裡的邏輯可能就不是直接控制 GPIO, 而是需透過 JTAG、I2C 或其他介面與 CPLD 通訊, 才能發出真正的 power control 指令。
看到這裡, 你應該不難想到會有一個問題, 既然大家控制的方式都不同, 我的power control script要放在哪裡???
莫慌~ 目前OpenBMC上code都是用gerrit, 這邊就直接給大家看一份近期才上的power control project code的實作吧! https://gerrit.openbmc.org/c/openbmc/openbmc/+/82321

從這裡你就可以看到他的service檔, 我假設大家上一期都有認真的學習, 所以你會去找他service檔真正去執行的程式是 “chassis-powercycle”
就在這裡你也會看到 “chassis-powercycle” 具體的內容, https://gerrit.openbmc.org/c/openbmc/openbmc/+/82321/14/meta-facebook/meta-lfdarwin/recipes-phosphor/state/phosphor-state-manager/chassis-powercycle
果不其然他就是一個script然後用gpio tool去控制了訊號讓cycle發生。
小練習(一)
你有發現這個cycle發生之際, script做了一下的動作?你們覺得這是為什麼呢?
# Force the buffers to flush
echo "Force filesystem buffers flush..."
sync
mount -o ro,remount /run/mnt-persist
小練習(二)
每一支程式都應該有error handling這是一個韌體工程師的基本素養, 那我們來想一想, 如果是power on, 你可以檢查最終power的狀態是不是on? 來判斷power on是不是真的發生, 如果你是power off 也是一樣檢查最終狀態。但如果你是power cycle, 系統本來在on的狀態重開之後還是on的狀態, 要如何確保你的script真的有讓系統發生power cycle呢?快訊息給寶妮, 分享你的想法吧!















