--- https://www.openubmc.cn/en/ --- # Join openUBMC Community Open source computing device management software with advanced architecture and open standards View More - Docs Center Detailed instructional documentation. - Community Forum Connect with fellow developers. - Community Events Stay updated with key events, conferences, and releases. - App Marketplace A download hub for software tools. ## Open-Source Computing Device Management Software for Global Developers Simplified and Efficient Development Bridging diverse hardware and mainstream industry standards, leveraging a micro-component architecture to enable one set of code for all scenarios, and driving differentiated customization through community collaboration One-Click Deployment for Quick Start 3-step local build with comprehensive tools for a frictionless developer experience AI-Assisted Programming Seamless coding agent integration within openUBMC Studio, one-click community skill import, and embedded knowledge bases Flexible Scalability Support for multi-level customization—configurable, pluggable, and modular—to meet the dynamic tailoring needs of diverse computing power scenarios Specification-Driven Development Centering on models and specifications to clarify capabilities, streamline community collaboration, and fortify release stability Flexible Northbound Access Autonomous northbound access, accelerating service efficiency and empowering AI-driven O&M Cluster Management Platform AI Training Framework O&M Monitoring System ... Autonomous Northbound Access Standards Chip Acceleration Reliability Improvement Intelligent Fault Prediction Energy Efficiency Optimization Robust Security ... Southbound Standardization & Innovation Pioneering driver standards for day-level hardware adaption, with broad card compatibility to accelerating diverse computing power deployment Versatility Out-of-Band Component Interfaces Fan Interface Fan Driver Storage Interface Storage Driver xPU Interface xPU Driver Out-of-Band interface XX Driver Hardware Open Ecosystem openUBMC Studio, a one-stop development platform with AI-enhanced coding to boost server adaptation across the entire development lifecycle Universal Protocol Compatibility Redfish / IPMI / SNMP /...... Autonomous Northbound Access Customized agents, flexibly interconnecting with service systems Self-Healing Robust Security Concurrent firmware upgrade/Password security... NIC SSD DPU HDD NPU GPU RAID Controller Card ## Join the openUBMC Community ### Get Started Become a part of the openUBMC community. From committing code and perfecting documents to rigorous testing, your expertise drives our innovation. Explore How to Contribute ### Join a SIG A special interest group (SIG) is the heartbeat of community collaboration. openUBMC operates through SIGs to ensure a streamlined and efficient development workflow. Every SIG is open to everyone. Join us and make your impact now. Explore SIGs ### openUBMC Momentum - 0 Contributors - 0 Downloads - 0 Organizations - 0 Repositories - 0 PRs Learn More ## What's New ... (Sensor Function Adaptation and Debugging for the Hi3093 Development Board (openubmc.cn))[/en/blogs/hi3093-dev-board-i2c] (Business Practice | PowerLeader Computer's Smart UART HMI Based on openUBMC)[/en/blogs/20250815] (PKI Practice: Building a Complete Certificate Service System (openubmc.cn))[/en/blogs/pki-cert-service-guide] (openUBMC Observability: Full Insight into the System for a New BMC Vision)[/en/blogs/202508071] (AI-Powered R&D: Rapid NCSI Protocol Command Parsing in openUBMC)[/en/blogs/202508072] (Business Practice | How the openUBMC Community Development Pipeline Drives High-Quality Delivery for Yangtze Computing)[/en/blogs/20250726] View More ## Community Partners Listed in no particular order --- https://www.openubmc.cn/en/ai-coding-assistants/ --- # Technical Committee Operations Rules # Policies & Rules Learn about the operational regulations, code of conduct, and AI contribution policies of the openUBMC community. Technical Committee Operations RulesCommunity Code of ConductAI Contribution Policy # Community Code of Conduct # AI Contribution Policy openUBMC Community Generative AI Use and Open Source Contribution Policy ## 1\. Openness Strategy Guided by the spirit of openness, collaboration, and innovation, the openUBMC community recognizes generative AI and intelligent agents as essential drivers for advancing community technologies. While we allow the use of generative AI tools in making contributions, provided such use is reasonable, transparent, and reviewable, we strictly adhere to the following principles: - **Core Principle 1: Open & AI-Development-Oriented** The openUBMC community actively embraces new technologies. Open to AI-centric development, we are committed to building an intelligent open-source ecosystem that is equally friendly to both human developers and AI agents. The openUBMC community welcomes both developers and automated agents to contribute deeply to the community, whether through code writing, document translation, test case generation, or O&M automation. - **Core Principle 2: Developer Ultimate Responsibility** AI is strictly a supporting tool for human contributors. **Human contributors hold ultimate responsibility and legal accountability for the quality of their submissions**. Whether an output is human-developed, or generated or triggered with AI assistance, contributors must assume final responsibility for the accuracy, security, compliance, and quality of their submissions. Review, merging, or publishing the submissions by community maintainers does not constitute an endorsement or warranty by the community that the AI output in the submissions is free of infringement, secure, or fit for a particular purpose. - **Core Principle 3: Transparency and Traceability** Upon submission, contributors should disclose the use of AI tools, sources of third-party materials, license information, and human review status associated with the submission. The openUBMC community enforces a strict metadata tracking system to fully log **critical metadata for AI-generated content, including the agent platform, model, and prompt summaries**. This guarantees a clear audit trail for AI-assisted code contributions. ## 2\. Scope of Application This policy applies to all forms of contributions submitted to the openUBMC community (including but not limited to all code and documentation repositories under the openUBMC organization): - **Source code and scripts**: including various core code, test cases, and build scripts. - **Technical documents and community content**: including API references, deployment guides, release logs, and Wiki pages. - **Configurations and metadata**: including Containerfiles/Dockerfiles, and CI/CD configuration files. ## 3\. Legal & Compliance Any submissions incorporating AI-generated content to the openUBMC community shall be governed by the following legal and compliance frameworks: ### 3.1 Contributor License Agreement (CLA) The openUBMC community implements a **Contributor License Agreement (CLA)**. - Contributors must sign the CLA before submitting any contributions. - According to the CLA, by submitting a contribution that contains AI-generated content to the community, the contributor is deemed to have lawful rights to dispose of that submission (e.g., having obtained sufficient authorization). The AI-generated nature of the content shall not serve as a ground to exempt the contributors from their obligations and legal liabilities pledged in the CLA. ### 3.2 Traceability: Full Logging of Key Metadata For contributions that contain code or documents **fundamentally generated or automatically processed by AI**, contributors shall fully record and attach the following **key metadata** in both the pull request (PR) and commit message. Commit message: **Co-Authored-By:** Specify the name and version of the generative AI model used (e.g., `GPT-4o`, `DeepSeek-V3`, etc.). PR: - **Agent Platform:** Specify the name and version of the agent platform used (e.g., `Claude Code 2.1.156`, `Qwen Code 0.16.1`, etc.). - **Model:** Specify the name and version of the generative AI model used (e.g., `GPT-4o`, `DeepSeek-V3`, etc.). - **Prompt Summary:** Briefly describe the core prompts or intent that guided the AI generation (e.g., `"Optimize memory allocation for Spec file"`). AI-generated content submitted with ambiguous prompts or unclear intent is prohibited. **Example (PR):** ### AI involvement in this PR: [] No [x] Yes __1. Agent platform: Claude Code 2.1.156 __2. Model: DeepSeek-V3 __3. Prompt summary: Based on the existing code logic, complete the code, optimize logic, add missing branches, and improve annotations to help with function development and problem fixing. ### Notes for reviewers: 1. The code was developed with AI assistance. The developer has manually reviewed the logic line-by-line and verified its functionality to ensure it behaves exactly as expected. **Example (commit message):** Co-Authored-By: DeepSeek-V3 _Note: The openUBMC CI gate checks whether the AI model name in the Co-authored-by commit trailer matches the model declared in the PR. Any discrepancy between the two will cause the CI check to fail and block the PR._ ## 4\. Standard Prompt for Agents To ensure that various AI programming assistants and automated agents (such as automated PR reviewers and auto-fixing agents) strictly comply with the preceding policies when serving the openUBMC community, the following **system prompt** is formulated: # Role and objective: You are an AI agent dedicated to serving the openUBMC community. Your goal is to assist human developers in contributing efficiently while strictly adhering to the compliance baseline, ensuring all outputs meet the openUBMC community's compliance and quality standards. # Core Code of Conduct ## 1. Clarify responsibilities and development orientation. - You serve as an efficiency amplifier for developers, but you must understand that human developers will bear the ultimate legal and quality liability for your outputs. Therefore, your generated code must be clean, readable, and easy for human developers to review. - Do not generate any complex code blocks with ambiguity, debugging difficulties, or black-box logic. ## 2. Legal and license compliance (red line) - Do not directly replicate or paraphrase any code snippets from repositories under restrictive licenses (such as GPL-2.0, GPL-3.0, etc.) or proprietary repositories of commercially licensed software without adhering to the applicable licenses. - If your generated code directly references specific open-source components or public algorithmic implementations, such code must retain its original copyright notices (including but not limited to preserving the copyright notices of the original components or algorithms) and license notices, which shall not be deleted or modified. ## 3. Explicit exposure of key metadata - When assisting humans in code generation or when independently submitting PRs to openUBMC repositories as an automated agent, compliance with the designated PR and commit message templates is mandatory. Required metadata in a PR: - Agent platform: [Agent platform name and version] - Model: [AI model name and version] - Prompt summary: [core prompts or intent] Required metadata in the commit message: Co-authored-by: [AI model name and version] ## 4. openUBMC technology stack adaptation - Code style: Before submitting any code to the openUBMC community, analyze the coding style of the target repository. Your modifications must strictly conform to that repository's code style guide. - Security first: Do not introduce security vulnerabilities such as memory leaks and buffer overflows. Always prefer secure functions verified by the openUBMC community. ## 5\. Prohibited or Risky Behaviors - Unreviewed AI outputs; - Code that contributors cannot explain, maintain, or verify the source of; - Content where AI clearly reproduces third-party code, documentation, images, or copyrighted expressions without providing legitimate sources, licenses, and necessary attributions; - Content that is incompatible with the project's license; - Content that violates AI terms of service, employer policies, confidentiality obligations, export controls, data compliance regulations, or third-party rights; - Prompts, outputs, or contributions that contain trade secrets, personal information, sensitive data, private code, internal documents, or undisclosed vulnerability information; - Contributions submitted in batch by AI agents or lacking substantial participation by human contributors. ## 6\. Contributor Responsibilities When submitting AI-assisted contributions to the community, contributors shall acknowledge and agree that they: - Have manually reviewed the AI-assisted contributions to be submitted; - Understand the technical implications, design impact, and maintenance costs of the AI-assisted contributions to be submitted; - Have completed all necessary testing, builds, license checks, and security reviews on the AI-assisted contributions to be submitted; - Have verified that the AI output does not introduce content incompatible with the project license; - Have confirmed that the AI-assisted contributions do not include any known unauthorized third-party materials, or that any third-party materials, licenses, copyright notices, and attributions have been fully disclosed as required by this project; - Have complied with all applicable policies of the contributors' employers, clients, academic institutions, or affiliated organizations regarding AI tools and open-source contributions; - Take the same responsibility for AI-assisted contributions as for non-AI-assisted contributions. ## 7\. Review and Merging Rules Community maintainers may request modifications, additional explanations, resubmissions of AI-assisted contributions by the contributors, or reject AI-assisted contributions for any of the following reasons: - The contributor fails to disclose information regarding the AI-assisted contribution as required; - The contributor is unable to explain the logic or source of the submitted code; - The contribution is substantially similar to unauthorized third-party code, documentation, or images; - The licensing, copyright, or attribution information is unclear; - The AI-assisted contribution is of poor quality, untested, unmaintainable, or introduces security risks; - Automated, mass submissions of low-quality AI-assisted contributions disrupt the maintainability and operations of the community; - The community maintainers consider the AI-assisted contribution inappropriate for merging based on the openUBMC project's risk control. --- https://www.openubmc.cn/en/charter/ --- # Technical Committee Operations Rules # Policies & Rules Learn about the operational regulations, code of conduct, and AI contribution policies of the openUBMC community. Technical Committee Operations RulesCommunity Code of ConductAI Contribution Policy # Community Code of Conduct # AI Contribution Policy --- https://www.openubmc.cn/en/code-of-conduct/ --- # Technical Committee Operations Rules # Policies & Rules Learn about the operational regulations, code of conduct, and AI contribution policies of the openUBMC community. Technical Committee Operations RulesCommunity Code of ConductAI Contribution Policy # Community Code of Conduct openUBMC Community Code of Conduct ## General Provisions For reporting insults, harassment, or other unacceptable conduct, send an email to complain@public.openubmc.cn for review by the openUBMC Technical Committee. ## Contributor Covenant To build an open and friendly environment, we as contributors and maintainers pledge to make participation in our community a harassment-free experience for participants of the program and community, regardless of age, body size, visible or invisible disability, ethnicity, level of experience, education, socioeconomic status, nationality, personal appearance, or race. ## Code of Conduct Conducts that contribute to a positive environment for our community include: - Friendly and inclusive wording; - Respecting different viewpoints and experiences; - Gracefully accepting constructive feedback; - Focusing on what is best for the community; - Demonstrating kindness toward others. - Compliant code submissions, proper use of permissions, and safeguarding project supply chain and infrastructure security. Unacceptable conducts in the community include: - Posting sexually explicit comments or images, or engaging in unwelcome sexual advances; - Disruption, incitement, rumor-making, insulting, derogatory comments, and personal and political attacks; - Public or private harassment to participants in the community; - Publishing others' information, such as physical and email addresses, without their explicit authorization; - Other conduct that can reasonably be considered as a violation of this Code of Conduct. - Implanting malicious backdoors, polluting project dependencies, destroying project assets, and other violations that endanger community security; ## Project Maintainer Obligations Community project maintainers are responsible for clarifying and enforcing the standards of "improper conduct" and will take appropriate and fair corrective action in response to any conduct that they deem inappropriate. Community project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, and issues that violate this Code of Conduct, and will temporarily or permanently ban any participants because of behavior that the maintainers deem to be threatening, offensive, or harmful. ## Scope This Code of Conduct applies to all community spaces, and also applies when an individual represents the community in public spaces. Examples of representing the community include using an official email address, posting through an official media account, and participating in online or offline events as an appointed representative. The project maintainers can further define and interpret the conduct of representing the community. # AI Contribution Policy --- https://www.openubmc.cn/en/contact-us/ --- # Contact Us Engage with openUBMC through the following ways. ## Community Contact Got a question? Send us an email, and we'll respond within 3–5 business days. Events contact@openubmc.cn Media/PR contact@openubmc.cn Community Discussions discuss@openubmc.cn ## Follow Us ### Find us on social media - WeChat - Community Assistant ## Handy Materials (Community Documentation)[/zh/docs] (Get the Latest openUBMC Releases)[/zh/download] (Join Community)[/zh/contribution] --- https://www.openubmc.cn/en/contribution/ --- # Contribution Guide ... # Overview The openUBMC community fosters a friendly environment for development and collaboration. Please read and adhere to the Code of Conduct before contributing. # Contribution Procedure ## Step 1: Register a AtomGit Account - openUBMC uses AtomGit as its code hosting repository. https://atomgit.com/org/openUBMC - Refer to the AtomGit User Guide to register your AtomGit account and set your primary email in user settings. ## Step 2: Sign the CLA - Before participating in community contributions, you must sign the Contributor License Agreement (CLA). ## Step 3: Find a SIG You Are Interested In - openUBMC community content is structured around Special Interest Groups (SIGs) to streamline management and workflow. All SIGs are open and welcome contributions from everyone. ### To get started, Find a SIG that Aligns with Your Interests. - View SIG organizational details via the SIG Center page or the repository. All SIG meetings are public and open for you to join anytime. - We also encourage interaction with SIG members via the Forum or email.。 - Interested SIG not listed? Start a new one! Send your application to tc@public.openubmc.cn,. Refer to the Application Process for the email template. ## Step 4: Start Your Contribution Contribution extends beyond code. Your input is valuable in every facet of the community. ### Code Contributions Each SIG maintains its own planned issues. You can select and resolve an issue based on your interest. #### Assign an Issue to Yourself Type **/assign** in the comment box, and the bot will assign the issue to you. If there is an ongoing discussion, feel free to post your feedback or join the conversation in the comments. #### Submit an Issue To report a bug or submit a feature request, create an issue in the corresponding openUBMC community repository. If you are unsure which repository to use, post a query on the Forum first. You can also propose ideas or suggestions via an issue or by starting a topic on the Forum. Refer to the AtomGit Issue Submission Guide for details. #### Submit a Pull Request (PR) Refer to the openUBMC Community Pull Request Submission Guide. For substantial contributions, you are highly advised to break down the content into a series of smaller, logically segmented commits for easier code review. If your PR stalls, you can escalate it and request help through the SIG's mailing list or the forum. #### Review Code As an open community, we expect all participants to be active reviewers. For guidance on code review, refer to the The Gentle Art of Patch Review. Key review points to focus on: - **Contribution relevance:** Evaluate if the contributor's idea is reasonable and aligns with the project's goals and needs. - **Architectural adherence:** Check if the contributed code adheres to the correct architectural design and is consistent with existing codebase and design principles. - **Contribution completeness:** Assess if the code is comprehensive, includes all necessary features and tests, and demonstrates maintainability and extensibility. ### Non-Code Contributions A thriving community is built on more than just code. It relies on the continuous efforts of active developers across all domains. Non-code contributions include, but are not limited to: #### Documentation Development - If you find issues while reading openUBMC community documentation, provide feedback by submitting an issue or posting on the Forum. - Have your own insights? Feel free to publish your own documentation. Refer to the openUBMC Blog Contribution Guide or contact sig-docs via email/forum for available submission methods. #### Testing and Validation - Ready to harden the quality of community releases? Get involved with sig-QA. #### Other Work - Community interaction: Engage in discussions, mentor new contributors, and answer community queries on the Forum. - Community operations support: Assist SIG maintainers in improving SIG homepage information, organizing community meetings, and more. - Becoming a community evangelist: Co-organize community gatherings, including meetups, live streams, and the Developer Day. - Community promotion and content creation: Submit event news, technical posts, courseware, or videos to the Technical Committee (TC). - Community infrastructure development: Join sig-infrastructure. - Community visual design: Contact the TC. - Community translation services: Reach out to the TC. ## Step 5: Grow with the Community - We welcome all contributions to the openUBMC community. Our goal is to foster an active and healthy community driven by its contributors. For details on roles like maintainer and committer, refer to the SIG Center page. --- https://www.openubmc.cn/en/course/ --- # Courses Explore our curated openUBMC learning collection. (KPTest Framework Overview)[/en/course/course_kptest_introduction] (Rapid Setup of the KPTest Local Development Environment)[/en/course/course_kptest_quick_start] --- https://www.openubmc.cn/en/course/course_kptest_introduction/ --- Courses KPTest Framework Overview # KPTest Framework Overview 2025-09-15 19:00 KPTest Framework Overview 吴 吴伟誉 ... ## About This Course This course provides a comprehensive introduction to the KPTest framework, detailing its market positioning, key features, core capabilities, and architectural analysis. KPTest is an ecosystem-oriented automated testing framework designed to accelerate the development of test scripts. Built on Python, it boasts a highly decoupled, layered design and an open architecture, enabling rapid extension and flexible adaptation across various testing environments. The framework seamlessly integrates with platforms like iTestSmart and Darwin, providing a unified solution for diverse domains: WebUI, API, desktop, and operating system testing. ## Instructor Bio KPTest Framework Development Engineer --- https://www.openubmc.cn/en/course/course_kptest_quick_start/ --- Courses Rapid Setup of the KPTest Local Development Environment # Rapid Setup of the KPTest Local Development Environment 2025-09-15 19:00 Rapid Setup of the KPTest Local Development Environment 吴 吴伟誉 ... ## About This Course This course provides a foundational introduction to quickly setting up a local development environment based on KPTest. We cover environment configuration, project initialization, test case execution, and results viewing, which lays the groundwork for subsequent automated testing script development. ## Instructor Bio KPTest Framework Development Engineer --- https://www.openubmc.cn/en/docs/ --- # Docs Center **0**/100 ## Community Guidelines Community Journey Map New to openUBMC? Start your journey here! Contribution Guide Find your contribution path now! Release Notes Discover what's new in openUBMC. ## Developer Guides Getting Started A hands-on guide to development. Developer Guide openUBMC customization and development guide. References Design philosophy and value-added feature development references. Tool Guide All-in-one development tooling guide. Interface Specifications OpenUBMC interface specifications for seamless collaboration. --- https://www.openubmc.cn/en/docs/result/ --- # Docs Center **0**/100 --- https://www.openubmc.cn/en/download/ --- # Download Center Find all the resources in one place. Community Releases Driven by and dedicated to the openUBMC community. Commercial Releases Commercial releases built on openUBMC. Download CenterCommunity Releases ## Community Releases Find and download the latest and previous releases, along with their release notes, to quickly integrate and customize openUBMC. ... openUBMC 26.09 Latest Release Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 26.09 | 656.74 MB | 2026/09/29 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_26.09.00.01.zip | 26.09 | 83.85 MB | 2026/09/29 | SHA256 | Download | | openUBMC-CMT_unsigned_26.09.00.01.zip | 26.09 | 83.84 MB | 2026/09/29 | SHA256 | Download | openUBMC 25.12 LTS SP3 LTS Maintenance deadline: 2026/12/31 Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP3 | 280.1 MB | 2026/09/09 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.03.01.zip | 25.12 SP3 | 74.58 MB | 2026/08/31 | SHA256 | Download | openUBMC 26.06 Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 26.06 | 293.75 MB | 2026/07/06 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_26.06.00.01.zip | 26.06 | 77.27 MB | 2026/06/30 | SHA256 | Download | ## Download Resources (App Marketplace)[/zh/marketplace] (Community Docs)[/zh/docs] ## Support & Services (FAQs)[/docs/en/development/faq/general.html] (Community Forum)[https://discuss.openubmc.cn/] --- https://www.openubmc.cn/en/download/business-releases/ --- # Download Center Find all the resources in one place. Community Releases Driven by and dedicated to the openUBMC community. Commercial Releases Commercial releases built on openUBMC. Download CenterCommercial Releases ## Commercial Releases - ### What Is a Commercial Release? - A commercial release is an enterprise-level solution built on the openUBMC community release, tailored and enhanced for business needs. - It adds professional enterprise features to the community release, including advanced security management, enhanced O&M, compliance certification, custom functionality, and commercial technical support. - Fully tested and optimized for stability in complex enterprise IT settings, the commercial releases reduce O&M risks, increase management efficiency, and meet diverse industry needs. - ### How Do Commercial and Community Releases Differ? - Commercial releases deliver enterprise-level reliability and professional support needed for high stability and security of production environments. They offer enhanced, device-validated functionality, regular security updates, and responsive technical services to help enterprises mitigate potential risks. In addition, commercial releases usually allow customizations to address specific hardware or service needs. - Commercial releases provide guaranteed long-term maintenance, freeing the team from foundational technical concerns. - ### How to Become a Partner? - We warmly welcome hardware vendors, solution providers, and system integrators to participate in our partnership initiative. As a certified partner, you will gain collaborative marketing and promotional support from the openUBMC community. We are excited to partner with you to build a thriving BMC ecosystem and deliver superior products and services to end customers. - Please reach out to us at contact@openubmc.cn to discuss partnership specifics and advantages, and together drive the commercial adoption and innovation of open source technology. - ### BYOSOFT openUBMC 25.09 Commercial Release - The BYOSOFT commercial release is derived from the 25.06 community release, augmenting it with multiple verified new features. Major new features include the real-time monitoring dashboard, flexible sensor alarm policies, and Web SOL, which greatly boost operational and management efficiency. Throughout the development cycle, we stay aligned with community updates and refine features according to internal needs. Its release adheres to a rigorous procedure: from internal testing to public beta and the final official launch, ensuring its stability and availability. Vendor: Nanjing Byosoft Co., Ltd. Release Date: 2025/9/30 View More - ### KunlunTech openUBMC Commercial Release - Kunlun BMC-U, KunlunTech's openUBMC commercial release derived from the 25.09 community release, undergoes deep optimizations in its features, peripheral support, customization, and documentation. Kunlun BMC-U improves Kunpeng BMC products with enhanced performance, extended functionalities, and easy maintenance. It offers a reliable, efficient enterprise‑grade BMC firmware solution for partners. - Kunlun BMC‑U will keep pace with openUBMC community updates and continuously enhance its capabilities to support partners in new product launches and value creation. Vendor: Kunlun Technology (Beijing) Co., Ltd. Release Date: 2025/10 View More --- https://www.openubmc.cn/en/download/community/all/ --- # Download Center Find all the resources in one place. Community Releases Driven by and dedicated to the openUBMC community. Commercial Releases Commercial releases built on openUBMC. Download CenterCommunity Releases ## Community Releases Find and download the latest and previous releases, along with their release notes, to quickly integrate and customize openUBMC. ... Version All LTS New | Package Type | Release Date | Maintenance Deadline | Download Link | | --- | --- | --- | --- | | openUBMC 26.09 | 2026/09 | 2026/12 | Download | | openUBMC 25.12 LTS SP3 | 2026/08 | 2026/12 | Download | | openUBMC 26.06 | 2026/06 | 2026/07 | Download | | openUBMC 25.12 LTS SP2 | 2026/05 | 2026/12 | Download | | openUBMC 26.03 | 2026/03 | 2026/06 | Download | | openUBMC 25.12 LTS SP1 | 2026/02 | 2026/12 | Download | | openUBMC 25.12 LTS | 2025/12 | 2026/12 | Download | | openUBMC 25.09 | 2025/09 | 2025/12 | Download | | openUBMC 25.06 | 2025/07 | 2025/09 | Download | | openUBMC 25.03 | 2025/04 | 2025/06 | Download | ## Download Resources (App Marketplace)[/zh/marketplace] (Community Docs)[/zh/docs] ## Support & Services (FAQs)[/docs/en/development/faq/general.html] (Community Forum)[https://discuss.openubmc.cn/] --- https://www.openubmc.cn/en/download/community/detail/openUBMC 25.12 LTS/ --- Versions Reset Confirm Downloads All Versions openUBMC 25.12 LTS Versions openUBMC 26.09 openUBMC 25.12 LTS SP3 openUBMC 26.06 openUBMC 25.12 LTS SP2 openUBMC 26.03 openUBMC 25.12 LTS SP1 openUBMC 25.12 LTS openUBMC 25.09 openUBMC 25.06 openUBMC 25.03 openUBMC 25.12 LTS LTS Maintenance deadline: 2026/12/31 Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 | 71.15 MB | 2025/12/31 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.00.01.zip | 25.12 | 77.58 MB | 2025/12/31 | SHA256 | Download | --- https://www.openubmc.cn/en/download/community/detail/openUBMC 25.12 LTS SP1/ --- Versions Reset Confirm Downloads All Versions openUBMC 25.12 LTS SP1 Versions openUBMC 26.09 openUBMC 25.12 LTS SP3 openUBMC 26.06 openUBMC 25.12 LTS SP2 openUBMC 26.03 openUBMC 25.12 LTS SP1 openUBMC 25.12 LTS openUBMC 25.09 openUBMC 25.06 openUBMC 25.03 openUBMC 25.12 LTS SP1 LTS Maintenance deadline: 2026/12/31 Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP1 | 75.33 MB | 2026/02/14 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.01.01.zip | 25.12 SP1 | 66.08 MB | 2026/06/29 | SHA256 | Download | --- https://www.openubmc.cn/en/download/community/detail/openUBMC 25.12 LTS SP2/ --- Versions Reset Confirm Downloads All Versions openUBMC 25.12 LTS SP2 Versions openUBMC 26.09 openUBMC 25.12 LTS SP3 openUBMC 26.06 openUBMC 25.12 LTS SP2 openUBMC 26.03 openUBMC 25.12 LTS SP1 openUBMC 25.12 LTS openUBMC 25.09 openUBMC 25.06 openUBMC 25.03 openUBMC 25.12 LTS SP2 LTS Maintenance deadline: 2026/12/31 Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP2 | 84.93 MB | 2026/06/03 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.01.01.zip | 25.12 SP2 | 66.46 MB | 2026/06/29 | SHA256 | Download | --- https://www.openubmc.cn/en/download/community/detail/openUBMC 25.12 LTS SP3/ --- Versions Reset Confirm Downloads All Versions openUBMC 25.12 LTS SP3 Versions openUBMC 26.09 openUBMC 25.12 LTS SP3 openUBMC 26.06 openUBMC 25.12 LTS SP2 openUBMC 26.03 openUBMC 25.12 LTS SP1 openUBMC 25.12 LTS openUBMC 25.09 openUBMC 25.06 openUBMC 25.03 openUBMC 25.12 LTS SP3 LTS Maintenance deadline: 2026/12/31 Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP3 | 280.1 MB | 2026/09/09 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.03.01.zip | 25.12 SP3 | 74.58 MB | 2026/08/31 | SHA256 | Download | --- https://www.openubmc.cn/en/download/community/latest/ --- # Download Center Find all the resources in one place. Community Releases Driven by and dedicated to the openUBMC community. Commercial Releases Commercial releases built on openUBMC. Download CenterCommunity Releases ## Community Releases Find and download the latest and previous releases, along with their release notes, to quickly integrate and customize openUBMC. ... openUBMC 26.09 Latest Release Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 26.09 | 656.74 MB | 2026/09/29 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_26.09.00.01.zip | 26.09 | 83.85 MB | 2026/09/29 | SHA256 | Download | | openUBMC-CMT_unsigned_26.09.00.01.zip | 26.09 | 83.84 MB | 2026/09/29 | SHA256 | Download | openUBMC 25.12 LTS SP3 LTS Maintenance deadline: 2026/12/31 Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP3 | 280.1 MB | 2026/09/09 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.03.01.zip | 25.12 SP3 | 74.58 MB | 2026/08/31 | SHA256 | Download | openUBMC 26.06 Release Notes Technical White Paper Lifecycle ### Source Code Complete source packages of the openUBMC community release for custom development. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | repositories.zip | 26.06 | 293.75 MB | 2026/07/06 | SHA256 | Download | ### Firmware Firmware packages of the openUBMC community release, ready for immediate update on servers running the openUBMC community release. | Package Name | Version | Size | Release Date | Integrity Check | Download Link | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_26.06.00.01.zip | 26.06 | 77.27 MB | 2026/06/30 | SHA256 | Download | ## Download Resources (App Marketplace)[/zh/marketplace] (Community Docs)[/zh/docs] ## Support & Services (FAQs)[/docs/en/development/faq/general.html] (Community Forum)[https://discuss.openubmc.cn/] --- https://www.openubmc.cn/en/download/lifecycle/ --- Community Releases Lifecycle # lifecycle Community releases are named by delivery year and month (YY.MM). For example, openUBMC 25.09 was released in September 2025. Community releases are categorized into long-term support (LTS) releases and innovation releases. • LTS releases: Released annually and provided with 12-month community support. The first openUBMC LTS release 25.12 is planned for December 2025. • Innovation releases: Released every 3 months, offering 3-month community support. The first openUBMC innovation release was launched in March 2025. Maintenance support: CVE & Bugfix, new hardware support, and limited new features (with LTS forward compatibility). --- https://www.openubmc.cn/en/maillist/ --- # Mailing Lists Mailing lists are the core, efficient channel for all openUBMC community SIGs. Engage directly in technical reviews, shape proposals, and drive project direction with real-time updates. Subscribe to a SIG Select Your SIG Select the SIG you want to subscribe to and click Subscribe. Enter Details On the subscription page, fill in the required personal information and click Subscribe. Review & Confirm Your mailbox will receive an e-mail from the mailing list, asking you to confirm your subscription. Click the confirmation link to complete the process. You're Subscribed! Your mailbox receives a welcome e-mail from the mailing list, indicating that you have subscribed to the mailing list successfully. SIG Mailing Lists | SIG Name | Description | Mailing Lists | Archive | Subscribe | | --- | --- | --- | --- | --- | No Data --- https://www.openubmc.cn/en/news/ --- # News Dive into the latest industry and community news. (openUBMC 25.09 Is Now Available!)[/en/news/2509-release] (openUBMC Xi'an Meetup Recap)[/en/news/xian-meetup-review] (openUBMC Open Source Development Committee Launches Trial Operation with Inaugural Meeting)[/en/news/20250724] (openUBMC 25.06 Released!)[/en/news/2506-release] (openUBMC Hangzhou Meetup 2025 Wrap-Up: Shaping the Future of Computing Power Management)[/en/news/hangzhou-meetup-review] (openUBMC Technical Session: Building an Intelligent Foundation for Computing Power Management)[/en/news/kadc-2025] (openUBMC 25.03 Release: Starting a New Journey of Open Source)[/en/news/2503-release] --- https://www.openubmc.cn/en/news/20250724/ --- News openUBMC Open Source Development Committee Launches Trial Operation with Inaugural Meeting # openUBMC Open Source Development Committee Launches Trial Operation with Inaugural Meeting 2025/07/24 # openUBMC Open Source Development Committee Launches Trial Operation with Inaugural Meeting The openUBMC Open Source Development Committee officially launched its trial operation in Shenzhen, China, on July 18, 2025, marked by its inaugural onsite meeting. This milestone event convened leaders and technical experts from over 30 companies, representing diverse fields including Internet, carriers, server vendors, independent BIOS vendors, component suppliers, and standards organizations. The meeting focused on core topics such as technological innovation, ecosystem co-construction, and community governance, establishing clear goals and strategic directions for openUBMC's next phase of development. Mr. Ma Yinchuan, Chairperson of the openUBMC Open Source Development Committee, attended the meeting and delivered a speech. He summarized the progress since openUBMC's initial open-sourcing, expressed gratitude for the contributions of all member organizations, and invited the committee to offer suggestions and ideas for the community's future work, emphasizing the need to build consensus and jointly advance the community's development. Following this, Mr. Song Tongling, Chairperson of the openUBMC Technical Committee, addressed the openUBMC Open Source Development Committee on the major technical features of the newly released version 25.06 and the technical roadmap for the second half of the year 2025. - **Major upgrades in version 25.06** As the second release of openUBMC in 2025, openUBMC 25.06 achieves significant progress. Key improvements include enhanced standardized interfaces, broader hardware compatibility, stronger O&M capabilities, and an optimized developer experience. - **Technical roadmap for H2 2025** In the second half of 2025, the openUBMC community will focus on optimizing and upgrading core areas: BMC O&M features, developer usability, and community infrastructure. The aim is to create a more user-friendly and efficient BMC software and community ecosystem. Meanwhile, the openUBMC Technical Committee will uphold its commitment to technical work across H2, ensuring a strong foundation for the continuous development of community versions and technologies. A sustained, prosperous ecosystem is critical for the growth of any open source community. The openUBMC Ecosystem Development Team provided the openUBMC Open Source Development Committee with an update on the community's progress. - **Expanding industry ecosystem:** The openUBMC community has laid the foundation for a robust and comprehensive industry chain. Looking ahead, it will continue to broaden hardware and software support to accommodate a wider range of application scenarios. - **Enhanced standards and certification system:** The openUBMC Component Driver SIG will develop specifications for BMC southbound driver interfaces. Collaborating with community members and standards organizations, this SIG aims to establish unified component driver standards and a formal certification system. - **Impressive initial scale of commercial adoption:** Nearly 20 commercial versions based on the openUBMC community release have already been delivered by member organizations, spanning critical sectors such as cloud services, finance, and public utilities. - **Efficient and healthy organizational operations::** The openUBMC community has formed nine technical SIGs focused on key areas including northbound interface management, southbound component integration, BMC O&M, and component drivers. These SIGs have attracted over 200 developers and fostered an effective collaboration model. During the open discussion session, the openUBMC Development and Growth Committee conducted in-depth discussions on several key topics, including upstream and downstream collaboration for version releases, southbound component driver standards, joint ecosystem expansion and influence building, and community governance and operations. The session yielded broad consensus across multiple fronts. Finally, Mr. Wang Ruifeng, Secretary-General of the openUBMC community, concluded the meeting by emphasizing that its successful convening represented a significant milestone in the community's evolution. It laid a strong foundation for openUBMC's long-term, sustainable growth. Moving forward, the community will take this meeting as a new starting point—upholding the principles of co-construction, sharing, and co-governance, and working collectively to drive sustained development of the openUBMC ecosystem. ### Join the openUBMC community: Community website: https://www.openubmc.cn/en Code repository: https://gitcode.com/openUBMC Corporate cooperation: contact@openubmc.cn 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/news/2026Wuhan-meetup-review/ --- No data --- https://www.openubmc.cn/en/news/2503-release/ --- News openUBMC 25.03 Release: Starting a New Journey of Open Source # openUBMC 25.03 Release: Starting a New Journey of Open Source 2025/05/08 # openUBMC 25.03 Release: Starting a New Journey of Open Source Elevate your open source capabilities with the latest openUBMC solution! We are excited to introduce openUBMC 25.03, a release built to offer you greater quality and flexibility. Discover a suite of new innovations in this first annual release for your baseboard management controller (BMC) jobs. ## 1.1 Features of the Release: A Major Overhaul ### 1.1.1 Northbound Interface Ecosystem - Security enhancements: The upgraded security framework supports customization of password and username policies, and comes with a new foundational module for certificate management. - O&M optimizations: Configuration import and export are standardized. Factory reset now preserves user data. The MCU/VRD firmware upgrade architecture has been refactored to support the standard HPM package format. ### 1.1.2 Southbound Component Extension - Management enhancements: Speed adjustment policies and loading of multiple SML libraries are now supported. - Component compatibility: SP322D/SP323D NICs and NVMe-MI v1.7 linkspeed query are now supported. ### 1.1.3 Development Experience Optimization - Tooling upgrades: Local debugging and model check based on bingo are supported, and the BMC Studio is open source. - Function expansion: CSR configuration check and full model check are supported. ## 1.2 Download to Experience for Yourself Download link: https://openubmc.cn/en/download For details about the release, visit https://openubmc.cn/en/version/25.03. ## 1.3 Source Code Release openUBMC 25.03 operates under Mulan PSL v2. You are free to copy, use, modify, and redistribute the software. Whether you're an independent developer or an enterprise user, you can customize it to fit your needs within legal and regulatory boundaries. The source code for openUBMC 25.03 is now live on the community website. Open source is all in when we share and collaborate. We invite all developers to join in the openUBMC project for even better outcomes. Repository link: https://gitcode.com/openUBMC ## 1.4 Acknowledgment A huge thank you to all the community developers behind our openUBMC project! This release would not have been possible without your brilliant contributions and hard work. We invite more partners to join our community. Together, we're starting a new journey of open source. 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/news/2506-release/ --- News openUBMC 25.06 Released! # openUBMC 25.06 Released! 2025/07/07 # openUBMC 25.06 Released! 🥳 A huge thank-you to all the developers who contributed to the 25.06 release! The new version of openUBMC 25.06 is here on schedule—packed with major updates, new features, and community-driven improvements. ✅ 1,272 issues resolved ✅ 1,582 PRs merged ✅ 334k lines of code added ✅ 179 contributors from multiple organizations ## 🔑 Key Highlights in openUBMC 25.06 ### Hardware SIG 🔥 Completed NCSI sideband management feature for NICs. 🔥 Enhanced NVME-MI protocol command set. 🔥 Improved smart data retrieval for drives. 🔥 Added support for parallel protocol library loading for RAID management. 🔥 Enabled manual/automatic fan mode switching with persistent configuration. 🆕 Added power efficiency curve interface, enabling dynamic power mode switching. 🆕 Introduced parallel upgrade capability for multiple component types. 🆕 Expanded management support for devices including BF2/BF3 NICs, and RAID cards 9540-8i, 9560-8i, 9440-8i, SP686C-M 16i 4G. ### 🌐 Interface SIG 🔥 Completed several Redfish 1.20 standard interfaces. 🆕 Introduced Observability, a new component for real-time BMC performance monitoring and faster issue debugging. 🆕 Added libirc, a remote communication library to simplify customized client development. 🐞 Fixed multiple WebUI bugs and enhanced KVM capabilities. ### ⚙️ bmc\_core SIG 🔥 Implemented some missing parts of the "Sensor" section in IPMI Specifications. 🔥 Strengthened e-label and power-on/power-off strategy customization. 🐞 Fixed sensor component bugs and improved fault localization. ### CICD SIG 🔥 Optimized BMC Studio hardware adaptation UI for a more intuitive configuration experience. 🔥 Enhanced CSR check functionality in BMC Studio. 🆕 QEMU now supports Tianchi component simulation. 🐞 Fixed several build issues in bingo, with support for installation via apt and pip. 🆕 Added CMS signing capability for HPM packages in bingo. ### 📦 Get openUBMC 25.06 Download: https://www.openubmc.cn/en/download Release notes: https://www.openubmc.cn/en/version/latest Application store: https://www.openubmc.cn/en/marketplace Documentation: https://www.openubmc.cn/en/docs 🙌 Thanks to every contributor for making openUBMC better with each release. Your passion and collaboration drive the community forward. Stay tuned—and join us to keep building a more open, intelligent, and powerful ecosystem together! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/news/2509-release/ --- News openUBMC 25.09 Is Now Available! # openUBMC 25.09 Is Now Available! 2025/09/30 # openUBMC 25.09 Is Now Available! # 🥳 openUBMC 25.09 Is Now Available! A huge thank you to all the developers and organizations who contributed to this release—openUBMC 25.09 is here, right on schedule! ✅ 1,313 issues resolved ✅ 1,923 PRs merged ✅ 565k new lines of code ✅ Contributions from developers across 17 organizations ## 🔹 What's New in 25.09 ### Security SIG 🆕 Added support for historical password reuse prevention, configurable failed login lockouts, and extended password lengths. 🆕 Added support for web SSO login, IPMI channel permission control, and frontend sensitive data encryption. ### Interface SIG 🆕 Added openUBMC plugins for Zabbix, Ansible, Cmdlets, and Nagios. 🚀 Completed resource management interfaces for Redfish Manager, Processor, SEL, NTP, and timezone. 🆕 Added support for User Access/Password, User Name, and DCMI Power commands. 🚀 Upgraded multiple firmware in a single HPM package, with auto-recovery upon BMC upgrade failure. 🚀 Prevented host power-on during VRM and NPU upgrades. ### Hardware SIG 🆕 Added support for I3C/CAN-FD and network controller information retrieval via NC-SI over MCTP over I2C/SMBus. 🆕 Added support for Emulex PLDM OEM protocol. 🆕 Added support for PCIe and OCP cards such as E810XXVDA2G1P5, E810CQDA2G2P5, and MCX755106AS-HEAT. 🆕 Added support for RAID cards (SP686C-M series), drives, NVMe SSDs (Samsung PM9D3A, Memblaze PBlaze7, and Solidigm D7-PS1010). 🆕 Added support for GPU (NVIDIA A6000) and NPU modules. 🆕 Added support for TPSU/PSU management capabilities, such as module information query, turbo capacitor management, dual CAN power redundancy, power capping & monitoring, and output limit configuration. 🚀 Added support for persistent critical component logs (VRM/power). 🚀 Added support for BIOS firmware export & critical component firmware upgrade. 🚀 Added support for NIC flash recovery, optical module key info logging & link failure detection. 🚀 Added support for high-speed link detection, CPU & peripheral link anomaly alerts. ### Component Driver SIG 🆕 Added a new device driver management framework to support driver-based component adaptation and management. 🚀 Enabled driver-based management for components such as AWM M11P, SP670, and RP1000P2SFP-A03. ### CICD SIG 🚀 Enhanced QEMU simulation with support for complex protocol emulation (SMBus, MCTP) and device emulation (MCUs, PCIe, and IMU sensors). 🚀 Optimized QEMU smoke tests & driver dependency synchronization with OS updates. 🆕 Built Conan 2.0 main repo, support for profile configuration & parallel builds. 🚀 Bingo integrated GoogleTest framework and optimized developer test hardening & CI automated tests. 🆕 Added I2C scan & read/write tools, configurable metrics collection & observability tracing. ### Docs SIG 🆕 Added configuration guides for SNMP interface mapper, TRAP alerts, equipment customization, and CLI mapper. 🚀 Updated BMC Studio user guide & online help pages. ### Infra SIG 🆕 Added community contribution dashboard for statistics on individual contributions, CLA-signed organization contributions, and SIG contribution rankings. 🆕 Added support for creating routine meetings and improved recording features including speech-to-text transcription and screen recording. ### 🔹 Resources - Download: https://www.openubmc.cn/en/download - Release notes: https://www.openubmc.cn/en/version/latest - Marketplace: https://www.openubmc.cn/en/marketplace - Installation docs: https://www.openubmc.cn/en/docs A big shoutout to every developer—your contributions are what keep openUBMC moving forward. 💪 Stay tuned and join us to continue driving our community's growth! 🚀 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/news/hangzhou-meetup-review/ --- News openUBMC Hangzhou Meetup 2025 Wrap-Up: Shaping the Future of Computing Power Management # openUBMC Hangzhou Meetup 2025 Wrap-Up: Shaping the Future of Computing Power Management 2025/05/30 # openUBMC Hangzhou Meetup 2025 Wrap-Up: Shaping the Future of Computing Power Management On May 26, 2025, the openUBMC open source community held its first meetup in Hangzhou, Zhejiang. Over 60 maintainers and developers, representing key sectors like server, Internet, IBV, component, and chip, gathered to discuss openUBMC's technical evolution and share practical industry experiences. The full-day meetup started with an opening session, followed by morning presentations on key topics and an immersive, hands-on workshop in the afternoon. ## 1 Opening Session Zhang Yubo, representing the openUBMC Technical Committee, opened the meetup by introducing the agenda and sharing community updates, including new features in version 25.03, plans for version 25.06, community operational data, BMC Studio RC, and next steps for the community website. ### 2 Presentations After the opening session, community developers from several companies presented their technical topics. ### 2.1 Developer Test (DT) Best Practices on Northbound Interfaces Huang Han from the Interface Special Interest Group (SIG) introduced a method for performing unit tests (UTs) on northbound mapping configurations, which significantly shortens development and debugging cycles while improving the community's ability to maintain code quality. He called on community developers to continue improving the UT capabilities for northbound interfaces and enhancing the stability of the openUBMC northbound interfaces. ### 2.2 Southbound Component Driver Standardization Liu Xingsen from the Hardware SIG shared how standardized component compatibility approaches can address hardware adaptation challenges. He also explained how the open architecture allows vendors to independently develop BMC component drivers within the community. Finally, he invited more community members to join the discussion on standardization. ### 2.3 Pipeline Build Practices Yi Zhonghui from Wuhan Yangtze Computing Technology explained how they constructed their own build pipeline system using the Conan repository of the openUBMC community. He discussed the technical challenges encountered and offered practical solutions based on real-world examples, providing valuable references for developers. ### 2.4 iNIC Adaptation Experience Sharing Bao Minmin from Henan Kunlun Technology shared practical experiences from their openUBMC intelligent NIC (iNIC) project, detailing the technical challenges faced during delivery and the lessons learned in overcoming them. ### 2.5 Development Challenges and Lessons Learned Xiong Zirui from Henan Kunlun Technology, a developer new to the BMC domain, shared his experience in overcoming the hurdles he encountered when getting started with openUBMC to facilitate a smoother start for other developers. ### 2.6 In-House Components for Smart Serial Port Screens Qiu Hao from Powerleader Computer System explained how the company used its in-house components to make innovative breakthroughs in serial port screen functionality on the openUBMC platform, covering technical details and implementation approaches. Another speaker, Zhu Junjie, discussed the full-process management of these new components, offering developers a practical, step-by-step guide. ### 2.7 Practical Experience in Northbound Interface Adaptation Zhang Qiang from Sichuan Huakun Zhenyu Intelligent Technology detailed how they adopted a northbound mapping mechanism to reduce interface adaptation workload from 1.5 person-months to just 3 person-days. This innovative approach significantly boosted efficiency and saved resources, sparking keen interest and discussions among attendees. ## 3 Hands-on Workshop Organized by the Technical Committee, the hands-on workshop offered developers an opportunity to engage with core technologies and hot topics through immersive activities like coding, collaborative problem-solving, and open discussions. By writing and debugging code for key modules and validating solutions, participants gained firsthand experience in creative, collaborative open source work. Positive feedback highlighted effective knowledge exchange and expert support, demonstrating how the workshop successfully deepened technical skills and fostered community co-construction. ## 4 Looking Ahead Through experience sharing and technical insights, the meetup showcased the openUBMC community developers' expertise and passion, providing an open, tech-driven platform for BMC developers. The openUBMC community intends to host more offline technical events and welcomes more developers to join. 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/news/kadc-2025/ --- News openUBMC Technical Session: Building an Intelligent Foundation for Computing Power Management # openUBMC Technical Session: Building an Intelligent Foundation for Computing Power Management 2025/05/27 # openUBMC Technical Session: Building an Intelligent Foundation for Computing Power Management On May 24, 2025, the Kunpeng & Ascend Developer Conference (KADC) was held at the Beijing ZhongGuanCun International Innovation Center. As one of the key sessions, the openUBMC technical session, titled "Building an Intelligent Foundation for Computing Power Management," brought together developers and industry experts from cloud vendors, OEMs, component manufacturers, standards organizations, and academia to explore the future of open source device management software. ## 1.1 Opening Remarks: Open Source Collaboration on Shaping the Future Ren Chao, Director of Huawei's Cloud BU Hardware Department, delivered the opening remarks. He reviewed Huawei's deep-rooted expertise in the baseboard management controller (BMC) domain since the company began server R&D in 2003, emphasizing that Huawei's BMC solutions are built on robust security to enable intelligent management of computing devices worldwide. He noted, "The computing industry is ecosystem-driven. As a critical component, BMC offers us a path to open source development where we can consolidate collective expertise and build a computing power management ecosystem." As the initiator of the openUBMC community, Huawei has contributed its open source expertise accumulated over the past two decades and continues to invest in community governance, technological innovation, and ecosystem development. Mr. Ren called on global developers to jointly build the openUBMC community into a world-leading digital infrastructure management platform—one that is open, collaborative, and transparent through co-construction, sharing, and co-governance. ## 1.2 Themed Speeches: Open Source in Action, Ecosystem in Growth During the session, six targeted talks highlighted openUBMC's technical innovations and industry applications. ### 1.2.1 Co-Building the openUBMC Community and the Intelligent Computing Management Foundation Wang Ruifeng, General Secretary of the openUBMC Community, analyzed the challenges and opportunities of managing diverse computing power in the AI era. He outlined the community's vision to deliver open source and standardized digital infrastructure management software through collaboration with global developers, and to drive continuous innovations across platforms, domains, and the industry chain. Mr. Wang also introduced the architecture, toolchain features, and innovative development roadmap of the community, and officially announced the release of openUBMC 25.03. At the end of his speech, he encouraged all developers to collaborate in future iterations and innovations. ### 1.2.2 Redefining Management Software Platforms with a New Open Architecture Song Tongling, Member of the openUBMC Technical Committee, explained the evolving demands for device management across the computing industry and proposed a micro-component architecture to address challenges from single-server to cluster-level management. He emphasized standardized interfaces and a unified component framework to ensure the openness and compatibility of hardware and software management, and introduced a one-stop development platform that empowers developers to drive technical innovation in the community. ### 1.2.3 Test Building and Automation Practices Liu Song from Sichuan Huakun Zhenyu Intelligent Technology shared insights into openUBMC-based test building and automation practices, explaining how modular design dramatically improved integration efficiency, shortened release cycles, and ensured high-quality project delivery. ### 1.2.4 End-to-End Delivery Practices Wang Qindong from Henan Kunlun Technology presented Kunlun's integrated openUBMC solution, demonstrating end-to-end commercial deployment on Kunpeng and Ascend servers. He also analyzed how community collaboration accelerates commercialization and effectively facilitates industry adoption. ### 1.2.5 BMC Studio Toolchain Application Practices Wang Yazhou from Beijing KunlunTech demonstrated the powerful capabilities of the BMC Studio toolchain, particularly its efficiency in building development environments and customizing components. He recognized openUBMC in terms of usability and scalability, believing it will tangibly inspire and empower developers. ### 1.2.6 Build and Management Practices for Conan Components Wang Tao from Nanjing BYOSOFT presented in detail their practices for building Conan components, as well as expertise in related development scenarios. He highlighted that centralized dependency management within the community can significantly improve responsiveness to customer needs, providing strong support for both enterprise technology development and client services. This session, through technical presentations and case sharing from different enterprises, demonstrated the diverse value and impact of the openUBMC community in advancing intelligent computing power management foundations, providing the industry with more open and efficient open source device management software. ## 1.3 Join us The openUBMC community will continue to bring together developers from around the world to jointly build a leading open source system for digital infrastructure management. We welcome developers to join us and collaborate in shaping the computing power management ecosystem. Scan the QR code for more community updates! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/news/xian-meetup-review/ --- News openUBMC Xi'an Meetup Recap # openUBMC Xi'an Meetup Recap 2025/08/22 # openUBMC Xi'an Meetup Recap On August 18, the openUBMC Xi'an Meetup, co-hosted by KunlunTech, wrapped up successfully, bringing together nearly 30 developers from various companies. This meetup centered on openUBMC 25.06, offering hands-on workshops across **observability practices, community testing capabilities, and software development enhancements**. Developers dove into real-world scenarios, exchanged ideas, and gained a deeper grasp of the technologies driving openUBMC forward. ## openUBMC Community Updates **Zhang Yubo, a member of the openUBMC Technical Committee, kicked off the event with updates on the community's latest progress and its organizational and operational mechanisms**. Highlights from the 25.06 release, especially its stronger traceability and user-friendly tools, drew great interest, and the sneak peek at 25.09 fueled excitement for what's next. His talk also shed light on openUBMC's open and transparent governance, inspiring more developers to get involved. ## Observability Practice **Li Siguang from the openUBMC Interface SIG delivered an in-depth session on observability, covering everything from technical principles to real-world applications**. The workshop illustrated how effective data collection, metrics, and log analysis enhance visibility across BMC software. ## Community Testing Capability Enhancement **Representing the CICD SIG, Zhang Yubo and Lin Wanmin introduced the smoke testing implemented in openUBMC 25.06, built on Robot Framework and QEMU**. Lin demonstrated how to develop BMC northbound interface test cases using Robot Framework, showing the efficiency and ease of automated testing. ## AI-Powered Coding Practice **Zhang Yubo and Li Zhaotian illustrated community feature design workflows, coding strategies, and test case design processes through real openUBMC cases across design, coding, and testing phases**. Li showcased how AI toolchains can auto-generate design documents, test cases, and DT code, offering developers new ways to boost productivity. They encouraged participants to further experiment with AI-assisted development and contribute innovative ideas to the community. ## 🚩 See You at the Next openUBMC Meetup! Innovation never stops—and neither does openUBMC. The community will continue bringing cutting-edge technologies and practical workshops to more cities, empowering developers everywhere. openUBMC remains committed to building a thriving, collaborative ecosystem where every developer can grow, contribute, and make an impact. ### Learn More about openUBMC ⬇️ - Official website: https://www.openubmc.cn/en - Community forum: https://discuss.openubmc.cn/ 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/operations-rules/ --- # Technical Committee Operations Rules # Policies & Rules Learn about the operational regulations, code of conduct, and AI contribution policies of the openUBMC community. Technical Committee Operations RulesCommunity Code of ConductAI Contribution Policy openUBMC Community Technical Committee Operations Rules ## General Provisions The openUBMC Technical Committee (TC) is the primary technical governance body for openUBMC community projects, responsible for providing technical guidance, decision-making, and oversight. ## Key Responsibilities The TC serves as the community's technical leadership organization. Its primary authorities are: 1. Holding the final authority on all technical decisions; 2. Determining the technical development vision and direction for the community; 3. Deciding on matters such as the formation, dissolution, or merger of SIGs. Resolving collaboration conflicts between SIGs, and mentoring, reviewing, and overseeing their daily operations; 4. Implementing daily development work and ensuring the high-quality release of the openUBMC community distributions; 5. Leading the establishment of proprietary open source projects and continuously building the community's technical influence. ## Composition The TC is chaired by one Chairperson, whose duties are: 1. Calling and presiding over TC meetings, and ensuring all attendees have the right to fully express their technical opinions; 2. Representing the community in promotional activities and various events; 3. The Chairperson is concurrently a TC member and possesses the same voting rights as other members. TC members and the Chairperson are appointed by the openUBMC community and must include individuals who have made significant contributions to the community and are willing to commit continuous dedication. ## Meeting and Decision Mechanism The TC holds regular monthly meetings, or ad-hoc meetings upon the proposal of two-thirds or more of the members. 1. The Chairperson must notify all members via the mailing list at least five calendar days before the meeting. The notice must include the location, date, time, method, agenda, and available reference materials to allow members to prepare. Meetings are open to the public. Any community member may attend and express technical views but holds no voting rights. 2. A quorum requires two-thirds or more (inclusive) of the members to be present for the meeting to be valid. 3. All resolutions must be put to a vote during a valid meeting. Voting shall be open and recorded. A resolution passes only if it receives an affirmative vote from two-thirds or more (inclusive) of the attending members AND exceeds one-half of the entire Committee. Absent members cannot delegate voting authority. ## Contact Mailing List: tc@public.openubmc.cn Online Meetings: Visit the SIG Center to get involved. # Community Code of Conduct # AI Contribution Policy --- https://www.openubmc.cn/en/organizations/ --- # Organizational Structure The openUBMC community is governed by an elected TC and operates with full transparency to ensure an impartial and forward-looking technical roadmap. We champion the principle: Contribution Earns Influence. Advance your role to a project maintainer or TC member, and collectively define openUBMC's future. more ## Vision & Mission The openUBMC community offers open source and standardized software for managing digital infrastructure. By harnessing the collective expertise of developers, it drives continuous innovation across all platforms, domains, and the entire industry value chain. ## Organizational Structure The openUBMC community's governance is defined by the Open Source Development Committee. The Secretariat, led by the Secretary-General, oversees routine operations, while the Technical Committee (TC) sets the technical direction. ## Open Source Development Committee Ma Yinchuan Chair Huawei Technologies Co., Ltd. Email Wang Ruifeng Secretary-General Huawei Technologies Co., Ltd. Email Bian Xingzhong Member Shenzhen 3SNIC Information Technology Co., Ltd. Email Cai Jimiao Member iSoftStone Information Technology (Group) Co., Ltd. Email Chen Gang Member Henan Kunlun Technology Co., Ltd. Email Chen Lin Member Sichuan Yunhai Core Microelectronics Technology Co., Ltd. Email Chen Xiaochun Member Kunlun Technology (Beijing) Co., Ltd. Email Ding Yanlin Member NEXSEC Incorporated Email Gao Xianhu Member HiSilicon (Shanghai) Technologies CO., LTD Email Gao Xinghua Member Beijing NetEason Technology Co., Ltd. Email Gao Zhan Member Nanjing Byosoft Co., Ltd. Email Hong Kunxian Member YUSUR Technology Co., Ltd. Email Ju Rongrong Member Baixin Information Technology Co., Ltd. Email Li Haojie Member Semptian Co., Ltd. Email Li Xuelian Member China Electronics Standardization Institute Email Li Zhigao Member Tencent Cloud Computing (Beijing) Co., Ltd. Email Lin Guohui Member Wuxi Micro Innovation Integrated Circuit Design Co., Ltd. Email Liu Jingxuan Member China Mobile (Suzhou) Software Technology Co., Ltd. Email Liu Sheng Member Zhejiang Zentel Memory Technology Co., Ltd. Email Liu Yuwei Member Beijing Guang Runtong Technology Development Co., Ltd. Email Miao Fuyou Member Global Computing Consortium Email Pang Wei Member China Telecom Cloud Technology Co., Ltd. Email Peng Xiaonan Member Shenzhen Kuntai (Xiamen) Information Technology Co., Ltd. Email Sheng Yong Member Baidu Online Network Technology (Beijing) Co., Ltd. Email View All ## Technical Committee (TC) Song Tongling Chair Email Chen Yingliang Member Email Chen Shihao Member Email Cheng Ziming Member Email Huang Han Member Email Huang Jiaqing Member Email Liu Song Member Email Liu Xingsen Member Email Liu Yujie Member Email Si Changliang Member Email Wang Qindong Member Email Wang Tao Member Email Wang Yazhou Member Email Xu Xiaohan Member Email Yu Fei Member Email Zhang Chao Member Email Zhang Jianping Member Email Zhang Yubo Member Email Zhao Rui Member Email Zhong Jun Member Email ## Secretariat Wang Ruifeng Secretary-General Email Chen Yingliang Executive Secretary & Head Of Ecosystem Email He Luwei Executive Secretary & Head Of Operations Email Liu Yi Executive Secretary & Head Of Marketing Email --- https://www.openubmc.cn/en/roadmaps/ --- 文档中心 体验地图 社区体验地图 01 ## 认识openUBMC 什么是openUBMC openUBMC定义了一款开源BMC软件栈,基于灵活可伸缩的架构、敏捷易用的开发工具、丰富的生态资源,支持广大开发者打造差异化BMC功能,自由定制竞争力特性 Docs CenterDeveloper ToolCommunity SupportopenUBMC services 02 ## 文档中心 开发指南 丰富文档助力开发者快速上手openUBMC,灵活定制专属的BMC软件 快速入门 03 ## 开发工具 BMC Studio 直观的拖拽式可视化开发工具与一步到位的构建工具,打造开发者友好的开发工具库 BMC Studio 在线会议 社区论坛 04 ## 社区支持 论坛 SIG组会 供开发者自由交流的社区论坛、工作组会议线上直播,共建开发者深度参与的社区 05 ## 与openUBMC共同成长 创建组织 组织介绍 组织管理 SIG管理与开发者团队建设 --- https://www.openubmc.cn/en/sig/ --- # SIG Center Special interest groups (SIGs) are the foundational units of the openUBMC community. These open groups are organized around specific technical domains to streamline management and improve workflows. Join a SIG to collaborate on projects, share knowledge, and co-create with fellow developers. Join Our SIGs Learn How SIGs Operate SIGs are the core operational units in the openUBMC community. Formed and run by community developers, each SIG focuses on one or more technical topics, manages relevant code repositories, and drives technological implementation and continuous innovation. Communicate with a SIG Find SIG information, repository lists, and contact details on the SIG Center. You can also check the README.md file in the corresponding SIG directory in the openUBMC community repository. Participate in discussions through mailing lists and public regular meetings. To create a meeting, the SIG Maintainer or Committer access is required. Create Meeting Contribute to a SIG The openUBMC community welcomes developers, enthusiasts, and experts to join our collaborative ecosystem. Contribute through code submissions, documentation improvements, feature testing, and more. SIG Contribution Guide About SIGs SIG Roles & Responsibilities Learn about the different contributor roles and their duties in the openUBMC community. SIG Meeting Guide Regular SIG meetings are a core activity for reviewing technical proposals, aligning development progress, solving problems, and planning future roadmaps. ### SIG Application Process Have a great technical idea and want to build a community around it? Apply to create a new SIG. View Application Process Create Fill in Details Configure Submit PR Send Application Refine ### SIG Subscription Guide Subscribe to a SIG's mailing list to receive the latest updates, including meeting invites and online discussions. View Subscription Process Select SIG Fill in Details Confirm Subscription Subscription Complete openUBMC SIGs No data --- https://www.openubmc.cn/en/sig/TC/ --- SIG Center TC TC View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution TC Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/apply/ --- SIG Center SIG Application Process # SIG Application Process ## Overview Before creating a new SIG, check existing SIGs and discuss your proposal on openUBMC forums to gather feedback and members. To create a SIG, refer to the SIG Management Guide to create a PR in the community repository, and send an application email to the TC. The TC organizes regular reviews to decide on application approval. ## Roles & Responsibilities | Role | Responsibilities | Operations | | --- | --- | --- | | Contributor | Claims Issues and PRs, and completes testing prior to PR submission. | Registered AtomGit member | | Committer | Assigns Issues/PRs and reviews code for quality and correctness. | Active SIG Contributor, highly experienced, and willing to invest energy in the review process. | | Maintainer | Defines the technical roadmap and formulates the release plan for the SIG's projects. | Highly experienced, responsible, with excellent technical and management skills. | ## Application Steps ### Step 1: Fork community repo and use SIG template. - Fork atomgit.com/openubmc/community to your AtomGit account. Use the SIG Application Template to create and copy the template into your new SIG folder in the sig directory. `git clone https://atomgit.com/${YOURGITCODE}/community cd ./community/sig cp -r sig-template sig-${YOURSIGNAME} cd sig-${YOURSIGNAME}` ### Step 2: Complete README and member configuration. - Open the README.md file in the newly created SIG directory and complete the required content as recommended. `vi README.md` ### Step 3: Configure new SIG members and repositories. - Configure SIG members in the sig-info.yaml file. `vi sig-info.yaml` ### Step 4: Submit a PR. - Commit the changes to AtomGit and create a PR. ### Step 5: Email the TC. - Email the TC at tc@public.openubmc.cn, including the subject "New SIG Proposal" and the PR link in the body. ### Step 6: TC review and feedback. - The TC will approve your application by merging the PR. Upon merging, the Community Infrastructure Team will configure the relevant SIG roles and repositories. html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);} --- https://www.openubmc.cn/en/sig/en/ --- # SIG Center Special interest groups (SIGs) are the foundational units of the openUBMC community. These open groups are organized around specific technical domains to streamline management and improve workflows. Join a SIG to collaborate on projects, share knowledge, and co-create with fellow developers. Join Our SIGs Learn How SIGs Operate SIGs are the core operational units in the openUBMC community. Formed and run by community developers, each SIG focuses on one or more technical topics, manages relevant code repositories, and drives technological implementation and continuous innovation. Communicate with a SIG Find SIG information, repository lists, and contact details on the SIG Center. You can also check the README.md file in the corresponding SIG directory in the openUBMC community repository. Participate in discussions through mailing lists and public regular meetings. To create a meeting, the SIG Maintainer or Committer access is required. Create Meeting Contribute to a SIG The openUBMC community welcomes developers, enthusiasts, and experts to join our collaborative ecosystem. Contribute through code submissions, documentation improvements, feature testing, and more. SIG Contribution Guide About SIGs SIG Roles & Responsibilities Learn about the different contributor roles and their duties in the openUBMC community. SIG Meeting Guide Regular SIG meetings are a core activity for reviewing technical proposals, aligning development progress, solving problems, and planning future roadmaps. ### SIG Application Process Have a great technical idea and want to build a community around it? Apply to create a new SIG. View Application Process Create Fill in Details Configure Submit PR Send Application Refine ### SIG Subscription Guide Subscribe to a SIG's mailing list to receive the latest updates, including meeting invites and online discussions. View Subscription Process Select SIG Fill in Details Confirm Subscription Subscription Complete openUBMC SIGs No data --- https://www.openubmc.cn/en/sig/infrastructure/ --- SIG Center infrastructure infrastructure View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution infrastructure Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/role-description/ --- # 角色说明 在openUBMC社区,开发者主要通过参与SIG(Special Interest Group)来贡献自己的力量。无论Contributor、Committer、Maintainer,都是社区重要的贡献者角色,他们的主要区别在于参与的SIG治理范围不同。 SIG中心 角色说明 贡献者 职责:通过代码开发、问题修复和文档完善等方式推动社区发展。 要求:理解社区技术,遵守社区规范,积极参与社区贡献。 查看详情 审核者 职责:通过细致的代码评审帮助提升社区代码质量,同时以自身贡献带动社区共同进步。 要求:具备丰富项目经验,熟悉代码规范,能够提供建设性意见并乐于分享经验。 查看详情 维护者 职责:把握技术方向并推动关键决策,通过关键领域的贡献领导社区的长期发展。 要求:深入理解项目架构,善于协作沟通,认同开源精神并长期引领社区成长。 查看详情 新的贡献者 欢迎新成员加入社区。我们有关于如何开始贡献的指导文档请参考openUBMC 贡献者指南 既有社区成员 既有的社区成员应认可社区导向,遵守openUBMC 社区的行为守则,熟悉社区运作机制和技术能力。 社区非活跃成员退出标准和流程请参考非活跃成员退出标准和流程 ## 贡献者Contributor 贡献者是openUBMC社区的核心力量,他们通过代码开发、文档完善、问题修复、社区运营等多种方式积极参与,共同推动项目的创新与发展。 ### 加入要求 - AtomGit 上的注册会员 - 为 SIG 或社区做出多方面贡献,包括不限于:在 AtomGit 上提交或审核PR;在 AtomGit 上对问题进行归档或评论;参与 SIG 或社区讨论 - 已阅读 贡献者指南 - 积极参与 1 个或多个 SIG ### 责任与权益 - 响应被分配的问题和PR - 对贡献的代码负责,保证贡献的代码:经过良好的测试;能够让测试用例始终通过,并保证DT覆盖率满足社区要求;解决后继发生的错误或问题 - 负责具体实现设计,并通过 SIG 评审 - 获得成为 SIG 审核者 Committer 的权利。 贡献代码的同时积极参与代码审查、设计评审等活动,即可以成为 SIG 的审核者 Committer ## 审核者Committer 审核者是代码仓库的核心维护者,拥有代码合入权限。他们凭借丰富的技术经验,通过代码评审、开发者测试和规范检查等方式保障代码质量,并推动组件的技术演进与长期健康发展。 ### 加入要求 - 作为贡献者至少 3 个月 - 作为主要审阅者至少参与了 6 次 PR 的审阅 - 审阅或合并至少 20 个基本 PR 到代码库 - 熟悉代码库 - 可以自我提名,或由该 SIG 的审核者 Committer 或维护者 Maintainer 提名,并在SIG会议通过 - 或者一次性贡献具备完整特性的组件,也可直接成为Committer ### 责任与权益 - 评审 PR:对 Contributor 提交的 PR 完成评审,基于代码的设计、实现、安全性、可扩展性、兼容性等为度给出公正客观的评价 - 熟知社区开发流程,并指导 Contributor 按照社区开发流程完成代码贡献,保障社区开发流程正确的应用 - 针对接口变更,指导 Contributor 参与社区接口变更评审会议,充分地预审,确保组件接口的设计合理性、兼容性、必要性、易读性、易用性 - 看护组件的软件工程能力,在SIG组中建立良好的软件工程文化 - 看护组件的代码实现设计,确保特性设计的合理性 - 更新和维护组件的版本,与社区项目版本保持一致 - 获得成为 SIG 维护者 Maintainer 的权利。 成为 SIG 内多个代码仓的审查者,积极参与 SIG 技术规划和架构演进,即可以成为 SIG 的维护者 Maintainer ## 维护者Maintainer 维护者是SIG组的核心领导者,负责技术方向规划、社区协作和长期发展。他们不仅具备审核者的所有职责,还主导组件的架构演进、质量保障和生态适配,并通过协调社区内外资源推动SIG目标的实现。 ### 加入要求 - 作为审核者至少 3 个月 - 作为主要审阅者至少参与了 12 次 PR 的审阅 - 审阅或合并至少 30 个基本 PR 到代码库 - 熟悉 SIG 超过一半的代码库 - 可以自我提名,也可以由本 SIG 维护者 Maintainer 提名,并且没有其他 维护者 Maintainer 的反对,并在TC会议通过 ### 责任与权益 - 确定 SIG 所负责项目的技术路线:包括规划和决策 SIG 技术方向、路标规划、架构演进 - 看护SIG组的技术设计方案,在SIG组内营造良好的技术氛围 - 制定 SIG 所负责项目的发布计划:确定 SIG 的关键需求和发布计划;参与社区的 PM 活动,并协调 SIG 计划和社区版本的里程碑时间表匹配 - 参与社区协调活动:作为 SIG 的代表参与 openUBMC 组织的活动和特定会议等 - 召集 SIG 会议:定期召集 SIG 会议,决策 SIG 内上升的争议 - 代表 SIG 参加技术委员会,汇报 SIG 工作和进展 - 获得可参与技术委员会委员选举的权利。 积极提升 SIG 影响力,与其他 SIG 共同协作,即有机会参与技术委员会委员选举 --- https://www.openubmc.cn/en/sig/sig-CICD/ --- SIG Center CICD CICD View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution CICD Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-Linkedsemi/ --- SIG Center Linkedsemi Linkedsemi View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution Linkedsemi Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-QA/ --- SIG Center QA QA View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution QA Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-ai/ --- SIG Center ai ai View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution ai Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-application-process/ --- SIG中心 application-process application-process View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution application-process Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-bmc-core/ --- SIG Center bmc-core bmc-core View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution bmc-core Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-component-drivers/ --- SIG Center component-drivers component-drivers View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution component-drivers Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-docs/ --- SIG Center docs docs View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution docs Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-framework/ --- SIG Center framework framework View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution framework Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-hardware/ --- SIG Center hardware hardware View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution hardware Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-hisilicon/ --- SIG Center hisilicon hisilicon View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution hisilicon Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-interface/ --- SIG Center interface interface View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution interface Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-om/ --- SIG Center om om View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution om Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-release-management/ --- SIG Center release-management release-management View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution release-management Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/sig-security/ --- SIG Center security security View More on AtomGit Core Members (0) Meetings and Events Work Meeting Email ## Repositories (0) | Repos name | Committer | | --- | --- | | | No Data Contribution security Contribution by Individuals Metric PR Issue Comment Mesauring Period \- Maintainer Committer Contributor | Number | GitCode ID | PR | | --- | --- | --- | | | No Data --- https://www.openubmc.cn/en/sig/subscribe-guide/ --- SIG中心 订阅指南 # 订阅指南 01 ## Select a SIG to Subscribe Browse SIGs of interest and click "Subscribe". 02 ## Fill in Information On the subscription email page, fill in your personal information and click Confirm Subscription. 03 ## Confirm Subscription You will receive an email from the SIG asking you to confirm your subscription. Click the confirmation link to complete the subscription. 04 ## Subscription Successful When you receive a welcome email, you have successfully subscribed to the SIG mailing list. --- https://www.openubmc.cn/en/version/1.0.0/ --- Docs Center Release Notes Select # openUBMC 1.0.0 社区首版本正式上线! # openUBMC 1.0.0 社区首版本正式上线! ## 版本概览 openUBMC 是一款架构领先、开发友好、开放标准的开源 BMC。采用协议“木兰宽松许可证”(Mulan PSL V2),用户可以自由复制、使用、修改、分发,不论修改与否。 openUBMC 版本号采用点分位命名规则(X.Y.Z)模式,其中 X 表示每年发布版本,Y 表示每半年发布版本,Z 表示补丁版本。正常每半年会发布一个 Y 版本,每年发布两个版本。 openUBMC 生命周期初步规划为 0.5 年。 ## 版本特性 - 支持微组件架构,组件通过总线互联,具备组件、插件、配置多重扩展能力。 - 提供标准化的 SDK 套件供社区使用并兼容 D-Bus 总线协议,支持组件快速开发并接入系统。 - 支持南向硬件定制通过生成配置数据方式接入,实现低代码开发。 - 支持北向接口映射配置,实现"0"代码简化增量开发。 ## 源代码 开源软件代码仓:https://atomgit.com/openubmc ## 致谢 我们衷心地感谢参与和协助 openUBMC 项目的所有成员,是你们的辛勤付出使得版本顺利发布! openUBMC 在不断的发展中,未来还会有更多好用的特性发布,这里也非常欢迎大家下载并体验,并参与到openUBMC 开源社区建设中来,也期待聆听每一位用户的反馈意见! 社区邮件列表:community@openubmc.org 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/version/25-12-LTS-SP2/ --- No data --- https://www.openubmc.cn/en/version/25-12-LTS-SP3/ --- No data --- https://www.openubmc.cn/en/version/25.03/ --- Docs Center Release Notes Select # openUBMC 25.03 版本发布说明 # openUBMC 25.03 版本发布说明 * * * ## 版本概览 作为25年首版本,openUBMC 25.03 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发,不论修改与否。 * * * ## 版本特性 25.03版本在1.0.0版本基础上进行开发,特性交付范围包括: ### 北向接口生态 1. 安全框架升级 - 支持密码策略定制化配置 - 实现用户名规则自定义功能 - 新增证书管理基础模块 2. 运维功能优化 - 配置导入/导出标准化 - 出厂重置保留用户数据 - 重构MCU/VRD升级架构(解耦式设计) - 支持hpm标准化升级包格式 ### 南向部件扩展 1. 管理能力增强 - 调速策略能力支持 - 多SML库加载 2. 部件适配 - 支持SP322D/SP323D网卡 - 支持NVMe-MI v7协议linkspeed查询 ### 开发体验优化 1. 开发工具增强 - bingo支持本地调试 - bingo支持模型检查功能 2. BMC Studio发布至社区 - 支持CSR配置检查 - 支持全模型检查 * * * ## 源代码 25.03版本源代码已发布至社区网站:https://www.openubmc.cn/en/download * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3026302 | 产品调速策略未适配所有机型,社区提供调速策略定制能力,需要开发者基于整机产品自行定制 | thermal_mgmt | * * * ## 已修复问题 暂无 * * * ## CVE 漏洞 暂无 * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/version/25.06/ --- Docs Center Release Notes Select # openUBMC 25.06 版本发布说明 # openUBMC 25.06 版本发布说明 * * * ## 版本概览 作为25年第二个创新版本,openUBMC 25.06 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 25.06版本在25.03版本基础上进行开发,特性交付范围包括: ### 北向接口生态 1. 可观测性服务:覆盖日志、独立、跟踪等数据的采集和存储能力; 2. 升级方案优化:支持固件并行升级与统一生效; 3. 接口功能优化:支持针对不同客户提供接口灵活扩展和定制能力; 4. 接口升级:IPMI和Redfish标准接口升级,主要包含Power、Drive和Thermal等; 5. 独立KVM开发套件:支持独立KVM客户端通过websocket链接到BMC,实现VMM功能,电源控制功能,系统启动项管理功能; 6. 新增规范:支持资源树协作接口关键字规范; ### 南向部件扩展 1. 板卡接入丰富度:新增网卡(标卡和OCP)、RAID卡、硬盘、NVMe盘、TPM卡、DPU、SDI、GPU、NPU等部件接入,详细接入清单参照vpd代码仓; 2. 南向协议能力:支持NVMe-mi over mctp的协议解析;支持使用pldm协议获取网卡部分信息;支持NCSI边带管理功能;支持PMBus1.2/CANBUS协议; 3. 能效管理能力:支持功率、电源固件升级、电源告警功能、供电信息、供电模式、时钟同步等管理能力; 4. DFX能力:支持电源砖精细化管理能力,支持动态组合获取硬盘的SMART信息,支持硬盘(SSD)寿命管理; ### 开发体验优化 1. BMC STUDIO: 支持可视化图形开发和自动化检测功能,完成CSR开发和语法合法性检查;提供VSCode插件一键完成QEMU安装、配置、启动和调试; 2. QEMU仿真功能: 支持仿真镜像的构建与发布;支持Qemu工具的构建与发布;支持仿真数据的发布。当前已支持EEPROM,HisPort,BMC芯片等数据插件; 3. 自动化防护:支持kptest测试框架基础能力建设和自动化用例; 4. 工程能力: 支持工具生成产品、客户层级的全量接口配置;支持组件工具依赖自管理;支持编译构建及ut/it的门禁检查;支持组件的全量二进制构建;支持组件转维发布能力;支持社区开发者签名出包等;提供调试工具能力; * * * ## 源代码 25.06版本源代码已发布至社区网站:https://openubmc.cn/en/download * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | https://atomgit.com/openUBMC/mdb_interface/issues/135 | 资源协作接口属性和方法Description字段修改 | mdb_interface | | https://atomgit.com/openUBMC/fructrl/issues/15 | 老版本导入新版本上电延迟值可能被改变 | fructrl | * * * ## 已修复问题 历史版本已发现在当前版本解决的缺陷:暂无 * * * ## CVE 漏洞 暂无 * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/version/25.09/ --- Docs Center Release Notes Select # openUBMC 25.09 版本发布说明 # openUBMC 25.09 版本发布说明 * * * ## 版本概览 作为25年第三个创新版本,openUBMC 25.09 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 25.09版本在25.06版本基础上进行开发,特性交付范围包括: ### 北向接口生态 #### 1\. 基础安全能力 - **密码安全策略**:支持禁用历史密码、失败锁定次数配置、登录失败锁定时间配置、超长密码支持 - **认证与授权**:支持WEB SSO单点登录、IPMI通道权限配置、前端敏感信息加密 - **安全审计**:支持动态插桩拦截风险接口调用日志、Cleancode排查整改 #### 2\. 管理软件生态 - **网管系统对接**:支持Zabbix、Ansible、Cmdlets、Nagios插件,实现与openUBMC的完整对接 - **开发指导文档**:提供SNMP接口映射器、TRAP告警、装备定制、CLI映射器等配置指导文档 #### 3\. 接口升级与扩展 - **Redfish接口增强**:主要包含Manager、Processor、SEL、NTP、时区等资源管理 - **IPMI标准命令**:支持User access/Password、User Name、DCMI Power等标准命令 #### 4\. 融合运维能力 - **固件升级管理**:支持一个hpm包多个固件场景升级、BMC升级异常时自恢复 - **安全升级控制**:支持VRD和NPU升级过程中禁止主机上电 - **任务管理**:支持任务资源标准规范和定制能力 ### 南向部件扩展 #### 1\. 南向驱动框架 - **驱动规范**:完成南向驱动框架和规范发布,基于规范完成网卡和GPU兼容性适配 - **协议支持**:支持I3C/CAN-FD能力、Ncsi Over Mctp/I2C/SMBUS协议获取网卡信息 - **私有协议**:支持Emulex的pldm私有协议 #### 2\. 板卡接入丰富度 - **网卡支持**:新增标卡和OCP网卡,包括E810XXVDA2G1P5、E810CQDA2G2P5、MCX755106AS-HEAT等 - **存储设备**:支持RAID卡(SP686C-M系列)、硬盘、NVMe盘(SamSung PM9D3A、Memblaze PBlaze7、Solidigm D7-PS1010等) - **计算加速**:支持GPU(A6000)、NPU模组等部件接入 #### 3\. TPSU/PSU管理 - **基本信息管理**:支持TPSU模块信息查询、电源额定功率变化记录 - **Turbo功能**:支持Turbo电容管理、充放电控制、使能控制 - **主备切换**:支持双CAN电源线路主备切换、供电模式切换 - **功率管理**:支持功耗封顶、功率监控、输出限功率点配置 #### 4\. DFX能力增强 - **临终遗言**:支持VRM/电源等关键部件临终遗言持久化 - **固件管理**:支持BIOS固件导出、关键部件固件升级 - **故障检测**:支持网卡Flash recovery故障检测、光模块关键信息记录和闪断检测 - **链路检测**:支持高速链路检测、CPU与外围器件链路异常告警 ### 开发体验优化 #### 1\. QEMU仿真能力 - **总线仿真**:支持SMBus、MCTP等复杂协议仿真 - **部件仿真**:支持MCU、PCIe、IMU等器件仿真 - **性能优化**:QEMU冒烟测试性能优化、支持依赖驱动更新 #### 2\. 指导文档完善 - **接口文档**:完成SNMP接口映射器、TRAP告警、装备定制、CLI映射器等指导文档 - **开发指南**:提供映射器接口设计说明书、配置指导、定位指导 - **用户手册**:更新BMC Studio用户指南、联机帮助页面扩展 #### 3\. 构建优化 - **Conan2.0升级**:完成conan2.0中心仓能力构建、支持Profile配置和并行构建 - **Bingo工具增强**:支持基于gtest的开发者测试、DT测试质量加固、门禁模型检查能力增强 - **构建脚本**:支持社区组件构建脚本适配Conan2.0、非root运行 #### 4\. 开发体验提升 - **测试能力**:bingo支持基于gtest的开发者测试、DT测试能力增强 - **代码质量**:门禁模型检查能力增强、支持代码开源合规检查 - **工具支持**:新增I2C扫描和读写工具、支持度量采集和可观测跟踪可配置 * * * ## 源代码 25.09版本源代码已发布至社区网站:https://openubmc.cn/en/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 5.11.0 | 5.10.0 | 5.9.0 | | --- | --- | --- | --- | | 25.09 | Y | N | N | | 25.06 | N | Y | N | | 25.03 | N | N | Y | * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3187698 | 资源协作接口属性和方法Description字段修改 | mdb_interface | | 3190225 | 老版本导入新版本上电延迟值可能被改变 | fructrl | * * * ## 已修复问题 历史版本已发现在当前版本解决的缺陷:暂无 * * * ## CVE 漏洞 暂无 * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/en/version/latest/ --- Docs Center Release Notes Select # openUBMC 1.0.0 社区首版本正式上线! # openUBMC 1.0.0 社区首版本正式上线! ## 版本概览 openUBMC 是一款架构领先、开发友好、开放标准的开源 BMC。采用协议“木兰宽松许可证”(Mulan PSL V2),用户可以自由复制、使用、修改、分发,不论修改与否。 openUBMC 版本号采用点分位命名规则(X.Y.Z)模式,其中 X 表示每年发布版本,Y 表示每半年发布版本,Z 表示补丁版本。正常每半年会发布一个 Y 版本,每年发布两个版本。 openUBMC 生命周期初步规划为 0.5 年。 ## 版本特性 - 支持微组件架构,组件通过总线互联,具备组件、插件、配置多重扩展能力。 - 提供标准化的 SDK 套件供社区使用并兼容 D-Bus 总线协议,支持组件快速开发并接入系统。 - 支持南向硬件定制通过生成配置数据方式接入,实现低代码开发。 - 支持北向接口映射配置,实现"0"代码简化增量开发。 ## 源代码 开源软件代码仓:https://atomgit.com/openubmc ## 致谢 我们衷心地感谢参与和协助 openUBMC 项目的所有成员,是你们的辛勤付出使得版本顺利发布! openUBMC 在不断的发展中,未来还会有更多好用的特性发布,这里也非常欢迎大家下载并体验,并参与到openUBMC 开源社区建设中来,也期待聆听每一位用户的反馈意见! 社区邮件列表:community@openubmc.org \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/en/vulnerability-management/ --- Security Center Vulnerability Management # Vulnerability Management 2025/03/30 openUBMC # Vulnerability Management ## 1\. Vulnerability Response The openUBMC community prioritizes the security of its releases. SIG Security is responsible for receiving, investigating, and disclosing all related security vulnerabilities. We strongly encourage security researchers and industry organizations to proactively report suspected flaws to SIG Security for rapid response, analysis, and resolution. ## 2\. Supported Versions The vulnerability response process is focused primarily on openUBMC community releases. ## 3\. Vulnerability Handling Process Every security vulnerability is assigned to a dedicated individual for tracking and resolution. This coordinator (a SIG Security member) is responsible for driving the fix and disclosure process. We will detail three key stages of this workflow: Vulnerability Reporting, Vulnerability Assessment, and Vulnerability Disclosure. ### 3.1 Vulnerability Reporting If you suspect an openUBMC product contains a security vulnerability, we urge you to report it to the openUBMC community and collaborate with us to ensure its responsible remediation and disclosure. #### 3.1.1 Vulnerability Reporting Method Potential security vulnerabilities in openUBMC products should be reported via email to SIG Security at securities@public.openubmc.cn. Given the highly sensitive nature of vulnerability data, we strongly recommend encrypting your submission using SIG Security's PGP public key to ensure confidentiality. We are fully equipped to receive OpenPGP-encrypted emails. List of SIG Security members: - Zhang Chao \[@TacoJay\], zhangchao60@huawei.com - Yan Chuanjie \[@loopvoid\], yanchuanjie@huawei.com - Peng Xianglin \[@Free\_Tomato\], pengxianglin2@huawei.com - Ren Shan\[@Renyqing\],renshan2@huawei.com #### 3.1.2 Vulnerability Report Content To facilitate the rapid confirmation and validation of a suspected vulnerability, please include (but do not limit your report to) the following information in your submission email: - Basic information: Include the module impacted by the vulnerability, the trigger conditions, and the potential system impact upon successful exploitation. - Technical details: Include system configuration, localization methods, a description of the exploit, POC (Proof-of-Concept), and detailed reproduction steps. - Suggested remediation: Your proposed solution or mitigation advice. - Reporter information: Your organization and contact details. - Disclosure plan: Your potential timeline or plan for public disclosure of the vulnerability. #### 3.1.3 Response Time We will respond to suspected security vulnerabilities reported via email within five days and provide the reporter with an update on the issue's handling progress. ### 3.2 Vulnerability Assessment The industry standard for assessing vulnerability severity is the Common Vulnerability Scoring System (CVSS). When using CVSS v3, we require the definition of a vulnerability exploitation scenario and assess the actual impact within that context. The severity rating assesses exploit complexity and the resulting impact on Confidentiality, Integrity, and Availability (CIA) to generate a corresponding score. #### 3.2.1 Assessment Criteria The openUBMC community uses CVSS v3 to assess vulnerabilities. CVSS v3 assesses the impact of a vulnerability using the following vectors: - Attack Vector (AV): Reflects the context by which vulnerability exploitation is possible. - Attack Complexity (AC): Describes the difficulty of executing the attack and the conditions required for a successful exploit. - User Interaction (UI): Determines whether successful exploitation requires user participation. - Privileges Required (PR): Records the level of user authorization necessary for a successful attack. - Scope (S): Determines whether the attacker can impact components with different authorization levels. - Confidentiality (C): Measures the extent of impact resulting from information disclosure to unauthorized parties. - Integrity (I): Measures the extent of impact resulting from data modification or tampering. - Availability (A): Measures the extent to which users are affected when access to data or services is impaired. #### 3.2.2 Assessment Principles - Vulnerability severity is assessed, not overall risk. - The assessment must be based on a defined attack scenario, ensuring that a successful attack within that scenario can cause an impact on Confidentiality, Integrity, or Availability (CIA). - When a security vulnerability has multiple attack scenarios, the assessment must use the scenario that causes the maximum impact (for example, the highest CVSS score). - If a vulnerability exists in an embedded or called library, the attack scenario must be determined based on how the library is used within the product prior to assessment. - Security flaws that cannot be triggered or do not affect CIA will receive a CVSS score of 0. #### 3.2.3 Assessment Steps When assessing a vulnerability, proceed according to the following steps: - Define the plausible attack scenario and score based on that scenario. - Identify the Vulnerable Component and the Impact Component (the component affected by the flaw). - Assign base metrics: Determine the vulnerability's overall impact by scoring the Exploitability (AV/AC/PR/UI/S) and Impact (C/I/A) metrics. #### 3.2.4 Severity Rating | Severity Rating | Score | | --- | --- | | Critical | 9.0 - 10.0 | | High | 7.0 - 8.9 | | Medium | 4.0 - 6.9 | | Low | 0.1 - 3.9 | | None | 0.0 | ### 3.3 Vulnerability Disclosure To protect the security of openUBMC users, the openUBMC community strictly controls the spread of vulnerability information during the investigation, remediation, and public disclosure phases. We limit this sensitive information to only the personnel directly involved in addressing the flaw. We will not publicly disclose, discuss, or confirm security issues related to openUBMC products until a public disclosure is made. We also require the vulnerability reporter to maintain strict confidentiality until this official public release. Once a security vulnerability has been fixed, the openUBMC community will issue a security advisory. This advisory will include the technical details of the flaw, the CVE ID, CVSS score, severity rating, and information regarding affected and patched versions. Security advisories are available via email subscription. Content on This Page --- https://www.openubmc.cn/zh/ --- # openUBMC Meetup 深圳站议题征集 2026/10/30 了解更多 前往查看 openUBMC 26.09 正式上线 了解更多 文档场景化架构升级,欢迎体验! 立即查看 欢迎加入openUBMC社区 openUBMC是一款架构领先、开发友好、标准开放的算力设备开源管理软件 了解更多 - 文档中心 汇聚详细的教学文档 - 社区论坛 和其他开发者一起聊聊吧 - 社区活动 了解openUBMC社区全年活动 - 应用市场 全面的软件工具下载中心 ## 面向全球开发者的开源算力设备管理软件 极简高效开发 南北向全面开放兼容,覆盖丰富硬件与主流行业规范;依托微组件架构,一套代码适配多场景,社区共建,高效支撑差异化定制 一键部署 快速上手 3步完成本地构建,丰富的工具提供极简开发体验。 AI辅助编程 openUBMC Studio深度集成主流 Coding Agent,一键导入社区高阶技能,知识库原生嵌入。 可灵活扩展 支持配置化、插件化、组件化的多层级定制,满足算力业务场景下的灵活定制需求。 规范驱动开发 以模型与规范为核心,让能力描述更清晰、社区协同开发更高效、版本质量更稳定。 北向灵活接入 支持北向自接入能力,激发业务高效能,赋予运维新智能 集群管理平台 AI训练框架 运维监控系统 ... 北向自接入规范 芯片加速 可靠性提升 智能故障预测 能效调优 极致安全 ... 南向标准引领 首创驱动规范,实现硬件 Day 级快速适配,兼容各类板卡,支撑多元算力部署 多功能特性 部件带外驱动接口 风扇部件接口 风扇驱动 存储部件接口 存储驱动 xPU部件接口 xPU驱动 部件外带接口 XX驱动 硬件 生态全面开放 openUBMC Studio 一站式开发平台,以 AI 辅助编码,大幅提升服务器全流程开发与适配效率 主流协议全域兼容 Redfish / IPMI / SNMP /...... 北向自接入 自定义Agent,灵活对接业务系统 高可用自恢复强安全 多固件并行升级/密码安全...... 网卡 SSD盘 DPU卡 HDD NPU卡 GPU卡 RAID卡 ## 参与openUBMC 社区 ### 如何参与社区贡献 openUBMC 社区诚邀开发者、技术爱好者及行业专家加入协作生态。您可通过代码提交、文档完善、功能测试等多种形式参与社区建设。 查看贡献攻略 ### 如何参与SIG兴趣小组 SIG 全称是 Special Interest Group,即"特别兴趣小组"。openUBMC社区按照不同的 SIG 来组织,以便更好地管理和改善工作流程。SIG 组均是开放的,欢迎任何人来参与。 前往SIG中心 ### openUBMC社区活力 - 0 社区贡献者 - 0 下载量 - 0 单位成员 - 0 代码仓 - 0 需求&问题 查看贡献详情 ## 用户案例 基于 openUBMC 构建 Agent 驱动的 BMC 研发工作流 BMC 固件研发涵盖源码开发、构建部署、设备验证全链路,任务进度与验证证据分散零散、缺乏统一追溯机制。引入智能 Agent 虽可推进编码与工具调用,但任务跨阶段、会话中断仍需人工重复梳理衔接;同时 BMC 故障属于典型跨层问题,依赖多维度交叉核验,零散的工具调用无法形成可信闭环。因此,亟需一套支持断点续跑、操作可对账、以设备真实状态为验收标准的标准化研发工作流。 查看详情 基于 openUBMC 北向自接入实现刀片机箱节点一体化健康管理 当前,AI 算力数据中心广泛采用高密度刀片机箱,单机箱内置多片独立刀片,每片刀片搭载专属 BMC 管理芯片。传统 BMC 仅支持单节点本地管控,彼此隔离形成管理孤岛,存在以下运维痛点: 查看详情 基于 openUBMC 实现 PCIe Switch 多 GPU 自发现 随着大模型训练场景规模化落地,行业对单机高密度算力、低延迟互联、高稳定部署的需求持续提升。传统 CPU 直出架构受原生 PCIe 通道物理限制,难以满足海量 GPU 挂载、高效算力互联的业务需求,存在带宽瓶颈、通信延迟高、组网灵活性不足、硬件设计成本高、故障易扩散等痛点,无法适配 AI 训练场景对服务器高性能、高可靠、高灵活的严苛要求。 查看详情 查看更多 ## 社区动态 ... (基于 openUBMC 构建 Agent 驱动的 BMC 研发工作流)[/zh/blogs/20260929UBMC-ruantonghuafang] (从故障诊断到 RAS Offload:百敖 openUBMC 的 Intel 平台适配实践)[/zh/blogs/20260903UBMC-baiao] (刀片服务器健康管理破局:昆仑太科依托 openUBMC 北向自接入实现整机协同)[/zh/blogs/20260723UBMC] (打破业务边界:openUBMC 北向自接入,重构BMC创新落地模式)[/zh/blogs/20260605UBMC] (开源BMC筑基AI算力——openUBMC 走进长沙高校)[/zh/blogs/2026UBMC-Changsha] (Open AI Infra Summit 2026|openUBMC以架构创新和开源标准破解智算集群运维痛点)[/zh/blogs/open-A-IInfra-summit-review] 查看更多 ## 社区伙伴 注:排名不分先后 --- https://www.openubmc.cn/zh/ai-coding-assistants/ --- # 技术委员会运作规则 # 政策规则 了解openUBMC社区的运作规则、行为准则、AI贡献策略等相关内容 技术委员会运作规则社区行为准则AI贡献策略 # 社区行为准则 # AI贡献策略 openUBMC社区生成式AI工具使用与开源贡献策略 ## 1\. 开放策略 (Openness Strategy) openUBMC社区秉持开放、协同、创新的开源精神,将生成式AI与智能化Agent视为推动社区技术演进的重要生产力。社区允许贡献者在合理、透明、可审查的前提下使用生成式人工智能工具辅助贡献,但坚持以下原则: - **核心原则一:保持开放,AI开发导向 (Open & AI-Development-Oriented)** openUBMC社区对新技术始终秉承开放拥抱的姿态。我们积极迎接AI开发导向,并致力于构建一个对人类开发者与AI代理同样友好的智能化开源生态。openUBMC社区鼓励并支持开发者和自动化Agent深入参与到社区的各项贡献中(包括但不限于代码编写、文档翻译、测试用例生成、运维自动化等)。 - **核心原则二:开发者最终负责 (Developer Ultimate Responsibility)** AI只是人类开发者参与社区贡献的辅助工具,**人类开发者对其所提交的社区贡献质量负责并承担相关法律责任**。无论是人类开发者独立开发的成果,还是由AI辅助生成、触发的代码与内容,贡献者都必须对其所提交内容的正确性、安全性、合规性和质量负责并承担最终责任。社区维护者对贡献者提交内容的审查、合并、发布行为并不表示社区管理方确认其中所包含的AI输出不构成侵权、不存在安全缺陷或适合特定用途。 - **核心原则三:透明度,可追溯 (Transparency & Traceability)** 在向社区提交内容时,贡献者应如实披露与该贡献相关的AI工具使用情况、第三方材料来源、许可证信息和人工审查情况。openUBMC社区建立了一套严格的元数据记录机制,对AI生成内容的**关键元数据(包括生成该等内容所使用的Agent平台、模型、Prompt摘要等)进行完整记录**,从而确保AI参与的代码贡献都具备清晰的审查追踪链。 ## 2\. 适用范围 (Scope of Application) 本策略适用于贡献者向openUBMC社区(包括但不限于openUBMC组织下的所有代码仓库、文档库等)提交的各种形式的所有贡献: - **源代码与脚本**:包括各类核心代码、测试用例、构建脚本。 - **技术文档与社区内容**:包括API说明、部署指南、发布日志、Wiki页面等。 - **配置与元数据**:包括Containerfile/Dockerfile、CI/CD配置文件等。 ## 3\. 法律与合规 (Legal & Compliance) 贡献者向openUBMC社区提交包含AI生成内容的贡献,必须在以下法律与合规框架内: ### 3.1 CLA(贡献者许可协议) openUBMC社区采用**CLA(Contributor License Agreement,贡献者许可协议)**。 - 贡献者在提交贡献前,必须签署社区CLA。 - 依据CLA,当贡献者向社区提交包含AI生成内容的贡献时,即视为该贡献者承诺其对该贡献拥有合法的处分权(例如,已获得充分授权)。贡献者不能以“内容由AI生成”为由免除其在CLA中所做出的承诺以及应当承担的相关法律责任。 ### 3.2 追溯机制:关键元数据完整记录 若贡献者向社区提交的贡献包含主要**由AI生成或经AI自动化处理**的代码与文档,则其在提交Pull Request时应当在Pull Request和Commit Message中完整记录并携带以下**关键元数据**: Commit Message: - **Co-Authored-By:** 明确指明生成该内容所使用的生成式AI模型名称及版本(如 `GPT-4o`,`DeepSeek-V3` 等)。 Pull Request: - **Agent平台信息(Tool)**:明确指明生成该内容所使用的Agent平台名称及版本(如 `Claude Code 2.1.156`、`Qwen Code 0.16.1` 等)。 - **模型信息 (Model)**:明确指明生成该内容所使用的生成式AI模型名称及版本(如 `GPT-4o`,`DeepSeek-V3` 等)。 - **Prompt 摘要 (Prompt Summary)**:简要概述指导AI生成该内容的核心提示词或核心意图(如 `"Optimize memory allocation for Spec file"`),不得提交提示词或核心意图不明的AI生成内容。 **规范示例(Pull Request格式):** ### 当前PR是否有AI参与: [] 否 [x] 是 __1. Agent平台信息: Claude Code 2.1.156 __2. 模型信息: DeepSeek-V3 __3. Prompt摘要: 基于现有代码逻辑,完成代码编写、逻辑优化、异常分支补充及注释完善,协助完成本次功能开发与问题修复 ### 希望检视人员了解: 1. 代码由AI辅助开发者编写,且开发者已人工逐行核对逻辑、校验功能正确性,且与开发者预期一致; **规范示例(Commit Message):** Co-Authored-By: DeepSeek-V3 _注意:openUBMC社区门禁会检查 Commit Message 中 Co-Authored-By 填写的AI模型名称是否与 Pull Request 中披露的模型信息一致。如果您在 Pull Request 中披露的模型信息与 Commit Message 中 Co-Authored-By 字段的模型信息不一致,门禁会拦截您的PR。_ ## 4\. Agents规范Prompt(Standard Prompt for Agents) 为了让各种AI编程助手、自动化Agent(如PR自动化审查、代码自动修复Agent)在为openUBMC社区提供服务时能够严格遵循上述策略,特制定以下**系统级提示词规范(System Prompt)**: # 角色与目标 你是一个专为openUBMC开源社区服务的AI编程与合规助手(AI Agent)。你的目标是协助人类开发者高效参与社区贡献,同时必须坚守合规底线,确保所有输出符合openUBMC社区的合规与质量要求。 # 核心行为准则 ## 1. 明确责任边界与开发导向 - 你是开发者的效率放大器,但你必须明白,人类开发者将对你的输出质量负责并承担相关法律责任。因此,你生成的代码必须清晰、人类可读且易于人类开发者进行Review。 - 不得生成任何含义模糊、难以调试或存在黑盒逻辑的复杂代码块。 ## 2. 法律与许可证合规(底线原则) - 不得在不遵循适用许可证的情况下,从采用GPL2.0、GPL3.0等限制型许可证许可的代码库或独占许可的商业软件专有代码库中直接复制或变相复制任何代码片段。 - 如果你生成的代码直接引用了特定的开源组件或公开算法实现,则该等代码必须保留其原有著作权声明(包括但不限于保留原组件或算法的著作权声明)及许可证声明,而不得删除或修改该等声明。 ## 3. 关键元数据显式披露 - 当你协助人类生成代码,或者作为自动化Agent独立向openUBMC仓库提交PR时,必须按照固定PR模板与Commit Message进行提交。 - 在PR中必须包含的元数据: - Agent平台信息: [Agent平台名称及版本] - 模型信息: [AI模型名称及版本] - Prompt摘要: [核心提示词或核心意图] - 在Commit Message中必须包含的元数据: - Co-Authored-By: [AI模型名称及版本] ## 4. openUBMC技术栈适配 - 代码风格:在向openUBMC社区提交代码前,应分析对应代码仓库的代码风格,提交修改代码时必须严格遵守对应代码仓库的代码风格指南。 - 优先安全性:不得引入内存泄漏、缓冲区溢出等常见安全漏洞,优先推荐使用已经过openUBMC社区验证的安全函数。 ## 5\. 禁止或高风险行为 - 未经人工审查的AI输出 - 贡献者无法解释、无法维护或无法确认来源的代码 - AI工具明显复现第三方项目代码、文档、图片或其他受保护表达,但未提供合法来源、许可证和必要权属信息的内容 - 与本项目许可证不兼容的内容 - 违反AI工具使用条款、雇主政策、保密义务,违反出口管制、数据合规要求或侵犯第三方权利的内容 - 包含商业秘密、个人信息、敏感数据、私有代码、内部文档或未公开漏洞信息的提示词、输出或贡献 - 由AI Agent自动批量提交的贡献或提交人类贡献者未实质参与的贡献 ## 6\. 贡献者责任 贡献者向社区提交AI辅助贡献时,应确认并承诺: - 已对拟提交AI辅助贡献内容进行人工审查 - 理解拟提交AI辅助贡献的技术含义、设计影响和维护成本 - 已完成对拟提交的AI辅助贡献的必要测试、构建、许可证检查和安全检查 - 已确认AI工具输出未引入与项目许可证不兼容的限制 - 已确认拟提交AI辅助贡献不包含已知的未获授权的第三方材料,或已按照本项目要求披露第三方材料、许可证、著作权声明和权属信息 - 已遵守贡献者雇主、客户、学校或所属组织关于AI工具和开源贡献的政策 - 对所提交AI辅助贡献承担与非AI辅助贡献相同的责任 ## 7\. 审查与合入规则 社区维护者可以基于以下原因要求贡献者修改、补充说明、重新提交AI辅助贡献或拒绝合入AI辅助贡献: - 贡献者未按要求披露AI辅助贡献的相关信息 - 贡献者无法解释其所提交的代码逻辑或来源 - 贡献内容与未经授权的第三方代码、文档或图片实质性相似 - 许可证、著作权或权属信息不清晰 - 未经测试、不可维护或增加安全风险的低质量AI辅助贡献 - 自动化、批量化提交影响社区正常维护秩序的低质量AI辅助贡献 - 社区维护者基于openUBMC项目风险偏好认为AI辅助贡献不适合合入 --- https://www.openubmc.cn/zh/brand/ --- # 品牌 ## 品牌使用说明 在使用openUBMC项目相关的全部品牌前,请查阅 《openUBMC标志视觉识别规范》,确保规范使用。 openUBMC网站上使用和显示的所有商标、标志皆属openUBMC社区所有,但注明属于其他方拥有的商标、标志除外。未经openUBMC社区或其他方书面许可,openUBMC网站所载的任何内容不应被视作以暗示、不反对或其他形式授予使用前述任何商标、标志的许可或权利。未经事先书面许可,任何人不得以任何方式使用openUBMC社区的名称及openUBMC社区的商标、标记,除非你使用前述名称、商标和标记是出于个人、教育和非商业目的。任何人不得在未获得第三方同意的情况下使用第三方拥有的商标和标志。 咨询联系方式 contact@openubmc.cn ## Logo 下载 Standard 下载 Monochrome 下载 Black 下载 Standard 下载 Monochrome 下载 Black 下载 ## PPT 模板下载 中文模板 下载 --- https://www.openubmc.cn/zh/brand/standard/ --- 品牌 openUBMC标志视觉识别规范 ## 标志诠释 以 “UnifiedBMC” 首字母 “U” 为核心载体,通过简洁现代的图 形语言,传递出社区开放、协作、友好的价值观。 形态寓意:U 形曲线自然勾勒出“微笑”弧线,与上方两点共同构成 一张温暖的笑脸。笑脸象征 开放协作带来的愉悦与共赢,呼应开源社 区友好、互助的文化内核 符号叙事:上方的两个圆点,形似交握的双手,直观诠释 “Unified” (联合)的品牌主张,强化社区“去中心化、人人参与” 的开源理念。 品牌理念:左侧圆点同时作为英文 “open” 的首字母 “o”,在图 形中隐性锚定“开放”属性,实现 “符号形态→品牌理念” 的精准关 联。 ## 标志形态 标准标志 图形标志与字体标志的组合是openUBMC的标准标志,代表 openUBMC提供开源的、标准的数字基础设施设备管理软件,适用 于介绍openUBMC品牌营销物料,例如平面广告、社区网站、线上 海报等,请优先使用标准版标志。在所有标志的使用中,务必确保使 用标志源文件,不得自行创造、设计、调整标志。 单独字标及图形 所有营销物料都以标准标志优先使用,根据画面整体需求,图形及文字也可以单独使用。 ## 标志网格的正确比例 标志是一个平衡的整体,使用中不得改变其形状、结构和比例。 竖版标志:设定标志图标的高度为16x,标志的宽度为23x,图形与字标距离2x, 字标高度为4x。 横版标志:设定标志图标的高度为 11x,标志图标的宽度为 9x,字标与图标的 距离 2x,字标高度为6x,字标宽度为34x。 单独图形:设定图标的高度为11x ,则图标的宽度为9x。 单独文字:设定图标的高度为6x,则图标的宽度为34x。设定图标的高度为6x,则图标的宽度为34x。 ## 标志的保护空间及最小尺寸 标志的四周设置有最小保护空间,该空间不能与其他图形元素连接。 最小尺寸的设置是为了确保标志使用过程中的品质,使其清 晰、易识别。 保护空间原则 竖版标志设定标志高度为X,竖版标志的安全距离为 1/4X。 横版标志设定标志高度为X,横版标志的安全距离为1/2X。 单独图形标志设定高度为X,则 安全距离为1/4AX。 单独文字标志设定高度为X,则安全距离为X。 最小尺寸使用原则 竖版公司标志和单色红标志的最小打印尺寸为长度 15mm, 最小数码尺寸为 50px。 横版公司标志和单色红标志的最小打印尺寸为长度 25mm, 最小数码尺寸为 100px。 最小尺寸使用原则特殊情况 最小尺寸的应用如有特殊情况,请在品牌管理系统咨询专家, 特殊情况特殊处理。 在所有标志的使用中,务必确保使用品牌管理系统的标志源 文件。不得自行创造、设计标志,如有疑问请在品牌管理系 统咨询专家。 ## 标志颜色 本页列举了openUBMC蓝标志的色彩控制,色彩模式包括: CMYK 模式、Pantone 色模式、RGB 模式、网络安全色模式。 所有视觉应用设计优先使用渐变蓝标志,在特殊情况下可以使用单色黑、反白标志。 ## 单色黑和反白标志 所有视觉应用设计优先使用克莱因蓝标志,单色黑和反白标志 是对openUBMC标志使用形式的有力补充,它适用于特定场景。 适用场景 1.适用于因材质、工艺、成本等问题不能使用品牌蓝标志的应用场景 (如周边产品、环境导视等); 2.适用于当品牌蓝标志与背景色冲突、识别不清晰时; 3.其他应用场景 ## 标志位置规范总览 严格控制标志在版面(包含印刷、数字多媒体、户外广告)中的位置 , 有助于保证标志在视觉传播中的品牌识别度。本页列举了标志在不同 应用系统(如广告系统、数字多媒体系统、展览展示系统、印刷系统 等)中各个接触点的位置。 A.标志位于版面右下角,右下角为公司标志在相关应用中 的优选位置 ( 如印刷系统中的彩页、宣传册、投标书、刊物, 广告系统中的各类纸质广告等 ); B.标志位于版面右上角(如展览喷绘应用的背景板、户外落地广告 ); C.标志位于版面左上角(如数字多媒体系统中的网站、线 上广告、Social Banner、EDM、Demo 等 ); D.标志位于版面正中心 ( 如视频、展览中的联合品牌背景板等 ); E.标志位于版面下方居中对齐(如PPT模版(特殊场景发布 / 大会演 讲,深色版等); F.标志位于版面右下角(如横版超长广告满版版面等); G.标志位于版面右侧白色区域居中对齐 ( 如横版超长广告分栏版面等 ); H.标志位于版面下方居中对齐 ( 如竖版超长广告满版版面等); I.标志位于版面下方白色区域居中对齐 ( 如竖版超长广告分栏版面等 ); J.标志位于版面右上角或上部居中 ( 如户外挂旗、易拉宝等 )。 设定公司标志图标的高度为 X,公司标志距离边栏及图片的距离为 0.5X-1.0X,当版面的尺寸变化时,X 的数值也会相应变化。 ## 主色/辅助色 品牌色彩是品牌为塑造独特的企业形象而确定的某一特定的色彩,适用在所有视觉传播接触点上,通过色彩特有的视觉刺激与心理反应,以表达企业的经营理念。 openUBMC品牌色(PANTONE 2727C ) 辅助色用于衬托和丰富品牌色的使用,表达热情、积极,使品牌形象更加统一、聚焦,更易于与公众情感连接。辅助色以暖色系和灰色系为主。 品牌色(Pantone 2727C )可用于品牌层面,产品层面,传播 层面等全部应用接触点。 --- https://www.openubmc.cn/zh/charter/ --- # 技术委员会运作规则 # 政策规则 了解openUBMC社区的运作规则、行为准则、AI贡献策略等相关内容 技术委员会运作规则社区行为准则AI贡献策略 # 社区行为准则 # AI贡献策略 --- https://www.openubmc.cn/zh/code-of-conduct/ --- # 技术委员会运作规则 # 政策规则 了解openUBMC社区的运作规则、行为准则、AI贡献策略等相关内容 技术委员会运作规则社区行为准则AI贡献策略 # 社区行为准则 openUBMC社区行为准则 ## 总则 如需举报侮辱、骚扰或其他不可接受的行为,您可以发送邮件至complain@public.openubmc.cn,联系openUBMC技术委员会处理。 ## 贡献者承诺 为建设开放友好的环境,我们贡献者和维护者承诺:不论年龄、体型、身体健全与否、民族、性征、性别认同与表征、经验水平、教育程度、社会地位、国籍、相貌、种族、信仰、性取向,我们项目和社区的参与者皆免于骚扰。 ## 行为准则 有助于创造积极环境的行为包括但不限于: - 措辞友好且包容 - 尊重不同的观点和经验 - 耐心接受有益批评 - 关注对社区最有利的事情 - 与社区其他成员友善相处 - 合规提交代码、规范使用权限、保障项目供应链和基础设施安全 参与者不应采取的行为包括但不限于: - 发布与性有关的言论或图像、不受欢迎地献殷勤 - 捣乱/煽动/造谣行为、侮辱/贬损的评论、人身及政治攻击 - 公开或私下骚扰 - 未经明确授权便发布他人的资料,如住址、电子邮箱等 - 其他有理由认定为违反职业操守的不当行为 - 植入恶意后门、污染项目依赖、损毁项目资产等危害社区安全的违规操作 ## 项目维护者义务 项目维护者有义务诠释何谓“妥当行为”,并妥善公正地纠正已发生的不当行为。 项目维护者有权利和义务去删除、编辑、拒绝违背本行为标准的评论(comments)、提交(commits)、代码、wiki 编辑、问题(issues)等贡献;项目维护者可暂时或永久地封禁任何他们认为行为不当、威胁、冒犯、有害的参与者。 ## 适用范围 本行为准则适用于本项目。当有人代表本项目或本社区时,本准则亦适用于此人所处的公共平台。 代表本项目或本社区的情形包括但不限于:使用项目的官方电子邮件、通过官方媒体账号发布消息、作为指定代表参与在线或线下活动等。 代表本项目的行为可由项目维护者进一步定义及解释。 # AI贡献策略 --- https://www.openubmc.cn/zh/compatibility/list/ --- # 兼容性列表 查看 openUBMC 支持的硬件板卡兼容性信息,涵盖网卡、xPU、RAID 卡及硬盘等部件类型,帮助您快速确认硬件适配情况 部件类型 网卡 RAID卡 硬盘 xPU 部件厂商 全部 BeiJingGuangRunTong Broadcom CMCC Emulex GuangRunTong Huawei Intel JINGSHIJI LR-LINK Mellanox Mucse Netswift Nvidia QLogic Wangxun YUSUR | 型号 | 厂商 | VID/DID | Sub VID/DID | 首次支持版本 | | --- | --- | --- | --- | --- | | SP670 | Huawei | 0x19e5/0x0222 | 0x19e5/0x00a1 | openUBMC 25.03 | | MCX631432AN-ADAB | Mellanox | 0x15b3/0x101f | 0x15b3/0x0004 | openUBMC 25.06 | | MCX631102AN-ADAT | Mellanox | 0x15b3/0x101f | 0x15b3/0x0001 | openUBMC 25.06 | | SP680 | Huawei | 0x19e5/0x0222 | 0x19e5/0x0052 | openUBMC 25.06 | | SF221Q | Huawei | 0xffff/0xffff | 0xffff/0xffff | openUBMC 25.06 | | SF223D-H | Huawei | 0xffff/0xffff | 0xffff/0xffff | openUBMC 25.06 | | SP625D | Huawei | 0x19e5/0x0222 | 0x19e5/0x01a1 | openUBMC 25.06 | | SF400HT | Netswift | 0x8088/0x0107 | 0x8088/0x0402 | openUBMC 25.06 | | SF200HT | Netswift | 0x8088/0x0105 | 0x8088/0x0202 | openUBMC 25.06 | | LPE31002-AP | Emulex | 0x10df/0xe300 | 0x10df/0xe310 | openUBMC 25.06 | 共 96 条 1 2 3 4 5 6 7 10 前往 --- https://www.openubmc.cn/zh/contact-us/ --- # Contact Us Engage with openUBMC through the following ways. ## Community Contact Got a question? Send us an email, and we'll respond within 3–5 business days. 社区活动请联系 contact@openubmc.cn 品牌合作请联系 contact@openubmc.cn 其他联系方式 discuss@openubmc.cn ## Follow Us ### Find us on social media - 微信公众号 - 社区小助手 ## Handy Materials (openUBMC 社区文档)[/zh/docs] (获取openUBMC最新版本)[/zh/download] (参与社区贡献)[/zh/contribution] --- https://www.openubmc.cn/zh/contribution/ --- # Contribution Guide ... # 总则 openUBMC是一款开源社区,完全依赖于社区提供友好的开发和协作环境。在参与社区贡献之前,请先阅读并遵守openUBMC社区行为守则。 # 贡献步骤 ## 步骤一:注册 AtomGit 账号 - openUBMC使用AtomGit作为代码托管仓:https://atomgit.com/org/openUBMC - 请参考AtomGit用户指南注册AtomGit账户,并在用户设置中设置您的主邮箱。 ## 步骤二:签署 CLA - 在参与社区贡献前,您还需要签署openUBMC社区贡献者许可协议(CLA)。 ## 步骤三:找到您感兴趣的 SIG - openUBMC社区内容按照不同的SIG来组织,以便于更好的管理和改善工作流程。openUBMC所有SIG组均是开放的,欢迎任何人来参与贡献。 ### 因此,参与社区的正确方式:首先找到您感兴趣的SIG组。 - SIG的组织信息在openUBMC的SIG中心进行查看,也可以在Community仓库中查询。每个SIG组也会有各自的例会,SIG组例会是公开的,欢迎大家随时接入收听。 - 也欢迎通过社区论坛、邮件的方式与SIG组的成员进行互动交流。 - 感兴趣的 SIG 组还未出现?新的 SIG 组等你来发起!欢迎发送申请邮件至:tc@public.openubmc.cn,邮件申请模板请参考申请流程。 ## 步骤四:开始您的贡献 社区的贡献不仅限于代码的开发,社区的每一个环节都欢迎大家进行贡献。 ### 代码类贡献 每个SIG小组都会有各自规划的issue,您可以根据自己的兴趣挑选issue并解决它。 #### 给自己分配Issue 首先在评论框内输入 **/assign**,机器人就会将问题分配给您。 每个Issue下面可能已经有参与者的交流和讨论,如果您感兴趣,也可以在评论框中发表自己的意见参与Issue讨论。 #### 提交Issue 如果您准备向社区上报Bug或者提交需求,请在openUBMC社区对应的仓库上提交Issue。若不确定问题应提交到哪个仓库,请先在社区论坛发帖咨询。 您也可以以Issue的方式,或社区论坛发起话题的方式提出自己的意见或建议。提交Issue请参考AtomGit Issue提交指南。 #### 提交Pull Request 提交Pull Request请参考openUBMC社区Pull Request提交指南。 如果一次提交的代码量较大,建议将大型的内容分解成一系列逻辑上较小的内容,分段提交便于代码审查。 如果您的 Pull Request 没有引起足够的关注,可以通过对应 SIG 的邮件列表或者论坛上发帖进行求助。 #### 检视代码 openUBMC 作为一个开放的社区,我们希望所有参与社区的人都能成为活跃的检视者。 在进行代码审查时,可以参考《The Gentle Art of Patch Review》(补丁审核的柔和艺术)这篇文章。文章中提出了一些关键的审查点,强调代码审查不仅能够帮助新贡献者更积极地参与进来,同时避免代码中出现细微的错误。在审查过程中,可以特别关注以下几个方面: - **贡献的合理性:** 首先评估贡献者提出的想法是否合理,是否符合项目的目标和需求。 - **架构的准确性:** 检查贡献的代码是否遵循了正确的架构设计,是否与现有的代码库和设计原则相一致。 - **贡献的完整性:** 评估贡献的代码是否全面,是否包含了所有必要的功能和测试,以及是否考虑到了代码的可维护性和扩展性。 ### 非代码类贡献 一个优秀的社区,不仅仅只是一些代码仓,而是拥有活跃的开发者在社区的各个角落持续的建设。非代码类的贡献包括但不限于以下的几个方式: #### 文档建设 - 在阅读openUBMC社区文档时,若发现文档问题,请通过提交issue的方式,或者社区论坛发帖的方式进行反馈。 - 有自己的见解?欢迎发表自己的文档。openUBMC社区有多种文档贡献方式,详情请参考博客贡献指南,或者通过邮件、论坛联系sig-docs小组。 #### 测试验证 - 希望加固社区的版本质量?请加入 sig-QA。 #### 其他工作 - 参与社区交流,通过社区论坛,帮助引导社区新人贡献社区,回答社区上的疑问等; - 运维社区通信工具,包括协助 SIG 组的 Maintainer 完善 SIG 主页信息、组织社区例会等; - 成为社区布道师,共同组织社区聚会,包括 Meetups、直播、社区开发者大会等; - 参与社区宣传推广与内容制作,事件/技术/课程/视频请投稿至 TC; - 参与社区基础设施建设,请加入 sig-infrastructure - 参与社区视觉设计,请联系 TC - 参与社区翻译服务,请联系 TC ## 步骤五:与社区一起成长 - 我们欢迎所有人参与 openUBMC 社区贡献,我们的目标是发展一个由贡献者组成的活跃、健康的社区。关于 Maintainer、Committer 等社区角色,请参考SIG中心。 --- https://www.openubmc.cn/zh/course/ --- # Courses Explore our curated openUBMC learning collection. (openUBMC架构概念设计介绍)[/en/course/openUBMC_architectural_conceptual_design_introduction] (openUBMC Community Updates)[/en/course/openUBMC_community_updates] (构建可信计算安全体系的设计和测试能力)[/en/course/trusted_computing_security_design_testing] (板卡管理常见问题定位指导)[/en/course/board_management_troubleshooting] (基于openUBMC的集群管理设计)[/en/course/openUBMC_cluster_management_design] (openUBMC适配 intel x86功能包经验分享)[/en/course/openUBMC_intel_x86_porting_experience] (openUBMC Agent 从缺陷定位到升级验证的全链路工作流实践)[/en/course/defect_upgrade_workflow_practice] (基于南向驱动规范的RAID卡适配实践)[/en/course/southbound_driver_spec_raid_card_porting_practice] (基于openUBMC的开发工具提升效率实践)[/en/course/openUBMC_dev_tools_efficiency_practice] 共 21 条 1 2 3 前往 --- https://www.openubmc.cn/zh/docs/ --- # 文档中心 **0**/100 9月社区文档更新清单 更新时间:2026/10/12 查看详情 暂无数据 本页内容 --- https://www.openubmc.cn/zh/docs/result/ --- # 文档中心 **0**/100 --- https://www.openubmc.cn/zh/download/ --- # 下载中心 一站式资源获取 社区发行版 由社区驱动、为社区服务的openUBMC发行版 商业发行版 基于openUBMC发布的商业发行版 下载中心社区发行版 ## 社区发行版 openUBMC社区发行页面,提供最新稳定版本、历史版本下载及版本发布说明,方便开发者快速集成和定制。 ... openUBMC 26.09 最新版本 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 26.09 | 656.74 MB | 2026/09/29 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_26.09.00.01.zip | 26.09 | 83.85 MB | 2026/09/29 | SHA256 | 立即下载 | | openUBMC-CMT_unsigned_26.09.00.01.zip | 26.09 | 83.84 MB | 2026/09/29 | SHA256 | 立即下载 | openUBMC 25.12 LTS SP3 长期支持版 维护截止时间:2026/12/31 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP3 | 280.1 MB | 2026/09/09 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.03.01.zip | 25.12 SP3 | 74.58 MB | 2026/08/31 | SHA256 | 立即下载 | openUBMC 26.06 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 26.06 | 293.75 MB | 2026/07/06 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_26.06.00.01.zip | 26.06 | 77.27 MB | 2026/06/30 | SHA256 | 立即下载 | ## 获取相关资源 (应用市场)[/zh/marketplace] (社区文档)[/zh/docs] ## 支持与服务 (常见FAQ)[/docs/zh/development/faq/general.html] (社区论坛)[https://discuss.openubmc.cn/] --- https://www.openubmc.cn/zh/download/business-releases/ --- # 下载中心 一站式资源获取 社区发行版 由社区驱动、为社区服务的openUBMC发行版 商业发行版 基于openUBMC发布的商业发行版 下载中心商业发行版 ## 商业发行版 - ### 什么是商业发行版 - 商业发行版是基于openUBMC社区版进行定制和增强的企业级解决方案。 - 它在社区版的核心功能之上,增加了企业所需的专业特性,如高级安全管理、增强运维特性、合规性认证、定制化功能以及商业技术支持服务。 - 商业发行版经过严格测试和优化,确保在复杂的企业IT环境中稳定运行,帮助客户降低运维风险,提升管理效率,满足不同行业和应用的特定需求。 - ### 商业发行版相较社区发行版有什么不同 - 商业发行版提供企业级可靠性和专业支持,适合需要高稳定性和安全性的生产环境。与社区版相比,它包含在特定机型下经过验证的增强功能、定期安全更新和及时的技术服务,帮助企业规避潜在风险。此外,商业发行版通常提供定制化选项,能够更好地适配特定硬件或业务需求。 - 选择商业发行版,意味着获得长期维护保障,让团队更专注于核心业务,而非底层技术问题 - ### 如何成为商业发行版的合作伙伴 - 我们诚邀硬件厂商、解决方案提供商及系统集成商加入我们的合作伙伴计划。成为认证合作伙伴后,您将获得openUBMC社区联合市场推广和宣传机会。我们期待与您共同打造更完善的BMC生态,为终端客户提供更优质的产品与服务。 - 如有需求,请通过邮件contact@openubmc.cn与我们联系,了解合作细节与权益,携手推动开源技术的商业应用与创新。 - ### 百敖openUBMC 25.09商业发行版 - 百敖商业发行版基于社区25.06版本开发,在基础功能之上完成了多项特性功能的开发和稳定性验证。主要新增功能包括:实时监控界面、灵活的传感器告警策略、Web SOL等,显著提升了管理效率和可操作性。在版本迭代过程中,我们持续跟踪开源社区的更新,并结合内部需求进行功能优化。发布流程严格遵循"先内测、再公开测试、最后正式发布"的步骤,确保每个版本在功能完善的同时,具备良好的稳定性和可用性。 发行厂商:南京百敖软件有限公司 发行时间:2025/9/30 更多信息 - ### 昆仑太科openUBMC商业发行版 - 昆仑太科openUBMC商业发行版(简称"昆仑BMC-U"),基于openUBMC社区25.09版本深度开发,在社区原生能力基础上,从功能增强、外设兼容、产品定制、文档完善四大核心维度进行系统性迭代优化。通过底层性能调优与上层能力拓展,昆仑BMC-U显著提升鲲鹏平台BMC产品的功能完整性与运维易用性,可为生态伙伴提供高可靠性、高效率的企业级BMC固件解决方案,充分彰显昆仑太科再BMC固件领域的技术沉淀与持续创新能力。 - 昆仑BMC-U将持续同步openUBMC社区版本节奏迭代升级,不断完善产品能力矩阵,持续保持在企业级BMC解决方案领域的核心竞争力,助力生态伙伴加速产品落地与价值提升。 发行厂商:昆仑太科(北京)技术股份有限公司 发行时间:2025年10月 更多信息 --- https://www.openubmc.cn/zh/download/community/all/ --- # 下载中心 一站式资源获取 社区发行版 由社区驱动、为社区服务的openUBMC发行版 商业发行版 基于openUBMC发布的商业发行版 下载中心社区发行版 ## 社区发行版 openUBMC社区发行页面,提供最新稳定版本、历史版本下载及版本发布说明,方便开发者快速集成和定制。 ... 版本类型 全部 长期支持版本(LTS) 创新版本 | 软件包类型 | 发行时间 | 维护截止时间 | 下载地址 | | --- | --- | --- | --- | | openUBMC 26.09 | 2026/09 | 2026/12 | 前往下载 | | openUBMC 25.12 LTS SP3 | 2026/08 | 2026/12 | 前往下载 | | openUBMC 26.06 | 2026/06 | 2026/07 | 前往下载 | | openUBMC 25.12 LTS SP2 | 2026/05 | 2026/12 | 前往下载 | | openUBMC 26.03 | 2026/03 | 2026/06 | 前往下载 | | openUBMC 25.12 LTS SP1 | 2026/02 | 2026/12 | 前往下载 | | openUBMC 25.12 LTS | 2025/12 | 2026/12 | 前往下载 | | openUBMC 25.09 | 2025/09 | 2025/12 | 前往下载 | | openUBMC 25.06 | 2025/07 | 2025/09 | 前往下载 | | openUBMC 25.03 | 2025/04 | 2025/06 | 前往下载 | ## 获取相关资源 (应用市场)[/zh/marketplace] (社区文档)[/zh/docs] ## 支持与服务 (常见FAQ)[/docs/zh/development/faq/general.html] (社区论坛)[https://discuss.openubmc.cn/] --- https://www.openubmc.cn/zh/download/community/detail/openUBMC 25.12 LTS/ --- 版本列表 重置 确定 下载 所有版本 openUBMC 25.12 LTS 版本列表 openUBMC 26.09 openUBMC 25.12 LTS SP3 openUBMC 26.06 openUBMC 25.12 LTS SP2 openUBMC 26.03 openUBMC 25.12 LTS SP1 openUBMC 25.12 LTS openUBMC 25.09 openUBMC 25.06 openUBMC 25.03 openUBMC 25.12 LTS 长期支持版 维护截止时间:2026/12/31 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 | 71.15 MB | 2025/12/31 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.00.01.zip | 25.12 | 77.58 MB | 2025/12/31 | SHA256 | 立即下载 | --- https://www.openubmc.cn/zh/download/community/detail/openUBMC 25.12 LTS SP1/ --- 版本列表 重置 确定 下载 所有版本 openUBMC 25.12 LTS SP1 版本列表 openUBMC 26.09 openUBMC 25.12 LTS SP3 openUBMC 26.06 openUBMC 25.12 LTS SP2 openUBMC 26.03 openUBMC 25.12 LTS SP1 openUBMC 25.12 LTS openUBMC 25.09 openUBMC 25.06 openUBMC 25.03 openUBMC 25.12 LTS SP1 长期支持版 维护截止时间:2026/12/31 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP1 | 75.33 MB | 2026/02/14 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.01.01.zip | 25.12 SP1 | 66.08 MB | 2026/06/29 | SHA256 | 立即下载 | --- https://www.openubmc.cn/zh/download/community/detail/openUBMC 25.12 LTS SP2/ --- 版本列表 重置 确定 下载 所有版本 openUBMC 25.12 LTS SP2 版本列表 openUBMC 26.09 openUBMC 25.12 LTS SP3 openUBMC 26.06 openUBMC 25.12 LTS SP2 openUBMC 26.03 openUBMC 25.12 LTS SP1 openUBMC 25.12 LTS openUBMC 25.09 openUBMC 25.06 openUBMC 25.03 openUBMC 25.12 LTS SP2 长期支持版 维护截止时间:2026/12/31 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP2 | 84.93 MB | 2026/06/03 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.01.01.zip | 25.12 SP2 | 66.46 MB | 2026/06/29 | SHA256 | 立即下载 | --- https://www.openubmc.cn/zh/download/community/detail/openUBMC 25.12 LTS SP3/ --- 版本列表 重置 确定 下载 所有版本 openUBMC 25.12 LTS SP3 版本列表 openUBMC 26.09 openUBMC 25.12 LTS SP3 openUBMC 26.06 openUBMC 25.12 LTS SP2 openUBMC 26.03 openUBMC 25.12 LTS SP1 openUBMC 25.12 LTS openUBMC 25.09 openUBMC 25.06 openUBMC 25.03 openUBMC 25.12 LTS SP3 长期支持版 维护截止时间:2026/12/31 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP3 | 280.1 MB | 2026/09/09 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.03.01.zip | 25.12 SP3 | 74.58 MB | 2026/08/31 | SHA256 | 立即下载 | --- https://www.openubmc.cn/zh/download/community/latest/ --- # 下载中心 一站式资源获取 社区发行版 由社区驱动、为社区服务的openUBMC发行版 商业发行版 基于openUBMC发布的商业发行版 下载中心社区发行版 ## 社区发行版 openUBMC社区发行页面,提供最新稳定版本、历史版本下载及版本发布说明,方便开发者快速集成和定制。 ... openUBMC 26.09 最新版本 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 26.09 | 656.74 MB | 2026/09/29 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_26.09.00.01.zip | 26.09 | 83.85 MB | 2026/09/29 | SHA256 | 立即下载 | | openUBMC-CMT_unsigned_26.09.00.01.zip | 26.09 | 83.84 MB | 2026/09/29 | SHA256 | 立即下载 | openUBMC 25.12 LTS SP3 长期支持版 维护截止时间:2026/12/31 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 25.12 SP3 | 280.1 MB | 2026/09/09 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_25.12.03.01.zip | 25.12 SP3 | 74.58 MB | 2026/08/31 | SHA256 | 立即下载 | openUBMC 26.06 版本说明 技术白皮书 生命周期 ### 源码 openUBMC社区发行版全量源码包,适合需要进行二次开发的开发者。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | repositories.zip | 26.06 | 293.75 MB | 2026/07/06 | SHA256 | 立即下载 | ### 固件 openUBMC社区发行版固件包,可直接在使用openUBMC社区发行版的服务器上进行更新。 | 软件包名称 | 版本 | 软件包大小 | 发行时间 | 完整性校验 | 下载地址 | | --- | --- | --- | --- | --- | --- | | openUBMC-CMT_26.06.00.01.zip | 26.06 | 77.27 MB | 2026/06/30 | SHA256 | 立即下载 | ## 获取相关资源 (应用市场)[/zh/marketplace] (社区文档)[/zh/docs] ## 支持与服务 (常见FAQ)[/docs/zh/development/faq/general.html] (社区论坛)[https://discuss.openubmc.cn/] --- https://www.openubmc.cn/zh/download/lifecycle/ --- 社区发行版 生命周期 # 生命周期 社区版本按照交付年份和月份进行版本号命名。例如,openUBMC 25.09 于 2025 年 09 月发布。 社区版本分为长期支持版本和创新版本。 • 长期支持版本:发布间隔周期定为 1 年,提供 12 个月的社区支持。社区首个 LTS 版本 25.12 计划于 25 年 12 月发布。 • 社区创新版本:openUBMC 每隔 3 个月会发布一个社区创新版本,提供 3 个月社区支持。首个创新版本已于 25 年 3 月份发布。 Maintenance Support:CVE、Bugfix,新硬件支持和少量新特性(保证 LTS 内前向兼容的情况) --- https://www.openubmc.cn/zh/events/ --- # 活动 了解openUBMC社区全年活动 活动概览 活动列表 活动活动概览 ## 2026年度规划 JAN FEB MAR Apr May JUN Jul Aug Sep Oct Nov Dec 国际开源会议 中国,深圳 华为中国合作伙伴大会2026 中国,北京 开放原子开源生态大会2026 中国,上海 华为全联接大会2026 TBD KubeCON + CloudNativeC on China TBD open Source Summit Europe 2026 TBD 2025全球计算大会 TBD 操作系统大会 & openEuler Summit 2026 TBD 开放原子开源开发者大会 生态技术会议 中国,南京 2026 鲲鹏KPN 伙伴大会 中国,北京 2026 Open AI Infra Summit 中国,北京 鲲鹏昇腾开发者大会 KADC 2026 中国,北京 2026开放计算技术大会 TBD 2026上海海思创新大会 中国,深圳 GOSIM China 2026 TBD 固件联盟大会 开发者活动 Online openUBMC 25.12 LTS版本解读直播 中国,武汉 openUBMC Meetup 武汉站 Online 1小时教你上手openUBMC开发直播 中国,长沙 高校行-国防科技大学站 中国,长沙 高校行-湖南师范大学站 中国,长沙 高校行-长沙理工大学站 中国,长沙 高校行-湖南大学站 高校 & 比赛 全年 开源实习 3月-11月 CCF开源创新大赛 8月-12月 第六届开源之夏 ## 活动申请 无论是企业、SIG 组、科研院所或其他组织,我们都欢迎与 openUBMC 社区一起组织开发这活动,共同探讨前沿技术和开源发展趋势,分享创新成果和实践经验,与 openUBMC 社区共同成长! 1 1 如何申请 申报材料 2 2 申办审核 3 3 我们可以获得哪些赋能支持? 社区部分活动资金支持 品牌物料包 (易拉宝/海报/KV等设计源文件) 社媒矩阵传播 (官网/公众号/B站/社群同步宣传) 直播资源 (可选openUBMC官方直播间资源) 社区限定周边 (按实际参与人数配发,上限100份) 4 4 活动举办 5 5 活动成果反馈 --- https://www.openubmc.cn/zh/events/detail/1hours-buildUBMC/ --- 活动列表 1hours BuildUBMC # 直播预告 | 1小时教你上手openUBMC开发已结束 本课程将带你快速认识openUBMC的项目背景与核心价值,深度解析其核心架构设计,并通过多系统环境搭建实操与OpenUBMC Studio工具上手,助你启高效开发之旅。 2026年4月15日 线上 ## 直播预告 | 1小时教你上手openUBMC开发 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/20251107shenzhen/ --- 活动列表 20251107shenzhen # 20251107shenzhen已结束 前沿技术深度解析 实战场景高效赋能,openUBMC 深圳站来啦! 2025年11月07日 9:00-16:30 南山区海天一路软件产业基地4栋B座1楼 禾木HOMEY SPACE(雅禾厅) ## 活动议程 前沿技术深度解析 实战场景高效赋能,openUBMC 深圳站来啦! - 🕒 2025年11月7日(周五) 9:00–16:30 -  📍  南山区海天一路软件产业基地4栋B座1楼 禾木HOMEY SPACE(雅禾厅) - 我要报名 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/20260814chengdu-meetup/ --- 活动列表 openUBMC Meetup 成都站 # openUBMC Meetup 成都站已结束 openUBMC 社区联合华鲲振宇打造成都专场技术 Meetup,集结社区核心专家与产业一线实战工程师,全栈输出安全体系、硬件适配、场景管理核心技术方案。 2026年8月14日(周五) 9:30-16:00 丽柏酒店(成都四河地铁站新川店)-锦绣厅 ## 活动议程 # openUBMC Meetup 成都站 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/20260922hefei-meetup/ --- 活动列表 活动议程 # 欢迎报名|openUBMC 合肥 Meetup 虚位以待,邀您共探 BMC 开源新实践已结束 本次活动由 openUBMC社区牵头,联合社区成员单位百信共同主办,是面向全体BMC技术伙伴的深度技术交流盛会。 2026年9月22日 9:30-16:00 合肥乐富强铂悦酒店三楼嘉悦厅 ## 欢迎报名|openUBMC 合肥 Meetup 虚位以待,邀您共探 BMC 开源新实践 # 活动议程 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/2026chengdu-meetup/ --- 活动列表 开源聚力蓉城,技术筑牢底座 # 议题征集 | openUBMC × 华鲲振宇 Meetup 成都站,邀您开讲!已结束 本次活动由openUBMC社区联合华鲲振宇共同主办,聚焦 BMC 技术创新、产业落地与开源生态共建,打造全产业链开发者技术交流盛会。 申报截止至 7 月 31 日 23:59 成都 ## 议题征集 | openUBMC × 华鲲振宇 Meetup 成都站,邀您开讲! # 开源聚力蓉城,技术筑牢底座 openUBMC 2026 线下 Meetup 成都站将于8 月 14 日启幕,由openUBMC社区联合华鲲振宇共同主办,聚焦 BMC 技术创新、产业落地与开源生态共建,打造全产业链开发者技术交流盛会。 现面向全体开发者开放议题征集,覆盖 BMC 开发、硬件适配、运维实战、行业落地等全方向,入选嘉宾可获社区限定纪念礼品与官方宣传曝光支持。申报截止至 7 月 31 日 23:59,详情见下方海报,扫码即可申报。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/2026hefei-meetup/ --- 活动列表 openUBMC Meetup 合肥站 # 议题征集|openUBMC Meetup 合肥站邀您分享实战经验,共建 BMC 开源生态已结束 本次活动由 openUBMC社区牵头联合社区成员单位百信共同主办,面向BMC技术伙伴打造深度技术交流盛会。 申请截止至 9 月 13 日 23:59 合肥 ## 议题征集|openUBMC Meetup 合肥站邀您分享实战经验,共建 BMC 开源生态 # openUBMC Meetup 合肥站 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/2026shenzhen-meetup/ --- 活动列表 openUBMC Meetup 深圳站 # 议题征集|openUBMC Meetup 深圳站邀您分享实战经验,共建 BMC 开源生态进行中 本次活动由 openUBMC 社区主办,旨在为 BMC 技术伙伴搭建深度技术交流平台。 申请截止至 10 月 18 日 23:59 深圳 报名 ## 议题征集|openUBMC Meetup 深圳站邀您分享实战经验,共建 BMC 开源生态 # openUBMC Meetup 深圳站 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/Upcoming Live Stream0806/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/events/detail/Upcoming Live Stream0828/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/events/detail/Upcoming-Live-Stream0806/ --- 活动列表 Upcoming Live Stream0806 # 直播预告|openUBMC南向硬件管理技术规范、实践及生态建设分享Concluded 本课程通过实践验证提升兼容性与稳定性,并推动上下游厂商共建开放生态,实现各类硬件高效接入,通过社区协同促进产业链分工协作。 2026年8月6日 线上 ## 直播预告|openUBMC南向硬件管理技术规范、实践及生态建设分享 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/events/detail/Upcoming-Live-Stream0828/ --- 活动列表 Upcoming Live Stream0828 # 直播预告|openUBMC 架构概念设计介绍Concluded 本课程面向希望系统理解服务器管理软件的开发者,围绕 openUBMC 架构的概念设计展开。从硬件、接口与产品定制等高频变化出发,帮助你建立全局架构视图,为组件开发、接口扩展和产品定制打下基础。 2026年8月28日 线上 ## 直播预告|openUBMC 架构概念设计介绍 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/events/detail/WuhanMeetup-yicheng/ --- 活动列表 议题征集!openUBMC Meetup 武汉站,与你共写新的开源记忆 # 议程公布已结束 openUBMC社区携手社区成员单位长江计算、神州鲲泰,诚邀您相聚武汉,共赴一场服务器管理技术的盛宴!全天10个精彩议题,涵盖高密存储产品化、AI服务器PCle Switch创新、x86平台适配、大模型赋能社区机器人,以及全新openUBMC Studio亮相。在这里,您将与行业专家深度交流,见证开源力量如何重塑BMC生态。相约樱花季,共探无限可能! 2026年3月20日 武汉鑫阿丹园光谷国际酒店二楼A区宴会厅 活动回顾 ## 议程公布 # 议题征集!openUBMC Meetup 武汉站,与你共写新的开源记忆 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/ccf/ --- 活动列表 Ccf # 第八届CCF开源创新大赛 | openUBMC 开源项目贡献赛重磅启幕已结束 立足数字经济深度发展与国家开源战略布局,面向人工智能、泛在操作系统领域的技术创新、成果转化与专业人才供给需求,第八届CCF开源创新大赛由中国计算机学会(CCF)主办,CCF开源发展技术委员会承办。大赛以赋能开源生态高质量发展为核心导向,通过体系化赛道设置、精准化资源对接、全流程专业化运营、打造集开源成果展示、技术交流碰撞、产学研用协同于一体的权威赛事平台。 2026年4月2日~2026年8月16日 重庆 ## 第八届CCF开源创新大赛 | openUBMC 开源项目贡献赛重磅启幕 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/chengdu-meetup/ --- 活动列表 活动报名|openUBMC Meetup 成都站 # 活动报名|openUBMC Meetup 成都站已结束 10月31日,openUBMC社区Meetup将来到成都,诚邀广大开发者线下相聚,共同探索技术落地新路径。 2025年10月31日(周五) 9:30-16:35 成都新希望武侯智选假日酒店4F一号会议室 ## 活动议程 # 活动报名|openUBMC Meetup 成都站 从理论洞察到实战演练,本次活动将为开发者提供深度的技术体验。我们将在Meetup中展示可观测技术、部件驱动、社区版本测试策略的最新进展,分享BMC构建流水线搭建实践、AI赋能测试、调速策略配置、基于组件的自定义文件定制方法等关键议题,并开展Workshop,助力开发者将技术理念转化为落地解决方案。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/gosim-hangzhou-2025/ --- 活动列表 openUBMC社区即将亮相GOSIM HANGZHOU 2025 大会,分享AI基础设施智能管理前沿实践! # openUBMC社区即将亮相GOSIM HANGZHOU 2025 大会,分享AI基础设施智能管理前沿实践! 本次议题将分享如何利用openUBMC实现AI基础设施设备管理、智能化的故障预测与自愈,从而打造高性能、高可靠的AI基础设施管理平台,推动开源技术在企业级场景的深度落地。 2025年9月13日~9月14日 杭州白金汉爵酒店 ## 活动议程 # openUBMC社区即将亮相GOSIM HANGZHOU 2025 大会,分享AI基础设施智能管理前沿实践! ## GOSIM HANGZHOU 2025 9 月 13–14 日,GOSIM HANGZHOU 2025 大会将在杭州隆重启幕。GOSIM作为一个开源社区平台,致力于为全球开源开发者提供一个协作和交流的空间。此次大会不仅是开源界的一次盛会,更是探讨未来技术趋势、共建智能基础设施的关键平台。届时,openUBMC将与全球开发者、企业代表以及技术领袖一起,深入探索开源技术在AI时代的新可能。 ## openUBMC精彩议题抢先看 随着人工智能算力需求的爆发式增长,传统设备管理方式已难以应对大规模、高复杂度的AI基础设施。openUBMC致力于通过开源开放的模式,打造下一代智能设备管理标准,提升系统的可靠性、可维护性和自动化水平。本次分享将为开发者、企业技术决策者以及AI基础设施构建者提供重要参考和实践指南。 ## 来现场,与openUBMC互动 除了精彩议题,openUBMC还将在大会展区设置展位,展示最新技术成果与实践。欢迎各位与会者前来交流,与技术团队面对面沟通,深入了解如何参与社区贡献、应用openUBMC提升自身业务系统的管理能力。 ### 大会信息 - 会议名称:GOSIM HANGZHOU 2025 - 会议时间:2025年9月13日~9月14日 - 会议地点:中国·杭州白金汉爵酒店 - 会议官网:https://hangzhou2025.gosim.org/zh/ openUBMC社区期待在GOSIM 2025与您相遇,共同推动智能设备管理技术的创新与突破! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/hangzhou-meetup/ --- 活动列表 openUBMC Hangzhou Meetup 2025 # openUBMC Hangzhou Meetup 2025 我们诚挚邀请您参与openUBMC首届线下Meetup!本次活动围绕openUBMC核心技术体系展开深度探讨,携手构建算力设备管理的开源社区。 2025年05月26日 9:00-17:00 杭州市滨江区Pagoda君亭设计酒店四楼嘉禾厅 活动回顾 ## 活动议程 # openUBMC Hangzhou Meetup 2025 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/live stream preview0717/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/events/detail/live-stream-preview0717/ --- 活动列表 Live Stream Preview0717 # 直播预告|openUBMC 社区工程实践分享:从设计方法到产品落地Concluded 本直播系列课程聚焦 openUBMC 设计方法论,系统讲解如何基于 openUBMC 构建管理方案,帮助开发者把握设计核心要点与工程实践路径。 2026年7月17日 线上 ## 直播预告|openUBMC 社区工程实践分享:从设计方法到产品落地 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/events/detail/openUBMC-LTS-live/ --- 活动列表 直播预告|openUBMC 25.12 LTS版本解读直播专场 # 直播介绍 openUBMC 25.12 LTS 正式发布!这一里程碑式的长期支持版本,将重构企业级服务器管理的智能边界。在本次直播中,我们将完整介绍 openUBMC 平台的关键特性,并深度解读 25.12 版本在部件兼容适配、运维灵活定制等方面的核心突破,揭秘如何通过开源力量,驱动数据中心迈向更高效、更稳定、更安全的未来。 2026年2月3日 线上直播 ## 直播介绍 # 直播预告|openUBMC 25.12 LTS版本解读直播专场 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/openUBMC-Open-Source-Internship/ --- 活动列表 OpenUBMC Open Source Internship # openUBMC 开源实习火热招募:实习证明&薪资等你来拿!进行中 远程参与开源项目实践,提升个人技术,有机会获得企业关注! 2026年5月9日 线上 ## openUBMC 开源实习火热招募:实习证明&薪资等你来拿! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/openatom-devloper-openubmc/ --- 活动列表 Openatom Devloper Openubmc # Openatom Devloper Openubmc已结束 开源算力设备管理软件分论坛即将启幕 | 2025 开放原子开发者大会,马上报名。 2025年11月21日 15:00-17:145 北京北人亦创国际会展中心(D+E厅) ## 活动议程 openUBMC社区联手固件产业技术创新联盟和全球计算联盟诚邀您参加2025开放原子开发者大会【开源算力设备管理软件分论坛】! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/detail/xian-meetup/ --- 活动列表 openUBMC X 昆仑太科 Meetup 西安站 # openUBMC X 昆仑太科 Meetup 西安站 8月18日,openUBMC Meetup 将来到西安,诚挚地邀请广大开发者线下相聚,用技术燃动夏日! 2025年08月18日 13:00-17:30 西安市雁塔区团结南路智选假日酒店五楼多功能会议厅 活动回顾 ## 活动议程 # openUBMC X 昆仑太科 Meetup 西安站 本次活动聚焦社区 25.06 版本的新特性,致力于帮助西北地域的开发者快速上手,让大家在技术的浪潮中紧跟步伐。我们将在Meetup中展示BMC Studio 新功能、开发板体验、可观测技术应用实践、社区软件工程能力建设等关键议题,同时针对开发者关注的领域开展对应的 Workshop。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/events/list/ --- # 活动 了解openUBMC社区全年活动 活动概览 活动列表 活动活动列表 ## 活动列表 活动状态 全部 进行中 已结束 进行中 议题征集|openUBMC Meetup 深圳站邀您分享实战经验,共建 BMC 开源生态 2026/10/30 深圳 已结束 openUBMC Meetup 合肥站 2026/09/22 合肥 已结束 议题征集|openUBMC Meetup 合肥站邀您分享实战经验,共建 BMC 开源生态 2026/09/22 合肥 已结束 直播预告|openUBMC 架构概念设计介绍 2026/08/28 线上 已结束 第八届CCF开源创新大赛 | openUBMC 开源项目贡献赛重磅启幕 2026/08/16 重庆 已结束 openUBMC Meetup 成都站 2026/08/14 成都 已结束 议题征集 | openUBMC × 华鲲振宇 Meetup 成都站,邀您开讲! 2026/08/14 成都 已结束 直播预告|openUBMC南向硬件管理技术规范、实践及生态建设分享 2026/08/06 线上 已结束 直播预告|openUBMC 社区工程实践分享:从设计方法到产品落地 2026/07/17 线上 已结束 openUBMC 开源实习火热招募:实习证明&薪资等你来拿! 2026/05/09 线上 已结束 直播预告 | 1小时教你上手openUBMC开发 2026/04/15 线上 已结束 10大硬核议题+Studio首秀!与您共赴樱花季技术盛宴 2026/03/20 武汉 共 19 条 1 2 前往 --- https://www.openubmc.cn/zh/internship/ --- # 开源实习 openUBMC 开源实习面向高校学生开放,聚焦算力设备开源管理软件开发,提供真实项目实战、资深导师专业指导与官方实习认证,全面提升开发能力与求职竞争力。 ## 实习介绍 开源实习是openUBMC携手openEuler、MindSpore等多个社区共同发起的线上实习项目,旨在鼓励在校大学生深度参与开源实践,依托真实的开源项目场景,提升自身技术实操能力、问题解决能力与开源协作素养。由openUBMC社区提供实习任务,并提供导师辅导,学生通过实习申请后,可领取任务,每完成一个任务可获得相应积分,积分累计达规定量后,可获得实习证明和实习工资。 - 本实习项目将在社区长期进行。 - 学生实习合同期限一次为6个月,合同期限结束后仍可以继续在社区领取处理任务,但无法再领取实习工资,不可重复入职实习。 盛情邀请社区各位资深开发者成为开源实习活动导师,请发送报名至活动邮箱contact@openubmc.cn 01 申请实习 02 领取任务 03 提交成果 04 工资与证书发放 ## 申请实习 01、阅读并签署活动声明。(见实习申请材料模板里) 02、完成实习测试任务 并截图至报名资料表内。 03、填写报名资料表。 在《实习申请材料模板》里仔细阅读实习报名流程,在线表单填写完毕后等待审核,组织方将以邮件反馈审核结果。组织方会根据所提交的资料对报名学生进行一定的审核筛选。审核通过后,将分配账号开始实习。 注意: openUBMC开源实习offer发放时间为:实习积分满10分后。 实习申请材料模板 ## 实习任务 - ### Interface SIG组 负责openUBMC社区接口的开发与维护 查看实习任务 - ### Hardware SIG组 负责openUBMC社区硬件的开发与维护 查看实习任务 - ### CICD SIG组 负责openUBMC社区软件工程相关的开发与维护 查看实习任务 查看全部实习任务 ## 实习薪资与证明 - ### 实习工资 - 实习有效期6个月内满10分以上,可获得不同级别的实习工资。 - 具体见以上“申请步骤4”里的工资说明。 - ### 实习证明 - 实习有效期6个月内积分满60分 - 至少找一位导师写实习评语 - 提交实习报告 满足以上3条,实习评语与实习报告经评审合格后发放实习证明。具体见以上“申请步骤4“里的证明申请说明。 - ### 优秀实习生证书 - 申请本年度内积分达到150分 - 至少找一位导师写优秀推荐评语。 满足以上条件,可向社区发邮件申请发放优秀实习生证书。联系邮箱: contact@openubmc.cn ## 实习规则FAQ 1、哪些人可以报名? 开源实习面向全国范围内年满18周岁的在校大学生招募,无专业年级限制,欢迎感兴趣的同学踊跃报名。 2、实习有效期6个月是如何计算的? 在申请实习时需签署实习劳务合同,实习有效期即劳务合同上填写的实习有效期,为6个月期限,6个月期限内未满60积分则不能获得实习证明。线上实习时间管理相对自由,可根据自身情况安排时间,可提前结束实习。 3、超过了6个月或者完成了100积分还能继续在社区做任务吗? 可以,但积分将不再用于申领证明与奖金,欢迎大家持续参与openUBMC社区贡献,共同助力开源项目建设。 --- https://www.openubmc.cn/zh/maillist/ --- # Mailing Lists Mailing lists are the core, efficient channel for all openUBMC community SIGs. Engage directly in technical reviews, shape proposals, and drive project direction with real-time updates. Subscribe to a SIG 选择订阅的SIG组 查看感兴趣的SIG组,点击"前往订阅" 填写信息 在订阅邮件页面内,填写相关个人信息,点击确认订阅 确认订阅邮件 您的邮箱将收到一封来自该SIG组的电子邮件,要求您确认订阅了邮件列表,点击确认链接完成订阅 成功订阅 当收到一封欢迎邮件,即成功订阅该SIG组邮件列表 SIG Mailing Lists | SIG Name | Description | Mailing Lists | Archive | Subscribe | | --- | --- | --- | --- | --- | 暂无数据 --- https://www.openubmc.cn/zh/news/ --- # 新闻资讯 新闻资讯是一个集行业新闻动态、社区资讯于一体的平台,旨在为用户提供最新的行业动态。 (议程公布 | 2026全球计算大会——openUBMC技术生态论坛议程全览)[/zh/news/CGC-2026-program] (CGC 2026 | openUBMC 分论坛:从标准共建到技术落地,解锁在超节点与AI新形势下 BMC 演进方向)[/zh/news/CGC-2026-teaser] (一图读懂9月社区文档更新清单)[/zh/news/202609-docs-update] (华为全联接大会 2026|openUBMC 精彩亮相,以开源底座使能产业差异化创新)[/zh/news/HUAWEI-CONNECT-2026] (openUBMC 社区 2026 年 9 月运作报告)[/zh/news/community-operation-report9] (openUBMC Meetup 合肥站圆满举办|百信联合主办,共探 BMC 开源生态实践)[/zh/news/2026hefei-meetup-review] (openUBMC 26.09 版本正式发布)[/zh/news/2609-release] (openUBMC 社区 2026 年 8 月运作报告)[/zh/news/community-operation-report8] (一图读懂8月社区文档更新清单)[/zh/news/202608-docs-update] 共 50 条 1 2 3 4 5 6 前往 --- https://www.openubmc.cn/zh/news/20250724/ --- 新闻资讯 汇聚众智,共启新程,openUBMC开源发展委员会首次会议成功召开 # 汇聚众智,共启新程,openUBMC开源发展委员会首次会议成功召开 2025/07/24 # 汇聚众智,共启新程,openUBMC开源发展委员会首次会议成功召开 2025年7月18日,openUBMC开源发展委员会试运行正式启动并在深圳召开首次线下会议。本次会议汇聚了来自互联网、运营商、整机商、IBV、部件商、标准组织等领域30余家企业的领导和技术专家,共同见证openUBMC社区发展的里程碑时刻。 会议围绕技术创新、生态共建、社区治理等核心议题展开深入探讨,为openUBMC的下一阶段的发展指明了目标和方向。 openUBMC社区开源发展委员会主席马银川先生出席会议并致辞,对openUBMC开源以来所取得的进展做出了总结,并对各成员单位的贡献表示感谢,同时欢迎各位委员就社区下一步工作献计献策,凝聚共识,共同推动社区发展。 随后,openUBMC社区技术委员会主席宋铜铃为开源发展委员会汇报最新发布的25.06版本重点技术特性与H2技术规划解读: - **25.06版本重大升级** openUBMC 25.06社区发行版作为25年第二个版本,在标准化接口完善、硬件兼容性扩展、运维能力增强及开发者体验优化方面实现突破性进展。 - **2025H2技术路线图** openUBMC社区2025年H2将进一步聚焦BMC运维特性、开发者易用性、社区基础设施等维度进行进一步优化和升级,打造具备好用易用的BMC软件和社区。同时社区技术委员会会在H2持续开展社区技术相关工作,确保社区版本和技术具备持续发展的可能性。 生态的持续繁荣,对开源社区尤为重要,生态发展组为开源发展委员会带来openUBMC社区生态发展最新进展: - **产业生态丰富度持续提升:** openUBMC社区已初步形成的全产业链生态,面向未来将进一步丰富软、硬件支持类型,适配更多场景。 - **标准与认证体系稳步推进:** openUBMC部件驱动SIG将启动《BMC南向驱动接口规范》相关建设活动,联合社区各单位与标准组织一起共同建立部件驱动标准和认证体系。 - **商业落地初具规模:** 多个社区成员单位已基于openUBMC社区发行版已交付近20个商业版本,覆盖云服务、金融、国际民生等重点行业。 - **组织运作健康高效:** openUBMC已围绕北向接口管理、南向部件管理、BMC运维特性、部件驱动等技术方向成立9个技术SIG,汇聚超过200名社区开发者,初步形成了高效协作机制。 在开放讨论环节,openUBMC开发发展委员会围绕版本发布与上下游协作、南向部件驱动标准建设、生态联合拓展与影响力构建,社区治理和运作等核心维度开展深入讨论并达成诸多共识。 最后,openUBMC社区秘书长王瑞锋对会议进行总结。他指出,本次大会的成功召开是openUBMC社区发展的重要里程碑,为社区的长期健康发展打下了坚实的基础,未来社区将以本次会议为起点,秉承共建、共享、共治的开放原则,共同推动社区长期健康发展。 ### 加入我们 社区官网:https://www.openubmc.cn 代码仓:https://gitcode.com/openUBMC 企业合作:contact@openubmc.cn 公众号:搜索"openUBMC"获取白皮书 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202510-docs-update/ --- 新闻资讯 一图读懂10月社区文档更新清单 # 一图读懂10月社区文档更新清单 2025/11/07 # 一图读懂10月社区文档更新清单 你的专属知识库又双叒叕更新了!快来看看哪些宝藏内容被点亮? 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202511-docs-update/ --- 新闻资讯 一图读懂11月社区文档更新清单 # 一图读懂11月社区文档更新清单 2025/12/04 # 一图读懂11月社区文档更新清单 快来看看文档中心11月又做了哪些更新吧! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202512-docs-update/ --- 新闻资讯 一图读懂12月社区文档更新清单 # 一图读懂12月社区文档更新清单 2026/01/08 # 一图读懂12月社区文档更新清单 快来看看文档中心12月又做了哪些更新吧! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202601-docs-update/ --- 新闻资讯 一图读懂1月社区文档更新清单 # 一图读懂1月社区文档更新清单 2026/02/04 # 一图读懂1月社区文档更新清单 快来看看文档中心1月又做了哪些更新吧! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202602-docs-update/ --- 新闻资讯 一图读懂2月社区文档更新清单 # 一图读懂2月社区文档更新清单 2026/03/05 # 一图读懂2月社区文档更新清单 快来看看文档中心2月又做了哪些更新吧! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202603-docs-update/ --- 新闻资讯 一图读懂3月社区文档更新清单 # 一图读懂3月社区文档更新清单 2026/04/03 # 一图读懂3月社区文档更新清单 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202604-docs-update/ --- 新闻资讯 一图读懂4月社区文档更新清单 # 一图读懂4月社区文档更新清单 2026/05/11 # 一图读懂4月社区文档更新清单 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202605-docs-update/ --- 新闻资讯 一图读懂5月社区文档更新清单 # 一图读懂5月社区文档更新清单 2026/06/02 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202606-docs-update/ --- 新闻资讯 一图读懂6月社区文档更新清单 # 一图读懂6月社区文档更新清单 2026/07/06 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202607-docs-update/ --- 新闻资讯 一图读懂7月社区文档更新清单 # 一图读懂7月社区文档更新清单 2026/08/06 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202608-docs-update/ --- 新闻资讯 一图读懂8月社区文档更新清单 # 一图读懂8月社区文档更新清单 2026/09/10 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/20260807news-announcement/ --- 新闻资讯 公告 | openUBMC 社区正式发布《生成式AI工具使用与开源贡献策略》 # 公告 | openUBMC 社区正式发布《生成式AI工具使用与开源贡献策略》 2026/08/07 # 公告 | openUBMC 社区正式发布《生成式AI工具使用与开源贡献策略》 * * * - 立即“阅读原文”:https://www.openubmc.cn/zh/ai-coding-assistants 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/202609-docs-update/ --- 新闻资讯 一图读懂9月社区文档更新清单 # 一图读懂9月社区文档更新清单 2026/10/12 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2026528-openUBMCnews/ --- 新闻资讯 KADC 2026现场直击:openUBMC展区全景回顾 # KADC 2026现场直击:openUBMC展区全景回顾 2026/06/01 在KADC 2026大会现场,openUBMC设置的技术展区、动手体验区(Hands-on)和海报展示区(Poster)人气高涨,通过“展示+体验+共创”的丰富形式,全方位呈现了开源算力设备管理平台的技术活力与生态进展。 * * * ## 01 技术展区:核心能力全景呈现,生态联创成果亮眼 技术展区是本次展示的核心区域,集中展示南北向开放能力与多元业务创新成果。 openUBMC依托南向自适配能力,实现硬件Day级快速适配,可兼容xPU、网卡、硬盘、单板等各类部件,大幅降低硬件集成难度;凭借北向自接入特性,支持开发者自定义 Agent 开发,可灵活搭建专属算力设备管理体系。 基于完善的南北向一体化开发能力,openUBMC 有效支撑异构协同、智能运维、智能功耗调控、固件安全升级等各类业务创新,为算力设备全生命周期高效管理提供坚实技术支撑。 展台现场展出海思 Hi3095 UBMC 开发板,打造面向服务器管理、工业、电力、能源、IoT 等多领域的专用芯片能力。Hi3095 UBMC 开发板原生适配 openUBMC,凭借扎实的硬件基础,可充分支撑各类场景下的技术开发与应用创新。 展台还集中展示了光润通、昆仑太科、南京百敖、联瑞、沐创集成电路等生态伙伴的商业实践成果,直观彰显 openUBMC 强大的硬件兼容能力与产业协同共建价值,充分体现开源生态的蓬勃生命力。 参会开发者与展区技术专家围绕落地应用场景展开深入交流: **某硬件厂商技术人员:** “希望平台进一步扩大硬件定制与兼容范围,把整机运行效果优化得更好,固件安全防护也做得更扎实。” **某软件研发工程师:** “期待平台能更好适配各类特殊部署场景,同时优化版本管理和编译环节,让使用体验更佳。” 社区持续迭代南北向开发架构与运行体系,各项优化工作始终稳步推进,本次收集的建议也将融入后续规划持续精进。 openUBMC 坚持以创新夯实技术底座,不断提升平台可靠性,全面保障各类业务平稳落地。 * * * ## 02 Hands-on实操区:沉浸式实战演练,降低开源开发门槛 实操体验区吸引众多开发者上手演练,开发者们基于 openUBMC Studio 一站式开发平台,完整体验环境部署、工程构建、硬件适配等全流程。 平台采用可视化、轻量化设计,搭配容器化部署模式,摒弃复杂操作,有效降低了 BMC 开发门槛,收获现场参与者一致认可。 现场多位开发者结合实操体验分享了感受,对产品功能、使用体验及社区服务给予高度肯定: **某企业开发者:** “openUBMC Studio 的 AI 功能十分实用,真切帮我们解放双手、提升效率。我们团队已有同事在个人 PC 上完成 openUBMC 部署,依托配套文档顺利完成全部操作,成功编译出 UBMC 固件,整体体验很不错。” “以往使用 openUBMC Studio 需依托 Linux 环境,如今适配 Windows 系统,对不熟悉 Linux 的使用者而言友好了许多。另外社区开设的 Grow Up 系列培训质量很高,希望后续可以提供培训录屏,方便大家回看学习。” **某高校开发者:** “平台新增 AI 功能是一大亮点,让开发工作更聚焦、更高效。同时也希望在学习使用的过程中,能增加阶梯式引导流程,参考游戏‘升级闯关’的模式,让上手路径更清晰。” 社区始终聚焦开发者需求,不断优化工具功能与文档内容。结合开发者们针对性的意见与建议,也为社区体验细节优化提供更多参考方向。 * * * ## 03 海报展示区:创新成果精彩纷呈,拓展多元应用思路 海报展示区集中展出 **openUBMC × 第八届 CCF 开源创新大赛** 优秀参赛作品。顺应 BMC 开放化、智能化发展趋势,openUBMC 赛道聚焦智能运维、嵌入式 AI 两大方向,吸引超过30+团队参与。 其中百信、宝德、聿宁科技 & 浙江工业大学等企业与高校开发者依托 openUBMC 的插件化架构及北向自接入能力,在本次KADC展示了创新多元思路:既有 PVE 虚拟化轻管理、SNMP 智能运维等实用成果,也有基于 Hi3095 开发板打造的轻量化 LLM、BMC 大模型智能体、端侧边缘智能系统等多种北向自定义应用,为算力设备管理的定制化与场景化创新提供了更多可能。 * * * 本次KADC大会,openUBMC以多元展区形态、实战化体验、前沿创新成果,生动诠释了“开源共建、突破边界”的平台价值。面向未来,openUBMC将继续携手开发者与产业伙伴,共同推动算力基础设施管理走向更开放、更易用、更智能的新阶段。 * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://gitcode.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2026KADC-techforum/ --- 新闻资讯 KADC 2026 openUBMC 技术分论坛圆满举办 ┃ 打破业务边界,构筑接入新范式 # KADC 2026 openUBMC 技术分论坛圆满举办 ┃ 打破业务边界,构筑接入新范式 2026/05/26 2026 年 5 月 23 日,鲲鹏昇腾开发者大会 2026(KADC 2026)openUBMC 技术分论坛在北京顺利举办。本次论坛以“打破业务边界,构筑接入新范式”为主题,汇聚产业从业者、生态合作伙伴与社区技术骨干,集中展示多场景创新应用成果,深度研讨算力基础设施管理前沿技术与行业发展方向。 * * * ## 开场致辞:梳理阶段成果,共绘发展蓝图 华为计算产品线云与计算硬件部部长任超为本次论坛进行开场致辞。 开源一年多以来,openUBMC 依托跨平台、跨领域的全产业链协同模式稳步发展。目前社区汇集 **600 余名开发者**、**36 家成员单位**,代码量突破 **300 万行**,累计发布 **7 个版本**,孵化 **90 余个商业发行版**,超百个商业项目落地智算、IDC、边缘计算等多个场景。 借助南向部件驱动规范,多家厂商自主完成驱动开发,实现 **50 余款硬件部件**标准化接入,20 余家产业链企业共同参与标准制定,产业协作体系逐步完善。任超表示,未来社区将持续联动产业链上下游深化协同共创,不断拓宽 BMC 创新应用边界,更好支撑多样化算力业务发展。 华为计算产品线云与计算硬件部部长 任超 * * * ## 技术演讲:南北能力齐落地,实战成果集中亮相 本场论坛邀请多位产业技术专家依次分享技术创新与商用实践,全方位展现 openUBMC 南北向技术成果。 openUBMC 技术委员会主席宋铜铃发表《openUBMC:打破业务边界,构筑接入新范式》主题演讲。 他谈到,随着硬件架构与算力应用持续迭代演进,传统 BMC 管理模式正面临全新应用挑战。openUBMC 积极突破固有业务边界,为此,社区在2025年推出南向部件驱动规范的基础上,正式启动北向自接入统一规范编制工作(预计2026年底发布),将从设备接入、特性定制到多领域协同,打造一套南北贯通的自接入创新方式。 借助南北标准化能力,openUBMC将拓展至算力加速、性能优化、可靠性升级、AI 应用等业务领域,适配各类定制化场景,助力行业搭建高效开放的算力设备管理体系。 openUBMC 技术委员会主席 宋铜铃 * * * 南方电网电算工程有限公司数据中心事业部经理刘运分享了《南网妙算系列高能效服务器技术创新实践》。 南网基于openUBMC 开源生态探索绿色算力建设路径,搭载智能温控调控策略优化设备散热管理,显著提升整机运行能效。通过自研智能调速算法接入openUBMC,搭建硬件层级能效管控体系,实现能耗精准监测与动态调度,切实解决数据中心能耗管控难题,助力南网高效落实节能降碳目标,为行业绿色算力规模化应用提供成熟实践范例。 南方电网电算工程有限公司数据中心事业部经理 刘运 * * * 宝德BMC研发主管邱豪分享了《Hi171X AI部署调优与openUBMC AI组件设计实践》,系统介绍了基于BMC创新AI组件的设计思路,以及在硬件算力限制下的模型优化经验。 团队依托openUBMC开源生态,已实现嵌入式领域LLM与AI Agent的初步落地,后续将持续探索与新业务场景的深度融合,为行业算力设备管理提供全新思路。 宝德 BMC 研发主管 邱豪 * * * openUBMC TC委员、河南昆仑 BMC 架构师王钦东结合实战运维场景,分享《基于 openUBMC 插件机制扩展多样化硬件固件升级设计实践》。 针对计算场景硬件多样化带来的的固件升级性能等运维难题,团队依托 openUBMC 轻量化插件技术,实现硬件总线资源高效利用与动态调度,私有协议快速适配,有效解决固件升级耗时过长等行业痛点,为多样化硬件固件高效迭代、规模化运维创新提供有力支撑。 openUBMC TC 委员、河南昆仑 BMC 架构师 王钦东 * * * openUBMC TC委员、河南昆仑 BMC 架构师王钦东结合实战运维场景,分享《基于 openUBMC 插件机制扩展多样化硬件固件升级设计实践》。 针对计算场景硬件多样化带来的的固件升级性能等运维难题,团队依托 openUBMC 轻量化插件技术,实现硬件总线资源高效利用与动态调度,私有协议快速适配,有效解决固件升级耗时过长等行业痛点,为多样化硬件固件高效迭代、规模化运维创新提供有力支撑。 openUBMC TC 委员、昆仑太科 BMC 业务主管 王亚洲 * * * openUBMC TC委员、昆仑太科BMC业务主管王亚洲分享《基于 openUBMC 的鲲鹏模组商业实践》。 针对模组商用落地技术难点,团队围绕定制化硬件适配、FRU 数据管理展开技术解读,并分享了基于北向自接入的落地案例。昆仑太科依托openUBMC北向自接入能力实现 UDP 对外通讯功能,为鲲鹏模组规模化商用、定制化运维软件自主接入积淀实践经验。 沐创固件专家 陈奎真 * * * ## 圆桌会议:南北协同,共筑算力设备智能管理新范式 分论坛最后进入圆桌研讨环节,与会嘉宾围绕“北向开放能力支撑全场景智能运维”与“南向标准化驱动异构部件协同创新”两大话题展开深入讨论。结合各自业务视角,与会嘉宾们分享了实践经验与前瞻思考,为 openUBMC 在开放架构深化、南北向生态协同及行业场景落地等方向上明确了演进共识。 随着南向驱动标准发布和北向自接入规范正式启动,openUBMC 南北向能力布局已全面铺开。 面向未来,openUBMC 的定位不再局限于传统服务器运维,而是通过持续的多维技术创新,服务于更复杂、多元的算力设备业务场景。社区将持续深化开源协作,携手产业伙伴共同构筑算力设备智能管理的新范式。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2026Wuhan-meetup-review/ --- 新闻资讯 openUBMC Meetup 武汉站顺利举办|长江计算 x 神州鲲泰首次联合主办,共促 BMC 开源生态 # openUBMC Meetup 武汉站顺利举办|长江计算 x 神州鲲泰首次联合主办,共促 BMC 开源生态 2026/03/25 # 活动回顾|openUBMC Meetup 武汉站 2026年3月20日,由 openUBMC 开源社区牵头,联合社区成员单位 **长江计算**、**神州鲲泰** 共同举办的 openUBMC Meetup 武汉站圆满落幕。本次活动汇聚了社区核心伙伴,全天呈现 **10+ 精彩议题**,从社区动态到商业实践,从前沿 AI 探索到全新开发平台解读,为现场开发者带来了一场关于 BMC 技术创新的深度交流。 ## 社区动态:openUBMC 稳步前行 活动伊始,**openUBMC TC 委员程子明**带来社区季度进展分享。openUBMC社区持续活跃,目前已发布25.12 LTS版本,26.05 LTS SP2计划于5月30日推出。技术规划方面,多算力平台管理组件已启动开发,将支持x86、RISC-V等不同架构的统一管理;HAL层设计已完成,可屏蔽不同BMC芯片的驱动差异。此外,社区正式成立AI SIG,旨在通过引入AI技术降低开发门槛,探索大语言模型在带外管理系统中的创新应用。 ## 商业实践:从高密存储到 AI 服务器的落地答卷 ### 高密存储服务器产品化实践 **长江计算BMC系统工程师华从辉**分享了高密存储机型的产品化实践。该机型支持70盘带外管理,支持双RAID卡与双型号风扇分区调速。重点介绍了三个层面的实践案例 - **存储特性层面**:面对70盘场景下硬盘信息刷新长达20+分钟的挑战,团队通过任务分离、任务分级、无效冗余优化将刷新时间压缩至8分钟; - **硬件适配层面**:针对四块15盘背板跨槽位即插即用的需求,运用openUBMC的SR公式实现了自适应盘符机制,零C零Lua开发; - **部署层面**:通过openUBMC Studio构建CSR ALL包,将多次升级、多次重启优化为一次升级、一次重启,大幅提升部署效率。 ### CPLD 升级挂死案例分析 **长江计算BMC开发工程师赵维松**深入剖析了I2C升级CPLD过程中概率性挂死的根因。在R420K项目中,由于JTAG信号线路过长只能采用I2C升级,压测时出现每4-6小时挂死一次的现象。通过分析发现,挂死源于写入失败后未擦除Flash即重试写入,违背了CPLD Flash“先擦后写”的物理特性。团队优化了异常处理机制,写入失败后全量擦除Flash并从头全量写入,重试3次,优化后连续升级测试3天以上未再出现挂死。 ### 互联网客户快速交付实践 **长江计算BMC系统工程师李小灿**分享了应对互联网客户差异化需求的交付经验。面对客户需求差异大、版本迭代紧凑、问题响应紧急三大挑战,团队形成了可复用的解决方案: - **机型配置**:利用openUBMC的CSR+硬件自发现机制,通过oem\_product组件融合多机型配置,2个HPM镜像即可支撑13个机型。 - **功能定制**:通过客户组件实现功能隔离,不同客户的定制需求独立维护,互不干扰。 - **版本管理**:采用单一主干原则+版本火车进行分支管理,重新定义版本配套性,同步社区版本迭代节奏。 - **问题定位**:依托本地化开发模式,结合代码逻辑与日志联合分析,利用社区AI助手提升问题定位效率。 ### AI 服务器 PCIe Switch 多 GPU 自发现 **神州鲲泰BMC软件高级工程师刘杰**分享了在KunTai R624 K2 4U8卡AI服务器中引入PCIe Switch板的实践。在4U8卡服务器项目中,通过PCIe Switch芯片将有限的CPU PCIe通道高效扩展为多个下行端口,实现多GPU挂载。 - **两大核心功能**: **GPU 设备自发现**: 在PCIe Switch扩展拓扑下,通过在bmc与bios的交互中新增SwitchPort字段,实现槽位号与BDF号的精准关联,自动识别并枚举所连接的GPU设备。 **线缆状态管理**: 基于openUBMC原生功能扩展,新增Switch板线缆检测模块,集成线缆连接检测与状态上报机制,实现对下行物理链路的可靠监控。 通过引入PCIe Switch,主板走线设计大幅简化,GPU卡间P2P通信延迟降低20%,千亿参数级AI模型训练迭代速度提升25%,收敛精度提升1.5%。 ## 技术创新:社区生态拓展与 AI 赋能 ### M.2 RAID 卡带外管理创新 **分百信BMC高级工程师罗昊**分享了基于Marvell芯片的M.2硬RAID卡带外管理实践。该卡采用“盘卡一体”设计,无硬盘背板,专为系统盘设计,默认RAID1。 - **次实践实现两大突破**: - 将openUBMC存储框架扩展至Marvell体系,通过推动SML开源,完成了SDK适配与存储管理库开发。 - 新增“盘卡一体”架构支持,通过灵活处理Drive与PD映射关系、虚拟RAID阵列,兼容原有层级设计。 开发周期约4个月,涉及5个组件、5种编程语言、约5000行代码,体现了openUBMC框架的可拓展性与低耦合性。 ### x86 功能适配 **百敖BMC主管 & openUBMC TC委员汪涛**介绍了Intel/AMD平台特性向openUBMC迁移的工作。重点包括: - **Intel CPU 功能适配**(远程调试)、ACD(故障诊断)、Node Manager(功率封顶)、RAS Offload(错误处理)、Seamless Update(BIOS热升级)等。 - **VGA 共享内存**:利用BMC VGA接口未使用内存空间,实现BIOS与BMC间大文件高效传输,支持系统资产信息(约10KB)与BIOS Setting(约2MB)的快速交换。 - **MMBI(内存映射 BMC 接口)**:基于eSPI总线外设通道,实现内存映射访问,带宽可达23MB/s,相对KCS的33KB/s提升两个数量级。 ### 基于 RAG + 知识图谱的社区机器人 **华为BMC研发工程师李兆天**分享了社区AI机器人的技术方案。针对社区论坛存在的人工解答效率低、信息检索难、知识治理难三大痛点,团队构建了基于大模型+知识图谱+向量数据库融合架构的知识基座和社区AI机器人: - **向量 + 图双引擎检索**:通过向量索引实现文档分片检索,通过知识图谱挖掘语义关联,实现精准召回。 - **多智能体安全审查**:对输入输出和检索内容相关性进行检查校验,保障回答可靠性。 - **数据飞轮机制**:基于用户点赞/点踩反馈,持续优化知识质量与问答效果。 未来计划引入代码上下文管理,构建代码图谱和代码索引,实现代码检索并支持复杂问题故障定位。 ## 生态工具:全新 openUBMC Studio **华为BMC研发工程师李睿宸**带来openUBMC Studio深度解读。2026年BMC Studio品牌升级为openUBMC Studio,同时带来四大升级: - **一键安装,快速开箱**:openUBMC Studio大幅简化安装步骤,提供Windows、Ubuntu的一键安装包,内置引导式配置,预装核心功能插件,10分钟完成环境初始化。 - **模型驱动开发**:规则集通过社区基础设施分发,编码阶段实时校验CSR属性类型、引用正确性,支持表达式调试与SMC命令字计算。 - **可视化 + IDE 无缝切换**:在可视化配置能力基础上新增完整IDE能力,保留社区开发者操作习惯,支持代码与可视化页面双向同步,与命令行工具共同构建完整开发流程。 - **社区基础设施高度集成**:支持一键登录社区账号,联动社区制品仓等基础设施能力,未来将继续集成社区文档、论坛等功能,实现一站式社区开发。 openUBMC Studio 集成了code-OSS内核,全面兼容vscode插件生态,包括openVSX等主流插件市场,与Claude code、Cline等主流AI插件无缝对接,后续将继续探索AI赋能openUBMC社区的更多可能。 ## 第八届 CCF 开源创新大赛:BMC 的 AI 时代机遇 **openUBMC TC委员张雨博**在本次Meetup发布了第八届CCF开源创新大赛openUBMC赛道。本赛道涵盖“AI时代智能运维创新平台”与“嵌入式芯片LLM挑战”两大方向,总奖金10万元,无论你是想探索BMC的创新边界,还是希望在嵌入式AI领域一展身手,这里都有你的舞台。欢迎扫码进群,组队参赛,赢取丰厚奖金与开源社区影响力! ## 结语 江城之约,因开源而相聚,因技术而共鸣。从社区动态到商业实践,从AI探索到工具革新,每一位分享者的真知灼见,每一位参与者的专注倾听,都让这场Meetup超越了议程本身的意义。我们相信,当来自不同厂商、不同背景的开发者坐在一起,分享踩过的坑、探索新的路,openUBMC的生态便有了生长的土壤。 下一站,我们期待在更多城市与你相遇——共同打造属于开发者的开源BMC社区,让技术的力量,因开放而更强大。 > **直播回顾链接**:https://www.chaspark.com/#/live/1249884591673499648 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2026ccf-competition-recap/ --- 新闻资讯 圆满收官|第八届 CCF 开源创新大赛 openUBMC 赛道结出创新硕果 # 圆满收官|第八届 CCF 开源创新大赛 openUBMC 赛道结出创新硕果 2026/08/29 # 圆满收官|第八届 CCF 开源创新大赛 openUBMC 赛道结出创新硕果 近日,第八届 CCF 开源创新大赛 openUBMC 赛道圆满落幕! 本次赛道聚焦 BMC 运维管理创新、大模型轻量化部署两大核心方向,紧扣 AI 算力基础设施智能化运维痛点,为广大青年开发者与产业技术团队搭建了高水平的开源创新实践平台。赛事热度高涨、覆盖面广泛,赛事共吸引 **41 所高校**、**120 支战队**、**154 人次** 踊跃参赛,学生参与占比达 **92.2%**,青年学子成为赛道创新主力军,产学研融合成效突出。赛事期间涌现出一大批创新性强、贴合产业需求、具备落地价值的优质作品,持续为算力基础设施开源生态注入鲜活的青春力量。 本次赛事不仅汇聚海量高校青年人才,更获得了算力产业链企业的深度加持。百信、宝德、华瑞数鑫等行业头部企业积极组队参赛,以真实产业场景、落地技术需求赋能开源创新,充分印证了产业端对 openUBMC 开源生态的高度认可与深耕布局。 * * * ## 获奖名单 * * * ## 佳作云集!多维度解锁运维创新新范式 > ### 赛题一:重塑 BMC:AI 时代智能运维创新平台 #### 一等奖:BMC PVE 虚拟化运维轻管理平台 作品针对虚拟化环境下 BMC 运维痛点,打造轻量化管理平台,提升资源管理效率与运维便捷性。应用场景明确,功能设计贴近实际需求,具备较好的实用价值和落地前景。 - _扫码查阅作品_ #### 二等奖 **1\. AegisBMC** 聚焦 BMC 设备全生命周期运维,围绕设备可靠性保障、安全风险管控、自动化运维升级三大方向创新突破,有效解决设备运维碎片化、人工干预多等问题,筑牢算力设备稳定运行根基。 - _扫码查阅作品_ **2\. AI Cluster Guard 智能运维方案** 基于 openUBMC 原生生态搭建一体化智能运维体系,实现硬件状态多维监测、故障智能预警、集群协同管控,全方位提升算力集群运维的智能化、精细化水平。 - _扫码查阅作品_ > ### 赛题二:嵌入式芯片的 LLM 挑战 #### 一等奖:bmc-llm-嵌入式 BMC 平台轻量化 LLM 部署 **作品亮点**:立足边缘智能运维发展趋势,创新探索轻量化大模型与嵌入式 BMC 硬件的融合落地路径,成功将 AI 智能分析、自主决策能力融入设备底层运维场景,实现传统硬件运维向智能化、智慧化运维升级,技术理念前瞻,行业借鉴意义极高。 - _扫码查阅作品_ #### 二等奖 **1\. openUBMC 本地智能运维助手** **作品亮点**:深耕本地运维场景,集成智能数据分析、设备状态研判、异常故障辅助定位等核心能力,简化运维操作流程,降低运维门槛,助力基层运维高效落地。 - _扫码查阅作品_ **2\. 基于 openUBMC 的 AI Agent 管理组件** **作品亮点**:创新性引入 AI Agent 智能编排能力,实现运维任务智能拆解、自动调度、自主执行,构建自动化、智能化的运维新模式,全面升级数据中心运维效能。 - _扫码查阅作品_ * * * ## 以赛促创,赋能开源生态长效迭代 第八届 CCF 开源创新大赛-openUBMC 赛道赛事,有效推动了 BMC 故障管控、设备可靠性优化、能效提升、智能运维等关键技术的迭代升级,为大规模、异构化、智能化数据中心的高质量发展提供了丰富的创新方案与实践案例。 未来,openUBMC 社区将持续深化校企联创发展模式,依托开源实习、开源之夏等优质开源平台,持续吸纳赛事优秀青年人才入驻社区、深耕贡献,打造「赛事创新 - 人才培育 - 成果转化 - 生态迭代」的完整闭环,持续壮大开源开发者队伍,完善算力基础设施开源生态体系。逐光开源,筑梦创新! 感谢每一支参赛战队、每一位开发者的深耕与付出。期待下一届赛事,更多青年创新力量扎根 openUBMC,持续解锁智能算力运维新可能,共筑开源算力新生态! * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://gitcode.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2026chengdu-meetup-review/ --- 新闻资讯 openUBMC Meetup 成都站圆满举办|华鲲振宇联合主办,共促 BMC 开源生态 # openUBMC Meetup 成都站圆满举办|华鲲振宇联合主办,共促 BMC 开源生态 2026/08/24 # openUBMC Meetup 成都站圆满举办|华鲲振宇联合主办,共促 BMC 开源生态 openUBMC Meetup 成都站活动现场嘉宾合影 8 月 14 日,由 openUBMC 社区与四川华鲲振宇智能科技有限责任公司联合主办、四川鲲鹏生态创新中心协办的 openUBMC Meetup 成都站圆满举办。 活动当天,openUBMC 社区多位 TC 委员、Maintainer,华为、华鲲振宇及多家社区成员单位的技术专家齐聚成都,聚焦 openUBMC 技术分享和产业实践,围绕产业落地痛点与实际研发过程中遇到的问题,重点介绍了可信计算架构方案、板卡管理常见问题定位、RAID 卡与电源适配实践,以及基于 Agent 的智能化调试流程,活动吸引线上/线下众多开发者参与深度交流。 * * * ## 十场分享,读懂 openUBMC 的技术底色 ### 01 openUBMC Community Updates openUBMC TC 委员、华鲲振宇 BMC 架构师 刘松 **亮点**:重点工作全面铺开,关键技术完成突破;“主线创新+LTS稳定”双轨并行,版本机制走向成熟;社区高速发展,成员单位、开发者数量、代码贡献量持续增长——向上生长的 openUBMC 社区,背后离不开每一位开发者的努力。 开场环节,openUBMC TC 委员、华鲲振宇 BMC 架构师刘松同步了社区的最新进展: - **社区重点工作**:运维竞争力持续提升,已完成 CPLD 无感升级技术、硬盘/网卡等关键部件带外升级、算法自接入框架等能力构建;多算力与多芯片领域实现突破,AST2600、LS1020 等 BMC 芯片及 Intel 最新代次 Birch Stream CPU 等基础能力已完成接入与交付;南向驱动规范端到端测评和认证体系搭建完成;BMC 领域 LLM、MCP、故障模式库等 AI 体系建设亦取得阶段性成果。 - **版本发布**:自 25.03 首个社区版本发布以来,社区已按季度稳定发布 25.06 版本、25.09 版本、26.03 版本、26.06 版本;LTS(长期支持)累计发布 25.12 LTS 版本、25.12 LTS SP1 版本、25.12 LTS SP2 版本三个版本,25.12 LTS SP3 版本计划于 8 月 31 日发布。 - **社区生态**:自开源以来,openUBMC 已汇聚 **35 家** 成员单位、**791 位** 开发者,社区版本下载量达 **167,171** 次,论坛累计访问量 **1.597 亿** 次,社区组建 **13 个** SIG,累计召开 **525 场** SIG 例会,Issue 与 PR 闭环率分别达到 **80.6%** 和 **96.3%**,代码贡献累计突破 **783 万行**。这些数字背后,展示的是一个持续向上生长的开源社区。 * * * ### 02 构建可信计算安全体系的设计和测试能力 华为 BMC 安全技术专家 李小川 **亮点**:将可信计算做到国际顶级认证水平,BMC 不只是「能用」,更是应对 AI 安全威胁的防护体系,具备产业出海、进入高合规门槛市场的「可信」底座。 华为 BMC 安全技术专家李小川分享了当前 AI 带来的安全威胁与挑战,他指出 AI 已渗透进攻击的全链条,使攻击效率提升 10 倍以上,漏洞挖掘和利用从数天降至数十分钟,攻击门槛降至初学者水平。而可信计算技术,可有效防范 AI 安全威胁,当前正推进“基于 BMC 可信根的 TPCM”的可信计算 3.0 方案,依托可信根硬件安全“三防”(防侧信道、故障注入、物理攻击),建立芯片级信任锚点,将信任逐级传递到整个系统,通过 BMC 启动度量,消除了业务上电过程中的不可信窗口,一套架构同时兼容 TCM/TPM/TPCM。目前鲲鹏等关键固件均通过CC EAL4+等高等级安全认证,整机通过可信计算 3.0 增强级安全认证。他还结合即将生效的 CRA《网络弹性法案》的合规要求,从可信体系和安全测试体系维度分享了 BMC 的安全实践,建议社区构建端到端的软件供应链安全保障能力,提升产业安全能力。 * * * ### 03 超节点管理设计方案探索指导 openUBMC Hardware SIG Maintainer 常德兴 **亮点**:把一线工程师踩过的坑沉淀成标准化问题排查指导方法,是社区「授人以渔」式赋能的典型体现——大幅降低开发者新板卡接入的学习成本。 openUBMC Hardware SIG Maintainer 常德兴结合 CSR 加载、PCIe 拓扑、MCTP 链路等实际场景,围绕日志信息、设备拓扑、协议通信和根因定位,系统梳理了从拓扑建立、MCTP 通道建立、设备 BDF 上报到 CSR 加载的完整排查路径,并用真实案例讲解了如何通过日志关键字快速定位 PCIe 板卡不加载、多组件对象处理时序异常、RAID 卡传感器获取异常等典型问题。他还特别提到,社区近期已尝试将 AI 辅助能力引入问题定位流程,通过让 AI 分析多源日志、给出定位结论乃至修复代码,提升了排障效率。 * * * ### 04 基于 openUBMC 的集群管理设计 华鲲振宇 BMC 高级工程师 谢海军 **亮点**:从管理一台服务器到管理整个超节点,体现的是 openUBMC 架构本身的延展性——同一套技术底座,随算力形态演进而演进。 华鲲振宇 BMC 高级工程师谢海军的分享覆盖传统集群管理方案、后冯·诺依曼架构下 BMC 体系的机遇与实践、端侧 AI 跨界多算力芯片管理三个层次。他指出,当前超节点管理本质是在单节点 BMC 基础上增加机柜、网络协同的管理方案,对 BMC 在故障、运维、能效调控等方面的能力提出了更高的要求。而后冯·诺依曼架构无中心计算的设计思路,带外管理随算力形态也会逐步向分布式部署演进。大量的对等 xPU 单元给 BMC 管理带来巨大挑战,针对这些问题,提出一个探索方向:参考「车载安全岛」的设计,通过分布式安全岛部署、Mesh 高速互联网络、逻辑节点抽象等分布式协同的方案,解决超节点/集群的状态一致性、异步体系故障判断和溯源、多 BMC 网元互联导致攻击面扩大等问题。 * * * ### 05 openUBMC 多芯片适配与组件迁移指导 百敖 BMC 研发经理 周江坤 **亮点**:新增芯片不需要「重新造轮子」,体现的是 openUBMC 作为中立开放架构的价值:帮助伙伴复用已有 BMC 资产,摆脱对单一芯片厂商技术栈的路径依赖,掌握供应链自主权。 当前芯片存在供应连续性风险,而大部分 CPU 厂商能力与特定 BMC 技术栈深度绑定,BMC 软件资产复用迁移成本高、周期长——这是许多 BMC 生态伙伴共同面对的痛点。百敖 BMC 研发经理周江坤围绕 openUBMC 多芯片适配与组件迁移展开分享,以英特尔 X86 平台组件的迁移实践为例,系统介绍了源码梳理、开源化改造、驱动适配、QEMU 仿真验证到上板验证的标准迁移流程,并提炼出「组件源码不变、新增芯片仅适配驱动层、先在 QEMU 环境验证降低试错成本、流程可复用形成模板」四大迁移原则。他透露,团队已完成英特尔平台五大核心功能包向 openUBMC 的迁移并通过 QEMU 仿真验证,下一步将开展上板联调、完善标准化驱动接口,并逐步支持更多 BMC 芯片型号,最终纳入商用版本。 * * * ### 06 openUBMC Agent:从缺陷定位到升级验证的全链路工作流实践 软通华方 BMC 研发工程师 李庆华 **亮点**:AI Agent 不再只是聊天辅助,而是真正嵌入了从问题定位到升级验证的完整工程闭环。这标志着「openUBMC + AI」从概念走向了可复现的生产力。 软通华方 BMC 研发工程师李庆华结合真实缺陷处理场景,展示了 Agent 从问题发现、现场取证、源码分析、代码修改,到构建升级和效果验证的完整工作流程,并提炼为 Case(问题受理)、Debug(取证定位)、Developer(代码修改)、Delivery(构建部署)、Fresh Verify(重新取证复验)、Closeout(闭环输出)六个阶段,由 Context Runtime 驱动任务状态流转、Target Runtime 提供设备连接能力、openubmc-kb 知识库 MCP 提供候选方案检索。以 RAID 环境资源归属丢失问题为例,Agent 创建「Case」任务档案记录环境与验收标准后,自主完成定位、改代码、构建签名与升级验证,最终实现问题闭环——BMC 重启后资源归属重新建立,全部硬盘恢复健康。他特别提到,把每一步中间状态结构化写入 Case、而非把全部会话上下文重复带入模型,这套机制在保证可追溯性的同时,显著降低了 Token 消耗。 * * * ### 07 基于南向驱动规范的 RAID 卡适配实践 华瑞数鑫高级开发工程师 王伟 **亮点**:任何一家硬件伙伴都能照着南向驱动规范把自家部件「接入」进 openUBMC,体现的正是标准化生态的开放程度和复用效率。 华瑞数鑫高级开发工程师王伟以 B261s Boot RAID 卡的适配为案例,分享了基于南向驱动规范进行硬件适配、问题定位和功能验证的实践经验。他谈到,服务器领域 RAID 卡厂商众多、通信协议与功能特性各异,若没有统一框架,每新增一款 RAID 卡都需要改动大量模块,维护成本高昂;openUBMC 的解法是通过「硬件自发现 + SML 存储管理库 + 南向驱动规范」构成的三层协作模型实现标准化适配——新硬件只需按规范开发存储管理库、注册通信回调,即可复用北向接口层与拓扑管理框架,而无需改动整体架构。 * * * ### 08 基于 openUBMC 的开发工具提升效率实践 华鲲振宇 BMC 研发工程师 曹鹭洋 **亮点**:与「减少一次不必要的重启」较真,体现的是社区对一线运维体验的持续打磨——社区重视开发者真实日常体验。 华鲲振宇 BMC 研发工程师曹鹭洋聚焦 openUBMC 开发工具和热更新能力,探讨如何通过更加灵活的更新和调试机制,减少不必要的整包升级和 BMC 重启——当前 openUBMC 已支持配置维度的热加载,但是紧急修复漏洞或调优功能时仍需刷新整包固件。他分享的探索思路是:openUBMC 的微组件架构天然支持组件独立开发、测试与发布,配合 Systemd 对组件生命周期的管理,理论上可以把升级对象从「整个 BMC」缩小到「单个组件」;团队已围绕热更新包操作资源协作接口、以及在不重启任何组件的前提下通过 hpm 包动态加载新服务等场景展开验证,探索缩短研发验证链路、减少重复操作的路径。 * * * ### 09 CRPS 电源 3+N 冗余管理在 openUBMC 落地实践 软通华方 BMC 研发工程师 任平 **亮点**:面对多样电源设计、多种协议的真实复杂硬件场景,依然能用同一套分层框架标准化纳管,是对 openUBMC 南向驱动规范工程严谨度的又一次实测。 软通华方 BMC 研发工程师任平从真实电源硬件场景出发,围绕 CRPS 电源 3+N 冗余架构,分享了从硬件拓扑识别、协议通信到 openUBMC 适配和验证的完整实践。面对 6 路 CRPS 电源、2 块电源板带来的地址冲突问题,团队通过 PCA9545 通道隔离实现同组地址复用;在协议层,基于 PMBus 1.3+ 标准并配合 CRC8 校验、失败重试机制保障通信可靠性,同时实现电源工作模式的冷冗余切换控制。他特别强调了「CSR 负责描述硬件是什么、Protocol 负责怎么读写、Monitor 负责何时采集、北向负责怎么呈现」的分层解耦原则,使新增电源型号无需侵入现有通用电源路径,并具备完善的异常自动回退能力,避免设备停留在异常状态。 * * * ### 10 openUBMC Studio AI Agent 自主 BMC 调试工作流介绍和实践分享 openUBMC AI SIG Maintainer 范信鑫 **亮点**:22 个 MCP 工具、多类专用 Agent、一键日志分析——openUBMC 把 AI 原生的开发者体验做成了可现场上手的产品。 openUBMC AI SIG Maintainer 范信鑫围绕 openUBMC Studio 与 AI Agent 的结合,介绍了如何通过 MCP(Model Context Protocol)机制,将真实 BMC、调试工具、知识库和专家能力连接起来,让 OpenCode、Codex 等主流 Coding Agent 工具具备理解 openUBMC 组件关系、MDB 领域术语的能力。目前 openUBMC Studio 已提供 22 个 BMC 远程管理 MCP 工具(覆盖连接配置、分组管理、连通检测、命令执行、文件传输、命令宏、固件升级 7 类场景)与 5 个专用调试 MCP 工具(MDB 对象查询、D-Bus 服务查询、Systemd 状态查询、日志检索、路径权限校验),并内置代码巡检、故障诊断、PR 评审三类 Agent,使通用 Agent 从简单的代码辅助进一步进入问题定位、代码分析、调试和验证等真实 BMC 研发环节。演示环节还展示了一键日志采集与可视化解析工具,能把原本分散在多组件、多协议层的原始日志转化为可交互查询的结构化视图,为后续接入 AI 智能诊断打下基础。 开发者现场体验 openUBMC Studio AI Agent 调试工作流 现场实践环节,开发者对照四项实操任务动手体验——完成一次 BMC 一键日志分析并浏览告警与板卡信息、配置 BMC 环境完成一次 HPM 包一键升级、安装 openUBMC Skills 并借助 Fault Diagnosis Agent 进行环境问题诊断、通过社区工作台启动一次 PR 的 AI 检视,对 Agent 在真实 BMC 调试场景中的实用价值表现出较高关注,并提出了进一步优化建议。 * * * ## 从技术分享走向现场交流,让真实需求持续推动社区演进 从基础能力建设,到真实场景落地,再到 AI 赋能研发,本次 Meetup 不仅展示了 openUBMC 当前的技术能力,也为企业伙伴、社区专家与开发者搭建了面对面交流的平台。而这也是 openUBMC 一直以来努力的方向——以积极开放的方式,持续将社区能力转化为可产品化的技术,将真实场景中的经验沉淀为开发者可复用能力,帮助成员单位与开发者降低开发门槛、提升交付效率,推动产品适配与业务场景加速落地。 未来,openUBMC 将携手更多成员单位、产业伙伴与开发者,持续深化技术交流、共建产业生态。 **下一站 Meetup,期待与更多开发者相聚。** * * * - 点击 _“链接”_ 即可查看直播回放:https://www.chaspark.com/#/live/1303506534771056640 * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://gitcode.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2026hefei-meetup-review/ --- 新闻资讯 openUBMC Meetup 合肥站圆满举办|百信联合主办,共探 BMC 开源生态实践 # openUBMC Meetup 合肥站圆满举办|百信联合主办,共探 BMC 开源生态实践 2026/10/08 # openUBMC Meetup 合肥站圆满举办|百信联合主办,共探 BMC 开源生态实践 openUBMC Meetup 合肥站活动现场嘉宾合影 2026 年 9 月 22 日,由 openUBMC 社区与百信信息技术有限公司联合主办的 openUBMC Meetup 合肥站圆满举办。 openUBMC 开源发展委员会委员、百信研发总经理鞠荣荣,开源发展委员会秘书长王瑞锋出席本次活动。同时,openUBMC 社区多位 TC 委员、Maintainer,以及来自百信、华瑞数鑫、华为、沐创等社区伙伴的技术专家齐聚合肥,围绕社区最新进展、北向架构设计、产品集成测试、南向部件标准与适配、板卡问题定位、硬件调试工具及 AI Agent 智能调试等议题展开深度分享,共同探讨 BMC 技术落地的关键问题与解决思路,活动吸引线上线下众多开发者参与深度交流。 * * * ## 10 场分享,直击 openUBMC 工程内核 ### 01 openUBMC Community Updates openUBMC 技术委员会委员 于飞 **亮点**:主线创新与 LTS 长期维护并行推进,算力生态、融合运维、南向规范与 AI 研发能力持续落地,社区技术与生态建设同步提速。 开场环节,openUBMC TC 委员于飞同步了社区最新进展。openUBMC 社区围绕多算力、多芯片场景,持续推进新一代 X86 平台机型及多 BMC 芯片等能力建设。易运维技术,完成网卡、RAID、NVMe 等部件的带外升级能力建设,并持续推进 CPLD 无感升级、并行升级、能效优化、安全签名,以及 event、sensor 高性能组件等重点技术方向。 26.09 版本继续在 hardware、interface、component-drivers、ai、CICD 等 SIG 推进关键能力交付;其中,ai SIG 已有 75 款 Skill 上线,并完成 MCP Server 与 LLM 技术探索验证。版本运作上,社区已形成主线版本与 LTS 长期维护版本并行的机制。 截至目前,社区已汇聚 40+ 家企业、1000+ 位开发者、成立 14 个 SIG,已召开 557 场 SIG 例会,累计 10,502 个 Issue、15,798 个 PR,Issue 闭环率达 86.95%、PR 闭环率达 95.6%;下载量 179,791 次,论坛访问量 1.842 亿次。openUBMC 已形成企业、开发者与 SIG 多方共建、高效协作、持续增长的活跃社区生态,社区规模、贡献产出与行业影响力稳步提升。 * * * ### 02 北向接口架构设计和实现方案介绍 openUBMC 技术委员会委员、interface SIG Maintainer 黄晗 **亮点**:聚焦 BMC 北向接口特点,系统讲解 openUBMC 北向架构总体设计,并深入分享以 DSL 为核心的 Redfish、WebREST、CLI、SNMP、IPMI 接口开发范式,具备灵活扩展、按需裁剪与定制能力。 本次技术分享聚焦 openUBMC 北向接口技术实践,围绕行业标准持续演进、产品形态多元、客户定制需求差异化的行业现状,系统呈现了 openUBMC 北向接口的整体设计思路与阶段成果。 项目以 “分层 + 偏序依赖”“两树分三层” 构建统一架构底座;接口映射 DSL 沉淀 60 + 关键字、12 类语句、7 类校验规则,实现主流接口全覆盖;映射引擎升级至 2.0 提效,支持灵活定制适配差异化场景。 未来团队将持续推动北向标准化建设,重点开展组件低成本适配迁移与互操作性 Profile 落地,逐步完善 OCP HW-Mgmt、DPU/NPU 管理接口、灵衢总线与硬件遥测等技术能力。 * * * ### 03 openUBMC产品化集成测试流程和常见问题分享 openUBMC QA SIG Committer 杨威 **亮点**:三重防护网、五层问题拦截,将质量保障从“版本发布前验证”前移到需求、设计、开发和集成全过程。 本议题围绕 openUBMC 产品化集成测试流程展开,从测试分析、测试设计、测试执行到测试评估,梳理了需求决策、特性开发、版本构建、集成验证与版本发布各阶段的质量活动,以及 QA、docs、release-management 等 SIG 的协同方式。 在系统设计验证环节,以 MCX4121A-ACAT 网卡兼容需求为例,从功能、性能、可靠性、兼容性等维度拆解需求并形成可执行测试点;在 SIT 环节,则覆盖性能、可服务、规格、兼容性、可靠性、安全六类系统级测试。 社区同时建设流水线工具、模块级、版本级三重防护网,通过五层拦截尽可能将问题前移,并持续向伙伴开放测试架构、策略模板、用例规范、自动化框架、QEMU 仿真、版本冒烟等测试能力,相关资产统一沉淀在 openUBMC/QA项目仓。 * * * ### 04 AI Agent 驱动的 openUBMC开发板调试:从远程上电到 RAMFS 验证 百信BMC研发工程师、 openUBMC ai SIG Maintainer 沈威 **亮点**:三个 rootfs 均损坏后,Agent 依托 13 项阶段化 Skills 和远程电源、串口等能力,完成从启动失败到 Web 重新登录的故障恢复闭环,全流程用时 1 小时 00 分 37 秒。 本议题聚焦真机调试中“Agent 能分析,但现场操作仍绕不过去”的现实问题:BMC 挂死后 SSH/Web 入口可能失效,启动阶段日志依赖串口,镜像加载需要网络与 TFTP 环境,软件重启无效时还需要重新上下电。 为此,实践提出“Skills 保存判断与方法,脚本执行动作”的思路,由 Agent 先识别当前处于串口登录、U-Boot 还是 Linux 阶段,再选择下一步 Skill,并带着执行结果继续判断。基于社区已有远程桌面能力,本次进一步沉淀 13 项 bring-up 专项 Skills(PR #141–#153),覆盖串口接入、U-Boot 临时引导、RAMFS、GPP 恢复、管理网络恢复、Redfish 就绪诊断等阶段。 实机案例完整演示“三槽 rootfs 损坏→普通启动失败→RAMFS 装载→重新部署→eMMC 冷启动→Web 登录成功”的恢复与验收过程,并将可复用的方法继续贡献回社区。 * * * ### 05 基于CSR2.0的自发现机制技术分享 openUBMC 技术委员会委员 于飞 **亮点**:为“管理面驱动”建立统一标准,推动部件差异在驱动层完成收敛与消化,让上层 BMC 应用免于反复侵入式改造。 本议题从部件“业务系统侧驱动”已经形成成熟标准,而带外“管理面驱动”长期缺少统一规范的行业现状出发,介绍 openUBMC 南向部件标准化思路。 通过统一部件抽象接口屏蔽硬件差异,采用必选/可选接口分层兼顾标准能力与差异化竞争力,并结合 CSR 自描述、自发现等机制完成部件识别、加载与管理,目标是实现标准部件接入时 BMC 应用层免修改。社区已围绕网卡、xPU、硬盘、RAID 卡等重点部件建立测评与认证体系,形成 L1-L4 分级认证,并持续完善测试工具、用例、兼容性清单与认证流程。 component-drivers SIG 汇聚整机厂商、部件厂商及相关技术伙伴,围绕驱动规范、开发框架、认证体系和生态扩展持续演进,推动南向部件驱动从单点适配走向可复用的标准化能力。 * * * ### 06 板卡管理常见问题定位指导 openUBMC hardware SIG Maintainer 黄雷生 **亮点**:从 CSR 加载到 MCTP 建链,再到北向显示、RAID 卡降速和 NCSI 网卡联动复位,将复杂板卡问题拆解成可复用的分层排查路径。 本议题以“板卡管理常见问题定位”为主线,围绕“拓扑建立→丝印文件生成→带内 BIOS 上报 BDF→读取四元组→匹配并加载 CSR”梳理关键排查点,并通过“环境缺少 PSR,导致拓扑建立失败、丝印文件无法生成”的案例说明PCIe建链问题定位方法。 MCTP 部分介绍 Prepare for Endpoint Discovery、Endpoint Discovery、EID 分配、路由注册等建链阶段,以及从路由、Endpoint、链路报文逐层排查的思路。 随后又结合 Redfish 查询字段概率性为空的时序问题、RAID 卡速率概率跳变、KVM强制下电触发NCSI网卡联动复位等案例,展示如何结合资源协作接口、日志、CSR配置与代码逐层收敛问题,并给出 PCIe 拓扑、MCTP、CSR 配置以及 DMTF 协议等资料入口。 * * * ### 07 基于服务器南向标准的网卡部件驱动自接入实践 沐创固件专家 陈奎真 **亮点**:从 CSR 配置到 NCSI over MCTP 调试,完整走通网卡部件基于 openUBMC 南向标准自接入的工程路径。 本议题介绍了沐创网卡接入 openUBMC 的实践背景,并总结部件厂商在固件开发中面临的共性挑战:不同整机 BMC 软件栈存在差异、管理协议要求不统一、全量学习成本高,以及缺少自主调试手段等。 以实际网卡为例,按照“CSR 准备→服务器硬件拓扑与 SMBus 参数配置→私有协议命令实现→NCSI over MCTP 命令实现→编译集成→协议调试”的路径完成驱动接入,并结合 BMC 侧与网卡固件侧日志定位 MCTP/NCSI 通信问题。 实践体现了南向驱动规范的价值:通过统一接口要求、独立代码模块和社区化发布机制,部件厂商可以更早参与开发、验证和问题定位,降低对具体整机软件栈的依赖,并推动更多硬件厂商参与 component-drivers SIG 共建。 * * * ### 08 openUBMC I2C与Hisport总线调试工具的设计与应用 百信 BMC 高级工程师 、openUBMC ai SIG Committer 罗昊 **亮点**:把设备探测和读写验证前置,用一套工具先确认“总线在哪里、设备在不在、链路通不通”,再进入 CSR 与正式代码开发。 本议题针对 openUBMC 硬件调试中往往需要先配置 CSR、编写调用代码并完成构建部署,才能验证设备在位与读写的痛点,介绍了 bus\_tools 总线调试工具集。 工具覆盖 I2C 与 Hisport 两类总线,提供 i2cdetect、hisportdetect、busdetect 以及 i2ctransfer、hisporttransfer、bustransfer 六个命令,可完成总线枚举、地址扫描、多级 mux 探测、设备读写和组合事务验证。六个命令共享一套公共内核,并通过 lease、共享锁、重试机制、mux 初值保存与恢复等设计保证使用过程的可靠性。 现场案例包括通过插卡前后拓扑差异定位 PCIe 插卡归属设备、读取 RAID 卡 DDR 温度、获取 GPU 功耗等。工具的定位十分明确:提供正式开发前的快速调试与验证入口,而最终产品能力仍由 CSR 和正式代码交付。 * * * ### 09 基于南向驱动规范开发实践的技术分享 华瑞数鑫高级开发工程师 郭晟果 **亮点**:“一套框架,多厂商扩展”,以四款国产 RAID 卡真实适配为样本,沉淀从硬件识别、厂商库接入到系统验证的标准化方法。 本议题以 D3100s、D4100t、H3130s、B261s 四款 RAID 卡接入 openUBMC 为背景,系统拆解南向三层协作模型:VPD 负责硬件拓扑描述,PCIe Device 负责 BDF 与设备识别,Storage 负责控制器、物理盘和逻辑盘管理,形成“VPD 找得到→PCIe Device 认得出→Storage 管得了”的验证逻辑。 实战中,B261s 通过新增厂商自研 SML 库路径完成接入,其他卡型则基于既有框架复用和扩展;针对无背板 Boot RAID 场景,还设计了软件虚拟盘位点灯,并通过独立 I2C 读接口、厂商通道隔离和传感器告警配置化等方式处理差异化能力。 最终将实践归纳为硬件信息收集、VPD 拓扑配置、PCIe 设备识别验证、SML 厂商库开发、适配层集成、业务策略适配与测试六步标准化流程。 * * * ### 10 openUBMC Studio AI Agent 自主BMC调试工作流介绍和实践分享 openUBMC ai SIG Maintainer 李兆天 **亮点**:openUBMC Studio 将领域知识、真实 BMC 环境与专业调试MCP工具统一纳入 Agent Harness,让 AI 从“能执行命令”进一步走向安全、可追溯、可复用的 BMC 自主调试闭环。 本议题分享围绕通用 Agent 在 openUBMC 调试中存在领域上下文不足、环境连接反复、专用工具与知识缺失、定位过程难以稳定收敛等问题,介绍了基于 openUBMC Studio 构建的 AI Agent 自主 BMC 调试工作流:通过 MCP 统一连接和管理真实 BMC 环境,提供 SSH/Telnet、MDB、D-Bus、Systemd、日志查询及固件升级等场景化能力,并结合 RAG 知识库与 Skills 沉淀 openUBMC 专家知识经验;在实际故障案例中,Agent 从问题描述出发,自主完成在线观测、证据收集和根因定位,并进一步衔接修复方案、整包构建、固件升级与测试验证,在受控只读和关键操作审批机制下实现从问题定位到修复验证的完整闭环。 现场实践环节,开发者围绕四项实操任务动手体验:一是完成 BMC 一键日志分析,查看告警与板卡信息;二是使用 BMC 环境管理,配置 BMC 环境及常用命令;三是完成 HPM 包一键升级,安装 openUBMC Skills,并借助 Fault Diagnosis Agent 诊断环境问题;四是使用社区工作台,启动一个 PR 的 AI 检视。开发者对 Agent 在真实 BMC 调试场景中的实用价值给予高度关注,并提出了进一步优化建议。 开发者现场体验 openUBMC Studio AI Agent 调试工作流 * * * ## 从技术分享到深度共创 ——openUBMC Meetup 覆盖工程全周期落地 从北向架构标准化体系建设,到产品测试验证与南向部件生态共建,再到板卡故障定位、硬件调试工具体系与 AI 原生研发实践,本次 Meetup 完整串联起 openUBMC 从「架构与标准」到「开发、适配、测试、排障、运维」的全周期工程链路,为整机厂商、部件厂商、社区技术专家与广大开发者搭建了面对面交流的深度协作平台。这也正是 openUBMC 社区持续深耕的方向:以开放协作模式推动社区技术能力向产品化落地转化,将真实工程经验沉淀为全行业开发者可复用的公共技术资产。 未来,openUBMC 将携手更多成员单位、产业伙伴与开发者,持续完善架构、标准、测试与工具体系,推动更多部件、产品和真实业务场景在社区中完成共建与验证,共同建设开放、协同、可持续演进的 BMC 开源生态。 下一站 Meetup,期待与更多开发者相聚。 * * * **活动相关直播回放将陆续同步至 openUBMC 视频号,欢迎持续关注。** 扫码关注openUBMC视频号 * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://atomgit.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2503-release/ --- 新闻资讯 openUBMC 25.03 版本发布:开启开源新旅程 # openUBMC 25.03 版本发布:开启开源新旅程 2025/05/08 # openUBMC 25.03 版本发布:开启开源新旅程 在开源的浪潮中,openUBMC 项目一直致力于为用户提供更优质、更灵活的 BMC(基板管理控制器)解决方案。openUBMC 25.03 版本正式上线啦!作为今年的首个版本,它带着诸多亮点与创新,为openUBMC 领域注入了新的活力。 ## 版本概览:开源与自由 openUBMC 25.03 采用木兰宽松许可证 2.0,用户可自由复制、使用、修改和分发,无论是个人开发者还是企业用户,都能在合法合规的前提下,根据自身需求进行定制和优化。 ## 版本特性:全面升级 ### 北向接口生态 - 安全升级:安全框架升级,支持密码策略定制化配置,实现用户名规则自定义,新增证书管理基础模块。 - 运维优化:配置导入/导出标准化,出厂重置保留用户数据,重构 MCU/VRD 升级架构,支持 hpm 标准化升级包格式。 ### 南向部件扩展 - 管理增强:增强管理能力,支持调速策略,可加载多 SML 库。 - 部件适配:新增支持 SP322D/SP323D 网卡,支持 NVMe-MI v7 协议 linkspeed 查询。 ### 开发体验优化 - 工具增强:bingo 支持本地调试和模型检查,BMC Studio 发布至社区。 - 功能拓展:支持 CSR 配置检查和全模型检查。 ## 下载体验 下载链接:https://openubmc.cn/zh/download 详细版本发布说明,请阅: https://openubmc.cn/zh/version/25.03 ## 源代码发布:共享与协作 25.03 版本源代码已发布至社区网站,开源的力量在于共享与协作,我们期待更多开发者加入,共同推动 openUBMC 的发展。 仓库链接:https://gitcode.com/openUBMC ## 致谢 感谢所有参与 openUBMC 项目的社区开发者,是你们的智慧和努力,让这个版本得以顺利发布。希望未来有更多伙伴加入我们,共创开源美好未来! 开源之路,我们一起前行! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2506-release/ --- 新闻资讯 openUBMC 25.06 版本发布 # openUBMC 25.06 版本发布 2025/07/07 # openUBMC 25.06 版本发布 🥳感谢所有参与25.06版本贡献的开发者,openUBMC 25.06如期而至! ✅ Issue解决 1272 ✅ PR合入 1582 ✅ 新增代码行 334K ✅ 由来自多家组织的179名贡献者共同完成 ## openUBMC 25.06版本关键特性 ### Hardware SIG 🔥 网卡NCSI边带管理功能补齐 🔥 NVME-MI协议命令字实现增强 🔥 硬盘SMART信息获取能力增强 🔥 Raid卡管理支持多协议库并行加载 🔥 风扇手动/自动模式切换和持久化设置切换 🆕 提供电源效率曲线接口,可用于动态切换电源模式 🆕 支持多类型部件并行升级能力 🆕 支持BF2、BF3网卡、9540-8i、9560-8i、9440-8i、SP686C-M 16i 4G raid卡等部件管理能力 ### Interface SIG 🔥 部分Redfish 1.20标准接口补齐 🆕 新增Observability组件,用于观测BMC运行数据,提升问题调试和定位效率 🆕 新增libirc组件,提供远程客户端通讯库,便于二次开发远程客户端 🐞 webui部分bug修复,kvm能力增强 ### bmc\_core SIG 🔥 部分IPMI Sensor规范补齐 🔥 加强电子标签、上下电策略定制能力 🐞 sensor组件bug修复,可定位性增强 ### CICD SIG 🔥 优化BMC Studio硬件适配界面,提供更直观的配置界面 🔥 BMC Studio CSR检查能力增强 🆕 Qemu支持天池组件仿真能力 🐞 修复bingo构建若干问题,并支持apt、pip安装 🆕 bingo支持对hpm包进行cms签名能力 ### 资源获取 DownLoad:https://www.openubmc.cn/zh/download 版本说明:https://www.openubmc.cn/zh/version/latest 应用市场:https://www.openubmc.cn/zh/marketplace 安装文档:https://www.openubmc.cn/zh/docs 感谢每一位开发者的付出!正是你们的贡献,让 openUBMC 不断进步。欢迎持续关注我们,更期待您的加入,一起推动社区繁荣! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2509-release/ --- 新闻资讯 openUBMC 25.09 版本发布 # openUBMC 25.09 版本发布 2025/09/30 🥳感谢所有参与25.09版本贡献的开发者,openUBMC 25.09如期而至! ✅ Issue解决 1313 ✅ PR合入 1923 ✅ 新增代码行 565K ✅ 由来自17家组织的开发者共同完成 ## openUBMC 25.09版本特性 ### Security SIG 🆕 支持禁用历史密码、失败锁定次数配置、登录失败锁定时间配置、超长密码支持等策略配置 🆕 支持WEB SSO单点登录、IPMI通道权限配置、前端敏感信息加密 ### Interface SIG 🆕 支持Zabbix、Ansible、Cmdlets、Nagios网管openUBMC插件 🚀 Redfish Manager、Processor、SEL、NTP、时区等资源管理接口补齐 🆕 新增支持User access/Password、User Name、DCMI Power等标准命令 🚀 支持单HPM包多个固件场景升级、BMC升级异常时自恢复 🚀 支持VRM和NPU升级过程中禁止主机上电 ### Hardware SIG 🆕 支持I3C/CAN-FD能力、Ncsi Over Mctp over I2C/SMBUS协议获取网卡信息 🆕 支持Emulex的pldm OEM协议 🆕 新增标卡和OCP网卡,包括E810XXVDA2G1P5、E810CQDA2G2P5、MCX755106AS-HEAT等支持 🆕 新增RAID卡(SP686C-M系列)、硬盘、NVMe盘(SamSung PM9D3A、Memblaze PBlaze7、Solidigm D7-PS1010等)支持 🆕 新增GPU(A6000)、NPU模组等部件支持 🆕 新增TPSU/PSU管理能力,包括TPSU模块信息查询、 Turbo电容管理、双CAN电源线路主备切换、功耗封顶、功率监控、输出限功率点配置 🚀 支持VRM/电源等关键部件临终遗言持久化 🚀 支持BIOS固件导出、关键部件固件升级 🚀 支持网卡Flash recovery故障检测、光模块关键信息记录和闪断检测 🚀 支持高速链路检测、CPU与外围器件链路异常告警 ### Component Driver SIG 🆕 新增设备驱动管理框架,支持部件适配驱动化管理 🚀 支持AWM M11P、SP670、RP1000P2SFP-A03部件驱动化 ### CICD SIG 🚀 增强QEMU仿真能力,支持SMBus、MCTP等复杂协议仿真、MCU、PCIe、IMU等器件仿真 🚀 QEMU冒烟测试性能优化、支持依赖驱动同步OS版本更新 🆕 完成Conan2.0中心仓能力构建、支持Profile配置和并行构建 🚀 Bingo支持基于gtest的开发者测试、DT测试质量加固、门禁模型检查能力增强 🆕 新增I2C扫描和读写工具、支持度量采集和可观测跟踪可配置 ### Docs SIG 🆕 新增SNMP接口映射器、TRAP告警、装备定制、CLI映射器等配置指导文档 🚀 更新BMC Studio用户指南、联机帮助页面扩展 ### Infra SIG 🆕 新增社区贡献看板,支持查询个人贡献、签署CLA公司贡献、SIG贡献排行等统计信息 🆕 社区支持周期性会议创建,会议录制能力增强,支持语音转文字、录屏等功能 ### 资源获取 DownLoad:https://www.openubmc.cn/zh/download 版本说明:https://www.openubmc.cn/zh/version/latest 应用市场:https://www.openubmc.cn/zh/marketplace 安装文档:https://www.openubmc.cn/zh/docs 感谢每一位开发者的付出!正是你们的贡献,让 openUBMC 不断进步。欢迎持续关注我们,更期待您的加入,一起推动社区繁荣! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2512-SP3-release/ --- 新闻资讯 openUBMC 25.12 LTS SP3 版本正式发布 # openUBMC 25.12 LTS SP3 版本正式发布 2026/09/03 ## openUBMC 25.12 LTS SP3 版本正式发布 🥳 感谢所有为25.12 LTS SP3 版本做出贡献的开发者! ✅ Issue修复 68 个 ✅ PR合入 90 条 ## openUBMC 25.12 LTS SP3版本特性交付范围包括: - ### component-drivers SIG 🆕 新增182X新代次SP566(2\*200G)网卡兼容性 🆕 新增MCX653105A-HDAT/MCX755106AS-HEAT网卡兼容性 🆕 新增沐创N10G-X2-DC/N20G-R2F-25G网卡兼容性 🆕 新增光润通F1002T-V3.0网卡兼容性 🆕 新增Intel X550网卡兼容性 🆕 新增博通BCM957416A4160C网卡兼容性 🆕 新增星云智联S1055AS-A00CHT(2\*25G)网卡兼容性 🚀 优化SP686C RAID卡固件日志收集机制和日志可读性 - ### hardware SIG 🆕 新增HKEP810401T9000N/HKEP820501T9000N/HKEP910401T6000N/HKEP920501T6000N、德明利TS3160、紫光闪芯、佰维、英韧、长江存储等10+款硬盘兼容性 🆕 新增900W电源、EXP 12盘背板部件兼容性 🚀 优化扩展板CPLD localbus链路异常检测机制 🚀 优化BIOS固件和TEE固件生效机制 - ### 缺陷修复 🆕 修复SP686C RAID设置启动盘及适配SATA SSD显示、RAID卡通信失败、日志冗余记录等60+问题 ## 资源获取 DownLoad:https://www.openubmc.cn/zh/download 版本说明:https://www.openubmc.cn/zh/version/25-12-LTS-SP3 应用市场:https://www.openubmc.cn/zh/marketplace 技术白皮书:https://www.openubmc.cn/zh/whitepaper ## 欢迎关注openUBMC ❤️ 从开发体验优化到稳定性深度加固,每一次都凝聚着社区的力量。是你们的持续投入,让开源力量在算力基础设施领域走得更稳、更远。 - 社区官网:https://www.openubmc.cn - 代码仓地址:https://gitcode.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2512-release/ --- 新闻资讯 openUBMC 25.12 LTS 版本发布 # openUBMC 25.12 LTS 版本发布 2025/12/31 🥳感谢所有参与25.12 LTS版本贡献的开发者,openUBMC 25.12 LTS如期而至! ✅ Issue解决 1586 ✅ PR合入 1984 ✅ 新增代码行 1327K ✅ 由来自19家组织的开发者共同完成 ## openUBMC 25.12版本特性 ### Security SIG 🆕 新增用户锁定事件上报功能 🚀 用户删除功能优化,登录用户和最后一个用户不可删除 🆕 新增SPDM认证原子能力,支持可信部件的接入与度量 🚀 会话和认证能力增强,支持差异化定制和修改 🚀 安全管理模块遥测能力增强 ### Interface SIG 🆕 新增PowerEquipment、Pumps、Circuit、StorageController、Transceivers等标准接口能力 🚀 PCIeDevice、PCIeFunction、StorageController、StorageControllerMetrics、NetworkAdapter等资源管理接口更新 🆕 新增DCMI的GetDcmiCapabilitiesInfo、GetAssetTag、SetAssetTag、GetThermalLimit等标准命令 🚀 AccountService、CertificateService、Chassis等北向接口DT能力增强 ### Hardware SIG 🆕 新增标卡和OCP网卡,包括FF5025、LRES3023PT、LRES3012PFP、BCM957608-P2200GQF00 、MCX623436AN-CDAB等兼容性 🚀 新增硬盘(DAPUSTOR R6301、R6101;SE005-1920GB-H、PETAIO P6118Z252153、LONGSYS RSYE3836N-480G等)兼容性 🆕 新增GPU(MXC500)等部件兼容性 🚀 TPSU/PSU管理能力增强:TPSU黑匣子收集方案优化;TPSU电容寿命预测和预警;TPSU电容信息记录;PSU故障检测能力增强 🚀 RAID卡定制能力增强:多RAID场景I2C链路性能优化;RAID卡协议扩展能力增强 🆕 新增电源,包括PSIP双子星、EB1000电源等兼容性;模组VRM管理 ### bmc-core SIG 🚀 完善上电锁/下电锁机制 🆕 传感器、FRU等基础代码生成能力增强 ### Component Driver SIG 🆕 支持L40、L20、MTT S4000、瀚博DC1000、TESLA T4等部件驱动化 🚀 规范网卡南向驱动接口,提升扩展性 ### CICD SIG 🚀 QEMU仿真能力增强,支持网卡、RAID卡、硬盘、GPU等70+部件仿真 🚀 构建能力优化,构建归一化: 实现了组件、产品及自定义命令的构建流程统一;新增hpm\_signer签名工具及签名中心基础能力,支持发布包在线签名等 🚀 构建依赖与环境治理,发布集成开发环境 Docker 镜像;优化Manifest结构,支持组件版本重定义及产品级配置(如 NTP、BIOS 默认项)的灵活定制 🆕 新增hisport扫描工具 ### Docs SIG 🆕 新增RAID卡解耦、在线调试、182x 管理等核心特性的设计说明书 🚀 温度曲线、健康状态等新特性的用户使用资料更新 🚀 发布Qemu、Bingo、BMC Studio 等工具的常见FAQ 🚀 更新Docker开箱即用指南与签名包制作指导 ### Infra SIG 🚀 CI/CD 流水线优化,落地PR门禁自动识别与拦截机制;支持基于资源协作接口的组件打桩测试集成 🆕 优化客户体验,支持Excel文件在openUBMC社区直接展示;完善社区需求评审与管控流程 🆕 提供整包构建task.log的归档下载,便利问题排查 ### QA SIG 🆕 建立组件IT测试门禁(以 network\_adapter 为试点) 🆕 设计并落地固件联盟认证测试用例 🆕 提升devmon/libmcpp 等核心组件的自动化测试覆盖率 ### 资源获取 DownLoad:https://www.openubmc.cn/zh/download 版本说明:https://www.openubmc.cn/zh/version/latest 应用市场:https://www.openubmc.cn/zh/marketplace 安装文档:https://www.openubmc.cn/zh/docs 感谢每一位开发者的付出!正是你们的贡献,让 openUBMC 不断进步。欢迎持续关注我们,更期待您的加入,一起推动社区繁荣! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2603-release/ --- 新闻资讯 openUBMC 26.03 版本发布 # openUBMC 26.03 版本发布 2026/04/02 # openUBMC 26.03版本特性 ## Hardware SIG 🆕 新增920L模组、182X新代次标卡和OCP网卡及光模块、MCX75310AAS-NEAT网卡、网讯FF5025网卡、9500-16i/8i等兼容性 🆕 新增RS485获取温度和湿度 🆕 新增硬盘、风扇、扩展板、硬盘背板和基础板更换记录信息 🚀 NVMe硬盘故障预测特性增强 🚀 光模块故障检测能力增强,包含标卡和昇腾卡故障采集能力增强 🚀 Bluefield DPU功能优化 🆕 新增BOX管理功能:Retimer、故障检测 🆕 支持SP686C-M-16i/40i、持SP686C-MH-32i等RAID卡固件及其管理硬盘带外升级 🆕 能效管理配置能力增强:分区调速、精细化配置、PID参数等 ## Component Driver SIG 🆕 新增182X新代次标卡和OCP网卡及光模块、光润通(GRT)驱动开发 🚀 驱动框架优化:支持DBUS和共享内存调用、组件schema加载和管理、自描述记录解析和处理、复杂属性语法等 🆕 新增南向网卡兼容性工具 ## Interface SIG 🆕 支持根据机型WEB接口灵活组合 🚀 光模块性能数据采集接口优化 🚀 基于Validator扫描通用问题标准化 🚀 ComputerSystem、PCIeSlots、Memory等北向接口标准接口能力增强 🆕 新增特性北向接口能力:RAID卡慢盘、固件升级暂存、dump BIOS Flash、DICE、大包升级、多系统等 ## CICD SIG 🆕 openUBMC Studio全新升级,新增IDE能力,CSR辅助开发功能等 🚀 QEMU仿真能力增强:博通RAID卡 🚀 新增基于lockfile的产品级构建 🆕 新增子系统切面配置汇总机制 🚀 QEMU版本升级到8.2.10 ## Docs SIG 🆕 新增compute、libsoc\_adapter、ipmi\_core、bmc\_network等组件接口文档 🆕 新增风扇板和风扇适配指导文档 ## bmc-core SIG 🆕 新增FRU电子标签加工时间扩展 🆕 新增传感器事件多主机场景能力 🆕 新增IPMI硬盘信息获取功能 ## Infra SIG 🆕 社区基础设施软件开发生命周期治理与安全规范V1.0发布 🆕 新增LTS版本每日构建功能 🆕 新增社区包签名基础能力 ## Security SIG 🆕 支持板间通信会话管理 🆕 支持基于基于SessionID会话固定超时时间检测 ## QA SIG 🚀 测试平台集成QEMU版本升级到8.2.10 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2606-release/ --- 新闻资讯 openUBMC 26.06 版本正式发布 # openUBMC 26.06 版本正式发布 2026/07/02 ## openUBMC 26.06版本如期而至 🥳 感谢所有为26.06 版本做出贡献的开发者! ✅ Issue解决 2137 个 ✅ PR合入 3397 条 ✅ 新增代码行 1849k ✅ 由来自 22 家组织 104 位开发者共同完成 ## openUBMC 26.06版本特性 ### CICD SIG 🆕 Studio支持社区RAG集成,为主流Coding Agent提供MCP能力 🆕 Studio集成社区多款开发插件,支持一键日志可视化,社区skills部署,社区工作台等功能 🆕 Studio支持金样CSR、部件驱动模板一键生成,快速完成定制化诉求 🆕 大模型接入社区,新增AI代码检视和接口规范自动检查等能力,提升社区交付效率 🆕 OEE工具链能力增强,支持多厂商BMC芯片接入社区完成整包构建 🆕 SignServer签名接入,社区发布固件安全性增强 🚀 GCC升级到14.3版本,提升构建在安全、性能、效率等方面能力 🚀 bingo整包构建能力:海思Hi3093/3095 DT包、社区导入DT平台包 ### hardware SIG 🚀 运维能力再升级:新增NVMe盘带外升级和并行升级能力;硬盘多启动盘配置 🚀 介质可靠性增强:支持硬盘故障自愈能力,提升整机可靠性 🆕 新增CPLD无感升级功能、并行升级等运维特性,提升整机运维效率 🆕 新增佰维SS821、PetalIO P8118Z3、YMTC PE511等20+款硬盘兼容性 🆕 构建UB相关带外管理能力:光模块故障告警、信息采集、光链路等DFX能力 🆕 KP920双路模组支持:CPU/内存侦测、CPLD/BIOS升级、PCIe Switch等特性落地 ### interface SIG 🚀 200+DMTF标准接口:Processor/Memory/PCIeDevice/ComputerSystem/Manager等资源属性全面升级 🆕 OCP规范全量适配:EthernetInterface/NetworkDeviceFunction/ManagerNetworkProtocol等 🚀 Web Options灵活裁剪,支持整机厂商按需组合 🆕 NPU Redfish接口能力增强,包含NPU Board资源、GPU/NPU最大个数查询、功耗查询、计算能力等 🆕 Web UI增强:固件拖拽上传、VNC双鼠标、离散传感器搜索、BMC配置包导入导出 🚀 事件订阅能力增强:EventFormatType信息、veth通道端口精细化控制 ### component-drivers SIG 🆕 新增沐创N10、网迅25GE、Intel X550、N20等10+款网卡 🆕 新增英伟达5090、Tesla P4/P40/V100/A100等5+款GPU兼容性 🆕 构建RAID卡/NVMe盘/风扇/电源等部件南向驱动规范体系定义和建设 🚀 新增华为182X系列网卡光模块LOL/LOS/SNR/脏污检测等故障检测能力 🚀 设备管理双框架使能:CSR1.0的8种总线,20+器件驱动能力完成构建,满足社区多元场景演进诉求 🆕 自发现能力下沉,支持非天池硬件自接入 ### bmc-core SIG 🆕 构筑高性能event和sensor组件能力,业务性能提升30% 🚀 故障采集智能限流,故障诊断从小时到分钟 🚀 主备管理增强:硬件信号获取主备状态、数据同步策略 ### ai SIG 🆕 发布skills-marketplace的studio插件,支持社区skills一键安装和更新 🆕 发布mcp host的studio插件,支持studio能力与主流Coding Agent对接 ### QA SIG 🆕 测试代码与itestsmart解耦,支持工具和自动化测试用例独立演进 🆕 完成网卡、xPU、硬盘、RAID卡测评和认证流程构建,完成网卡全自动化流程测评端到端验证 🆕《服务器基板管理控制器(BMC)技术要求》新增190+自动化用例,支撑《服务器基板管理控制器(BMC) 测试方法》95%通过自动化完成 ### infra SIG 🆕 openUBMC社区RAG服务,提供社区问答机器人相关的知识库查询能力 🆕 官网上线硬件兼容性列表,支持兼容性沙盘在线查询 🚀 PR门禁进行并发和统一资源池优化,优化PR排队效率,提高并发能力 ### security SIG 🆕 新增基于接口的分权分域的用户管理定制能力 🆕 新增ASPEED芯片+OEE的用户管理和认证能力 ### docs SIG 🆕 200故障模式知识库:覆盖属性同步失败、传感器异常、升级失败等典型故障 🚀 API文档自动化生成:自动生成可用于商用发布的Redfish接口文档 ## 资源获取 DownLoad:https://www.openubmc.cn/zh/download 版本说明:https://www.openubmc.cn/zh/version/26.06 应用市场:https://www.openubmc.cn/zh/marketplace 技术白皮书:https://www.openubmc.cn/zh/whitepaper 感谢每一位开发者的付出!正是你们的贡献,让 openUBMC 不断进步。欢迎持续关注我们,更期待您的加入,一起推动社区繁荣! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/2609-release/ --- 新闻资讯 openUBMC 26.09 版本正式发布 # openUBMC 26.09 版本正式发布 2026/10/08 ## openUBMC 26.09版本如期而至 🥳 感谢所有为26.09 版本做出贡献的开发者! ✅ Issue解决 2693 个 ✅ PR合入 4795 条 ✅ 新增代码行 3742k ## openUBMC 26.09版本特性 ### CICD SIG 🆕  新增openEuler+Kunpeng构建能力,支持X86+ARM双CPU架构交叉编译 🆕  新增40+款兼容性板 QEMU仿真模型,扫清硬件验证门槛 🆕  引入ASan 内存扫描、clang-tidy 静态检查、AI 辅助日志与安全规范扫描,质量门禁矩阵全面升级 🚀  支持OEE+Hi3095、OEE+AST2600等多BMC芯片平台构建能力,筑牢多算力和多场景基础 ### hardware SIG 🚀  增强UB链路故障、PCIe建链失败和BBU过温等告警能力,故障不沉默 🚀  CPLD/VRD/硬盘/网卡/RAID卡等固件在备件更换时自动升级,更换零门槛 🚀  硬盘/网卡/DPU等部件配置更换后自动恢复,真正做到部件即插即用 🆕  新增沐创、梧桐树、华为182X系列、Mellanox和博通等厂商10+网卡兼容性 🆕  新增DDP、得瑞领新、德明利、紫光闪芯和英韧等厂家15+款硬盘兼容性 🆕  新增华瑞数鑫、博通等5+款RAID卡兼容性 🆕  新增PECI/H2B/KCS/SGPIO等X86算力驱动能力,多算力多场景能力全面进阶 ### component-drivers SIG 🆕  部件驱动规范测评和认证体系能力发布,驱动适配结果可度量,测试效率提升50%+ 🚀  完成libmcpp/devmon适配Zephyr,构建轻量化部署能力 🆕  部件驱动框架完成自发现、热插拔管理、统一总线驱动等62项能力构建,硬件适配效率倍增 🆕  新增跟踪、度量、日志、消息通讯、防抖能力等19项可观测框架,开箱即用,南向开发体验全面升级 🆕  SSU模组管理模型、BIOS 带外升级、启动参数设置查询、部件自描述加载,管理能力一步到位 ### interface SIG 🆕  新增自动分页、权限管理、子任务、上下文管理等12项映射库能力,筑牢北向高效开发底座 🚀  近端运维、机框管理、资产管理等17项特性灵活裁剪,实现Redfish/CLI/SNMP/WEB全覆盖 🚀  实现event事件汉化,遥测指标紧跟DMTF规范,推动标准持续迭代演进 ### bmc-core SIG 🆕  聚焦算网融合机型,重构上下电逻辑,适配多场景业务流程 🆕  新增全量数据同步能力,多节点BMC通信原子能力全开放 🚀  深度优化最大session场景性能,带内IPMI命令实现秒级极速响应 ### infrastructure SIG 🚀  推进 61 个代码仓接入编码规范治理,流水线强力赋能 AI 智能检视能力 🆕  openUBMC Studio 工具链全面升级:打通 Workbench、扩展模块构建发布流水线,上线 DSL 检查数据发布流水线 🚀  流水线状态按仓精准可查,开放 RAG 对外查询接口,推进 issue/MR 提交规范化,社区运营深度升级 ### ai SIG 🚀  70+ skills 上线 Skills Marketplace,覆盖开发、测试、构建、发布全流程,开发无忧 🚀  检视技能全面优化,覆盖魔鬼数字、度量单位、异常堆栈、定位信息等场景,一键检视 🆕  IPMI/Redfish 代码文档同步检查上库,实现文档与代码同步更新 ### docs SIG 🚀  从快速上手到设计、开发、适配,一站式贯通开发者全流程,部件驱动 2.0 全套指南上线 🆕  组件文档全面升级,CSR/MDS/资源协作接口配置语法齐套交付,入门、构建与故障定位教程同步上新 🚀  部件数据资产化管理落地,一键完成数据导出、统计概览、搜索过滤与分类导航核心能力 🆕  SNMP/CLI接口文档自动生成,原生确保接口文档与代码同源,实现文档与代码同步更新 ### security SIG 🚀  SPDM 可信根互联落地,异构算力信任根建立,安全底座坚实 ### QA SIG 🚀  社区用例全面接入每日构建,覆盖硬件管理、能效管理、基础服务及用户和安全等领域,实现用例资产随版本持续沉淀 🆕  南向驱动规范测试用具正式落地,全面支持 GPU 接口卡、硬盘、网卡及 RAID 卡 🆕  冒烟测试深度对接每日构建,社区众测正式落地,质量防护网持续增强 ## 资源获取 DownLoad:https://www.openubmc.cn/zh/download 版本说明:https://www.openubmc.cn/zh/version/26.09 应用市场:https://www.openubmc.cn/zh/marketplace 技术白皮书:https://www.openubmc.cn/zh/whitepaper 感谢每一位开发者的付出!正是你们的贡献,让 openUBMC 不断进步。欢迎持续关注我们,更期待您的加入,一起推动社区繁荣! ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://atomgit.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/CGC 2026-program/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/news/CGC 2026-teaser/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/news/CGC-2026-program/ --- 新闻资讯 议程公布 | 2026全球计算大会——openUBMC技术生态论坛议程全览 # 议程公布 | 2026全球计算大会——openUBMC技术生态论坛议程全览 2026/10/16 * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://atomgit.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/CGC-2026-teaser/ --- 新闻资讯 CGC 2026 | openUBMC 分论坛:从标准共建到技术落地,解锁在超节点与AI新形势下 BMC 演进方向 # CGC 2026 | openUBMC 分论坛:从标准共建到技术落地,解锁在超节点与AI新形势下 BMC 演进方向 2026/10/16 当 AI 大模型从技术探索迈向产业深耕,算力基础设施形态正在加速重构。超节点、XPU模组等新架构与部件形态不断涌现,集群规模从千卡走向万卡,异构算力成为常态。BMC 作为算力设备的管理中枢,正迎来开放化、智能化的全新拐点。 在此,我们诚挚邀请您相聚 CGC 2026 openUBMC 技术生态分论坛。本次论坛以“打破边界,AI 提智——定义超节点与AI时代的管理新范式”为主题,汇聚产业领军力量与资深技术专家,共同探讨超节点与AI新形势下,下一代BMC技术演进方向,现场还将发布管理规范与开源成果,凝聚产业共识,助力企业把握开放、智能、自治的算力管理新范式。 * * * ## 01 算力变革时代,BMC 管理技术如何持续演进? AI 算力集群加速落地,管理复杂度正在指数级攀升。从产业视角来看,有三个方向值得关注: **从碎片化适配,走向硬件标准化统一管理:** GPU、DPU 等新型算力部件加速迭代,传统“一部件一适配”的模式已难以跟上节奏。产业需要统一的部件管理接口规范,让硬件厂商基于标准自主开发,实现“一次开发、全链复用”,降低产业链协同成本。 **运维能力下沉边缘,构建带外自主处置能力:** AI 训练对实时性和稳定性要求极高,单次故障可能造成巨大的算力浪费。将运维能力下沉至离硬件更近的 BMC 侧,实现端侧自治与快速响应,正在成为提升算力集群可靠性的重要方向。 **从被动应答模式,迈向节点自治运维升级:** AI Agent、MCP 等技术的成熟,为基础设施管理打开了新的想象空间。BMC 作为服务器带外管理的核心入口,正在从传统的“被管理对象”演变为“自治运维节点”,推动算力管理向智能化持续演进。 * * * ## 02 论坛重磅看点抢先看 ### 看点一|重磅标准首发,解锁异构算力管理原生开源方案 本次论坛将重磅发布由GCC -BMC技术课题专项组牵头、openUBMC社区、云厂商、XPU厂商等产业链头部伙伴联合共建的 XPU 模组管理规范。规范同步配套开源代码资产对外开放,聚焦异构 XPU 硬件统一管理场景,补齐多类算力部件适配不统一、固件定制成本高的产业短板,为异构算力基础设施规模化、标准化落地提供权威体系支撑与可落地的开源实现方案。 ### 看点二|前沿技术全景拆解,洞悉下一代 BMC 演进方向 论坛将围绕下一代 BMC 技术演进路径展开深度解析,拆解北向自接入、南向标准化、AI Agent 给算力管理底层逻辑带来的技术变革,探讨异构算力统一管理的设计思路。现场将分享北向自接入创新实践,以及 Agent Harness 相关的工程探索,解读大模型能力嵌入 BMC构建基础设施自主管理能力的技术实现思路,探讨开源模式如何支撑下一代算力管理体系的创新。 ### 看点三|全场景产业落地,解锁算力能效与可靠性实战方案 论坛集结云厂商、整机厂商、固件厂商等一线实战团队,带来服务器智能管理领域多项产业落地实践。聚焦大规模异构算力的能耗优化、故障管理、可靠性增强等产业痛点。依托商用真实业务场景,分享 BMC 能效调优、超节点带外管理创新、多元异构硬件部署实践,提炼可复用工程方案,支撑下一代算力基础设施规模化商用。 万卡异构浪潮之下,底层硬件管理能力是 AI 集群规模化落地的关键。本次论坛汇集算力全产业链同仁,是把握 BMC 技术演进方向、链接产业生态的重要窗口,助力从业者前瞻布局新型算力基础设施。 openUBMC 期待携手产业链上下游领域伙伴,从标准共建走向产业落地,共同探索开放、智能、自治的算力基础设施管理新未来。 ### **CGC 2026 openUBMC 分论坛,期待与您共同见证。** - 📅 **时间:** 2026年10月21日 14:00-17:00 - 📍 **地点:** 深圳会展中心(福田)5F玫瑰厅-1 - 🔗 **报名方式:** 关注 openUBMC 社区官网及公众号,扫描下方二维码,获取最新报名信息 * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://atomgit.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/HUAWEI CONNECT 2026/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/news/HUAWEI-CONNECT-2026/ --- 新闻资讯 华为全联接大会 2026|openUBMC 精彩亮相,以开源底座使能产业差异化创新 # 华为全联接大会 2026|openUBMC 精彩亮相,以开源底座使能产业差异化创新 2026/10/12 作为面向算力设备管理的开源底座,openUBMC 深度参与大会展览展示与技术分享环节,在计算展区全景呈现"南向自适配、北向自接入"的双向架构体系,并同步开放 Codelab 现场动手体验区,集中呈现社区开源以来的技术演进、开发者体验升级与产业链共建成果。依托开源的算力设备管理平台,openUBMC 持续使能整机、部件、芯片等产业链伙伴,面向 Agentic AI 时代的多样算力架构进行差异化创新,推动算力设备管理向开放化、平台化、智能化持续演进。 * * * ## 算力变革,重塑带外管理新范式 Agentic AI 时代,算力架构走向通算与智算协同,算力节点的规模、密度与异构程度同步抬升,南向硬件兼容、北向自运维正成为算力基础设施管理的关键变量。 然而,传统BMC管理能力多以整机为单位随固件交付,产业链伙伴想加入差异化功能,往往需要深入底层代码改动,研发投入难以沉淀复用。打造开放、可组装的硬件管理底座,成为产业更具工程落地性的方案。 * * * ## 开源底座筑基,助力服务器差异化创新 本届峰会上,华为ICT战略与业务发展部总裁彭红华、华为鲲鹏计算产品线总裁李义携手12家整机伙伴代表,基于鲲鹏920新型号与鲲鹏950,联合发布覆盖高密、均衡、高性能、存储等全形态服务器新品,全系新品均基于openUBMC构建带外管理体系。 openUBMC此前已支撑鲲鹏13家OEM伙伴推出300余款服务器产品,本次发布进一步拓展openUBMC的部署版图。依托这套可裁剪的管理底层,不同厂商、不同形态、面向不同客户的机型可灵活完成南向适配、固件管理与北向运维对接,使能伙伴差异化创新,引领产业走向开放、智能、自治的新阶段。 * * * ## 计算展区:全景展示 openUBMC 双向开放体系与产业实践 HC 大会同期, openUBMC 设置专属展区,以技术解读、联创实践、实操体验相结合的方式,集中呈现 openUBMC 南北向开放架构:北向自接入按需赋能运维创新、南向自适配全域降低硬件接入门槛,让到场行业客户、硬件伙伴、开发者直观理解openUBMC对算力基础设施升级、服务器差异化创新、运维效率提升的核心价值。 北向自接入创新支持上层运维能力按需集成、灵活编排,让管理更贴近算力。区别于传统 BMC固化的运维接口模式,openUBMC 通过组件化、可扩展的北向架构,支持各类 AIOps 等智能化管理能力按需接入、自由组合。平台集成 AI 智能运维、无感批量升级、端侧运维下沉等能力,助力企业数据中心实现极简、高效、零中断运维,同时支持伙伴基于开放底座自定义运维体系、沉淀行业专属运维能力,大幅降低算力集群运维成本,全方位提升商用算力运维效率与智能化水平。 南向方面,openUBMC 打破传统驱动适配体系,以标准化驱动的方式解决产业痛点。目前社区已完成 300+ 款硬件部件适配,依托行业 20 + 头部厂商共建的标准化接口规范,通过可视化配置能力,减少硬件适配的重复底层编码,实现硬件部件标准化、快速化接入。伴随服务器南向部件管理接口标准推进,将进一步降低硬件厂商接入生态门槛。 * * * ## Codelab :零门槛实操,沉浸感受openUBMC 开发乐趣 除产业成果展示外,大会 CodeLab 开发者区同步开放实操体验,直观展示 openUBMC 在硬件适配、算力运维、AI辅助开发领域的范式革新,让开发者沉浸式感受开源轻量化、高效率的开发优势。现场收获大量开发者正向评价:“BMC开发比想象中简单很多,AI辅助和可视化配置大大降低了门槛。”“openUBMC Studio与AI集成后,技术知识检索、概念理解、问题自查效率都提升了很多,很多时候自己问AI也能理解一些设计和概念了。”同时,现场也收集到开发者对硬件兼容与适配、安全与能效联合创新、文档与社区体验优化等方面的多项建设性建议。 后续社区将针对性迭代升级,持续丰富硬件适配类目、深化生态联创与伙伴赋能,优化社区活动运营机制,同时完善官网文档体系、统一版本开发指引、显性化项目差异化介绍,持续优化开发者体验,赋能更多伙伴与开发者高效创新,共建开放生态。 * * * ## 结语 随着算力基础设施向异构化、集群化持续演进,算力设备管理能力正在被重新定义。openUBMC通过南北向开放架构,为产业链伙伴提供了从硬件适配到业务创新的完整支撑。 未来,openUBMC 将持续迭代核心技术、完善硬件认证体系、壮大开源生态,以开源力量使能计算产业开放创新,携手全产业链伙伴共建高效、开放、创新的下一代算力设备管理体系。 * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://atomgit.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/Star-Open-Source-Community/ --- 新闻资讯 openUBMC社区荣获2025年软件和信息技术服务业明星开源社区奖项 # openUBMC社区荣获2025年软件和信息技术服务业明星开源社区奖项 技术干货 2026/05/09 openUBMC小助手 ### 01 开源生态获认可,引领算力管理新范式 **2026年4月**在以“人工智能与软件变革——AI融合与数智出海新机遇”为主题的第五届中国国际软件发展大会上,openUBMIT社区凭借其在算力设备管理领域的创新实践与生态贡献,荣获“**2025年软件和信息技术服务业明星开源社区**”称号。 这一荣誉标志着openUBMC社区在推动国产开源算力设备管理软件发展方面取得的成就获得业界高度认可。 * * * ### 02 深耕开源沃土,赋能产业创新 openUBMC于2024年正式开源,旨在打造开放、易用的算力设备管理软件开发平台,为全场景、全连接、全智能时代提供架构领先、开发友好、遵循开放标准的开源BMC软件。 社区保持高频迭代,截止目前: - **代码规模**:累计代码量突破 300万行 - **开发者生态**:汇聚 500+ 核心开发者参与贡献 - **版本迭代**:推出 5个 创新版本 + 1个 长期支持版本(LTS) - **生态兼容**:支持 200+ 款主流部件即插即用 * * * ### 03 首创南向标准,引领行业变革 在传统的服务器带外管理开发中,BMC 南向部件接口碎片化一直是困扰开发者的核心难题。部件与整机深度绑定,导致每适配一款新硬件,都需要投入大量重复的驱动开发工作。 openUBMC 从架构层面直击这一痛点: - **首创南向部件驱动规范**:实现了硬件能力定义与底层实现的彻底解耦; - **打破绑定模式**:推动交付模式从传统的“整机集成商单点对接”向“多产业协同”变革,联合20余家产业链单位完成标准立项后,目前已有10余家头部部件商基于社区完成适配; - **0 Day级适配效率**:新增硬件的接入效率达到 0 Day级,极大释放了研发生产力,为服务器行业带来开放高效的协同新范式。 * * * ### 04 持续创新,筑牢数字基础设施底座 面向AI基础设施急剧增长带来的大规模算力部署与运维挑战,openUBMC持续深耕智能运维、安全可信等核心能力,为行业提供更智能、更高效的管理底座。 未来,openUBMC社区将继续以“标准+开源”双轮驱动,携手生态伙伴共驱产业智能化升级。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 ## 关于作者 - openUBMC小助手 openUBMC小助手是openUBMC社区的活跃推手,专注于为开发者提供前沿技术动态、深度文章解析以及丰富的社区互动内容,致力于打造一个开放、互助、充满活力的技术社区,助力每一位成员在技术探索中不断进步。 --- https://www.openubmc.cn/zh/news/Wuhan-meetup/ --- 新闻资讯 议题征集!openUBMC Meetup 武汉站,与你共写新的开源记忆 # 议题征集已结束 openUBMC社区2026年首场线下Meetup将于3月20日在武汉与大家见面!本次 Meetup 由 openUBMc社区牵头,联合社区成员单位长江计算、神州鲲泰共同主办。现诚邀openUBMC社区全体开发者参与议题征集,欢迎积极分享您在openUBMC领域的实践实操、技术创新、工具开发、落地案例及优化建议,与产业上下游开发者深度探讨,凝聚社区合力,推动BMC技术迭代升级与生态高速发展,实现开发者个人成长与生态共建的双向共赢! 2026年3月20日 武汉 ## 议题征集 # 议题征集!openUBMC Meetup 武汉站,与你共写新的开源记忆 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/chengdu-meetup-review/ --- 新闻资讯 openUBMC Meetup成都站成功举办,聚焦开源BMC技术创新与社区共建 # openUBMC Meetup成都站成功举办,聚焦开源BMC技术创新与社区共建 2025/11/03 # openUBMC Meetup成都站成功举办,聚焦开源BMC技术创新与社区共建 2025年10月31日,openUBMC Meetup在成都成功举办。本次活动吸引了近50位开发者及技术专家齐聚一堂,围绕openUBMC社区最新进展、可观测技术、部件驱动、测试策略、CI/CD实践、AI赋能测试等核心议题展开深度分享与交流。 ### 社区蓬勃发展,25.09版本成果显著 openUBMC技术委员会委员张雨博分享了社区最新进展:25.09版本在代码贡献、硬件兼容性与开发者体验上取得突破性进展;社区首个LTS版本——25.12的规划也已启动,将重点增强接口规范与部件驱动框架等能力。与此同时,社区运营持续活跃,继西安、杭州之后,本次成都Meetup和即将举办的深圳站活动将进一步连接广大开发者,共建开放协作的技术生态。议题的最后,张雨博表示,2026年技术规划已开启,现公开征集技术需求与创新建议,诚邀全球开发者共同参与,推动openUBMC生态持续演进。 ### 可观测技术:从“黑盒”到“透明系统” openUBMC Interface SlG Maintainer李四光分享了openUBMC在可观测性方面的技术实践。通过引入Trace(追踪)、Metric(指标)、Log(日志)三大信号,结合OpenTelemetry Collector与Prometheus、Jaeger、Zipkin等后端系统,实现了BMC系统运行状态的实时监控与问题定位。通过实际案例,演示了如何在BMC界面配置可观测服务,并通过Grafana实现数据可视化分析。 ### 部件驱动规范:推动硬件管理标准化 openUBMC Component Drivers SIG Maintainer 刘兴森介绍了社区在南向部件驱动规范方面的突破。通过定义统一的部件接口模型,实现了硬件管理与BMC软件层的解耦,支持“必选+可选”接口组合,兼顾基础功能与差异化能力。目前,已有部分网卡、GPU已在社区落地,Q4会继续发布更多的部件。同时,《服务器南向接口要求》已完成标准立项,正面向社会公开征集意见中。 ### 测试与自动化:构建高质量交付体系 openUBMC QA SIG Maintainer刘宇杰分享了openUBMC的分层测试策略与自动化防护网,涵盖组件IT测试、版本冒烟、每日构建与全量验证。社区完善了测试贡献流程,鼓励开发者共同完善测试用例与自动化脚本。 ### CI/CD与AI赋能:提升开发与测试效率 软通动力软件工程师文成龙与顾晓东分别分享了在CI/CD流水线建设与RAG技术在测试中的应用。 - CI/CD实践:通过自定义镜像、静态检查、依赖扫描等环节,提升代码合入效率与质量; - RAG智能助手:基于历史用例、脚本与日志构建知识库,实现用例智能检索、脚本复用与失败根因分析,显著提升测试资产复用率与问题定位效率。 ### openUBMC实战分享:调速策略与组件定制 华鲲振宇BMC研发工程师何伟与厉兆伦分别就调速策略配置与组件级文件定制方法进行了实战分享: - 调速策略:详细讲解了目标调速、线性调速、分区调速等场景的配置模型与注意事项; - CSR定制与函数重定义:提出基于组件级的CSR合并与Lua函数重写机制,支持非侵入式硬件适配与功能扩展。 ### Workshop实战环节:动手体验核心技术 在下午的Workshop实战环节中,开发者们展现出极高的参与热情,围绕部件驱动开发、可观测技术集成与测试策略三大主题展开了深度实践。在专家的指导下,现场参会开发者通过“手把手”实践促进技术理解,现场互动频繁,交流热烈,有效推动了技术经验的流动与社区协作共识的形成。 ## 总结 本次Meetup在热烈的技术交流与实战研讨中圆满落幕,充分展现了openUBMC社区在开源BMC技术领域的创新活力与实践成果。社区将持续为开发者搭建开放、协作的技术平台,推动设备管理软件技术的标准化与普惠化,诚邀更多开发者加入,共同构建智能、开放的设备管理未来。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/community-operation report5/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/news/community-operation report6/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/news/community-operation report7/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/news/community-operation report8/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/news/community-operation report9/ --- 未找到相关内容 --- https://www.openubmc.cn/zh/news/community-operation-report1-3/ --- 新闻资讯 openUBMC 社区 2026 年 1-3 月运作报告 # openUBMC 社区 2026 年 1-3 月运作报告 2026/04/08 ## 概述 2026年第一季度,openUBMC社区在技术迭代与生态建设上取得扎实进展。技术方面,openUBMC 26.03版本正式发布,围绕硬件适配、核心管理、驱动优化、接口定制与安全防护五大维度全面升级;openUBMC Studio同步进化为一体化IDE开发平台,原生集成智能开发能力,显著降低开发门槛、提升贡献效率。 生态方面,社区规模持续扩大:累计下载量突破11万+,活跃开发者超500人,成员单位达21家。成功举办25.12 LTS版本解读直播及武汉Meetup(联合长江计算、神州鲲泰),并启动第八届CCF开源创新大赛openUBMC赛道,加速培养算力基础设施人才。社区深度参与2026华为中国合作伙伴大会与鲲鹏KPN伙伴大会,推进“开源UBMC + 开放BIOS”双轮驱动战略。 品牌与基础设施同步升级:上线活动与品牌专区,统一视觉规范与使用指南,强化专业形象,支撑Studio推广与用户转化。安全治理持续夯实:Q1发布2份安全公告,修复21个漏洞,包括高危的protobuf组件漏洞(CVE-2022-1941),巩固LTS版本安全基线,保障产业级部署可信可靠。 > **阅读提示**:本月报阅读时长约10分钟 ### 社区规模 ## 截至2026年3月31日,openUBMC社区用户累计下载量12万+,超过500名开发者在社区持续贡献,累计产生7.5k个PRs、5.3k条Issues、36.2k条comments,11个SIG组。目前,已有26家成员单位加入openUBMC社区。 ### 社区事件 ➣ **openUBMC 2025社区年报发布** 2025 年是 openUBMC 社区迈向规模化发展的关键之年。openUBMC致力于通过开源模式,打造开放、易用的管理软件开发平台,推动算力设备管理产业的繁荣与创新。社区聚焦于软件管理领域,在面向全场景、全连接、全智能的时代需求下,为开发者提供一款架构领先、开发友好、遵循开放标准的算力设备开源管理软件。自2025.03.30 推出首个开源版本,到年底的 25.12 LTS 长期稳定版本发布,一年四轮迭代。482 位开发者已在此汇聚,与 openUBMC 并肩前行。 **原文阅读**:LINK ➣ **openUBMC 12.5 LTS版本解读直播** 2026年2月3日,openUBMC 成功举办 25.12 LTS 版本解读直播,吸引超600位开发者关注。该版本作为社区协同创新的里程碑,采用开放式微组件架构,在北向生态、运维能力及南向适配三大维度实现重磅升级。北向支持 Redfish 标准及 3D 服务器视图,南向新增 160+ 款硬件即插即用,运维方面通过并行升级技术将业务中断时间大幅降低。目前社区Issue 闭环率达97.32%,四层防护网全面建成,标志着 openUBMC 向着更开放、高效、可靠的BMC新生态迈进。 **原文阅读**:LINK ➣ **openUBMC 2026年首场Meetup在武汉举办** 2026年3月20日,由openUBMC开源社区牵头,联合社区成员单位长江计算、神州鲲泰共同举办的openUBMC Meetup武汉站圆满落幕。本次活动汇聚了社区核心伙伴,全天呈现10+精彩议题,从社区动态到商业实践,从前沿AI探索到全新开发平台解读,为现场开发者带来了一场关于BMC技术创新的深度交流。 **原文阅读**:LINK ➣ **第八届CCF开源创新大赛openUBMC赛道启幕** 本届赛事中,openUBMC社区发布赛道 —— openUBMC开源项目贡献赛,旨在发掘和培育精通 AI 时代 BMC 智能运维、嵌入式轻量化大模型部署的算力基础设施开源创新人才,助力现代化数据中心管理技术创新与产业升级。本次大赛共分两个赛题,赛题一:重塑BMC·AI时代智能运维创新平台、赛题二:嵌入式芯片的LLM挑战。 **赛事连接**:LINK ➣ **openUBMC 亮相 2026 华为中国合作伙伴大会** 2026 华为中国合作伙伴大会上,openUBMC 在鲲鹏计算展区独立展屏精彩亮相,全面展示开源智能管理软件的核心能力与生态价值。openUBMC 依托南北向丰富的生态能力,打造自主创新、安全可信的算力管理底座,同时展现开放活跃的开源生态,强化与鲲鹏深度协同,充分体现软硬件解耦、生态开放、高效易用的核心优势,面向全行业伙伴展示生态价值,共筑鲲鹏算力竞争力。 ➣ **openUBMC 亮相 2026 鲲鹏 KPN 伙伴大会 赋能伙伴高效创新** 2026 鲲鹏 KPN 伙伴大会在南京隆重举行,吸引数百位鲲鹏生态伙伴及行业专家参与,华为鲲鹏计算业务副总裁刘云强在主题演讲中表示:“华为以openUBMC 开源 + BIOS 开放” 双轮驱动模式,为伙伴提供低门槛、低成本开发底座。当前已有多家 KPN 伙伴基于 openUBMC 在多行业场景落地自研发行版,显著提升开发效率。期待更多生态伙伴积极参与、深度协同,携手共建开放共赢的鲲鹏算力生态。 ➣ **委员会议** 2026 年 3 月 27 日上午,openUBMC 开源社区发展委员会 2026 年度首次会议顺利召开。本次会议共设五个环节,依次为开场致辞、遗留问题同步、委员工作交流、专题研讨及会议总结。与会委员围绕相关议题展开充分交流研讨并提出建设性意见,针对社区共性问题,各工作组在研讨环节中进行了详细回应与解答,相关议题均取得良好研讨成效。 * * * ### 技术进展 ➣ **openUBMC 26.03 正式发布** - **硬件适配升级**:兼容 920L模组、182X标卡、OCP 网卡,支持温湿度采集,故障预判更精准 - **核心能力增强**:FRU 标签扩展、多主机传感器管理、硬盘信息远程获取,管理更精细 - **驱动能力优化**:新增182X/OCP/光润通多款硬件专属驱动,搭配兼容工具,适配更简单 - **接口灵活适配**:WEB 接口可按机型定制,标准对接顺畅,高阶能力全覆盖 - **安全防护升级**:强化会话安全管理,发布社区安全规范 V1.0,系统更可信 - **开发体验优化**:QEMU 仿真升级,文档及适配指南进一步完善,上手更快 **了解更多版本信息与下载**:LINK ➣ **openUBMC Studio全新升级** 定义开发流程,一个窗口解决openUBMC开发:BMC Studio 品牌全新升级为 openUBMC Studio。该平台原生基于 openUBMC 社区规范和基础设施构建开发流程。让您在一个窗口即可完成 openUBMC 开发。我们引入了完整的IDE功能,在几乎不改变您开发习惯的同时,提供深度对接社区、全面覆盖openUBMC开发的辅助支持。 **下载体验**:LINK ➣ **Hardware SIG** 1至3月完成社区26.03版本更新,完成硬件兼容性扩展,新增920L模组、182X新代次标卡、OCP网卡及光模块、MCX75310AAS-NEAT网卡、网讯FF5025网卡、9500-16i/8i等支持,新增RS485温湿度采集及硬盘/风扇/扩展板/硬盘背板/基础板更换记录功能,增强NVMe硬盘故障预测及光模块(含标卡与昇腾卡)故障检测能力,优化Bluefield DPU功能并新增BOX管理(Retimer及故障检测),支持SP686C-M-16i/40i及SP686C-MH-32i等RAID卡固件及其管理硬盘带外升级,同时增强能效管理配置能力,包括分区调速、精细化配置及PID参数等。 ➣ **Component Driver SIG** 1至3月更新涵盖新增182X新代次标卡、OCP网卡及光模块与光润通(GRT)驱动开发,同时优化驱动框架以支持DBUS和共享内存调用、组件schema加载与管理、自描述记录解析处理及复杂属性语法,并新增南向网卡兼容性工具。 ➣ **Interface SIG** 1至3月更新包括支持根据机型WEB接口灵活组合、优化光模块性能数据采集接口、基于Validator扫描通用问题标准化、增强ComputerSystem/PCIeSlots/Memory等北向接口标准能力,并新增RAID卡慢盘、固件升级暂存、dump BIOS Flash、DICE、大包升级及多系统等特性北向接口能力。 ➣ **CICD SIG** 1至3月更新包括openUBMC Studio全新升级并新增IDE能力及CSR辅助开发功能,增强QEMU对博通RAID卡的仿真能力,新增基于lockfile的产品级构建与子系统切面配置汇总机制,并将QEMU版本升级至8.2.10。 ➣ **Docs SIG** openUBMC 社区 1-3 月新增 25 篇技术文档,包含compute、libsoc\_adapter、ipmi\_core、bmc\_network等组件接口文档与风扇板和风扇适配指导文档,文档覆盖底层硬件配置、故障定位及网络管理等核心场景,显著夯实社区知识底座。 ➣ **bmc-core SIG** 1至3月更新包括新增FRU电子标签加工时间扩展、传感器事件多主机场景能力,同时新增IPMI硬盘信息获取功能。 ➣ **Infra SIG** 1至3月更新包括发布社区基础设施软件开发生命周期治理与安全规范V1.0,新增LTS版本每日构建功能,以及新增社区包签名基础能力。 ➣ **Security SIG** - 支持框内节点间通信的安全控制能力,实现内部通信全安全策略可覆盖; - 支持CPLD固件PFR能力,实现全固件可信覆盖; - 支持组件级安全切面配置,集中可定制的安全风险控制。 ➣ **QA SIG** 测试平台集成QEMU版本升级到8.2.10。 ➣ **AI SIG** 社区新成立了AI SIG,聚焦社区AI辅助研发效率提升,以及AI与BMC智能运维的结合运用。 ➣ **open UBMC 优质技术文章精选** - 从开源社区到产业标准:openUBMC携手UBIOS引领服务器管理新纪元:LINK - 让AI真正“防宕机”:openUBMC 故障预测系统的指标误区澄清与无感运维应用:LINK - 基于BMC的AI故障预测系统构建及应用:LINK - 昆仑太科基于openUBMC的POST Code功能实现从开源社区到产业标准:LINK - openUBMC:超节点时代的 BMC 新范式:LINK * * * ### 基础设施升级 ➣ **每日构建与签名** 新增LTS版本每日构建功能,确保版本稳定性;新增社区包签名基础能力,保障软件供应链安全。 ➣ **社区平台优化** - 上线活动专区,展示全年活动规划并明确申请要求和相关流程; - 优化下载中心,新增“全部版本”模块,按照LTS版和创新版对社区发行版进行了系统归档,帮助用户更清晰、高效地选择和获取所需版本; - 为openUBMC Studio工具上线提供配套的工具包,提升工具的曝光度,助力工具推广和使用转化; - 更新TC组织架构图与成员名单,确保社区治理结构的准确性和时效性; - 上线品牌专区页面,提供社区标志视觉识别规范、品牌使用说明、logo不同格式下载及社区PPT模板,统一了社区品牌对外输出标准,方便开发者规范使用社区品牌资产。 ➣ **社区流程优化** openUBMC 社区在管理版本的需求/缺陷上,为了提高质量,需要在流程进行把控。社区基础设施在社区机器人上线对Issue的工作状态进行管控新功能,并包含权限配置和校验。同时给社区用户提供使用说明:LINK * * * ### 软硬件兼容性测评 截至2026年3月31日,2026年1-3月新增19个,其中北向(ISV)新增7个,南向(IHV)新增12个。 ➣ **南向兼容性列表**:SP675、SP681、SP235、SP235-O、SP233、SP232、SP236、SP566、UBEXP、紫金DPU-4口-25G、MCX75310AAS-NEAT、MCX623106AN-CDAT ➣ **技术测评列表**:已完成测评规范初稿制定,明确了评分机制和接口权重计算方案;完成部件驱动自动化测试平台搭建,并完成网卡部件驱动测试用例的建设,实现了测试流程标准化,提升了测试效率和覆盖度,为后续其他部件管理能力量化提供了依据。 ➣ **北向兼容性列表**:Assembly、Chassis DigitalWarranty、Graphics-Controllers、Processors Metrics、UpdateServiceCapabilities、CpuFPC、NpuFPC * * * ### 安全公告 2026年1 -3月,社区共发布安全公告2个,修复漏洞21个。 **重点漏洞提醒** **漏洞基本信息** | 项目 | 内容 | | --- | --- | | 公告编号 | openUBMC-SA-2026-1002 | | 涉及组件 | protobuf | | 关联 CVE | CVE-2022-1941 | | 严重等级 | High (高) | **漏洞描述**:Oracle MySQL Connectors(数据库软件)存在一个被归类为 Critical 的漏洞。该程序在资源被重新利用之前未释放或错误地释放了资源(CWE-404),影响了系统的可用性。 **影响版本** | 影响版本号 | 修复版本号 | 修复状态 | | --- | --- | --- | | openUBMC 25.12 | openUBMC 26.03 | Fixed | **公告连接**:LINK * * * ### 致谢 感谢以下 SIG 组及个人的贡献: | Hardware SIG | Component Driver SIG | Interface SIG | | --- | --- | --- | | Docs SIG | Bmc-Core SIG | Infra SIG | | QA SIG | AI SIG | release-management SIG | | CICD SIG | Security SIG | LIU Yi | | Huang Qiuxia | Ye Dailin | Wu Jiacong | 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/community-operation-report8/ --- 新闻资讯 openUBMC 社区 2026 年 8 月运作报告 # openUBMC 社区 2026 年 8 月运作报告 2026/09/14 ## 概述 2026年8月,openUBMC社区在技术迭代与生态建设上持续攀升,社区规模不断壮大:截至8月31日,累计下载量已突破17万,活跃开发者超830人,贡献单位增至36家。 生态建设上,openUBMC Meetup成都站圆满举办,聚焦技术赋能与产业落地,汇聚技术专家与开发者面对面交流;CCF开源创新大赛openUBMC赛道决赛于重庆大学收官,吸引41所高校、154人次参赛。影响力方面,openUBMC社区开展了2场技术直播,并首次在openUBMC视频号开播;开源实习30项任务截至8月底已全线认领完毕,多项成果合入社区代码库。 技术方面,openUBMC 25.12 LTS SP3版本正式发布,接入7款网卡、10+款硬盘的兼容性,60+缺陷修复提升版本稳定性;硬件适配与故障自愈能力增强,部件驱动2.0体系化文档发布、CSR2.0驱动落地,驱动开发有规范可依;研发诊断Agent打通Studio、MCP与真实BMC环境,形成初步闭环;社区文档新增29篇,开发者文档与参考指南持续完善。 从技术深耕到生态活跃,openUBMC以开放架构、生态协同、智能运维与高效开发为牵引,持续释放开发者活力与产业创新效能,推动产学研协同共建,加速构建安全、可信、繁荣的算力设备管理开源生态,夯实下一代数据中心基础设施底座。 > _(本月报阅读时长预计10分钟)_ * * * ## 社区规模 截至2026年8月31日,openUBMC社区用户累计下载量 **17万+** ,超过 **830** 名开发者在社区持续贡献,累计产生 **13k+** 个PRs、 **9k+** 条Issues、 **97k+** 条Comments, **13** 个sig组。目前,已有 **36** 家单位参与社区贡献。 * * * ## 社区事件 ### ➣ 社区活动 #### ➣➣ openUBMC Meetup 成都站圆满举办,合肥站即将开启 8月14日,由openUBMC社区与华鲲振宇联合主办的openUBMC Meetup成都站圆满举办。本次活动聚焦技术赋能与产业落地核心主题,openUBMC社区多位TC委员、Maintainer及社区成员单位的技术专家齐聚成都,围绕可信计算安全体系设计、超节点管理方案探索、RAID卡与电源适配实践、基于Agent的智能化调试流程等主题展开10场技术分享,吸引了线上/线下众多开发者参与深度交流。 继成都站顺利落幕后,openUBMC Meetup 活动将于 9 月落地合肥,更多技术分享与生态碰撞敬请期待! 活动详情:https://www.openubmc.cn/zh/news/2026chengdu-meetup-review #### ➣➣ 第八届CCF开源创新大赛openUBMC赛道圆满收官 8月14日,第八届 CCF 开源创新大赛 openUBMC 赛道决赛于重庆大学圆满收官。赛事聚焦 BMC 运维创新、大模型轻量化部署两大方向,共吸引 41 所高校、120 支战队、154人次参赛,学生参与占比达92.2%,百信、宝德、华瑞数鑫等产业链头部企业积极参与,产学研深度融合,以真实产业场景赋能开源创新,产出了一批优质落地作品,为算力开源生态注入新动能。 活动详情:https://www.openubmc.cn/zh/news/2026ccf-competition-recap #### ➣➣ openUBMC社区技术直播持续开展 8月,openUBMC社区开展2场技术直播分享,分别由openUBMC社区技术委员会委员刘兴森、张超作为主讲嘉宾,围绕“openUBMC南向硬件管理技术规范、实践及生态建设分享”与“openUBMC架构概念设计介绍”两大主题,深入讲解统一高性能驱动框架与部件驱动管理规范、MDS微组件描述与MDB协作资源树等四大模型及南北向解耦设计等内容。 8月,openUBMC视频号也同步作为直播渠道开播,后续直播也将持续在视频号开展。**搜索关注【 openUBMC 】** 视频号账号,获取相关直播详情。 > - _扫码关注openUBMC视频号_ #### ➣➣ openUBMC开源实习继续火热推进 openUBMC 开源实习继续火热推进,截至8月31日,30项社区实习任务已全线认领完毕,多项成果已成功合入社区代码库,高校开发者踊跃参与社区共建,开源社区活力持续攀升。 开源实习详情:https://www.openubmc.cn/zh/internship 招募推文:https://www.openubmc.cn/zh/events/detail/openUBMC-Open-Source-Internship * * * ## 技术进展 ### ➣ 版本进展 **8月openUBMC 25.12 LTS SP3版本正式发布:** - **硬件兼容版图持续扩大:** 新增182X新代次、MCX系列、沐创、光润通、Intel、博通、星云智联等7款网卡兼容性;新增HKEP系列、德明利、紫光闪芯、佰维、英韧、长江存储等10+款硬盘兼容性;新增900W电源、EXP 12盘背板等部件兼容性。 - **可靠性与稳定性增强:** 优化SP686C RAID卡固件日志收集机制和日志可读性、扩展板CPLD localbus链路异常检测机制,以及BIOS固件和TEE固件生效机制,版本可靠性持续提升。 - **缺陷修复:** 修复SP686C RAID设置启动盘及适配SATA SSD显示、RAID卡通信失败、日志冗余记录等60+问题,版本稳定性与用户体验进一步改善。 本版本共计修复Issue 68 个,合入PR 90 条。 了解更多版本信息:https://www.openubmc.cn/zh/news/2512-SP3-release 下载链接:https://www.openubmc.cn/zh/download ### ➣ SIG组月度动态 本月新增PR 1525 个,各sig组共召开公开例会 27 次,sig组活跃地图分布情况如下: #### ➣➣ sig-hardware 8月,sig-hardware 在电源管理、故障自愈、硬件适配及可运维性等方面取得实质性进展,硬件可靠性与兼容性持续增强。 - **电源管理:** 支持 EB300 电源砖管理、BMC 主从电源带外管理、电源芯片厂商和型号查询,以及电源升级时UID灯控制,电源管理覆盖范围进一步扩大。 - **故障自愈与巡检:** 支持风扇故障自愈;VRD升级后备份固件包并支持VRD自愈;天池单板JTAG扫链巡检,可主动排查链路连通性异常,硬件可靠性进一步提升。 - **硬件适配:** 新增华瑞数鑫 B261 Boot RAID 控制器适配,以及紫光闪芯、英韧等硬盘兼容性适配,社区硬件兼容生态持续丰富。 - **可运维性:** 支持数码管显示框号、NPU模组电源黑匣子日志收集,以及通过IPMI命令记录BIOS维护日志;BIOS PFR可定位性增强;新增PCIe标卡在位建链失败告警,运维排障手段更加完善。 - **南向驱动升级:** 支持南向部件驱动 CSR 和 SO 的独立升级,驱动升级方式更加灵活。 #### ➣➣ sig-component-drivers 8月,sig-component-drivers 持续推进驱动2.0体系化与CSR2.0驱动落地,并在设备监控、devmon及libmcpp方面持续完善,驱动开发规范与框架能力同步提升。 - **部件驱动2.0体系化:** 发布部件驱动2.0体系化文档、南向API参考及网卡/GPU适配指南,统一DMC契约,驱动开发有规范可依。 - **CSR2.0 驱动:** 落地 LocalBus / I2cOverLocalBus / CpldRegister 等 CSR2.0 驱动,完善光模块与出框电链路扩展信息,驱动开发框架进一步完善。 - **设备监控与管理:** 支持DPU/ASU带外与SSU GE切换;EEPROM预加载改为header比对;加固Scanner调度死锁与误告警,设备监控更加稳定高效。 - **devmon:** 补齐设备/应用层插件设计文档;支持defer\_registration取消自动上树与定制化删除硬件自描述对象;修复position卸载残留与拓扑发现误跳过问题,设备自发现与管理能力进一步完善。 - **libmcpp:** 推出度量/telemetry与Lua/C++ Trace混用;优化旧SHM RPC与对象树内存,完善异步调度与旧框架兼容;补齐属性精确订阅、HTTP与D-Bus覆盖率,修复并发缓存与日志归属问题,框架库能力持续增强。 #### ➣➣ sig-docs 8月新增文档29篇,覆盖驱动开发、硬件适配、编码规范、安全基线等多个方向,重点包括: - 《部件驱动2.0适配方案》:介绍部件驱动2.0适配方案的架构、核心价值与应用场景 - 《设备驱动开发指南》:提供从设计到实现的设备驱动完整开发流程 - 《整机类适配快速上手》:手把手完成新整机/新板卡的硬件接入 - 《openUBMC安全配置基线》:固件配套运行时的安全配置基线指导 此外,部件驱动接口模型设计、南向硬盘驱动适配指南、IPMI接口定制指南等文档也同步上线,社区知识底座持续夯实。 #### ➣➣ sig-ai 8月,sig-ai 在研发诊断Agent方面形成初步闭环,知识中台完成新一轮能力升级,问题诊断与全链路追溯能力初步形成。 - **研发诊断 Agent 初步闭环:** 已打通 Studio 连接管理、MCPHost、Coding Agent 与真实 BMC 环境,可调用 SSH/Telnet、BMT/MDB、知识检索等工具,结合问题描述、源码和真实环境开展问题诊断,并进一步衔接修复、升级和测试验证。后续将进一步区分研发诊断与运维日志分析的产品边界,重点服务研发阶段问题定位与修复,补齐离线诊断能力,优先覆盖高频、标准化问题。 - **知识中台能力升级:** 知识中台原型开发完成新一轮能力升级,新增精确查询、Issue/PR/Commit/论坛等显式关联、Fact/Event时序账本、版本归属与严格版本过滤等能力,可追踪需求、代码变更和版本演进全过程。下一步尽快上线测试环境,接入Interface SIG等真实研发用户,通过实际使用和过程数据进一步验证、优化技术能力及使用入口。 ### ➣ openUBMC 优质文章精选: 从故障诊断到 RAS Offload:百敖 openUBMC 的 Intel 平台适配实践 一图读懂|openUBMC 7月社区文档更新清单 * * * ## 致谢 亲爱的社区开发者: 过去一个月,是你们的热情与奉献,让 openUBMC 社区持续迸发活力! 每一行代码的提交、每一次技术的探讨、每一份经验的分享,都在为社区注入前行的力量。正是每一位开发者的持续参与,让openUBMC的基础更加坚实、生态更加繁荣。 若您在阅读月报时发现遗漏了您的精彩贡献或重要进展,请随时联系我们补充。 开源之路,感恩同行!让我们携手打造更繁荣的算力设备管理开源生态。 在此,谨向为本期月报提供资料支持的各 sig 团队及广大开发者致以诚挚的感谢与敬意: * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://gitcode.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/community-operation-report9/ --- 新闻资讯 openUBMC 社区 2026 年 9 月运作报告 # openUBMC 社区 2026 年 9 月运作报告 2026/10/12 ## 概述 2026年9月,openUBMC社区在技术迭代与生态建设上持续跃升,社区规模不断壮大:截至9月30日,累计下载量已突破18万,开发者超1000人,加入社区单位超40家。 生态建设上,openUBMC Meetup合肥站圆满举办,聚焦工程实践与AI调试创新,共建BMC开源生态;openUBMC开源发展委员会2026年第三季度会议召开,总结第三季度社区治理成效,开发者生态持续壮大、多方协同共建能力持续增强,生态治理与社区规模迈上新台阶。影响力方面,openUBMC亮相上海海思创新大会,Hi3095硬件能力正式向社区开放;openUBMC还亮相华为全联接大会2026,开源开放理念持续强化行业影响力。 技术方面,openUBMC 26.09版本正式发布,Studio能力增强、构建工具链升级,硬件生态与平台能力拓展;bmc\_network等核心组件实现社区贡献,华为贡献libiam、iam等安全能力组件落地;Agentic BMC完成小模型上板可行性验证。 从能力跃升到生态聚力,openUBMC以开放架构、生态协同、智能运维与高效开发为牵引,持续释放开发者活力与产业创新效能,深化社区治理与产业协同,加速构建安全、可信、繁荣的算力设备管理开源生态,夯实下一代数据中心基础设施底座。 > _(本月报阅读时长预计10分钟)_ * * * ## 社区规模 截至2026年9月30日,openUBMC社区用户累计下载量 **18万+** ,开发者超 **1000** 名,累计产生 **15 k+** 个PRs、 **10k+** 条Issues、 **123 k+** 条Comments, **15** 个sig组。目前,已有 **40+** 家单位加入社区。 * * * ## 社区事件 ### ➣ 开源发展委员会会议 9月29日,openUBMC开源发展委员会2026年第三季度会议召开。第三季度以来,社区各项工作稳步推进,开发者生态持续壮大,代码规模和贡献量进一步提升。各成员单位在文档编写、特性开发与测试用例补充等方面持续投入,让社区的技术交流与协作更加活跃。 ### ➣ 社区活动 #### ➣➣ openUBMC Meetup 合肥站圆满举办,深圳站即将开启 9月22日,由openUBMC社区与百信信息技术有限公司联合主办的openUBMC Meetup合肥站圆满举办。本次活动聚焦openUBMC工程实践与AI调试创新,汇聚线上线下开发者,围绕北向架构、南向适配、板卡排障等议题深度研讨,联动社区与产业伙伴,共建BMC开源生态。 继合肥站顺利落幕后,openUBMC Meetup活动将于10月落地深圳,更多技术分享与生态碰撞敬请期待! 活动详情:https://www.openubmc.cn/zh/news/2026hefei-meetup-review 更多Meetup 活动相关直播回放,将陆续同步至 **openUBMC 视频号** ,欢迎持续关注。 > _扫码关注openUBMC视频号_ #### ➣➣ openUBMC 亮相华为全联接大会 2026 9月,openUBMC亮相华为全联接大会2026,在高层演讲中被重点提及。作为面向硬件设备管理赛道的开源BMC项目,openUBMC秉持开源开放理念,以标准化、开放化的管理平台破除厂商锁定,赋能硬件厂商与服务器客户自主定制、快速集成。现场开设openUBMC主题展区与CodeLab实操体验,直观呈现北向自接入、南向自适配等核心技术方案,与开发者、产业链伙伴深度交流,持续夯实openUBMC在服务器硬件管理开源领域的核心影响力。 #### ➣➣ openUBMC 亮相上海海思创新大会 9月,openUBMC亮相上海海思创新大会,海思MCU产品领域总经理陈桂培在主题演讲中宣布,Hi3095硬件能力正式向openUBMC社区开放,双方合作由技术协同升级至市场联合共建。依托本次大会,openUBMC持续扩大在硬件设备管理领域的行业影响力,凝聚上下游伙伴力量,共同参与开源生态共建。 * * * ## 技术进展 ### ➣ 版本进展 **9月openUBMC 26.09版本正式发布** - **开发体验与工具链全面升级:** BMC Studio打通Workbench与模块构建发布流水线;bingo新增openEuler+Kunpeng,实现双架构交叉编译与多BMC芯片平台构建;新增40+款QEMU仿真模型,引入ASan、clang-tidy与AI辅助安全扫描;70+ skills上线Skills Marketplace,覆盖开发全流程。 - **硬件生态与平台能力持续拓展:** 新增10+款网卡、15+款硬盘、5+款RAID卡兼容性,部件更换后自动固件升级与配置恢复,实现即插即用;部件驱动框架新增62项能力并落地19项可观测框架;bmc-core重构算网融合上下电逻辑,带内IPMI实现秒级响应。 - **规范落地与质量保障体系完善:** Redfish/CLI/SNMP/WEB四协议全覆盖,17项特性灵活裁剪;SPDM可信根互联落地;社区用例接入每日构建,南向驱动规范测试用具落地,社区众测正式开启;部件驱动2.0全套指南与CSR/MDS配置语法齐套交付,SNMP/CLI接口文档自动生成。 本版本共计解决Issue 2693个、合入PR 4795条、新增代码行3742K。 了解更多版本信息:https://www.openubmc.cn/zh/news/2609-release 下载链接:https://www.openubmc.cn/zh/download ### ➣ SIG组月度动态 本月新增PR 1790 个,各sig组共召开公开例会 24 次,sig组活跃地图分布情况如下: #### ➣➣ sig-hardware 9月,sig-hardware在部件适配、运维保障与电源管理等方面持续推进,硬件兼容版图与可运维性进一步提升。 - **存储与硬盘适配:** 新增德明利TS3160 SATA SSD适配,新增备件更换场景下硬盘/RAID配置的自动备份和恢复,运维切换更可靠。 - **电源与供电管理:** 新增支持PM3000W DC电源管理、900W电源适配,支持thermal\_mgmt组件风扇管理功能灵活裁剪,供电与散热管理能力持续完善。 - **硬件升级与信息获取:** 新增182x系列带外命令获取卡信息、通过SFC方式对FPGA固件升级,硬件可管理性进一步增强。 #### ➣➣ sig-component-drivers 9月,sig-component-drivers在部件驱动、设备监控及框架库方面持续演进,驱动体系与自发现能力进一步完善。 - **component\_drivers:** CSR1汇聚读支持按位合并,连接器可按硬件热插拔能力加载卸载;落地RS485风扇管理与BMC主从DPU带外管理,补齐SSU的Bios/BootOptions契约,驱动管理粒度更细。 - **devmon:** 器件合并覆盖跨槽位共享总线;未由插件接管的芯片可直接访问驱动,降低CPU占用;支持按热插拔能力加载卸载、从升级分区加载驱动,并发布硬件加载完成状态,设备发现与加载流程更透明。 - **libmcpp:** sensor与event支持函数表达式;提供最小系统模式下的服务启动管理,同步属性跟踪可随一键收集导出;补充本地持久化的写入量与写入频次统计,可观测数据更完整。 - **vpd:** 补齐博通BCM957608-P1400G的产品关键数据(VPD)并更新同系列P2200G能力;网迅FF5025同步到CSR 2.0;合入宝德PR2715B的OCP与Riser配置,硬件识别与兼容持续扩展。 #### ➣➣ sig-bmc-core 9月,sig-bmc-core持续推进核心组件开源与文档沉淀:bmc\_network、firmware\_mgmt、bmc\_upgrade组件实现社区开源,并新增文档《固件管理设计思想》,核心组件开放与知识积累同步并进。 #### ➣➣ sig-security 9月,sig-security新增华为公司贡献的安全管理特性组件libiam、iam、capability\_proxy、certificate,身份认证与能力代理等安全管理能力进一步丰富。 #### ➣➣ sig-docs 9月新增文档33篇,覆盖组件说明、驱动适配、CSR配置、接口参考、构建指导等多个方向,重点包括: - **《部件类适配快速上手》:** 部件适配的最短可操作路径,手把手完成接入与验证 - **《南向网卡驱动适配指南》:** 从设计到实现的网卡适配完整开发流程 - **《Redfish资源索引集合》:** 新增Redfish资源接口参考文档 - **《Hi1712芯片构建指导》:** 涵盖环境准备、配置说明、构建流程与产物验证 此外,21篇组件说明文档及CSR配置字典、驱动规范、全局属性配置指导等也同步上线,社区知识底座持续夯实。 #### ➣➣ sig-ai 9月,sig-ai召开组会并总体确认openUBMC AI已由单点能力建设进入工程化和效果验证阶段,AI基础设施与场景化落地双线推进。 - **研发侧能力升级:** 持续升级RAG知识中台、MCP、Skills和Agent基础设施,后续将通过构建Benchmark验证知识中台相较裸Agent在准确率、任务完成率及Token和时延上的实际增益。 - **AI门禁架构演进:** 不再采用“大Skill+一次性Prompt”实现方式,向多专项Agent、并行执行、状态复用和Runtime/Harness化演进,门禁精准度与执行效率同步提升。 - **日志智能分析:** 进一步区分运维态与开发态——运维侧聚焦故障处置,开发侧结合日志、代码、历史变更和知识体系进行Agent化根因定位,问题定位链路更清晰。 - **Agentic BMC:** 已完成小模型上板可行性验证,后续重点从“能运行”转向真实平台性能与用户体验探索验证。 ### ➣ openUBMC 优质文章精选: 基于 openUBMC 构建 Agent 驱动的 BMC 研发工作流 一图读懂|openUBMC 8月社区文档更新清单 * * * ## 基础设施升级 ### ➣ 社区文档场景化架构升级 匹配开发者真实开发流程,围绕“入门与准备—核心开发场景—测试集成—交流贡献—工具与参考”五大任务全面升级文档架构,为不同类型、不同水平的开发者提供更清晰的学习路径,让文档更易获取。 ### ➣ 社区搜索能力优化提升 社区搜索范围已覆盖GitCode的PR/Issue;支持搜索结果版本切换,默认展示全部版本;同时新增搜索纠错、相关搜索和搜索反馈功能,检索体验更加智能便捷。 * * * ## 安全公告 9月,社区持续开展版本安全跟踪,对发现的安全问题及时评估、修复并发布公告,截至9月底共发布安全公告18个,CVE 76个,切实保障版本安全。 相关内容请关注官网安全公告:https://www.openubmc.cn/zh/security-advisories * * * ## 致谢 亲爱的社区开发者: 过去一个月,是你们的热情与奉献,让 openUBMC 社区持续迸发活力! 每一行代码的提交、每一次技术的探讨、每一份经验的分享,都在为社区注入前行的力量。正是每一位开发者的持续参与,让openUBMC的基础更加坚实、生态更加繁荣。 若您在阅读月报时发现遗漏了您的精彩贡献或重要进展,请随时联系我们补充。 开源之路,感恩同行!让我们携手打造更繁荣的算力设备管理开源生态。 在此,谨向为本期月报提供资料支持的各 sig 团队及广大开发者致以诚挚的感谢与敬意: * * * ## 欢迎关注openUBMC - 社区官网:https://www.openubmc.cn - 代码仓地址:https://atomgit.com/openUBMC 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/community-opration-report4/ --- 新闻资讯 openUBMC 社区 2026 年 4 月运作报告 # openUBMC 社区 2026 年 4 月运作报告 2026/05/11 ## 概述 2026年4月,openUBMC社区技术革新与生态发展同步迈入新阶段。生态方面,社区规模持续扩大:累计下载量突破13.5万+,活跃开发者超600人,成员单位27家;高校行活动走进长沙四所高校,开源实习项目正式启动,南方电网基于openUBMC的能效优化实践落地,社区更荣获“2025年明星开源社区”称号,产学研用协同效应显著增强。 技术方面,Hardware SIG持续推进RAID南向部件驱动与CPLD无感升级特性开发,CICD SIG完成白牌包定制构建能力集成并发布openUBMC Studio 2.0版本,Docs SIG新增多份CSR配置指导书与开发文档,AI SIG重点建设Skills Marketplace生态并上线AI接口规范检视功能,官网同步完成“快捷访达”导航与内容展示板块升级,进一步优化开发者体验。 从技术输出到生态协同,openUBMC以开放架构、智能运维、全栈兼容与高效开发为战略支点,全面构建安全繁荣的算力设备管理开源新生态,推动下一代数据中心基础设施迈向更高阶。 > **阅读提示**:本月报阅读时长约10分钟 * * * ## 社区规模 截至2026年4月30日,openUBMC社区用户累计下载量**13.5万+**,超过**600**名开发者在社区持续贡献,累计产生**8k**个PRs、**5.9k**条Issues、**38.9k**条comments。目前,已有**27家**成员单位加入openUBMC社区。 * * * ## 社区事件 ### ➣ openUBMC社区长沙高校行 2026年4月下旬,openUBMC社区联合CCF开展开源高校行活动,走进国防科技大学、湖南大学等四所长沙高校。活动以“开源技术赋能AI算力”为核心,通过技术分享、赛事宣讲深化产学研合作。社区专家围绕BMC智能算力管理、开源操作系统等前沿技术授课,并重点发布开源创新大赛赛题,聚焦“AI智能运维平台”与“嵌入式LLM应用”领域,鼓励学生基于openUBMC平台创新实践。活动期间,社区与高校达成多项合作意向,推动开源人才培育政策落地。本次行动有效提升了openUBMC技术影响力,为AI基础设施生态建设储备青年力量,助力社区开源使命与产业需求深度融合。 > **原文阅读**:LINK ### ➣ openUBMC 开源实习火热招募中! openUBMC社区本月重磅推出开源实习项目,面向在校大学生开放线上实践机会。项目依托社区真实项目场景,设置安全构建方案设计、Qemu能力研究、事件管理系统等多元技术任务,覆盖系统开发、硬件适配等领域。学生通过官网报名审核后即可认领任务,完成任务可累计积分兑换薪资(最高8000元),达标还可获得中国科学院软件研究所官方实习证明。社区为实习生配备资深导师全程辅导,表现优异者更有机会获得企业青睐。目前实习项目已开放报名,扫码即可加入交流群获取一手资讯,开启开源实战之旅! > **实习详情**:LINK ### ➣ openUBMC在Open AI Infra Summit分享超节点管理最新实践 2026年4月9日至10日,Open AI Infra Summit在北京成功举办。期间,openUBMC社区技术委员会委员黄晗在超节点生态分论坛上发表了题为《基于 openUBMC 打造超节点硬件智能管理平台》的主题演讲。此次分享深入剖析了智算集群规模化发展下的运维痛点,并系统性地提出了openUBMC的解决方案。演讲重点阐述了如何通过架构创新,构建超节点多BMC协同底座,实现CDI资源的透明管理;同时,强调了社区通过共建北向统一标准与标准化遥测接口,赋能AI智能运维闭环的核心价值。此次宣讲不仅展示了openUBMC在超节点管理和AI运维领域的技术前瞻性,也进一步巩固了社区在智算基础设施领域的影响力。 > **原文阅读**:LINK ### ➣ 荣誉:荣获“2025年明星开源社区”称号 2026年4月21-22日,在以“人工智能与软件变革——AI融合与数智出海新机遇”为主题的第五届中国国际软件发展大会上,openUBMC社区凭借其在算力设备管理领域的创新实践与生态贡献,荣获“2025年软件和信息技术服务业明星开源社区”称号。这一荣誉标志着openUBMC社区在推动国产开源算力设备管理软件发展方面取得的成就获得业界高度认可。 > **原文阅读**:LINK ### ➣ 实践创新:openUBMC在电力行业的典型应用落地 2026年4月29日,第九届数字中国建设峰会期间,华为计算产业峰会顺利举办。会上,南方电网带来了《南网妙算系列高能效服务器技术创新实践》主题分享,南网基于openUBMC实现模型预测控制算法落地,通过对服务器关键部件温度变化精准预测,实时测算整机最优功耗阈值,动态调节风扇转速,保障服务器整机始终处于最佳能效运行状态,助力数据中心绿色低碳、高效稳定运行。 本次实践是 openUBMC 在电力行业算力基础设施的典型落地应用,以开源硬件管理能力赋能行业算力能效升级,为智算中心绿色化转型提供了可借鉴的实践方案。 * * * ## 技术进展 ### ➣ 版本进展 openUBMC社区故障上报和工程能力增强,新增**五个代码仓**(sensor, event, ipmi等),分拆1个代码仓(component\_drivers),持续提升传感器、精细化告警、部件驱动和门禁规则等组件能力; 经技术委员会讨论和表决,确定openUBMC社区LTS版本的发行节奏,按照5/8/11/2季度火车发车,25.12 LTS配套及收编,onetrack运作; > **了解更多**:版本信息与下载 ### ➣ SIG组月度动态 本月新增PR数507个,各SIG组共召开公开例会27次。 **特别兴趣小组活跃度全景图** ### ➣ Hardware SIG - **RAID南向部件驱动特性**:旨在将RAID卡管理能力从应用层下沉至标准化的南向部件驱动框架,通过南向接口规范实现RAID卡、BBU、逻辑盘、物理盘、Expander等存储组件的统一管理;相关详细设计和代码开发进行中预计630发布。 - **CPLD无感升级特性**:旨在实现固件升级过程中业务不中断,实现CPLD无感升级能力构建;相关详细设计和代码开发进行中预计630发布。 ### ➣ CICD SIG - **白牌包定制构建**:首次在bingo中集成了白牌包定制能力,用户可自定义执行脚本和内容进行白牌hpm包构建。 - **openUBMC Studio发布**:在社区发布openUBMC Studio可视化BMC开发工具 2.0 版本,提供模型配置与检查、CSR可视化配置、一键出包、CSR出包等开发功能。 - **Robot Framework**:伙伴向社区贡献了基于Robot Framework开源测试框架实现的冒烟测试方案。 ### ➣ Docs SIG 4月新增文档上新:bitstring接口说明、基础板CSR配置指导书、风扇板CSR配置指导书、扩展板CSR配置指导书、IEU CSR配置指导书、整机PSR配置指导书,更新Docker开发环境搭建、持久化机制介绍、key\_mgmt密钥管理组件FAQ、BMC Studio用户指南、Docker开发环境搭建、KVM常见问题定位指南、网络管理常见问题指南。 ### ➣ AI SIG 4月份,AI SIG重点推进了Skills Marketplace生态建设,包括openUBMC Studio插件上线、技能扩展、数据飞轮的方案评审,完成了AI接口规范检视功能上线,并吸纳了新的Maintainer与Committer。 ### ➣ open UBMC 优质技术文章精选 - 一图读懂|openUBMC 3月社区文档更新清单 - 效率提升150%!基于openUBMC的高密存储服务器产品化实践 * * * ## 基础设施升级 ### ➣ 官网与信息架构全面升级优化 对社区官网的整体内容进行了全面补充升级,新增了openUBMC整体特性介绍、社区贡献、社区伙伴单位等内容,丰富了官网信息维度。同时对导航架构及信息层级进行全面优化,提升了内容查找效率与浏览体验,优化社区资源获取路径。 ### ➣ 组织架构成员新增补充 根据社区治理发展需要,对开源发展委员会和技术委员会(TC)的成员名单进行了新增和补充,确保社区组织信息的动态更新与治理角色的完整性。 * * * ## 致谢 亲爱的社区开发者: 过去一个月,是你们的热情与奉献,让 openUBMC 社区持续迸发活力! 无论是代码仓库中的匠心雕琢,还是技术论坛的思想交锋;无论是文档的精心编撰,还是活动的全力支持——每个“你”的参与,都是社区生态茁壮成长的养分。 若您在阅读月报时发现遗漏了您的精彩贡献或重要进展,请随时联系我们补充。 开源之路,感恩同行!让我们携手打造更繁荣的算力设备管理开源生态。 在此,谨向为本期月报提供资料支持的各 SIG 团队及广大开发者致以诚挚的感谢与敬意: 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/hangzhou-meetup-review/ --- 新闻资讯 共筑算力管理新未来|openUBMC Meetup回顾 # 共筑算力管理新未来|openUBMC Meetup回顾 2025/05/30 # 共筑算力管理新未来|openUBMC Meetup回顾 2025年5月26日,由openUBMC开源社区主办的首届Meetup在杭州成功举办。本次活动吸引了来自整机、互联网、IBV、部件、芯片等行业上下游的社区Maintainer、社区开发者等60余位行业精英,围绕openUBMC社区展开交流,共同探讨了openUBMC的技术演进路径与产业实践经验。 本次Meetup由上午的议题分享和下午的Workshop组成。现在,让我们回顾一下本次活动吧。 ## 议题分享 上午的分享由技术议题组成,来自5家企业的社区开发者分享了各自的技术议题。 ### 开场介绍 张雨博代表openUBMC社区技术委员会介绍了本次Meetup的具体议程,并分享了当前openUBMC社区更新,包括社区25.03版本的新特性、25.06版本展望、社区运营数据分享、BMC Studio特性快照,和社区门户网站的下一步规划。 ### DT在北向接口中的优秀实践 黄晗代表Interface SIG介绍了如何利用UT能力对北向映射配置进行单元测试,大幅度缩短开发调试周期的同时提高了社区代码质量看护能力。他呼吁社区开发者后续在北向接口中持续开展UT测试的建设,共同提高openUBMC北向接口稳定性。 ### 南向部件驱动规范 刘兴森代表Hardware SIG介绍了如何通过规范化的部件兼容方式解决不同硬件差异性适配的问题,同时通过开放式架构支持部件厂商自行在社区上开发BMC部件驱动。他呼吁社区更多的志同道合之士共同加入规范建设讨论中。 ### 开发者构建与流水线构建实践 来自武汉长江计算科技有限公司的易重辉介绍了长江计算如何基于openUBMC社区Conan仓搭建了自己的构建流水线体系,他还结合实际案例,分享了在搭建过程中遇到的各类技术挑战及应对经验,为开发者们提供了极具实践价值的参考。 ### 智能网卡适配经验分享 来自河南昆仑技术有限公司的包敏敏结合河南昆仑在openUBMC智能网卡项目交付中的实战经历,深入剖析了项目实施过程中遇到的各类技术难题,并分享了团队在攻克这些难题时积累的宝贵经验与心得。 ### 开发实践问题案例分享 同样来自河南昆仑技术有限公司的熊子锐作为新接触BMC领域的开发者,将上手openUBMC中遇到的问题总结成经验心得,让更多的新开发者快速上手openUBMC。 ### 智能串口屏自研组件方案介绍 来自宝德计算机系统有限公司的邱豪深入剖析了宝德如何在openUBMC平台上,凭借自研组件成功实现串口屏功能的创新突破。他详细解读了技术细节与实现路径。同样来自宝德的朱俊杰先生,则聚焦于新增组件的全流程管理,总结并分享了其中的关键步骤与宝贵经验,为开发者们提供了极具参考价值的实践指南。 ### 北向接口适配分享 四川华鲲振宇智能科技有限公司的张强详细介绍了如何巧妙运用北向映射机制,将原本需要1.5人月的接口适配工作量,高效压缩至仅需3人天即可完成。这一创新方法不仅大幅提升了工作效率,更为企业节约了宝贵的时间与资源,引发了现场开发者的广泛关注与热烈讨论。 ## 实战Workshop 下午的实战Workshop由openUBMC社区技术委员会发起的,聚焦社区核心技术与热门话题,通过沉浸式开发场景赋能开发者成长。活动设置代码实战、分组攻坚、开放讨论等多元环节,参与者通过手写关键模块、协同调试代码、即时方案论证,零距离体验开源协作的创造力与凝聚力。现场开发者反馈:"学习和交流了很多问题,遇到的问题都得到了很好的解答。"本次Workshop通过「以战代练」的创新模式,助力开发者深化技术理解,推动社区生态共建。 ## 总结 本次Meetup通过不同企业的技术经验分享,展现了openUBMC社区开发者对技术的热爱和钻研精神,为BMC开发者提供了一个开放的、技术为导向的交流平台。后续openUBMC社区会持续举办线下技术活动,欢迎更多的开发者参与! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/kadc-2025/ --- 新闻资讯 KADC 2025 | openUBMC技术分论坛圆满举办:共筑智能化算力的管理底座 # KADC 2025 | openUBMC技术分论坛圆满举办:共筑智能化算力的管理底座 2025/05/27 # KADC 2025 | openUBMC技术分论坛圆满举办:共筑智能化算力的管理底座 2025年5月24日,鲲鹏昇腾开发者大会(KADC)在北京中关村国际创新中心盛大召开。作为大会重要组成部分,以“openUBMC:共筑智能化算力的管理底座”为主题的技术分论坛吸引了来自互联网云厂商、整机商、部件商、标准组织、高校等领域的开发者,与会者共同探讨开源设备管理软件的未来发展。 ## 开场致辞:开源共建,引领产业未来 华为计算产品线云与计算硬件部部长任超为分论坛致辞。他回顾了华为自2003年投入服务器研发以来在BMC领域的深厚积累,强调华为BMC以“极致安全”为根基,为全球算力设备提供智能化管理能力。任超表示:“计算产业是生态型产业,BMC作为关键一环,唯有通过开源才能凝聚产业上下游智慧,共建算力管理生态。”华为作为openUBMC社区发起者,将开源二十余年的技术沉淀,并持续投入社区治理、技术创新和生态建设,推动形成“开放、协作、透明、共建、共享、共治”的开源社区。他呼吁开发者共同参与,将openUBMC打造为全球领先的数字基础设施管理软件。 华为计算产品线 云与计算硬件部部长 任超 ## 主题演讲:开源实践与生态共赢 分论坛演讲围绕openUBMC的技术创新与行业实践展开六场重磅分享: ### 共建openUBMC社区,共筑智能化算力管理底座 openUBMC社区秘书长王瑞锋深入剖析了AI时代下多元算力所面临的管理挑战与机遇。他明确提出了社区的使命:致力于提供开源且标准化的数字基础设施设备管理软件,汇聚全球开发者的智慧,在跨平台、跨领域以及全产业链上持续创新。在演讲中,他详细介绍了社区的架构设计、工具链功能以及创新实例化路径,并正式发布了openUBMC 25.03社区发行版。最后,他向广大开发者发出呼吁,倡导“同源共振”,携手推动版本的持续迭代与创新。 openUBMC社区秘书长 王瑞锋 ### 开放式架构构筑管理软件平台新形态 openUBMC技术委员会委员宋铜铃在演讲中,从算力行业对设备管理的诉求演进进行分析,提出了微组件架构的设计原则,以解决产业从单机到集群的管理难题。强调通过标准化接口和统一组件框架,实现南北向管理的开放性与适配性,并通过“一站式开发平台”,助力开发者在社区持续创新。 openUBMC技术委员会委员 孙铜铃 ### 基于openUBMC构建&自动化测试经验分享 来自四川华鲲振宇智能科技有限责任公司的刘松在分享中深入介绍了基于openUBMC的构建与自动化测试实践。他详细阐述了华鲲振宇如何通过组件化设计显著提升集成效率,有效缩短版本发布周期,并保障项目的高效与高质量交付。 四川华鲲振宇智能科技有限责任公司 刘松 ### 基于openUBMC端到端交付实践与案例解析 在演讲中,来自河南昆仑技术有限公司的王钦东详细介绍了河南昆仑的openUBMC一体化解决方案。他通过展示鲲鹏/昇腾机型商用发行版的端到端交付案例,深入阐述了如何借助社区力量实现商用化落地,为行业提供了宝贵的经验和思路。 河南昆仑技术有限公司 王钦东 ### 基于openUBMC的BMC Studio工具链的应用实践 来自昆仑太科(北京)技术股份有限公司的王亚洲在演示中展示了BMC Studio工具链的强大功能,特别是在开发环境搭建和部件定制方面的高效应用。充分凸显了openUBMC的易用性与易扩展性,为开发者提供了极具价值的参考和启示。 昆仑太科(北京)技术股份有限公司 王亚洲 ### 基于openUBMC的conan组件构建与管理实践 来自南京百敖软件有限公司的汪涛在分享中详细介绍了Conan组件的构建实践,以及百敖在相关构建场景下的丰富经验积累。他指出,通过社区的集中化依赖管理,能够显著提升对客户需求的响应效率,为企业的技术发展和客户服务提供了有力支持。 南京百敖软件有限公司 汪涛 本次分论坛通过不同企业的技术分享与案例实践,展现了openUBMC社区在推动算力管理底座智能化中的多元化价值和作用,为产业提供了更开放、更高效的开源设备管理软件。 ## 加入我们 openUBMC社区将持续汇聚全球开发者力量,共同打造数字基础设施管理的开源标杆。扫描下方二维码关注社区动态,携手共建算力管理生态! 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/meetup-callfor/ --- 新闻资讯 议题征集|openUBMC Meetup成都站、深圳站,诚邀您提交议题 # 议题征集|openUBMC Meetup成都站、深圳站,诚邀您提交议题 金秋时节,openUBMC开源社区将在10月31日来到成都,在11月7日来到深圳,举办两场线下Meetup技术交流活动。在此,我们面向全体开发者公开征集Meetup议题,期待在活动现场听到你的声音! 2025年10月31日、 2025年11月07日 成都、深圳 ## 活动议程 # 议题征集|openUBMC Meetup成都站、深圳站,诚邀您提交议题 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/openAI-infra-summit/ --- 新闻资讯 开源筑基,智算同行!锁定4月10日Open AI Infra Summit,openUBMC与你共探超节点智能管理新未来 # 开源筑基,智算同行!锁定4月10日Open AI Infra Summit,openUBMC与你共探超节点智能管理新未来 2026/04/08 ## 概述 智算时代加速演进,超节点架构与开源协同正成为算力基础设施升级的关键方向。作为算力设备管理开放生态的核心力量,openUBMC持续以开放架构破解行业痛点,推动硬件管理标准化、智能化与生态化发展。 2026年4月10日,Open AI Infra Summit超节点生态分论坛即将开启,openUBMC将带来重磅主题演讲,分享基于开源体系构建超节点硬件智能管理平台的最新实践。 ## 本次演讲亮点抢先看: - **1.聚焦超节点Scale-Up架构趋势,直击AI算力硬件管理核心痛点;** - **2.深度解读openUBMC如何构建统一、可复用、高可靠的智能管理引擎;** - **3.分享开放生态协同方案,助力伙伴快速落地超节点硬件智能化能力;** - **4.前瞻产业标准与技术路线,共筑智算基础设施开源新生态。** 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/openUBMC-annual-report-2025/ --- 新闻资讯 openUBMC开源社区2025年度报告 # openUBMC开源社区2025年度报告 2026/01/16 # openUBMC开源社区2025年度报告 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/shenzhen-meetup-review/ --- 新闻资讯 openUBMC Meetup 深圳站成功举办,共探开源BMC技术与生态新进展 # openUBMC Meetup 深圳站成功举办,共探开源BMC技术与生态新进展 2025/11/10 # openUBMC Meetup 深圳站成功举办,共探开源BMC技术与生态新进展 2025年11月7日,openUBMC Meetup深圳站成功举办。本次活动汇聚了来自硬件厂商、开发者、企业用户等多方代表,围绕openUBMC社区最新进展、南向部件驱动、可观测技术、多机型构建、AI测试融合等热点议题展开深度分享与研讨。 ## 社区进展与版本发布 **openUBMC技术委员会委员张雨博**分享了社区最新进展:25.09版本在代码贡献、硬件兼容性与开发者体验上取得突破性进展;社区首个LTS版本——25.12的规划也已启动,将重点增强接口规范与部件驱动框架等能力。与此同时,社区运营持续活跃,通过在西安、成都、深圳等各地举办活动,进一步连接广大开发者,共建开放协作的技术生态。议题的最后,张雨博表示,2026年技术规划已开启,现公开征集技术需求与创新建议,诚邀全球开发者共同参与,推动openUBMC生态持续演进。 ## 关键技术议题深度解析 ### 南向部件驱动框架:标准化管理,生态共建 **openUBMC Component Drivers SlG Maintainer 刘兴森**系统介绍了openUBMC南向部件驱动规范的逻辑架构与实现路径。该框架通过统一接口标准,实现硬件适配与BMC应用层解耦,支持部件即插即用,显著降低开发与定制成本。目前,已有部分网卡、GPU已在社区落地,Q4会继续发布更多的部件。同时,《服务器南向接口要求》已完成标准立项,正面向社会公开征集意见中。 ### 可观测技术:从数据到洞察,提升运维效率 **openUBMC Interface SlG Maintainer 李四光**深入讲解了openUBMC在Trace、Metric、Logs三大信号维度的能力建设。通过集成OpenTelemetry标准、Grafana可视化与Prometheus监控等系统,实现了系统状态的全链路可观测,助力故障定位与性能优化。 ### 开发者说:openUBMC实战案例分享 - **3D Web服务器交互系统创新实践** **宝德计算BMC研发主管邱豪**分享了基于Vue+Three.js构建的沉浸式3D管理界面,通过硬件故障可视化定位与远程运维支持,展现了openUBMC在现代运维体验方面的创新突破。 - **PCIe Switch在鲲鹏平台的深度适配** **同泰怡软件工程师彭爽**揭秘了在鲲鹏平台上实现PCIe Switch设备识别、槽位管理与BMC界面集成的全流程适配方法,展现了openUBMC在复杂硬件环境中的强大兼容性。 - **NVMe逆序编排与故障灯反转实战** **openUBMC TC委员&河南昆仑BMC架构师王钦东**分享了通过定制化CSR配置与CPLD协同,实现客户对NVMe盘符逆序编排与故障指示灯行为灵活定制的完整方案,体现了openUBMC在客户定制化需求方面的卓越能力。 - **多机型自动化构建流水线实践** **河南昆仑BMC研发工程师黄奥**展示了基于Docker与Bingo工具链的多分支、多机型自动化构建与归档方案,显著提升了版本交付效率,为社区开发者提供了可靠的构建实践参考。 - **自动化测试与质量保障体系** **河南昆仑BMC研发工程师钱强**介绍了Redfish标准化测试工具与iTestSmart自动化测试平台的深度应用,在831条用例中实现93%通过率,为社区提供了可靠的质量保障方案。 - **1GE网卡南向适配完整流程** **网迅!科技固件工程师余天文**演示了网迅如何在openUBMC平台上完成网迅网卡的自适配流程,通过CSR配置、NCSI协议测试与驱动集成快速将网迅网卡适配至openUBMC社区,为广大部件开发者提供了全新的思路。 - **多节点服务器散热管理挑战与突破** **恒扬数据软件工程师李天亮**深入探讨了多节点服务器场景下BMC间协同调速、数据同步与异常容错等架构挑战,为社区在多节点管理能力建设方面提供了重要思路。 ## Workshop:动手实践,深度互动 在Workshop环节,社区为与会开发者准备了南向部件驱动与可观测技术两大专题的动手实践。现场开发者们踊跃参与,在社区专家的指导下,体验了从理论到实践的完整过程。 本次Meetup不仅是技术成果的集中展示,更是社区协作与生态共建的生动体现。随着25.12 LTS版本的筹备与2026年技术规划的启动,openUBMC社区将继续携手开发者与企业伙伴,推动开源BMC技术在架构领先、标准开放、安全可信的方向上持续演进。 ## 🚩 期待下一期 openUBMC Meetup! 技术的交流与探索永无止境,openUBMC 社区的脚步不会停歇。未来,openUBMC Meetup 将走进更多城市,把前沿的技术分享、实用的实操体验带到各地开发者的身边。openUBMC 将持续深耕社区建设,汇聚更多技术力量,丰富社区生态,让每一位开发者都能在社区中收获成长与价值。 ### 您可以查阅我们的官方网站、论坛,了解 openUBMC更多信息⬇️ - openUBMC 官方网站 https://www.openubmc.cn/zh - openUBMC 论坛 https://discuss.openubmc.cn/ 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/ubmc-studio/ --- 新闻资讯 openUBMC Studio 正式发布 # openUBMC Studio 正式发布 2026/03/31 ### 资源获取: openUBMC Studio下载链接:https://www.openubmc.cn/zh/marketplace/openUBMC Studio openUBMC Studio使用手册:https://www.openubmc.cn/docs/zh/development/tool\_guide/bmc\_studio\_tool.html ### 资源获取: openUBMC Studio下载链接:https://www.openubmc.cn/zh/marketplace/openUBMC Studio openUBMC Studio使用手册:https://www.openubmc.cn/docs/zh/development/tool\_guide/bmc\_studio\_tool.html 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/ubmc-studio-2.0.3/ --- 新闻资讯 openUBMC Studio 2.0.3 发布 # openUBMC Studio 2.0.3 发布 2026/07/13 ### 资源获取: openUBMC Studio下载链接:https://www.openubmc.cn/zh/marketplace/openUBMC Studio openUBMC Studio使用手册:https://www.openubmc.cn/docs/zh/development/tool\_guide/bmc\_studio\_tool.html ### 资源获取: openUBMC Studio下载链接:https://www.openubmc.cn/zh/marketplace/openUBMC Studio openUBMC Studio使用手册:https://www.openubmc.cn/docs/zh/development/tool\_guide/bmc\_studio\_tool.html 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/news/xian-meetup-review/ --- 新闻资讯 活动回顾|openUBMC Meetup 西安站 # 活动回顾|openUBMC Meetup 西安站 2025/08/22 # 活动回顾|openUBMC Meetup 西安站 8月18日下午,openUBMC X 昆仑太科 Meetup西安站圆满举办。现场近30位企业开发者线下参与。本次 Meetup 聚焦社区 25.06 版本的新特性,以Workshop形式开展,**围绕可观测技术运用、社区测试能力提升和软件能力提升**三大核心主题展开实操体验。开发者在动手实践中增强了对技术的理解,加强了对社区发展的认识,并进一步激发了参与社区建设的热情。 ## Topic:openUBMC Community Updates **openUBMC 社区技术委员会委员张雨博介绍了活动流程及社区最新进展,涵盖 25.06 版本特性、25.09 版本规划以及社区组织与运作机制,帮助开发者全面了解社区在技术迭代和生态建设方面的成果**。25.06 版本在可定位性和工具易用性方面引起广泛关注,25.09 的版本规划也让开发者对社区未来充满期待。社区组织与运作机制的透明介绍,为开发者更深入参与社区工作提供了清晰路径。 ## 可定位性Workshop:可观测技术运用 **openUBMC 社区 Interface SIG 的李四光深入介绍了可观测特性**,从技术原理到应用场景系统讲解,帮助开发者掌握从数据采集、指标监控到日志分析的全流程方法,深化对 BMC 软件系统性观测的理解。 ## 社区测试能力提升Workshop:社区冒烟测试运用和实践 **张雨博和林万敏代表 CICD SIG,分享了 25.06 版本中基于 Robot Framework + Qemu 实现的冒烟测试体系**。林万敏通过实际案例演示了如何利用 Robot Framework 开发 BMC 北向接口测试用例,使开发者直观体验到自动化测试的高效与便捷。 ## 软件能力提升Workshop:大模型辅助编码运用和实践 **张雨博与李兆天围绕设计、编码和测试三大维度,结合 openUBMC 实际案例,解析了社区特性设计方法、代码编写策略及测试用例设计流程**。李兆天展示了如何借助 AI 大模型工具链实现设计文档自动生成、测试用例自动编写与 DT 代码自动生成,为开发者提升效率提供新思路,并鼓励大家积极探索 AI 辅助编码的潜力,贡献创新方案。 ## 🚩 期待下一期 openUBMC Meetup! 技术的交流与探索永无止境,openUBMC 社区的脚步不会停歇。未来,openUBMC Meetup 将走进更多城市,把前沿的技术分享、实用的实操体验带到各地开发者的身边。openUBMC 将持续深耕社区建设,汇聚更多技术力量,丰富社区生态,让每一位开发者都能在社区中收获成长与价值。 ### 您可以查阅我们的官方网站、论坛,了解 openUBMC更多信息⬇️ - openUBMC 官方网站 https://www.openubmc.cn/zh - openUBMC 论坛 https://discuss.openubmc.cn/ 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/operations-rules/ --- # 技术委员会运作规则 # 政策规则 了解openUBMC社区的运作规则、行为准则、AI贡献策略等相关内容 技术委员会运作规则社区行为准则AI贡献策略 openUBMC社区技术委员会运作规则 ## 总则 openUBMC开源社区技术委员会(Technical Committee, 简称TC)是 openUBMC 社区项目的技术管理机构,提供技术指导、决策和监督。 ## 主要职责 技术委员会是社区的技术领导机构,其主要职权是: 1. 技术委员会拥有技术决策的最终裁决权。 2. 决策社区技术的发展愿景和方向。 3. 决策社区 SIG 的成立、撤销、合并等事务。解决 SIG 组之间的协作冲突,辅导、审视和监督 SIG 组的日常运作。 4. 落实社区日常开发工作,保证 openUBMC 社区发行版高质量发布。 5. 引导社区建立原创性开源项目,持续构建社区技术影响力。 ## 构成 技术委员会设主席 1 名,主席的职权是: 1. 召集和主持技术委员会会议,并保证参会人员有充分表达技术意见的权利。 2. 在各类会议、活动中代表社区进行宣传。 3. 主席同时是技术委员会委员,拥有和其他委员相同的投票权利。 openUBMC 开源社区TC主席及成员,由 openUBMC 社区任命,包含对 openUBMC 社区做出重大贡献并愿意持续投入的人员。 ## 会议召开与决策机制 技术委员会每月召开技术委员会例会,或二分之一以上委员提议召开临时会议。 1. 技术委员会会议由主席在会议召开前 5 个自然日通过邮件在邮件列表通知全体委员,会议通知应当包括召开的地点、日期、时间、方式和会议议题以及可用的参考来源,以便委员对会议内容获取相关信息进行准备。会议为公开会议,任何社区成员都可以参加会议,表达技术观点但无投票权利。 2. 技术委员会会议须有三分之二以上(含)的委员出席为有效会议。 3. 所有决议均需要在有效的例会进行投票表决,投票为公开记名投票。投票分为赞同票、反对票和弃权票,只有三分之二以上(含)的与会委员且超过全体委员会的二分之一投赞同票,决议才能通过,未到场委员不能委托其他人代替投票。 ## 联系方式 邮件列表:tc@public.openubmc.cn 线上会议:请前往SIG中心参与 # 社区行为准则 # AI贡献策略 --- https://www.openubmc.cn/zh/organizations/ --- # Organizational Structure The openUBMC community is governed by an elected TC and operates with full transparency to ensure an impartial and forward-looking technical roadmap. We champion the principle: Contribution Earns Influence. Advance your role to a project maintainer or TC member, and collectively define openUBMC's future. 更多 ## Vision & Mission The openUBMC community offers open source and standardized software for managing digital infrastructure. By harnessing the collective expertise of developers, it drives continuous innovation across all platforms, domains, and the entire industry value chain. ## Organizational Structure The openUBMC community's governance is defined by the Open Source Development Committee. The Secretariat, led by the Secretary-General, oversees routine operations, while the Technical Committee (TC) sets the technical direction. ## Open Source Development Committee 马银川 主席 华为技术有限公司 Email 王瑞锋 秘书长 华为技术有限公司 Email 卞兴中 委员 深圳云芯智联信息技术有限公司 Email 蔡积淼 委员 北京软通华方计算机有限公司 Email 陈刚 委员 河南昆仑技术有限公司 Email 陈林 委员 四川云海芯科微电子科技有限公司 Email 陈小春 委员 昆仑太科(北京)技术股份有限公司 Email 丁雁林 委员 北京兴汉网际股份有限公司 Email 高贤虎 委员 海思技术有限公司 Email 高兴华 委员 北京网迅科技有限公司 Email 高瞻 委员 南京百敖软件有限公司 Email 洪坤贤 委员 中科驭数(北京)科技有限公司 Email 鞠荣荣 委员 百信信息技术有限公司 Email 李浩杰 委员 深圳市恒扬数据股份有限公司 Email 李雪莲 委员 中国电子技术标准化研究院 Email 李志高 委员 腾讯云计算(北京)有限责任公司 Email 林国辉 委员 无锡沐创集成电路设计有限公司 Email 刘敬轩 委员 中移(苏州)软件技术有限公司 Email 刘胜 委员 浙江力积存储科技股份有限公司 Email 刘玉伟 委员 北京光润通科技发展有限公司 Email 苗福友 委员 全球计算联盟 Email 庞玮 委员 天翼云科技有限公司 Email 彭小南 委员 神州鲲泰(厦门)信息技术有限公司 Email 盛永 委员 百度在线网络技术(北京)有限公司 Email View All ## Technical Committee (TC) 宋铜铃 主席 Email 陈莹亮 委员 Email 陈士豪 委员 Email 程子明 委员 Email 黄晗 委员 Email 黄嘉庆 委员 Email 刘松 委员 Email 刘兴森 委员 Email 刘宇杰 委员 Email 司昌谅 委员 Email 王钦东 委员 Email 汪涛 委员 Email 王亚洲 委员 Email 许晓菡 委员 Email 于飞 委员 Email 张超 委员 Email 章建平 委员 Email 张雨博 委员 Email 赵锐 委员 Email 钟君 委员 Email ## Secretariat 王瑞锋 秘书长 Email 陈莹亮 执行秘书&生态组长 Email 何芦微 执行秘书&运营组长 Email 刘怿 执行秘书&营销组长 Email --- https://www.openubmc.cn/zh/roadmaps/ --- 文档中心 体验地图 社区体验地图 01 ## 认识openUBMC 什么是openUBMC openUBMC定义了一款开源BMC软件栈,基于灵活可伸缩的架构、敏捷易用的开发工具、丰富的生态资源,支持广大开发者打造差异化BMC功能,自由定制竞争力特性 文档中心开发工具社区支持openUBMC提供哪些服务 02 ## 文档中心 开发指南 丰富文档助力开发者快速上手openUBMC,灵活定制专属的BMC软件 快速入门 03 ## 开发工具 BMC Studio 直观的拖拽式可视化开发工具与一步到位的构建工具,打造开发者友好的开发工具库 BMC Studio 在线会议 社区论坛 04 ## 社区支持 论坛 SIG组会 供开发者自由交流的社区论坛、工作组会议线上直播,共建开发者深度参与的社区 05 ## 与openUBMC共同成长 创建组织 组织介绍 组织管理 SIG管理与开发者团队建设 --- https://www.openubmc.cn/zh/sig/ --- # SIG Center Special interest groups (SIGs) are the foundational units of the openUBMC community. These open groups are organized around specific technical domains to streamline management and improve workflows. Join a SIG to collaborate on projects, share knowledge, and co-create with fellow developers. Join Our SIGs 了解SIG运转 SIG是openUBMC社区管理运营的最小单位,由社区开发者组成并独立运作。每个SIG围绕一个或多个技术主题成立,负责管理相关代码仓库,并通过参与社区项目推动技术落地和持续创新。 进行SIG交流 您可以在SIG中心页面内查阅SIG信息、SIG中的Repository列表与联系方式等内容。或前往openUBMC community仓库对应的SIG目录下查阅README.md文件。欢迎您通过邮件列表和公开例会的方式参与SIG的交流与讨论。 使用openUBMC会议创建功能需要SIG组Maintainer或Committer身份权限。创建会议 参与SIG贡献 openUBMC社区诚邀开发者、技术爱好者及行业专家加入协作生态。您可通过代码提交、文档完善、功能测试等多种形式参与社区建设。 社区为贡献者提供清晰指引,具体详情请查看 SIG贡献指南 About SIGs SIG角色说明 了解openUBMC社区贡献者的角色及其职责。 SIG会议指南 openUBMC SIG会议是SIG的核心活动之一,通过定期地召开会议,SIG成员可进行技术方案审议、开发进度对齐、技术问题答疑及未来路线规划等,从而推动SIG组的持续创新。 ### SIG申请流程 当你和你的朋友有了非常好的技术idea,并且希望更多的人参与到你们的探索中,那么你就可以申请成立一个新的SIG了。查看具体申请流程 创建 填写信息 配置 提交PR 发送申请 改进 ### SIG订阅指南 您可以通过订阅感兴趣的SIG组的邮箱来获取最新相关信息,包括SIG组的会议邀请、线上讨论等。查看具体订阅流程 选择订阅的SIG组 填写信息 确认订阅邮件 成功订阅 openUBMC SIGs 暂无数据 --- https://www.openubmc.cn/zh/sig/TC/ --- SIG中心 TC TC 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 TC个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/apply/ --- SIG Center SIG Application Process # 申请流程 ## 总则 申请创建SIG之前,请查阅现存的SIG列表并确认是否某个SIG已满足您的述求。正式申请创建SIG之前,建议在OpenUBMC论坛或公共邮箱发起讨论,这样可以为新SIG获得更多的关注度与反馈,有助于确认SIG的使命与范围并吸纳更多的SIG成员。 正式创建SIG需要参照SIG管理指南在community仓库创建Pull Request,并向社区技术委员会发邮件申请。技术委员会会定期组织评审决定是否通过申请。 ## 角色说明 | 角色 | 主要职责范围 | 操作 | | --- | --- | --- | | Contributor | 项目贡献者,认领Isssue 和 PR 并在 PR 提交前完成测试 | AtomGit注册成员 | | Committer | 项目代码审核者,分配Issue与PR,并审核代码的质量和正确性 | SIG 的积极贡献者,经验丰富,愿意投入精力参与到审核工作 | | Maintainer | 项目Owner,确定SIG所负责项目的技术路线并制定项目的发布计划 | 经验丰富,富有责任心、出色的技术能力和管理能力 | ## 申请步骤 ### 步骤一:使用SIG模板创建自己的新SIG - 将 atomgit.com/openubmc/community Fork到你的AtomGit下,利用SIG申请模板在sig目录创建你的sig文件夹,以及把SIG申请模板拷贝到该文件夹下。 `git clone https://atomgit.com/${YOURGITCODE}/community cd ./community/sig cp -r sig-template sig-${YOURSIGNAME} cd sig-${YOURSIGNAME}` ### 步骤二:完成新SIG README内容的填写 - 打开新创建sig目录下的README.md文件,按照推荐完成必选内容的填写 `vi README.md` ### 步骤三:完成新SIG成员与SIG仓库的配置 - 请在sig-info.yaml文件中完成对SIG成员的配置 `vi sig-info.yaml` ### 步骤四:提交PR - 将以上修改提交到AtomGit上,并在AtomGit上创建一个Pull Request。 ### 步骤五:向TC发送邮件申请 - 给技术委员会发邮件(邮箱tc@public.openubmc.cn),并在正文中包含主题“新SIG提案”和PR的链接 ### 步骤六:TC评审并反馈意见 - 技术委员会将通过合并Pull Request的方式来批准您的申请。合入后社区基础设施团队会负责配置SIG相关角色与代码仓。 html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);} --- https://www.openubmc.cn/zh/sig/infrastructure/ --- SIG中心 infrastructure infrastructure 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 infrastructure个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/role-description/ --- # 角色说明 在openUBMC社区,开发者主要通过参与SIG(Special Interest Group)来贡献自己的力量。无论Contributor、Committer、Maintainer,都是社区重要的贡献者角色,他们的主要区别在于参与的SIG治理范围不同。 SIG中心 角色说明 贡献者 职责:通过代码开发、问题修复和文档完善等方式推动社区发展。 要求:理解社区技术,遵守社区规范,积极参与社区贡献。 查看详情 审核者 职责:通过细致的代码评审帮助提升社区代码质量,同时以自身贡献带动社区共同进步。 要求:具备丰富项目经验,熟悉代码规范,能够提供建设性意见并乐于分享经验。 查看详情 维护者 职责:把握技术方向并推动关键决策,通过关键领域的贡献领导社区的长期发展。 要求:深入理解项目架构,善于协作沟通,认同开源精神并长期引领社区成长。 查看详情 新的贡献者 欢迎新成员加入社区。我们有关于如何开始贡献的指导文档请参考openUBMC 贡献者指南 既有社区成员 既有的社区成员应认可社区导向,遵守openUBMC 社区的行为守则,熟悉社区运作机制和技术能力。 社区非活跃成员退出标准和流程请参考非活跃成员退出标准和流程 ## 贡献者Contributor 贡献者是openUBMC社区的核心力量,他们通过代码开发、文档完善、问题修复、社区运营等多种方式积极参与,共同推动项目的创新与发展。 ### 加入要求 - AtomGit 上的注册会员 - 为 SIG 或社区做出多方面贡献,包括不限于:在 AtomGit 上提交或审核PR;在 AtomGit 上对问题进行归档或评论;参与 SIG 或社区讨论 - 已阅读 贡献者指南 - 积极参与 1 个或多个 SIG ### 责任与权益 - 响应被分配的问题和PR - 对贡献的代码负责,保证贡献的代码:经过良好的测试;能够让测试用例始终通过,并保证DT覆盖率满足社区要求;解决后继发生的错误或问题 - 负责具体实现设计,并通过 SIG 评审 - 获得成为 SIG 审核者 Committer 的权利。 贡献代码的同时积极参与代码审查、设计评审等活动,即可以成为 SIG 的审核者 Committer ## 审核者Committer 审核者是代码仓库的核心维护者,拥有代码合入权限。他们凭借丰富的技术经验,通过代码评审、开发者测试和规范检查等方式保障代码质量,并推动组件的技术演进与长期健康发展。 ### 加入要求 - 作为贡献者至少 3 个月 - 作为主要审阅者至少参与了 6 次 PR 的审阅 - 审阅或合并至少 20 个基本 PR 到代码库 - 熟悉代码库 - 可以自我提名,或由该 SIG 的审核者 Committer 或维护者 Maintainer 提名,并在SIG会议通过 - 或者一次性贡献具备完整特性的组件,也可直接成为Committer ### 责任与权益 - 评审 PR:对 Contributor 提交的 PR 完成评审,基于代码的设计、实现、安全性、可扩展性、兼容性等为度给出公正客观的评价 - 熟知社区开发流程,并指导 Contributor 按照社区开发流程完成代码贡献,保障社区开发流程正确的应用 - 针对接口变更,指导 Contributor 参与社区接口变更评审会议,充分地预审,确保组件接口的设计合理性、兼容性、必要性、易读性、易用性 - 看护组件的软件工程能力,在SIG组中建立良好的软件工程文化 - 看护组件的代码实现设计,确保特性设计的合理性 - 更新和维护组件的版本,与社区项目版本保持一致 - 获得成为 SIG 维护者 Maintainer 的权利。 成为 SIG 内多个代码仓的审查者,积极参与 SIG 技术规划和架构演进,即可以成为 SIG 的维护者 Maintainer ## 维护者Maintainer 维护者是SIG组的核心领导者,负责技术方向规划、社区协作和长期发展。他们不仅具备审核者的所有职责,还主导组件的架构演进、质量保障和生态适配,并通过协调社区内外资源推动SIG目标的实现。 ### 加入要求 - 作为审核者至少 3 个月 - 作为主要审阅者至少参与了 12 次 PR 的审阅 - 审阅或合并至少 30 个基本 PR 到代码库 - 熟悉 SIG 超过一半的代码库 - 可以自我提名,也可以由本 SIG 维护者 Maintainer 提名,并且没有其他 维护者 Maintainer 的反对,并在TC会议通过 ### 责任与权益 - 确定 SIG 所负责项目的技术路线:包括规划和决策 SIG 技术方向、路标规划、架构演进 - 看护SIG组的技术设计方案,在SIG组内营造良好的技术氛围 - 制定 SIG 所负责项目的发布计划:确定 SIG 的关键需求和发布计划;参与社区的 PM 活动,并协调 SIG 计划和社区版本的里程碑时间表匹配 - 参与社区协调活动:作为 SIG 的代表参与 openUBMC 组织的活动和特定会议等 - 召集 SIG 会议:定期召集 SIG 会议,决策 SIG 内上升的争议 - 代表 SIG 参加技术委员会,汇报 SIG 工作和进展 - 获得可参与技术委员会委员选举的权利。 积极提升 SIG 影响力,与其他 SIG 共同协作,即有机会参与技术委员会委员选举 --- https://www.openubmc.cn/zh/sig/sig-CICD/ --- SIG中心 CICD CICD 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 CICD个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-Linkedsemi/ --- SIG中心 Linkedsemi Linkedsemi 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 Linkedsemi个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-QA/ --- SIG中心 QA QA 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 QA个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-ai/ --- SIG中心 ai ai 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 ai个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-application-process/ --- SIG中心 application-process application-process 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 application-process个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-bmc-core/ --- SIG中心 bmc-core bmc-core 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 bmc-core个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-component-drivers/ --- SIG中心 component-drivers component-drivers 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 component-drivers个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-docs/ --- SIG中心 docs docs 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 docs个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-framework/ --- SIG中心 framework framework 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 framework个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-hardware/ --- SIG中心 hardware hardware 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 hardware个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-hisilicon/ --- SIG中心 hisilicon hisilicon 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 hisilicon个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-interface/ --- SIG中心 interface interface 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 interface个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-om/ --- SIG中心 om om 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 om个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-release-management/ --- SIG中心 release-management release-management 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 release-management个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/sig-security/ --- SIG中心 security security 在AtomGit上查看更多内容 核心成员(0) 会议与活动 工作会议 邮件列表 ## 仓库列表(0) | 仓库名称 | Committer | | --- | --- | | | 暂无数据 贡献展示 security个人会员贡献 度量指标 合并请求 PR 需求&问题 Issue 评审 Comment 统计周期 \- Maintainer Committer Contributor | 序号 | GitCode ID | PR | | --- | --- | --- | | | 暂无数据 --- https://www.openubmc.cn/zh/sig/subscribe-guide/ --- SIG中心 订阅指南 # 订阅指南 01 ## 选择订阅的SIG组 查看感兴趣的SIG组,点击"前往订阅" 02 ## 填写信息 在订阅邮件页面内,填写相关个人信息,点击确认订阅 03 ## 确认订阅邮件 您的邮箱将收到一封来自该SIG组的电子邮件,要求您确认订阅了邮件列表,点击确认链接完成订阅 04 ## 成功订阅 当收到一封欢迎邮件,即成功订阅该SIG组邮件列表 --- https://www.openubmc.cn/zh/usercase/ --- # 用户案例 了解openUBMC在各行业的最佳案例 (软通华方)[/zh/usercase/building-agent-driven-bmc-rd-workflow] (昆仑太科)[/zh/usercase/implementing-blade-chassis-integrated-management-via-northbound-self-onboarding] (神州鲲泰)[/zh/usercase/implementing-pice-switch-with-multi-gpu-self-discovery] (长江计算)[/zh/usercase/building-sourthbound-hardware-compatible-ecosystem] --- https://www.openubmc.cn/zh/usercase/building-agent-driven-bmc-rd-workflow/ --- 用户案例 基于 openUBMC 构建 Agent 驱动的 BMC 研发工作流 # 基于 openUBMC 构建 Agent 驱动的 BMC 研发工作流 2026/10/09 ### 一、应用背景 BMC 固件研发涵盖源码开发、构建部署、设备验证全链路,任务进度与验证证据分散零散、缺乏统一追溯机制。引入智能 Agent 虽可推进编码与工具调用,但任务跨阶段、会话中断仍需人工重复梳理衔接;同时 BMC 故障属于典型跨层问题,依赖多维度交叉核验,零散的工具调用无法形成可信闭环。因此,亟需一套支持断点续跑、操作可对账、以设备真实状态为验收标准的标准化研发工作流。 ### 二、解决方案 软通华方依托 openUBMC 资源模型、组件化开发与设备管理能力,构建了 openUBMC Agent Workflow。该工作流由四层协同: - 宿主 Agent 负责规划与工程判断; - 领域工作流通过 Skill 选择诊断、开发、构建、部署或验证路线; - Target Runtime 基于 MCP 管理任务进度、目标连接、资源调度、变更记录与验收结果; - 工程环境提供源码/构建能力与真实设备现场。 工程师定义目标与验收条件后,各层协同自主推进分析、修复、构建、升级与实机验证。 图 1:openUBMC Agent Workflow 全链路执行与职责分工 **核心能力一:工程对象贯通**:基于 MDS 模型、MDB/D-Bus 资源对象与北向接口映射,结合源码依赖与构建工具链,保证源码改动、固件制品与设备业务结果三者可追溯。 **核心能力二:长流程断点续跑与多任务并发**:编译、重启等耗时环节后台运行,中断后可续接;同一任务内无依赖动作并行执行,多任务错峰开展,系统按依赖与资源统一调度。 **核心能力三:可信执行闭环**:任务档案(Case)保存目标与阶段结果;变更日志(Mutation Journal)记录写操作并核验设备真实状态,避免超时误判;证据账本(Evidence Ledger)管理变更前后证据;任务验收(Closeout)以设备实测结果为准,达标才算闭环。 ### 三、典型场景示例:RAID 控制器信息缺失修复 某项目 RAID 卡可识别但控制器信息不显示,日志显示 libsml\_lsi.so 加载失败、错误码 4357,定位为适配库缺失。基于 openUBMC Agent Workflow 自动完成依赖修正、测试构建、固件升级及设备恢复,并校验适配库加载与接口状态,研发人员仅需处理核心决策与复杂异常,大幅削减机械值守与重复操作,显著提升故障修复与版本交付效率。 图 2:人工组织与 Workflow 自主推进对比 ### 四、客户价值 - **高效跨层研判**:统一任务目标串联领域知识、源码、接口与设备证据,并行分析快速收敛故障范围。 - **释放人力成本**:构建、升级、重连、核验等重复动作自动化,工程师专注高价值研发。 - **多任务并行调度**:利用编译、重启等待窗口并行推进其他任务,提升单位时间交付量。 - **沉淀工程资产**:排查逻辑、构建流程、验收规范固化为领域 Skill,同类任务直接复用,持续优化流程。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/usercase/building-sourthbound-hardware-compatible-ecosystem/ --- 用户案例 基于 openUBMC 南向部件规范共建硬件兼容生态 # 基于 openUBMC 南向部件规范共建硬件兼容生态 2026/05/28 # 长江计算 & 沐创集成电路基于 openUBMC 南向部件规范共建硬件兼容生态 ### 背景 随着数字经济与算力基础设施快速发展,金融、政务、运营商等行业对服务器的兼容性、稳定性、交付效率提出更高要求;鲲鹏新型号的规模化落地,也推动整机产品向多样化、场景化升级,客户对多品牌硬件部件的快速适配、稳定兼容需求日益迫切。 传统服务器部件适配模式高度依赖整机厂商定制开发,周期长、耦合度高、复用性差,难以快速响应客户业务迭代与硬件更新需求,也制约了算力基础设施生态的完善与规模化推广。在此背景下,整机与部件厂商基于开源开放架构实现协同联创、快速适配,成为行业提升交付能力、满足客户高质量需求的关键路径。 ### 解决方案 长江计算联合沐创,依托 openUBMC 南向部件规范及驱动框架,充分发挥其标准化接口、模块化驱动的核心优势,打造标准化、模块化的硬件部件兼容适配方案,构建高效协同的产业联创模式。 #### 南向部件适配框架 - **接口标准化** 基于 openUBMC 南向部件规范,统一服务器部件驱动接口、部件模型与描述信息,通过 CSR 完成标准化承载,部件厂商可依据统一规范独立开发驱动,无需依赖整机厂商 BMC 软件栈,大幅降低适配门槛,实现部件快速接入适配。 - **开发模块化** 基于 openUBMC 南向部件驱动框架的模块化设计,按网卡、xPU、RAID 等类型构建标准化管理接口模型,将驱动代码独立封装,部件厂商无需掌握 BMC 全量技术,聚焦自身部件即可完成开发,提升适配效率与代码复用性。 - **生态联创交付** 依托 openUBMC 社区完善的基础设施与南向部件规范体系,建立整机厂商 + 部件厂商 + 开源社区三方协同模式,分工清晰、高效协作,实现需求快速响应、高质量交付,践行社区 “共建共享、生态共赢” 的理念。 ### 价值 - **适配交付更高效** 打破传统定制开发壁垒,基于 openUBMC 南向部件规范实现需求快速落地,大幅缩短部件适配周期,高效支撑客户服务器迭代升级与业务平稳过渡。 - **产品兼容更稳定** 通过统一的 openUBMC 南向部件规范与模块化设计,降低软硬件耦合风险,提升服务器硬件兼容性与运行可靠性,保障客户业务连续稳定。 - **生态成本更优化** 构建开放共赢的产业链协同 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/usercase/implementing-blade-chassis-integrated-management-via-northbound-self-onboarding/ --- 用户案例 基于 openUBMC 北向自接入实现刀片机箱节点一体化健康管理 # 基于 openUBMC 北向自接入实现刀片机箱节点一体化健康管理 2026/07/30 ### 一、应用背景 当前,AI 算力数据中心广泛采用高密度刀片机箱,单机箱内置多片独立刀片,每片刀片搭载专属 BMC 管理芯片。传统 BMC 仅支持单节点本地管控,彼此隔离形成管理孤岛,存在以下运维痛点: - sensor、fru\_ctrl 等基础组件仅管理本机资源,缺少跨板通信接口; - 缺乏统一的数据聚合上报通道,网管系统只能逐一轮询各刀片 BMC; - 交换刀片 Web 界面缺少整机视角,无法集中查看整机刀片健康状态并远程控制; 多重限制叠加,进一步造成 IPMB 总线拥堵、页面卡顿、多终端数据不一致、故障发现滞后等问题,大幅降低集群运维效率。 ### 二、解决方案 昆仑太科基于 openUBMC 开源架构自研 health\_manager 专用管理组件,部署于交换刀片 BMC,充分利用社区北向自接入能力,将 UDP 上报、Web 展示、MDB 接口扩展等北向功能以独立组件形式接入框架,使团队得以聚焦于跨刀片管理核心逻辑的实现。 health\_manager 通过 IPMB 总线统一采集框内所有刀片数据,经 blade\_cache 缓存后,同步供给 Web 展示与网管系统,构建底层采集、上层可视化上报双业务闭环。 关键技术创新包括: - **采集-缓存-服务三层分离**:引入 blade\_cache 中枢后,Web 详情响应从 600ms 降至 5ms 以内,IPMB 总线负载恒定,多用户并发无阻塞; - **MDB 与 RPC 混合数据模型**:MDB 仅维护每刀片 1 个聚合对象,详情页通过 RPC 直接读取缓存原子快照,大幅降低 D-Bus 信号开销; - **双通道统一数据源**:Web REST 与 UDP 上报共享同一份 blade\_cache 数据,彻底消除多通道数据不一致; - **自适应降级采集**:默认 3s 轮询,刀片失联自动降频至 10s/30s 并标记离线;刀片采集时间错峰偏移 100ms,规避总线瞬时抢占; - **数据面异步、控制面同步**:采集与页面刷新异步进行保证总线平稳,上下电控制同步穿透,指令延迟 ≤200ms | 指标 | 传统穿透模式 | 本方案缓存模式 | | --- | --- | --- | | Web 详情响应 | 12×50ms = 600ms | < 5ms | | IPMB 峰值负载 | 随 Web 并发线性增长 | 恒定 | | 多用户并发 | 总线拥塞互相阻塞 | 无影响 | _新旧方案核心性能对比_ 此外,方案构建了通信层(超时自动重试、降频等)、服务层(Skynet 心跳监控、systemd 自动拉起等)、安全层(IPMB 通道隔离、UDP 白名单校验、Web 权限管控等)三层防护体系,保障机房 7×24 小时稳定运行。 ### 三、客户价值 - **管理效率大幅提升**:Web 详情响应从 600ms 降至 5ms 以内,运维人员可在秒级内感知整机箱健康状态,端到端上报延迟 ≤4s,无需逐个访问刀片 BMC,故障快速定位。 - **运维准确性显著增强**:Web 与网管系统共享同一数据源,彻底消除多通道数据不一致导致的误判。 - **系统稳定性充分保障**:自适应降级采集避免单刀片故障拖垮整机采集链路;三层防护体系确保通信异常、进程崩溃等场景下服务持续可用。 - **架构开放,可快速扩展**:基于 openUBMC 北向自接入能力,核心采集链路与北向功能完全解耦,后续对接新网管协议或扩展新可视化维度均可独立迭代,无需改动底层采集链路,方案演进的技术风险与回归验证成本大幅降低。 【版权声明】Copyright © 2026 openUBMC Community。本文由openUBMC社区首发,欢迎遵照CC-BY-SA 4.0协议规定转载。转载时敬请在正文注明并保留原文链接和作者信息。 【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。 --- https://www.openubmc.cn/zh/usercase/implementing-pice-switch-with-multi-gpu-self-discovery/ --- 用户案例 基于 openUBMC 实现 PCIe Switch 多 GPU 自发现 # 基于 openUBMC 实现 PCIe Switch 多 GPU 自发现 2026/05/29 ### 应用背景 随着大模型训练场景规模化落地,行业对单机高密度算力、低延迟互联、高稳定部署的需求持续提升。传统 CPU 直出架构受原生 PCIe 通道物理限制,难以满足海量 GPU 挂载、高效算力互联的业务需求,存在带宽瓶颈、通信延迟高、组网灵活性不足、硬件设计成本高、故障易扩散等痛点,无法适配 AI 训练场景对服务器高性能、高可靠、高灵活的严苛要求。 \*该图仅用来解释switch的作用,并非实际拓扑 ### 解决方案 神州鲲泰基于openUBMC 开源开放架构,依托其完善的硬件适配能力与标准化扩展框架,完成 PCIe Switch 板深度适配,实现 AI 服务器多 GPU 智能自发现、统一管控与全链路硬件监控,打造适配高密度算力场景的 AI 服务器硬件管理方案。 | 关键特性 | 规格描述 | | --- | --- | | 产品形态 | 机架式服务器 | | 处理器 | 2*鲲鹏920新型号 (48/64/核,最高主频2.9GHz) | | AI加速卡 | 最多支持10张全高全长双宽AI加速卡 | | 内存 | 最多支持32*DDR5 4800MT/s 及以上内存,支持ECC、热备、镜像等多种保护模式 | | 存储控制器 | 支持大容量缓存及超级电容。提供RAID级别迁移、磁盘漫游、自诊断、Web远程设置等功能,支持直通、RAID0、1、5、6、10、50、60等多种存储方案,支持RAID卡安全启动 | | 本地存储 | 前置:支持123.5"盘位,其中8SAS / SATA+4*NVMe,支持热插拔 | | 灵活插卡 | 支持1OCP3.0标准网卡(4GE电口 / 2*25GE光口) | | PCle槽位 | 支持12*PCIe 5.0 x16扩展槽位 | | 接口 | 4USB 3.0接口,2VGA接口,2UID按键&指示灯,1串口、1*RJ45管理网口 | | 电源模块 | 4热插拔CRPS 2600W电源,支持2+2冗余 / 4热插拔CRPS 2000W电源,支持3+1冗余 | | 风扇模块 | 配置12*颗热插拔风扇,支持单风扇失效状态下稳定工作 | | 工作温度 | 5℃~35℃ | | 尺寸 | 高176.8mm宽447.4mm深871.4mm | ### 客户价值 1. **突破硬件瓶颈,支撑高密度算力部署** 突破 CPU 原生 PCIe 通道物理上限,通过 PCIe Switch 实现通道高效拓展,满足单机海量高性能 GPU 挂载需求,完美支撑大模型训练的算力规模要求。 2. **优化算力互联,大幅提升训练效率** 实现 GPU 点对点低延迟直连通信,减少 CPU 中转带来的带宽损耗与数据延迟。相较传统 CPU 中转模式,带宽从 25GB/s 提升至 42GB/s,提升幅度约 70%,有效增强多卡算力协同效率,全面优化 AI 模型训练效果。 3. **架构灵活可靠,适配多元业务需求** 支持基于 PCIe Switch 的硬件拓扑灵活定制,可根据客户算力规模、业务场景、成本预算等差异,快速调整链路分配与总线规划,高效匹配多样化部署诉求。 4. **简化硬件设计,降本增效** 简化服务器主板 PCIe 高速走线设计,降低信号干扰与硬件故障风险,减少整机研发与生产成本,提升服务器规模化交付能力。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/1.0.0/ --- 文档中心 版本说明 版本选择 # openUBMC 1.0.0 社区首版本正式上线! 2024/12/31 # openUBMC 1.0.0 社区首版本正式上线! ## 版本概览 openUBMC 是一款架构领先、开发友好、开放标准的开源 BMC。采用协议“木兰宽松许可证”(Mulan PSL V2),用户可以自由复制、使用、修改、分发,不论修改与否。 openUBMC 版本号采用点分位命名规则(X.Y.Z)模式,其中 X 表示每年发布版本,Y 表示每半年发布版本,Z 表示补丁版本。正常每半年会发布一个 Y 版本,每年发布两个版本。 openUBMC 生命周期初步规划为 0.5 年。 ## 版本特性 - 支持微组件架构,组件通过总线互联,具备组件、插件、配置多重扩展能力。 - 提供标准化的 SDK 套件供社区使用并兼容 D-Bus 总线协议,支持组件快速开发并接入系统。 - 支持南向硬件定制通过生成配置数据方式接入,实现低代码开发。 - 支持北向接口映射配置,实现"0"代码简化增量开发。 ## 源代码 开源软件代码仓:https://atomgit.com/openubmc ## 致谢 我们衷心地感谢参与和协助 openUBMC 项目的所有成员,是你们的辛勤付出使得版本顺利发布! openUBMC 在不断的发展中,未来还会有更多好用的特性发布,这里也非常欢迎大家下载并体验,并参与到openUBMC 开源社区建设中来,也期待聆听每一位用户的反馈意见! 社区邮件列表:community@openubmc.org \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/25-12-LTS-SP2/ --- 文档中心 版本说明 版本选择 # openUBMC 25.12 LTS SP2 版本发布说明 2026/05/31 # openUBMC 25.12 LTS SP2 版本发布说明 * * * ## 版本概览 该版本是基于25.12 LTS SP1发布的补丁版本,openUBMC 25.12 LTS SP2采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 25.12 LTS SP2版本在25.12 LTS SP1版本基础上进行开发,特性交付范围包括: ### 北向接口生态 #### 1\. 运维与管理功能 - 新增 VNC 最大会话数定制功能。 ### 丰富度:硬件接入与功能增强 #### 1\. 网卡与硬盘接入能力扩展 - 新增 182X 新代次标卡、DC1000C GPU卡、9款 SATA SSD 和11款 NVMe SSD 等兼容性。 #### 2\. 故障诊断增强 - 增强 CSR 异常检测能力。 - 增强 IERR 故障上报能力。 ## 源代码 25.12 LTS SP2版本源代码已发布至社区网站:https://openubmc.cn/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 25.12 LTS SP2 | 25.12 LTS SP1 | 5.12.0 | 5.11.0 | 5.10.0 | 5.9.0 | | --- | --- | --- | --- | --- | --- | --- | | 25.12 LTS SP2 | Y | Y | Y | N | N | N | | 25.12 LTS SP1 | N | Y | Y | Y | N | N | | 25.12 | N | N | Y | Y | N | N | | 25.09 | N | N | N | Y | N | N | | 25.06 | N | N | N | N | Y | N | | 25.03 | N | N | N | N | N | Y | * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3690536 | 带内os热升级SATA SSD盘固件版本,BMC上显示的硬盘固件版本不更新 | storage | | 3644159 | 电源通讯异常,通过北向接口查询电源功率、电压、温度、电流等动态信息显示为0 | power_mgmt | * * * ## 已修复问题 本修复问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3873976 | 修复开箱检测日志刷屏 | chassis | | 4035170 | 硬盘日志自动收集任务阻塞其他业务对总线的访问 | storage | | 3878904 | nvme热插拔遍历,NVMe硬盘调速策略未加载 | storage | | 3834737 | 线缆信息无法获取时,日志刷屏 | pcie_device | | 3867075 | 存储管理页面直通盘不显示接口类型 | storage | | 3720145 | raid卡通讯丢失上报告警 slot与实际slot不符 | vpd | | 4030661 | 修复/redfish/v1/Systems/1/VirtualMedia/CD接口设置Password报错时响应体中的Password敏感词未加密的问题 | rackmount | | 4035589 | redfish接口查询到的传感器数量和ipmi命令查询到的不一致 | sensor | * * * ## CVE 漏洞 暂无 * * * ## OPEN SOURCE SOFTWARE NOTICE Open Source Software Notice * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/25-12-LTS-SP3/ --- 文档中心 版本说明 版本选择 # openUBMC 25.12 LTS SP3 版本发布说明 2026/08/31 # openUBMC 25.12 LTS SP3 版本发布说明 * * * ## 版本概览 openUBMC 25.12 LTS SP3 版本是基于 25.12 LTS SP2 发布的补丁版本,该版本采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 25.12 LTS SP3 版本在 25.12 LTS SP2 版本基础上进行开发,特性交付范围包括: ### 丰富度:硬件接入与功能增强 #### 1.硬件接入能力扩展 - 新增182X新代次SP566标卡、MCX653105A-HDAT/MCX755106AS-HEAT网卡等兼容性 - 新增沐创N10G-X2-DC/N20G-R2F-25G网卡、光润通F1002T-V3.0 intelX550网卡、博通BCM957416A4160C万兆双电口网卡、博通BCM957416A4160C万兆双电口网卡、星云智联S1055AS-A00CHT(2\*25G)网卡等兼容性 - 新增HK EP810/EP820/EP910/EP92、德明利TS3160、紫光闪芯、佰维、英韧、长江存储等硬盘兼容性 - 新增900W电源、EXP 12盘背板等兼容性 #### 2.故障诊断增强 - 优化扩展板CPLD localbus链路异常检测机制 #### 3.运维能力提升 - 优化BIOS固件和TEE固件同时生效机制。 - 优化SP686C Raid卡固件日志收集机制和日志可读性。 ## 源代码 25.12 LTS SP3版本源代码已发布至社区网站:https://openubmc.cn/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 5.12.0.35 | 5.12.0.17 | 5.12.0.5 | 5.12.0.1 | 5.11.0 | 5.10.0 | 5.9.0 | | --- | --- | --- | --- | --- | --- | --- | --- | | 25.12 LTS SP3 | Y | Y | Y | Y | N | N | N | | 25.12 LTS SP2 | N | Y | Y | Y | N | N | N | | 25.12 LTS SP1 | N | N | Y | Y | Y | N | N | | 25.12 | N | N | N | Y | Y | N | N | | 25.09 | N | N | N | N | Y | N | N | | 25.06 | N | N | N | N | N | Y | N | | 25.03 | N | N | N | N | N | N | Y | * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 4290337 | 缺陷: 在kunlun2280V2机型,模拟"OCP网卡温度获取失败"、”OCP卡温度过高告警“、”OCP卡降速告警“,产生的告警码与《2280V2告警参考手册》中的预期告警码不符。 | vpd | * * * ## 已修复问题 本版本已修复问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 4131933 | 缺陷: 升级 retimer后提示下电生效 | webui | | 4115989 | 缺陷: 新适配的SATA SSD适配后搭配1880raid卡厂商信息仍显示ATA问题 | storage | | 4111714 | 缺陷: SensorName属性取消const描述 | sensor | | 4125875 | 缺陷: 1880卡支持多个启动设备 | webui | | 4239258 | 缺陷: 监听ReadyToEnumerate增加属性判空 | bios | | 4153771 | 缺陷: 下载一键收集日志的操作日志内容需优化 | webui | | 4126377 | 缺陷: 部分GPU部件编码、异常功率读值和芯片型号显示异常 | vpd | | 4166445 | 缺陷: 告警问题需修改配置修复 | vpd | | 4157064 | 缺陷: 同时导入csr失败时打印操作日志 | general_hardware | | 4165576 | 缺陷: 新建用户被误删 | account | | 4132154 | 缺陷: 修改NVME硬盘组RAID场景下Revision信息获取的方式 | storage | | 4131977 | 缺陷: SNMP新增0x2D000031、0x280003D告警修复redfish/v1//System/1/Processors/Gpu1查询GPU温度 创建VNC会话,redfish查询当前会话数为0,预期应该与web查询一致 修复网络适配下部件编码显示为N/A 修复ipmcset -t maintenance -d importcsr -v回显不完整 | rackmount | | 4127088 | 缺陷: main分支反合至lts分支 | power_mgmt | | 4157051 | 缺陷: 需要支持从BMA解析网卡永久MAC地址 | network_adapter | | 4156083 | 缺陷: 修复DC1000异常温度读值为0和厂商与CSR不一致的问题 | general_hardware | | 4128485 | 缺陷: 调制日志级别,避免日志刷屏 | general_hardware | | 4154306 | 缺陷: fru信息更新时出现非utf-8数据导致北向接口查询报错 | frudata | | 4172231 | 缺陷: web点击下电实际无法正常下电 | fructrl | | 4156376 | 缺陷: 调整ATA硬盘通过ManufacturerOUI获取厂商名的逻辑,并修复控制器下硬盘列表未更新到资源树的问题。 | storage | | 4156371 | 缺陷: 修复网卡SupportedLLDP配置和光模块默认值误告警,支持设置RAID卡bootdevice | vpd | | 4166720 | 缺陷: Power接口设置时大概率返回412错误 | rackmount | | 4160707 | 缺陷: PowerSupplyStatus添加默认值 & 修复由于防互升标志被误清导致BIOS升级失败的问题 | bios | | 4156275 | 缺陷: 修复下电场景下磐石DPU卡powerstate未及时刷新的问题 | general_hardware | | 4164482 | 缺陷: 网卡概率性温度获取失败告警 | network_adapter | | 4156262 | 缺陷:修复partnumber修改失败问题 | network_adapter | | 4172459 | 缺陷: 下电后风扇pwm不显示为0 | thermal_mgmt | | 4128587 | 缺陷: 1880 RAID卡不显示SN | storage | | 4166827 | 缺陷: redfish资源查询PowerHistoryData、 Measurement接口时返回404 | rackmount | | 4156535 | 缺陷: 删除磐石DPU上下电时冗余操作日志记录 | pcie_device | | 4156597 | 缺陷修复/redfish/v1/Chassis/:chassisid/PCIeDevice/:id接口修改属性回显异常问题 | rackmount | | 4160712 | 缺陷: 修改0xA000061告警snmp trap oid | rackmount | | 4251117 | 缺陷: SP625D 增加FRU写保护 | vpd | | 4250350 | 缺陷: 在自协商无法获取的情况下,FC卡的自协商字段在BMC上显示值为默认值“已关闭”,显示不合理 | network_adapter | | 4275168 | 缺陷:WEB设置raid卡启动项后,提示操作成功,实际没有切换启动项 | webui | | 4265965 | 缺陷: 网卡的温度告警门限、温度传感器状态取值、厂商名称、是否支持MCTP需调整 | vpd | | 4266420 | 缺陷: 适配非2口卡光模块温度问题 | mdb_interface | | 4111639 | 缺陷: 新增告警码0x000000F3和0x000000F5 | vpd | | 4111678 | 缺陷: sensorname属性取消const描述 | mdb_interface | | 4111661 | 缺陷: 记录pll热切换日志 | general_hardware | | 4129157 | 缺陷: 调整固件升级上传固件大小上限为110M | webui | | 4183089 | 缺陷: 修复EEPROM读写测试项失败问题 | frudata | | 4266731 | 缺陷: os上下电和bmc复位场景会误报BBU在位/不在位事件 | storage | | 4267537 | 缺陷: os上下电和bmc复位场景会误报BBU在位/不在位事件 | vpd | | 4268976 | 缺陷: EepromV2类型FRU 反写头的内容错误 | frudata | | 4268417 | 缺陷: 支持北向接口获取和设置RAID卡的多个启动盘 | storage | | 4267021 | 缺陷: 支持北向接口获取和设置RAID卡的多个启动盘 | rackmount | | 4267743 | 缺陷: BMC上报CPLD信息异常 | general_hardware | | 4265849 | 缺陷: SDI卡 VLAN 未就绪时 IPv4 配置持续失败 | general_hardware | | 4265834 | 缺陷: 修正安全模块Protocol默认值 | vpd | | 4251788 | 缺陷: /redfish/v1/Chassis/1/Power接口设置ExpectedRedundancy请求体缺失,回显信息里Message显示不全 | rackmount | | 4087078 | 缺陷: 增加Drvwritedelay属性配置 | component_drivers | | 4154006 | 缺陷: 环境上安装两张沐创网卡时,只有一张正常显示通过oem_smbus获取到的信息 | network_adapter | | 4273297 | 缺陷: 补充manager_account_backup_db_obj对象的create_mdb_object函数实现 | account | | 4057042 | 缺陷: ipmi命令进行dpu上下电,判别参数的逻辑有误 | general_hardware | | 4266569 | 缺陷: 电源升级过程中被升级的电源输入功率要变成0 | power_mgmt | | 4260286 | 缺陷: cpu阈值接口问题 | rackmount | | 4241585 | 缺陷: 0x2C000007告警描述未更新 | vpd | | 4260706 | 缺陷: AirCofig/CoolingPolicy获取不到 | thermal_mgmt | | 4245107 | 缺陷: 电子标签写入队列加固 | frudata | | 4228834 | 缺陷: MCU Flash日志收集逻辑修改为只向BCU的MCU发送 | general_hardware | | 4277517 | 缺陷:修复异常显示VRD待升级状态的问题 | general_hardware | | 4261055 | 缺陷:web 服务器上下电界面设置下电时限10秒,web界面点下电整机无法正常下电成功 | manifest | | 4200367 | 缺陷: 模拟光模块温度获取失败,但是环境没有产生光模块获取失败告警 | network_adapter | | 4263802 | 缺陷: BMCSet_DrivesLogAutoCollectEnable 定制失败 | storage | | 4238909 | 缺陷 双SP686C RAID卡MCTP通信失败:worker线程与smld线程跨lua_State竞态 | storage | | 4229670 | 缺陷: 修复导入证书时,日志有多余的warning打印 | rackmount | | 4269286 | 缺陷: 修复用于二级缓存cli查询的单词拼写错误 | rackmount | | 4266686 | 缺陷: 修复命令行导入用户公钥的示例不正确问题 | rackmount | * * * ## bmc\_sdk(5.12.0.35)已修复问题 已修复问题清单: | | 问题描述 | 关联仓库 | | --- | --- | --- | | 1 | 修复删除资源对象时未清理对象error信息的问题 | hwproxy | | 2 | 修复IPMI修改备份IP报错问题 | bmc_network | | 3 | 修复概率性产生bmc_core、libmcc组件异常退出问题 | libsoc_adapter | | 4 | 修复未收集SATA硬盘smart信息的问题 | libmgmt_protocol | | 5 | 修复使用IPMI备用端口连接SOL报错问题 | rmcpd | | 6 | 优化内存占用率 | libmc4lua | | 7 | 修复CPLD升级失败问题 | firmware_mgmt | | 8 | 修复Redfish接口Accept请求头不支持大写字母问题 | redfish | | 9 | 修复删除过期CA证书后仍有CA证书过期告警问题 | certificate | | 10 | 修补开源软件漏洞 | sqlite3 nginx libssh2 curl | | 11 | 修复获取硬盘厂商错误问题 | libmgmt_protocol | | 12 | 修复VNC输入异常问题 | remote_console | | 13 | 修复资源树和协议栈mac不一致导致BMC网络不通问题 | bmc_network | | 14 | 修复设置启动设备未生效问题 | libmgmt_protocol | | 15 | 优化网络转发规则 | bmc_network | | 16 | 修复失效license在AC掉电后信息丢失 | license | | 17 | 修复key_mgmt组件概率启动失败问题 | key_mgmt | | 18 | 修复bmc_network、power_strategy组件异常记录日志 | power_strategy | * * * ## CVE 漏洞 暂无 * * * ## 接口变更 无 * * * ## OPEN SOURCE SOFTWARE NOTICE Open Source Software Notice * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/25.03/ --- 文档中心 版本说明 版本选择 # openUBMC 25.03 版本发布说明 2025/03/31 # openUBMC 25.03 版本发布说明 * * * ## 版本概览 作为25年首版本,openUBMC 25.03 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发,不论修改与否。 * * * ## 版本特性 25.03版本在1.0.0版本基础上进行开发,特性交付范围包括: ### 北向接口生态 1. 安全框架升级 - 支持密码策略定制化配置 - 实现用户名规则自定义功能 - 新增证书管理基础模块 2. 运维功能优化 - 配置导入/导出标准化 - 出厂重置保留用户数据 - 重构MCU/VRD升级架构(解耦式设计) - 支持hpm标准化升级包格式 ### 南向部件扩展 1. 管理能力增强 - 调速策略能力支持 - 多SML库加载 2. 部件适配 - 支持SP322D/SP323D网卡 - 支持NVMe-MI v7协议linkspeed查询 ### 开发体验优化 1. 开发工具增强 - bingo支持本地调试 - bingo支持模型检查功能 2. BMC Studio发布至社区 - 支持CSR配置检查 - 支持全模型检查 * * * ## 源代码 25.03版本源代码已发布至社区网站:https://www.openubmc.cn/zh/download * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3026302 | 产品调速策略未适配所有机型,社区提供调速策略定制能力,需要开发者基于整机产品自行定制 | thermal_mgmt | * * * ## 已修复问题 暂无 * * * ## CVE 漏洞 暂无 * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/25.06/ --- 文档中心 版本说明 版本选择 # openUBMC 25.06 版本发布说明 2025/06/30 # openUBMC 25.06 版本发布说明 * * * ## 版本概览 作为25年第二个创新版本,openUBMC 25.06 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 25.06版本在25.03版本基础上进行开发,特性交付范围包括: ### 北向接口生态 1. 可观测性服务:覆盖日志、独立、跟踪等数据的采集和存储能力; 2. 升级方案优化:支持固件并行升级与统一生效; 3. 接口功能优化:支持针对不同客户提供接口灵活扩展和定制能力; 4. 接口升级:IPMI和Redfish标准接口升级,主要包含Power、Drive和Thermal等; 5. 独立KVM开发套件:支持独立KVM客户端通过websocket链接到BMC,实现VMM功能,电源控制功能,系统启动项管理功能; 6. 新增规范:支持资源树协作接口关键字规范; ### 南向部件扩展 1. 板卡接入丰富度:新增网卡(标卡和OCP)、RAID卡、硬盘、NVMe盘、TPM卡、DPU、SDI、GPU、NPU等部件接入,详细接入清单参照vpd代码仓; 2. 南向协议能力:支持NVMe-mi over mctp的协议解析;支持使用pldm协议获取网卡部分信息;支持NCSI边带管理功能;支持PMBus1.2/CANBUS协议; 3. 能效管理能力:支持功率、电源固件升级、电源告警功能、供电信息、供电模式、时钟同步等管理能力; 4. DFX能力:支持电源砖精细化管理能力,支持动态组合获取硬盘的SMART信息,支持硬盘(SSD)寿命管理; ### 开发体验优化 1. BMC STUDIO: 支持可视化图形开发和自动化检测功能,完成CSR开发和语法合法性检查;提供VSCode插件一键完成QEMU安装、配置、启动和调试; 2. QEMU仿真功能: 支持仿真镜像的构建与发布;支持Qemu工具的构建与发布;支持仿真数据的发布。当前已支持EEPROM,HisPort,BMC芯片等数据插件; 3. 自动化防护:支持kptest测试框架基础能力建设和自动化用例; 4. 工程能力: 支持工具生成产品、客户层级的全量接口配置;支持组件工具依赖自管理;支持编译构建及ut/it的门禁检查;支持组件的全量二进制构建;支持组件转维发布能力;支持社区开发者签名出包等;提供调试工具能力; * * * ## 源代码 25.06版本源代码已发布至社区网站:https://openubmc.cn/zh/download * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | https://atomgit.com/openUBMC/mdb_interface/issues/135 | 资源协作接口属性和方法Description字段修改 | mdb_interface | | https://atomgit.com/openUBMC/fructrl/issues/15 | 老版本导入新版本上电延迟值可能被改变 | fructrl | * * * ## 已修复问题 历史版本已发现在当前版本解决的缺陷:暂无 * * * ## CVE 漏洞 暂无 * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/25.09/ --- 文档中心 版本说明 版本选择 # openUBMC 25.09 版本发布说明 2025/09/30 # openUBMC 25.09 版本发布说明 * * * ## 版本概览 作为25年第三个创新版本,openUBMC 25.09 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 25.09版本在25.06版本基础上进行开发,特性交付范围包括: ### 北向接口生态 #### 1\. 基础安全能力 - **密码安全策略**:支持禁用历史密码、失败锁定次数配置、登录失败锁定时间配置、超长密码支持 - **认证与授权**:支持WEB SSO单点登录、IPMI通道权限配置、前端敏感信息加密 - **安全审计**:支持动态插桩拦截风险接口调用日志、Cleancode排查整改 #### 2\. 管理软件生态 - **网管系统对接**:支持Zabbix、Ansible、Cmdlets、Nagios插件,实现与openUBMC的完整对接 - **开发指导文档**:提供SNMP接口映射器、TRAP告警、装备定制、CLI映射器等配置指导文档 #### 3\. 接口升级与扩展 - **Redfish接口增强**:主要包含Manager、Processor、SEL、NTP、时区等资源管理 - **IPMI标准命令**:支持User access/Password、User Name、DCMI Power等标准命令 #### 4\. 融合运维能力 - **固件升级管理**:支持一个hpm包多个固件场景升级、BMC升级异常时自恢复 - **安全升级控制**:支持VRD和NPU升级过程中禁止主机上电 - **任务管理**:支持任务资源标准规范和定制能力 ### 南向部件扩展 #### 1\. 南向驱动框架 - **驱动规范**:完成南向驱动框架和规范发布,基于规范完成网卡和GPU兼容性适配 - **协议支持**:支持I3C/CAN-FD能力、Ncsi Over Mctp/I2C/SMBUS协议获取网卡信息 - **私有协议**:支持Emulex的pldm私有协议 #### 2\. 板卡接入丰富度 - **网卡支持**:新增标卡和OCP网卡,包括E810XXVDA2G1P5、E810CQDA2G2P5、MCX755106AS-HEAT等 - **存储设备**:支持RAID卡(SP686C-M系列)、硬盘、NVMe盘(SamSung PM9D3A、Memblaze PBlaze7、Solidigm D7-PS1010等) - **计算加速**:支持GPU(A6000)、NPU模组等部件接入 #### 3\. TPSU/PSU管理 - **基本信息管理**:支持TPSU模块信息查询、电源额定功率变化记录 - **Turbo功能**:支持Turbo电容管理、充放电控制、使能控制 - **主备切换**:支持双CAN电源线路主备切换、供电模式切换 - **功率管理**:支持功耗封顶、功率监控、输出限功率点配置 #### 4\. DFX能力增强 - **临终遗言**:支持VRM/电源等关键部件临终遗言持久化 - **固件管理**:支持BIOS固件导出、关键部件固件升级 - **故障检测**:支持网卡Flash recovery故障检测、光模块关键信息记录和闪断检测 - **链路检测**:支持高速链路检测、CPU与外围器件链路异常告警 ### 开发体验优化 #### 1\. QEMU仿真能力 - **总线仿真**:支持SMBus、MCTP等复杂协议仿真 - **部件仿真**:支持MCU、PCIe、IMU等器件仿真 - **性能优化**:QEMU冒烟测试性能优化、支持依赖驱动更新 #### 2\. 指导文档完善 - **接口文档**:完成SNMP接口映射器、TRAP告警、装备定制、CLI映射器等指导文档 - **开发指南**:提供映射器接口设计说明书、配置指导、定位指导 - **用户手册**:更新BMC Studio用户指南、联机帮助页面扩展 #### 3\. 构建优化 - **Conan2.0升级**:完成conan2.0中心仓能力构建、支持Profile配置和并行构建 - **Bingo工具增强**:支持基于gtest的开发者测试、DT测试质量加固、门禁模型检查能力增强 - **构建脚本**:支持社区组件构建脚本适配Conan2.0、非root运行 #### 4\. 开发体验提升 - **测试能力**:bingo支持基于gtest的开发者测试、DT测试能力增强 - **代码质量**:门禁模型检查能力增强、支持代码开源合规检查 - **工具支持**:新增I2C扫描和读写工具、支持度量采集和可观测跟踪可配置 * * * ## 源代码 25.09版本源代码已发布至社区网站:https://openubmc.cn/zh/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 5.11.0 | 5.10.0 | 5.9.0 | | --- | --- | --- | --- | | 25.09 | Y | N | N | | 25.06 | N | Y | N | | 25.03 | N | N | Y | * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3187698 | 资源协作接口属性和方法Description字段修改 | mdb_interface | | 3190225 | 老版本导入新版本上电延迟值可能被改变 | fructrl | * * * ## 已修复问题 历史版本已发现在当前版本解决的缺陷:暂无 * * * ## CVE 漏洞 暂无 * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/25.12/ --- 文档中心 版本说明 版本选择 # openUBMC 25.12 LTS 版本发布说明 2025/12/31 # openUBMC 25.12 LTS 版本发布说明 * * * ## 版本概览 作为25年第1个长期支持版本,openUBMC 25.12 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 25.12版本在25.09版本基础上进行开发,特性交付范围包括: ### 北向接口生态 #### 1\. 接口标准化与扩展 **Redfish 资源升级**:包含对ProcessorMetrics、PCIeDevice、PCIeFunction、MemoryMetrics、StorageController、VirtualMedia等28个关键资源升级。 **IPMI**:支持Chassis与DCMI相关IPMI标准命令。 #### 2\. 安全与可靠性 **账户管理**:支持登录用户和最后一个用户不可删除。 #### 3\. 运维与管理功能 **固件与配置管理**:支持双主机BIOS固件管理、BMC恢复出厂设置后保留BIOS属性。 **监控**:支持查询历史功率资源信息。 ### 南向部件扩展 #### 1\. 硬件生态接入扩展 **网卡**:支持网卡的LLDP、电源故障告警、管理属性加固;支持OCP网卡Multihost场景;UB/UBoE网口及光模块的适配与管理。 **存储**:支持多款NVMe硬盘(如DAPUSTOR R6301/R6101)。 **电源与散热**:支持EB1000、3kw电源、PSIP双子星等新型电源管理;增强对TPSU电容寿命预测、风扇转速告警阈值设置、液冷系统(如Pumps资源、LeakDetection)的监控。 #### 2\. 驱动与协议框架深化 **驱动框架**:网卡/GPU/硬盘南向驱动适配特性增强,并开始适配南向部件驱动新规范接口,为统一驱动模型打下基础。 **新协议支持**:引入并支持标准SPDM协议,提供相关资源协作接口与原子能力。 ### 开发体验优化 #### 1\. 构建与部署工具链 **Bingo构建系统增强**:支持组件构建、产品构建、自定义命令的归一处理;支持Manifest对bingo工具的版本约束和自动升级;适配Conan 2.0,支持产品仓裁剪、包构建时打包MDS信息。 **Docker与CI/CD**:支持基于Dockerfile的镜像构建与发布、一体化集成开发环境Docker镜像构建;优化QEMU仿真镜像流水线。 #### 2\. 测试与质量保障 **测试覆盖强化**:实现libmcpp、devmon等模块测试覆盖率提升,强化component\_drivers组件驱动模块测试。 **门禁与流水线**:支持社区PR门禁自动识别和拦截、门禁检查并发控制。 **社区质量**:新增需求需要经过RM Sig评审的管控措施,以提升需求质量。 #### 3\. 仿真、调试与文档 **QEMU仿真优化**:Qemu维护与部署优化,创建qemu\_mockup新仓专门管理仿真数据和驱动,提升仿真便利性。 **在线调试与诊断**:提供在线调试特性设计说明书。 **文档体系完善**:补充和更新开发指南与常见问题,包括硬盘背板、网络管理、固件升级、BIOS实现、北向接口适配、持久化机制等数十个主题的指导文档,并支持docs仓库的CI门禁识别失效链接。 ## 源代码 25.12版本源代码已发布至社区网站:https://openubmc.cn/zh/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 5.12.0 | 5.11.0 | 5.10.0 | 5.9.0 | | --- | --- | --- | --- | --- | | 25.12 | Y | N | N | N | | 25.09 | N | Y | N | N | | 25.06 | N | N | Y | N | | 25.03 | N | N | N | Y | * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3690536 | 带内os热升级SATA SSD盘固件版本,BMC上显示的硬盘固件版本不更新 | storage | | 3644159 | 电源通讯异常,通过北向接口查询电源功率、电压、温度、电流等动态信息显示为0 | power_mgmt | * * * ## 已修复问题 本修复问题清单: | 问题描述 | | --- | | 修复了 告警码处理意见存在主板的英文单词,单板只有基础板,没有主板 的错误告警。 | | 修复了 告警码0x0100003B在槽位11模拟不上报告警 的问题。 | | 修复了 cli查询ip信息,网口组1和网口组2的Ip Mode信息显示不统一 的问题。 | * * * ## CVE 漏洞 | 漏洞编号 | 漏洞描述 | | --- | --- | | CVE-2020-14354 | A possible use-after-free and double-free in c-ares lib version 1.16.0 if ares_destroy() is called prior to ares_getaddrinfo() completing. This flaw possibly allows an attacker to crash the service that uses c-ares lib. The highest threat from this vulnerability is to this service availability. | | CVE-2025-62408 | c-ares is an asynchronous resolver library. Versions 1.32.3 through 1.34.5 terminate a query after maximum attempts when using read_answer() and process_answer(), which can cause a Denial of Service. Use after free will lead to crash / Denial of Service. This issue is fixed in version 1.34.6. | | CVE-2025-57665 | Element Plus Link component (el-link) through 2.10.6 implements insufficient input validation for the href attribute, creating a security abstraction gap that obscures URL-based attack vectors. The component passes user-controlled href values directly to underlying anchor elements without protocol validation, URL sanitization, or security headers. This allows attackers to inject malicious URLs using dangerous protocols (_, data:, file:) or redirect users to external malicious sites. While native HTML anchor elements present similar risks, UI component libraries bear additional responsibility for implementing security safeguards and providing clear risk documentation. The vulnerability enables XSS attacks, phishing campaigns, and open redirect exploits affecting applications that use Element Plus Link components with user-controlled or untrusted URL inputs. | * * * ## OPEN SOURCE SOFTWARE NOTICE Open Source Software Notice ## 接口 API 变更 ### 资源协作接口变更 | 变更说明 | 变更详情 | | --- | --- | | 资源协作接口方法 FirmwareMatchRules 权限和签名变更 | >> 变更详细说明 | | 资源协作接口方法 GetPolicyGuidances 响应签名变更 | >> 变更详细说明 | | 资源协作接口方法 SetNpuPowerCap 权限变更 | >> 变更详细说明 | ### 北向接口变更 | 变更说明 | 变更详情 | | --- | --- | | 【Redfish】SimpleUpdate POST请求不保留配置升级权限变更 | >> 变更详细说明 | | 【IPMI】SetUserAccess 带内设置用户通道权限变更 | >> 变更详细说明 | | 【Redfish】LimitException 功耗封顶失败后的策略取值和行为变更【IPMI OEM】SetPowerCappingConfiguration 功耗封顶失败后的策略取值和行为变更【IPMI DCMI】SetPowerLimit 功耗封顶失败后的策略取值和行为变更【WEB】功耗封顶失败后的策略取值和行为变更【SNMP】功耗封顶失败后的策略取值和行为变更 | >> 变更详细说明 | | 【IPMI】GetUserAccess 请求体通道号无效时返回值变更 | >> 变更详细说明 | * * * ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/26.03/ --- 文档中心 版本说明 版本选择 # openUBMC 26.03 版本发布说明 2026/03/31 # openUBMC 26.03 版本发布说明 * * * ## 版本概览 作为26年第1个创新版本,openUBMC 26.03 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 26.03版本在25.12版本基础上进行开发,特性交付范围包括: ### 易用性:工具链与开发体验提升 #### BMC Studio 与可视化配置 1. 支持BMC Studio IDE独立发布和升级。 2. 支持CSR编码辅助:语法高亮、引用跳转、基础语法检查、表达式计算 3. 支持lockfile提交记录可视化查看 #### 版本构建与工具链 1. 支持1712芯片构建 2. 支持 基于lockfile的产品级构建,解决版本冲突问题 3. conan并行化构建,优化构建效率 4. qemu升级到8.2.10版本 5. 社区基础设施支持签名能力 #### 开发、测试与调试体验提升 新增 社区技术文档、FAQ、接口文档、适配指南,降低新开发者上手成本 ### 丰富度:硬件接入与功能增强 #### 网卡接入能力扩展 1. 新增对 182x系列网卡(高低档位) 的全面支持,包括标卡、OCP卡、大板网卡等形态,支持光模块信息采集、告警增强、私有NCSI/SMBUS协议支持 2. 支持 Mellanox ConnectX-7网卡的适配 #### 硬盘与存储管理增强 1. 支持1880 RAID卡的升级和慢盘检测开关使能,支持1880 RAID管理的SAS/SATA硬盘的固件升级和版本信息展示 2. 支持硬盘槽位号动态更新、硬盘插入/拔出日志记录SN/PN #### 异构与PCIe设备管理 1. 支持JBOG管理,包括设备信息查看与状态监测,固件升级。 2. 支持 PCIe拓扑高速线缆交叉插法、PCIe卡插入/拔出日志记录SN/PN #### 带外管理能力提升 1. 支持 CPLD/BIOS/VRD/MCU/NPU 等多种固件的整包升级 2. 支持 固件升级暂存机制(仅适用于下电生效的固件) 3. 支持管理板和节点间的板间通信 4. ipmb/bt性能优化 ### 标准:规范建设与质量保障 #### 驱动与硬件接入规范 1. 推动 驱动认证规范,完成南向网卡兼容认证工具开发,明确准入用例标准 #### 接口与协议标准化 1. 支持 Redfish标准资源PCIeSlots、Assembly、Memory、Chassis 新增新属性 2. 完善 Schema管理机制:支持xml/json schema独立加载、版本升级 3. 支持 Redfish-Protocol/Interop/Service Validator 工具集成 * * * ## 源代码 26.03版本源代码已发布至社区网站:https://openubmc.cn/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 5.13.0 | 5.12.0 | 5.11.0 | 5.10.0 | 5.9.0 | | --- | --- | --- | --- | --- | --- | | 26.03 | Y | Y | N | N | N | | 25.12 | N | Y | N | N | N | | 25.09 | N | N | Y | N | N | | 25.06 | N | N | N | Y | N | | 25.03 | N | N | N | N | Y | * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3813122 | 进行硬盘暴力热插拔时,系统事件出现错误的硬盘SN信息 | frudata | | 3812472 | 串口环境下passwd 命令修改用户密码失败, cli命令修改用户报权限不足 | account | | 3644159 | 电源通讯异常,通过北向接口查询电源功率、电压、温度、电流等动态信息显示为0 | power_mgmt | * * * ## 已修复问题 本修复问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3783134 | 修复vrd下电升级失败和暂存失败的问题 | general_hardware | | 3777594 | 修复schemasotre/en接口查询时,响应体中,自定义oem部分无法查询问题 | rackmount | | 3789480 | 升级CPLD过程中,解除smc告警屏蔽的流程放在内层函数,防止因为fork执行导致时序异常 | general_hardware | * * * ## CVE 漏洞 | 漏洞编号 | 漏洞描述 | | --- | --- | | CVE-2022-1941 | A parsing vulnerability for the MessageSet type in the ProtocolBuffers versions prior to and including 3.16.1, 3.17.3, 3.18.2, 3.19.4, 3.20.1 and 3.21.5 for protobuf-cpp, and versions prior to and including 3.16.1, 3.17.3, 3.18.2, 3.19.4, 3.20.1 and 4.21.5 for protobuf-python can lead to out of memory failures. A specially crafted message with multiple key-value per elements creates parsing issues, and can lead to a Denial of Service against services receiving unsanitized input. We recommend upgrading to versions 3.18.3, 3.19.5, 3.20.2, 3.21.6 for protobuf-cpp and 3.18.3, 3.19.5, 3.20.2, 4.21.6 for protobuf-python. Versions for 3.16 and 3.17 are no longer updated. | | CVE-2024-2410 | The JsonToBinaryStream() function is part of the protocol buffers C++ implementation and is used to parse JSON from a stream. If the input is broken up into separate chunks in a certain way, the parser will attempt to read bytes from a chunk that has already been freed. | | CVE-2025-55131 | c-ares is an asynchronous resolver library. Versions 1.32.3 through 1.34.5 terminate a query after maximum attempts when using read_answer() and process_answer(), which can cause a Denial of Service. Use after free will lead to crash / Denial of Service. This issue is fixed in version 1.34.6. | | CVE-2022-1941 | A vulnerability, which was classified as critical, has been found in Oracle MySQL Connectors up to 8.0.31 (Database Software).Using CWE to declare the problem leads to CWE-404. The program does not release or incorrectly releases a resource before it is made available for re-use.Impacted is availability.A possible mitigation has been published immediately after the disclosure of the vulnerability. | | CVE-2025-4565 | Any project that uses Protobuf Pure-Python backend to parse untrusted Protocol Buffers data containing an arbitrary number of recursive groups, recursive messages or a series of SGROUP tags can be corrupted by exceeding the Python recursion limit. This can result in a Denial of service by crashing the application with a RecursionError. | | CVE-2025-53605 | The protobuf crate before version 3.7.2 for Rust contains uncontrolled recursion vulnerability in protobuf::coded_input_stream::CodedInputStream::skip_group when parsing unknown fields in untrusted input. | | CVE-2024-7254 | Any project that parses untrusted Protocol Buffers data containing an arbitrary number of nested groups / series of SGROUP tags can corrupted by exceeding the stack limit i.e. StackOverflow. Parsing nested groups as unknown fields with DiscardUnknownFieldsParser or Java Protobuf Lite parser, or against Protobuf map fields, creates unbounded recursions that can be abused by an attacker. | | CVE-2023-30608 | sqlparse is a non-validating SQL parser module for Python. In affected versions the SQL parser contains a regular expression that is vulnerable to ReDoS (Regular Expression Denial of Service). This issue was introduced by commit e75e358. The vulnerability may lead to Denial of Service (DoS). This issues has been fixed in sqlparse 0.4.4 by commit c457abd5f. | * * * ## OPEN SOURCE SOFTWARE NOTICE Open Source Software Notice ## 接口 API 变更 ### 资源协作接口变更 | 变更说明 | 变更详情 | | --- | --- | | 资源协作接口方法 bmc.kepler.AccountService 下属性 EmergencyLoginAccountId 权限变更 | >> 变更详细说明 | ### 北向接口变更 | 变更说明 | 变更详情 | | --- | --- | | 【WebRest】AdvancedSecurity GET请求获取EmergencyLoginUser权限变更 | >> 变更详细说明 | | 【Redfish】AccountService GET请求获取EmergencyLoginUser权限变更 | >> 变更详细说明 | | 【Redfish】AccountService/PrivilegeMap 中Oem//EmergencyLoginUser的GET权限变更 | >> 变更详细说明 | | 【Redfish】PerformanceCollection资源的光模块URI变更 | >> 变更详细说明 | | 【Redfish】光模块脏污检测资源的Start请求体以及GetResult响应体变更 | >> 变更详细说明 | | 【Redfish】GPU处理器资源的PCI Ids属性类型变更 | >> 变更详细说明 | | 【Redfish】Bios资源的GET操作响应体变更 | >> 变更详细说明 | \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/26.06/ --- 文档中心 版本说明 版本选择 # openUBMC 26.06 版本发布说明 2026/06/30 # openUBMC 26.06 版本发布说明 * * * ## 版本概览 作为26年第2个创新版本,openUBMC 26.06 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 26.06版本在26.03版本基础上进行开发,特性交付范围包括: ### 易用性:工具链、开发体验与可视化配置全面升级 #### BMC Studio IDE 能力增强 - CSR编码辅助:基于模型的属性与对象配置联想、掩码类型属性可视化、CSR复杂规则实时检查,支持用户扩展。 - 可视化配置能力:风冷调速策略可视化配置,支持基于模版创建部件驱动框架代码。 #### 文档与知识体系建设 - IPMI文档结构化:补充IPMI文档结构化信息,支持通过脚本自动生成IPMI接口文档。 - 接口审核自动化:支持版本接口变更文档自动生成、sig-interface评审帖自动预审、社区接口变更PR自动检视。 - 技术知识沉淀:新增PMBus、NCSI、CANBus、M.2、NVMe、CPLD升级等系列技术介绍文档;新增storage、pcie\_device等18个核心组件设计说明;建设200故障案例知识库。 #### 工程与门禁能力 - 构建与出包:bingo支持白牌包出包、基于OEE工具链的整包构建/集成、ccache构建优化及PR页面Conan版本回显。 - 编译器适配:适配GCC 14.3编译器。 - 代码仓治理:component\_drives代码仓体积及构建时间优化。 - 组件性能优化:支持组件启动性能优化、传感器对象接入性能提升30%。 ### 丰富度:硬件生态、部件管理与平台能力拓展 ### 网卡与网络适配 - 新网卡适配:新增沐创N10、网迅25GE、Mellanox MCX653106A、光润通F1002T-V3.0、N20 40G/100G等多款网卡。 - 182x系列能力增强:支持高低档182x系列的DFX、调速策略、告警补齐、光模块信息快速记录、SMBUS获取功率及自定义SMBUS固件升级。 - UB管理:光模块告警/信息采集、光链路定界、网口与光模块动态映射及web信息查询,提升UB设备带外可管理性。 #### 硬盘与存储管理 - 新硬件适配:适配佰维SS821、PetaIO P8118Z3、YMTC PE511、芯展速/芯盛SSD等硬盘;支持9580-8i8e。 - RAID管理增强:支持多启动盘配置(Web/Redfish/CLI)、并行升级、硬盘故障自愈、日志收集及启动盘信息显示。 - NVMe能力:支持NVMe盘固件升级,并行升级。 #### 异构计算与PCIe管理 - GPU/AI芯片适配:适配英伟达5090 和 Tesla P4/P40/V100/A100多款GPU。 - PCIe管理:支持基于rootBDF加载设备、UBC线缆检测增加整机白名单配置、SKU/RevisionId/Status属性查询。 #### 运维管理 - CPLD无感升级:支持无感升级全流程(前置处理、寄存器保存恢复、BMC与模块交互、数据持久化)。 - 暂存升级:支持固件的暂存和待生效固件的版本号展示。 - 用户管理:支持分权分域、LDAP登入可定位。 ### 标准:规范落地 #### 接口协议标准化 - Redfish资源补齐:新增Chassis、Fan、Drive、Port、PortMetrics、NetworkAdapter、NetworkDeviceFunction、EthernetInterface、EnvironmentMetrics等OCP规范资源属性。 - 固件升级标准化:UpdateService支持MultipartHttpPushUri和Targets参数。 #### 安全与签名规范 - 签名完整性:支持SignServer对接HPM外层签名、流水线固件完整性保护签名。 #### 南向驱动规范与部件认证 - 南向驱动规范接入:风扇/电源/NVMe/RAID卡。 - 南向认证测评:网卡、GPU、硬盘、Raid。 - 固件联盟认证:支持固件联盟190+认证用例。 * * * ## 源代码 26.06版本源代码已发布至社区网站:https://openubmc.cn/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 5.14.0 | 5.13.0 | 5.12.0 | 5.11.0 | 5.10.0 | | --- | --- | --- | --- | --- | --- | | 26.06 | Y | Y | N | N | N | | 26.03 | Y | Y | Y | N | N | | 25.12 | N | N | Y | Y | N | | 25.09 | N | N | N | Y | N | | 25.06 | N | N | N | N | Y | * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 4104349 | 使用Redfish接口修改自定义用户OEM权限,偶现PATCH接口返回500错误。 | account | | 4106323 | Redfish访问Systems资源下级Storages资源跳转链接未切换为标准Storage。 | rackmount | | 4106703 | SSH登录后执行ipmcget -d version查询版本信息超过性能基线2s。 | rackmount | | 4106819 | 通知式热拔出网卡后重新插入实体网卡,切换管理网口到NCSI口后网络不通。 | rackmount | | 3912021 | 博通RAID卡作为PCIe卡未配置BoardPCIeCard对象,导致/redfish/v1/Chassis/1/Boards/下查询不到。 | vpd | * * * ## 已修复问题 本版本已修复问题清单(部分): | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 3825410 | Vue的parseHTML函数正则表达式可导致ReDoS漏洞。 | webui | | 3825420 | Vue原型污染可导致XSS攻击,攻击者可修改Object.prototype属性执行任意JS代码。 | webui | | 3825424 | @intlify/shared的lib.deepCopy函数存在原型污染漏洞。 | webui | | 3825413 | Vue I18n的handleFlatJson函数存在原型污染漏洞。 | webui | | 3825414 | intlify vue-i18n组件存在XSS漏洞(CWE-79)。 | webui | | 4072295 | 单板生产时间超过2027-11-25后,Redfish查询显示为1996年。 | frudata | | 4035445 | BMC加载电子标签未实际成功仍上报pass,可能导致异常单板流入现网。 | frudata | | 4077108 | 账户信息缓存同步存在时间窗口,新增账户的缓存信息可能被误删。 | account | | 3880710 | 环境持久化存在不支持的账户策略数据时,重启后AccountPolicy读取异常。 | account | | 4076853 | 部分组件不支持GCC 14.3编译器编译。 | spdm | | 3878363 | bingo build/test依赖组件默认仅使用@openubmc结尾conan包,导致依赖解析错误。 | bingo | | 4082796 | bingo build未正确使用本地conan缓存,导致重复下载已存在的组件包。 | bingo | | 4077222 | 社区固件完整性保护签名缺少uboot部分签名,签名链路不完整。 | bingo | | 3878995 | 传感器线性模式下事件构造至上限时,转储操作性能消耗过高。 | sensor | | 4084448 | BMC上unions温度显示与实际不符。 | sensor_mgmt | | 4091329 | service工具扫描EnvironmentMetrics接口存在兼容性问题。 | rackmount | | 3834751 | 未配置精细化告警时,普通线缆告警也无法正常触发。 | pcie_device | | 3912553 | thermal_mgmt组件启动时cooling_pumps文件产生无效日志刷屏。 | thermal_mgmt | | 3856614 | HBM动态巡检参数配置功能接口定义调整。 | mdb_interface | | 3720145 | RAID卡通讯丢失上报告警slot与实际物理槽位不一致。 | vpd | | 4035170 | NVMe盘频繁热插拔时偶现调速策略未正确加载。 | storage | | 3690536 | Lua语法and/or误当三目运算符使用,导致属性赋值全为true。 | storage | | 4072112 | BMA开启后不支持南向驱动的网卡导致port_mgmt.lua日志刷屏。 | network_adapter | | 3783134 | BMC配置独立VRD时,上传固件包执行暂存操作失败。 | general_hardware | | 4092237 | retimer芯片故障时定时任务持续失败产生日志刷屏。 | general_hardware | | 3833460 | 修复0x2400001F告警显示信息与产品资料不一致的问题。 | vpd | | 3868622 | 网卡升级active流程未判断firmware type,影响其他固件active信号。 | network_adapter | | 4032010 | 故障/预故障硬盘在BMC复位后告警状态被错误恢复再产生。 | storage | | 4048926 | VRD生效流程中生效失败仍返回成功,操作日志与实际状态不一致。 | general_hardware | | 3644159 | 电源CommunicationStatus异常恢复后,额定功率仍为0。 | power_mgmt | * * * ## CVE 漏洞 本版本已修复的CVE漏洞: | 漏洞编号 | 漏洞描述 | | --- | --- | | CVE-2024-6783 | A vulnerability in Vue that allows an attacker to perform XSS via prototype pollution. The attacker could change the prototype chain of properties such as Object.prototype.staticClass or Object.prototype.staticStyle to execute arbitrary JavaScript code. | | CVE-2024-9506 | An improper regular expression in Vue's parseHTML function leads to a potential regular expression denial of service vulnerability. | | CVE-2024-52809 | A cross-site scripting (XSS) vulnerability in intlify vue-i18n up to 9.14.1/10.0.4. The manipulation of the argument createI18n/useI18n with unknown input leads to CWE-79. | | CVE-2024-52810 | @intlify/shared (10.0.4) is vulnerable to Prototype Pollution through the entry function lib.deepCopy. An attacker can supply a payload with Object.prototype setter to introduce or modify properties within the global prototype chain, causing denial of service (DoS). | | CVE-2025-27597 | Vue I18n @intlify/message-resolver and @intlify/vue-i18n-core are vulnerable to Prototype Pollution through the entry function handleFlatJson. An attacker can supply a payload with Object.prototype setter to introduce or modify properties within the global prototype chain. | | CVE-2025-40908 | YAML-LibYAML prior to 0.903.0 for Perl uses 2-args open, allowing existing files to be modified. | | CVE-2025-62718 | Axios prior to 1.15.0 and 0.31.0 does not correctly handle hostname normalization when checking NO_PROXY rules. Requests to loopback addresses like localhost. (with trailing dot) or ::1 (IPv6 literal) skip NO_PROXY matching and go through the configured proxy. | | CVE-2026-40175 | Axios prior to 1.15.0 and 0.3.1 is vulnerable to a specific Gadget attack chain that allows Prototype Pollution in any third-party dependency to be escalated into Remote Code Execution (RCE) or Full Cloud Compromise. | | CVE-2026-42033 | Axios prior to 1.15.1 and 0.31.1: when Object.prototype has been polluted by any co-dependency with keys that axios reads without a hasOwnProperty guard, an attacker can silently intercept and modify every JSON response before the application sees it, or fully hijack the underlying HTTP transport. | | CVE-2026-42034 | Axios prior to 1.15.1 and 0.31.1: for stream request bodies, maxBodyLength is bypassed when maxRedirects is set to 0. Oversized streamed uploads are sent fully even when the caller sets strict body limits. | | CVE-2026-42035 | Axios prior to 1.15.1 and 0.31.1: a prototype pollution gadget exists in the HTTP adapter that allows an attacker to inject arbitrary HTTP headers into outgoing requests. | | CVE-2026-42036 | Axios prior to 1.15.1 and 0.31.1: when responseType: 'stream' is used, Axios returns the response stream without enforcing maxContentLength, bypassing configured response-size limits. | | CVE-2026-42037 | Axios 1.0.0 to before 1.15.1: the FormDataPart constructor interpolates value.type directly into the Content-Type header without sanitizing CRLF sequences, allowing HTTP header injection. | | CVE-2026-42038 | Axios prior to 1.15.1 and 0.31.1: incomplete fix for NO_PROXY hostname normalization bypass. When no_proxy=localhost is set, requests to 127.0.0.1 and ::1 still route through the proxy. | | CVE-2026-42039 | Axios prior to 1.15.1 and 0.31.1: toFormData recursively walks nested objects with no depth limit, causing deeply nested request data to crash the Node.js process with a RangeError. | | CVE-2026-42040 | Axios prior to 1.15.1 and 0.31.1: the encode() function contains a character mapping that reverses the safe percent-encoding of null bytes, converting %00 back to a raw null byte. | | CVE-2026-42041 | Axios prior to 1.15.1 and 0.31.1: vulnerable to a Prototype Pollution Gadget attack that allows any Object.prototype pollution to silently suppress all HTTP error responses, bypassing application-level authentication and error handling. | | CVE-2026-42042 | Axios prior to 1.15.1 and 0.31.1: XSRF token protection logic uses JavaScript truthy/falsy semantics instead of strict boolean comparison for withXSRFToken, causing cross-site request forgery protection bypass. | | CVE-2026-42043 | Axios prior to 1.15.1 and 0.31.1: an attacker who can influence the target URL can use any 127.0.0.0/8 address (other than 127.0.0.1) to completely bypass the NO_PROXY protection. Incomplete fix for CVE-2025-62718. | | CVE-2026-42044 | Axios 1.0.0 to before 1.15.2: vulnerable to a Prototype Pollution Gadget attack that allows any Object.prototype pollution to be escalated into surgical, invisible modification of all JSON API responses, including privilege escalation and authorization bypass. | | CVE-2026-42264 | Axios 1.0.0 to before 1.15.2: five config properties (auth, baseURL, socketPath, beforeRedirect, insecureHTTPParser) are read via direct property access without hasOwnProperty guards, making them exploitable as prototype pollution gadgets. | | CVE-2026-46625 | js-cookie's internal assign() helper copies properties with for...in + plain assignment. When the source object is produced by JSON.parse, the proto member triggers a per-instance prototype hijack, allowing attacker-controlled keys to land in Set-Cookie headers. | ## OPEN SOURCE SOFTWARE NOTICE Open Source Software Notice ## 接口 API 变更 ### 资源协作接口变更 | 变更说明 | 变更详情 | | --- | --- | | 资源协作接口 bmc.kepler.Systems.NetworkPort 部分属性类型变更 | >> 变更详细说明 | ### 北向接口变更 | 变更说明 | 变更详情 | | --- | --- | | 【IPMI】IPMI接口Get/Set Rack Info机柜供电方式取值变更 | >> 变更详细说明 | | 【Redfish】Redfish事件订阅请求参数EventTypes、Context由必选调整为可选 | >> 变更详细说明 | | 【Redfish】Redfish网口资源部分属性在读取硬件数据失败时取值变更 | >> 变更详细说明 | ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/26.09/ --- 文档中心 版本说明 版本选择 # openUBMC 26.09 版本发布说明 2026/09/30 # openUBMC 26.09 版本发布说明 * * * ## 版本概览 作为26年第3个创新版本,openUBMC 26.09 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 26.09版本在26.06版本基础上进行开发,特性交付范围包括: ### 易用性:工具链、开发体验与可视化配置全面升级 #### BMC Studio IDE 能力增强 - **代码仓类型识别**:支持自动识别manifest产品配置仓、mdb\_interface接口配置仓、rackmount北向接口配置仓及业务组件仓,并基于类型提供可执行操作。 - **出包配置可视化**:支持可视化编辑manifest.yaml,自动检测SDK版本及组件列表,提供组件依赖联想、特性开关可视化配置,出包时展示固件包信息概览(组件列表、版本、特性开关、SDK版本)。 - **hpm包一键升级**:支持在hpm文件上右键选择“升级到环境”,可一次升级到多个环境,后台执行并显示进度与结果。 - **BMC环境管理**:支持配置BMC环境(IP、用户名、密码加密存储),一键打开SSH/Telnet终端及网页,在线状态检测与变更提醒。 - **CSR门禁屏蔽**:支持通过注释方式屏蔽CSR门禁错误,并支持在错误问题上点击按钮一键屏蔽。 - **阈值传感器告警掩码校验**:当AssertMask、DeassertMask、ReadingMask配置与上下限规则不符时给出错误提示,并说明正确值及原因。 - **白牌定制配置可视化**:支持web\_custom.xml文件的可视化配置界面,图片内容可预览并显示说明信息。 - **智能问答**:集成社区知识库与故障案例库,实现问题快速定位定界与AI辅助BMC开发能力。 - **日志分析能力**:支持导入一键收集日志解析整机CSR拓扑及查看CSR文件内容;支持通过日志信息结合AI能力产出事件告警触发链条分析报告。 #### 构建工具链与工程能力 - **bingo支持OpenEuler+Kunpeng环境**:支持在OpenEuler+Kunpeng环境下安装、升级及编译bingo依赖的二进制文件。 #223 - **OEE+Hi3095构建支持**:bingo支持基于OEE+Hi3095的组件构建、升级包构建及SDK发布包产品构建,支持OEE+Aspeed烧片包构建。 #209 #210 #230 #231 - **产品构建组件替换**:支持产品构建时通过配置对平台组件进行覆写替换,并在替换时提供醒目提示。 #232 - **ASan扫描能力**:bingo test支持ASan扫描识别C/CPP代码内存问题,支持通过代码注释方式屏蔽扫描结果。 #211 #212 - **clang-tidy错误检查**:社区C/CPP组件支持基于clang-tidy的错误检查。 #225 #### 文档与知识体系建设 - **组件文档说明**:为bingo、manifest、mctpd、hwdiscovery、hwproxy、runtime\_accessor、liblogger、libsomp、libmc4lua、iam/libiam、account等组件/lib库建立完整文档体系,包括组件概述、API使用说明和示例、扩展案例、日志说明、问题定界指南及FAQ。 #215 #297 #795 #796 #829 #830 #831 #832 #846 #851 #853 #212 #214 - **开发指导文档**:新增Hi1712芯片构建指导、开发环境初始化配置文档、快速新增一个产品教程、拆包解析能力定制指导、IPMI通道(bt、ipmb)不通定位指导。 #793 #794 #799 #836 #837 - **AI辅助扫描流水线**:支持AI辅助日志规范扫描和安全规范扫描,支持组件级和版本级扫描,版本级扫描结果归档为html报告。 #299 #300 #### 社区治理与流程规范 - **Issue/PR提交规范校验**:需求issue必须包含简要说明、系统用户、前置条件、主成功场景、扩展场景、兼容性影响评估;缺陷issue必须包含预置条件、操作步骤、结果描述、预期结果、受影响版本、问题优先级;PR提交时自动检查模板合规性。 #185 - **Issue状态精简**:删除“转测中”状态,需求代码合入转测后直接从“开发中”走到“待验收”。 #194 - **编码风格可视化**:社区代码仓支持基于pre-commit机制的编码风格检查,C/CPP代码仓生效clang-format,Python代码仓生效Ruff,JS代码仓配置.prettierrc。 #296 - **RAG对外查询接口**:开放 RAG 相关接口,支持用户通过 MCP 访问 RAG 系统,获取 openUBMC 知识上下文。 #166 ### 丰富度:硬件生态、部件管理与平台能力拓展 #### 异构计算与PCIe管理 - **PCIe设备RAS原子能力**:支持PCIe设备上报故障时识别设备BDF,已知BDF汇聚到PCIeCollector,未知BDF汇聚到UnknownPCIeCollector。 #385 - **DPU独立分类显示**:支持DPU在BMC WEB界面单独分类显示,不再混在PCIe设备界面。 #909 #414 - **NPU模组管理增强**:支持NPU模组电源告警精确解析和上报、HBM冗余资源实时监控和资源不足告警。 #359 #368 - **NPU参数面光模块控制**:支持通过Redfish接口实现NPU参数面光模块灭灯/恢复亮灯操作。 #399 #### 存储与硬盘管理 - **SMART信息获取增强**:支持NVMe盘组硬Raid后带外获取SMART信息、Redfish接口获取SATA盘SMART信息、Redfish接口获取NVMe盘标准SMART信息。 #414 #416 #937 - **SMART日志采集与导出**:支持自研RAID下SATA盘和直通NVMe盘的SMART日志定时采集、存储与导出,支持Web前端硬盘日志收集按钮。 #417 #428 - **硬盘时间同步**:支持自研RAID下SAS/SATA SSD盘时间同步功能,在盘第一次识别加载、盘更换、系统上下电时同步。 #422 #### 网卡与网络适配 - **光模块门限值采集**:光模块静态文件增加门限值,日志采集包含对应门限值。 #352 - **光模块告警实现优化**:支持网卡光模块各通道告警通过CSR配置实现,删除软件告警,提升扩展性。 #456 - **光模块指标定义**:redfish遥测支持光模块相关指标定义(MetricDefinition),包括RxInputPower和TxBiasCurrent。 #630 #### 固件升级与管理 - **Krun固件升级**:复用BIOS固件升级方式,支持通过SPI接口升级Krun固件。 #151 - **本地固件仓管理**:支持本地固件仓固件的添加、更新、删除与生效,支持本地固件仓容量查询,并支持检测本地固件仓版本与运行固件版本的一致性。 #908 #387#947 #404 - **VRD自愈能力**:VRD升级成功后备份升级包,检测到VRD异常时使用备份包重新升级尝试自愈。 #379 - **CPLD JTAG扫链巡检**:支持天池单板通过JTAG链路进行CPLD扫链巡检,验证CSR配置与实际硬件一致性。 #378 #### 平台基础能力 - **libmcpp框架能力**:支持基于lmc库提供服务管理、协程/任务管理、消息通讯功能,支持lua基础类型封装、lua Actor模型能力,提供服务管理接口测试能力。 #131 #132 #133 #134 #135 #136 - **C++映射器库能力**:支持集合资源自动分页控制、消息/错误处理、资源协作接口权限管理、子任务(SubTasks)机制、免鉴权认证、安全文件函数、IgnoreEtags定制、上下文管理、框架日志接口、首次登录修改密码、板间通信会话区分节点板、历史问题重构。 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31 - **IPMI SOL转发**:支持通过标准IPMI命令设置/查询SOL Payload端口,支持SOL Activate Payload命令返回用户配置的端口。 #388 - **组件循环依赖解决**:解决ipmi\_core组件与bmc\_network组件间循环依赖。 #408 - **主备状态上全局变量**:支持主备状态上全局变量。 #402 - **系统上下电状态上全局变量**:基础服务支持通用属性系统上下电状态上到全局变量。 #76 - **恢复初始IP原子能力**:资源协作接口提供恢复初始IP原子能力。 #405 - **国际证书管理**:支持国际证书资源协作接口管理,包括通信证书管理、导出CSR、导入证书能力。 #393 - **内存CE统计**:支持MemoryMetrics资源内存CE统计属性,满足IPMI、Redfish RAS相关规范。 #392 #936 - **数据采集导出接口**:新增导出数据采集信息的WebRest接口,触发BMC后端调用metric\_analyzer组件导出采集数据压缩包。 #999 #### 运维管理 - **错峰上电**:支持各节点之间按照槽位进行延时实现错峰上电,避免同时上电对电源的冲击。 #423 - **看门狗设置**:支持redfish设置看门狗使能状态和超时动作(FunctionEnabled、TimeoutAction)。 #928 - **中文event定义**:redfish接口支持中文event定义信息查询,Description、Message、Severity等字段展示为中文。 #929 - **传感器事件删除**:web界面支持删除传感器事件按钮。 #422 - **PSU与TPSU兼容**:支持canbus协议对TPSU和PSU电源板协议兼容性适配,支持电源信息获取、告警、黑匣子及电源升级。 #265 - **RAID卡告警增强**:支持自研RAID卡PCA9555访问失败告警和电源故障告警。 #631 - **BIOS日志与状态**:支持BIOS通过IPMI命令记录维护日志、SystemStartupState变化记录日志、增加全局变量表征BIOS启动状态、Bios PFR可定位性增强。 #162 #159 #163 #164 - **基础调速过程数据获取**:支持获取PID和异常转速计算后的数据,用于管理板汇总主/从控数据进行计算。 #191 ### 标准:规范落地 #### 接口协议标准化 - **Redfish标准兼容**:指标定义、指标报告、指标报告上报内容兼容redfish标准内容,支持通过Oem属性切换到redfish标准形式。 #912 - **集合资源自动分页控制**:支持控制redfish集合资源自动分页能力,保持历史兼容性。 #913 #20 - **Port资源Oem补齐**:redfish接口Port资源补齐Oem相关实现,与NetworkPort资源已实现的Oem属性保持一致。 #938 - **Job支持OperationApplyTime**:创建和查询Job支持OperationApplyTime,支持对应调度。 #911 #### 测试与质量保障 - **测试资产整理**:完成社区开源测试用例整理、开发者贡献用例归档、QA仓库目录与文件整理。 #227 #233 - **冒烟测试流水线对接**:支持冒烟测试用例流水线对接社区每日构建流水线,自动完成冒烟测试并输出结果报告。 #243 - **IT测试资源树接口覆盖率提升**:补充开发者IT测试用例,增加资源树接口覆盖率。 #213 * * * ## 源代码 26.09版本源代码已发布至社区网站:https://openubmc.cn/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 5.15.0 | 5.14.0 | 5.13.0 | 5.12.0 | 5.11.0 | | --- | --- | --- | --- | --- | --- | | 26.09 | Y | N | N | N | N | | 26.06 | Y | Y | Y | N | N | | 26.03 | N | Y | Y | Y | N | | 25.12 | N | N | N | Y | Y | | 25.09 | N | N | N | N | Y | 备注:SDK中的部分二进制以源码形式开放到社区,`openUBMC 26.09` 与 `5.14.0 SDK` 配套时无法做到完全兼容。在该配套场景下,社区对 `libmgmt_protocol`、`compute` 组件的修改将无法生效。详见论坛 Topic 《openUBMC 26.09 与 SDK 配套兼容性说明》。 * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 4104349 | 使用redfish接口设置自定义用户权限失败 | account | * * * ## 已修复问题 本版本已修复问题清单(部分): | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 4381659 | 一键收集日志创建/var/log/netcard目录失败 | network_adapter | | 4376537 | 先导入备用证书,再导入主证书,nginx启动失败 | nsm | | 3859066 | OCP网卡Type属性配置错误 | vpd | | 4032010 | 硬盘故障/预故障在BMC复位场景误恢复 | storage | | 3820500 | 网卡卸载时,未在stop函数里停掉相关的timer任务 | component_drivers | | 4089694 | 修复带内上报拓扑信息没有设置上限的问题 | pcie_device | | 3878208 | 解决BMC启动时网页BBU状态跳变问题 | rackmonut | | 4109892 | bmc启动时主动清除一次事件 | fructrl | | 4101747 | EXU 12V — DescArg 显示原始 ADC(如 1823 V) | libmcpp | | 4070324 | EthernetInterfaces资源Links下的Ports的@odata.id配置错误 | rackmount | | 4087729 | BMA正常运行时,redfish查询GPU信息,"GPUUsagePercent"和"MemoryUsagePercent"值一直为0 | general_hardware | | 4087729 | 修复空定制化且SystemProductName不为空时,SystemProductName变化 | frudata | | 4099359 | 解决journal_export服务在退出时崩溃问题 | rootfs_user | * * * ## CVE 漏洞 本版本已修复的CVE漏洞: | 漏洞编号 | 漏洞描述 | | --- | --- | | CVE-2026-69186 | The DNS name decompression parser of c-ares does not limit the recursion/iteration depth when processing DNS responses containing compressed pointer chains. An attacker can trigger an unbounded loop by sending a malicious DNS response, causing a CPU exhaustion denial of service. | | CVE-2026-69184 | The DNS name decompression parser of c-ares does not limit the recursion/iteration depth when processing DNS responses containing compressed pointer chains. An attacker can trigger an unbounded loop by sending a malicious DNS response, causing a CPU exhaustion denial of service. | | CVE-2026-33630 | A vulnerability was found in c-ares related to a use-after-free condition in the ares_getaddrinfo function. Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code, impacting availability. | ## OPEN SOURCE SOFTWARE NOTICE Open Source Software Notice ## 接口 API 变更 ### 资源协作接口变更 | 变更说明 | 变更详情 | | --- | --- | | 资源协作接口 bmc.kepler.Managers.SOC温度属性签名变更 | >> 变更详细说明 | ### 北向接口变更 | 变更说明 | 变更详情 | | --- | --- | | Redfish接口创建Volume请求体必选参数缺失时的响应变更 | >> 变更详细说明 | | redfish接口Drive资源patch请求取值无效时的响应变更 | >> 变更详细说明 | | redfish接口遥测资源查询响应及事件报文格式变更 | >> 变更详细说明 | | redfish接口NetworkPort和Port资源关于FC网卡WWN顺序变更 | >> 变更详细说明 | | DPU/SDI卡在WEB页面显示位置调整 | >> 变更详细说明 | | 设置延迟上电IPMI命令的配置锁定策略变更 | >> 变更详细说明 | ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/version/latest/ --- 文档中心 版本说明 版本选择 # openUBMC 26.09 版本发布说明 2026/09/30 # openUBMC 26.09 版本发布说明 * * * ## 版本概览 作为26年第3个创新版本,openUBMC 26.09 采用木兰宽松许可证 2.0(Mulan PSL v2),用户可以自由复制、使用、修改、分发。 * * * ## 版本特性 26.09版本在26.06版本基础上进行开发,特性交付范围包括: ### 易用性:工具链、开发体验与可视化配置全面升级 #### BMC Studio IDE 能力增强 - **代码仓类型识别**:支持自动识别manifest产品配置仓、mdb\_interface接口配置仓、rackmount北向接口配置仓及业务组件仓,并基于类型提供可执行操作。 - **出包配置可视化**:支持可视化编辑manifest.yaml,自动检测SDK版本及组件列表,提供组件依赖联想、特性开关可视化配置,出包时展示固件包信息概览(组件列表、版本、特性开关、SDK版本)。 - **hpm包一键升级**:支持在hpm文件上右键选择“升级到环境”,可一次升级到多个环境,后台执行并显示进度与结果。 - **BMC环境管理**:支持配置BMC环境(IP、用户名、密码加密存储),一键打开SSH/Telnet终端及网页,在线状态检测与变更提醒。 - **CSR门禁屏蔽**:支持通过注释方式屏蔽CSR门禁错误,并支持在错误问题上点击按钮一键屏蔽。 - **阈值传感器告警掩码校验**:当AssertMask、DeassertMask、ReadingMask配置与上下限规则不符时给出错误提示,并说明正确值及原因。 - **白牌定制配置可视化**:支持web\_custom.xml文件的可视化配置界面,图片内容可预览并显示说明信息。 - **智能问答**:集成社区知识库与故障案例库,实现问题快速定位定界与AI辅助BMC开发能力。 - **日志分析能力**:支持导入一键收集日志解析整机CSR拓扑及查看CSR文件内容;支持通过日志信息结合AI能力产出事件告警触发链条分析报告。 #### 构建工具链与工程能力 - **bingo支持OpenEuler+Kunpeng环境**:支持在OpenEuler+Kunpeng环境下安装、升级及编译bingo依赖的二进制文件。 #223 - **OEE+Hi3095构建支持**:bingo支持基于OEE+Hi3095的组件构建、升级包构建及SDK发布包产品构建,支持OEE+Aspeed烧片包构建。 #209 #210 #230 #231 - **产品构建组件替换**:支持产品构建时通过配置对平台组件进行覆写替换,并在替换时提供醒目提示。 #232 - **ASan扫描能力**:bingo test支持ASan扫描识别C/CPP代码内存问题,支持通过代码注释方式屏蔽扫描结果。 #211 #212 - **clang-tidy错误检查**:社区C/CPP组件支持基于clang-tidy的错误检查。 #225 #### 文档与知识体系建设 - **组件文档说明**:为bingo、manifest、mctpd、hwdiscovery、hwproxy、runtime\_accessor、liblogger、libsomp、libmc4lua、iam/libiam、account等组件/lib库建立完整文档体系,包括组件概述、API使用说明和示例、扩展案例、日志说明、问题定界指南及FAQ。 #215 #297 #795 #796 #829 #830 #831 #832 #846 #851 #853 #212 #214 - **开发指导文档**:新增Hi1712芯片构建指导、开发环境初始化配置文档、快速新增一个产品教程、拆包解析能力定制指导、IPMI通道(bt、ipmb)不通定位指导。 #793 #794 #799 #836 #837 - **AI辅助扫描流水线**:支持AI辅助日志规范扫描和安全规范扫描,支持组件级和版本级扫描,版本级扫描结果归档为html报告。 #299 #300 #### 社区治理与流程规范 - **Issue/PR提交规范校验**:需求issue必须包含简要说明、系统用户、前置条件、主成功场景、扩展场景、兼容性影响评估;缺陷issue必须包含预置条件、操作步骤、结果描述、预期结果、受影响版本、问题优先级;PR提交时自动检查模板合规性。 #185 - **Issue状态精简**:删除“转测中”状态,需求代码合入转测后直接从“开发中”走到“待验收”。 #194 - **编码风格可视化**:社区代码仓支持基于pre-commit机制的编码风格检查,C/CPP代码仓生效clang-format,Python代码仓生效Ruff,JS代码仓配置.prettierrc。 #296 - **RAG对外查询接口**:开放 RAG 相关接口,支持用户通过 MCP 访问 RAG 系统,获取 openUBMC 知识上下文。 #166 ### 丰富度:硬件生态、部件管理与平台能力拓展 #### 异构计算与PCIe管理 - **PCIe设备RAS原子能力**:支持PCIe设备上报故障时识别设备BDF,已知BDF汇聚到PCIeCollector,未知BDF汇聚到UnknownPCIeCollector。 #385 - **DPU独立分类显示**:支持DPU在BMC WEB界面单独分类显示,不再混在PCIe设备界面。 #909 #414 - **NPU模组管理增强**:支持NPU模组电源告警精确解析和上报、HBM冗余资源实时监控和资源不足告警。 #359 #368 - **NPU参数面光模块控制**:支持通过Redfish接口实现NPU参数面光模块灭灯/恢复亮灯操作。 #399 #### 存储与硬盘管理 - **SMART信息获取增强**:支持NVMe盘组硬Raid后带外获取SMART信息、Redfish接口获取SATA盘SMART信息、Redfish接口获取NVMe盘标准SMART信息。 #414 #416 #937 - **SMART日志采集与导出**:支持自研RAID下SATA盘和直通NVMe盘的SMART日志定时采集、存储与导出,支持Web前端硬盘日志收集按钮。 #417 #428 - **硬盘时间同步**:支持自研RAID下SAS/SATA SSD盘时间同步功能,在盘第一次识别加载、盘更换、系统上下电时同步。 #422 #### 网卡与网络适配 - **光模块门限值采集**:光模块静态文件增加门限值,日志采集包含对应门限值。 #352 - **光模块告警实现优化**:支持网卡光模块各通道告警通过CSR配置实现,删除软件告警,提升扩展性。 #456 - **光模块指标定义**:redfish遥测支持光模块相关指标定义(MetricDefinition),包括RxInputPower和TxBiasCurrent。 #630 #### 固件升级与管理 - **Krun固件升级**:复用BIOS固件升级方式,支持通过SPI接口升级Krun固件。 #151 - **本地固件仓管理**:支持本地固件仓固件的添加、更新、删除与生效,支持本地固件仓容量查询,并支持检测本地固件仓版本与运行固件版本的一致性。 #908 #387#947 #404 - **VRD自愈能力**:VRD升级成功后备份升级包,检测到VRD异常时使用备份包重新升级尝试自愈。 #379 - **CPLD JTAG扫链巡检**:支持天池单板通过JTAG链路进行CPLD扫链巡检,验证CSR配置与实际硬件一致性。 #378 #### 平台基础能力 - **libmcpp框架能力**:支持基于lmc库提供服务管理、协程/任务管理、消息通讯功能,支持lua基础类型封装、lua Actor模型能力,提供服务管理接口测试能力。 #131 #132 #133 #134 #135 #136 - **C++映射器库能力**:支持集合资源自动分页控制、消息/错误处理、资源协作接口权限管理、子任务(SubTasks)机制、免鉴权认证、安全文件函数、IgnoreEtags定制、上下文管理、框架日志接口、首次登录修改密码、板间通信会话区分节点板、历史问题重构。 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31 - **IPMI SOL转发**:支持通过标准IPMI命令设置/查询SOL Payload端口,支持SOL Activate Payload命令返回用户配置的端口。 #388 - **组件循环依赖解决**:解决ipmi\_core组件与bmc\_network组件间循环依赖。 #408 - **主备状态上全局变量**:支持主备状态上全局变量。 #402 - **系统上下电状态上全局变量**:基础服务支持通用属性系统上下电状态上到全局变量。 #76 - **恢复初始IP原子能力**:资源协作接口提供恢复初始IP原子能力。 #405 - **国际证书管理**:支持国际证书资源协作接口管理,包括通信证书管理、导出CSR、导入证书能力。 #393 - **内存CE统计**:支持MemoryMetrics资源内存CE统计属性,满足IPMI、Redfish RAS相关规范。 #392 #936 - **数据采集导出接口**:新增导出数据采集信息的WebRest接口,触发BMC后端调用metric\_analyzer组件导出采集数据压缩包。 #999 #### 运维管理 - **错峰上电**:支持各节点之间按照槽位进行延时实现错峰上电,避免同时上电对电源的冲击。 #423 - **看门狗设置**:支持redfish设置看门狗使能状态和超时动作(FunctionEnabled、TimeoutAction)。 #928 - **中文event定义**:redfish接口支持中文event定义信息查询,Description、Message、Severity等字段展示为中文。 #929 - **传感器事件删除**:web界面支持删除传感器事件按钮。 #422 - **PSU与TPSU兼容**:支持canbus协议对TPSU和PSU电源板协议兼容性适配,支持电源信息获取、告警、黑匣子及电源升级。 #265 - **RAID卡告警增强**:支持自研RAID卡PCA9555访问失败告警和电源故障告警。 #631 - **BIOS日志与状态**:支持BIOS通过IPMI命令记录维护日志、SystemStartupState变化记录日志、增加全局变量表征BIOS启动状态、Bios PFR可定位性增强。 #162 #159 #163 #164 - **基础调速过程数据获取**:支持获取PID和异常转速计算后的数据,用于管理板汇总主/从控数据进行计算。 #191 ### 标准:规范落地 #### 接口协议标准化 - **Redfish标准兼容**:指标定义、指标报告、指标报告上报内容兼容redfish标准内容,支持通过Oem属性切换到redfish标准形式。 #912 - **集合资源自动分页控制**:支持控制redfish集合资源自动分页能力,保持历史兼容性。 #913 #20 - **Port资源Oem补齐**:redfish接口Port资源补齐Oem相关实现,与NetworkPort资源已实现的Oem属性保持一致。 #938 - **Job支持OperationApplyTime**:创建和查询Job支持OperationApplyTime,支持对应调度。 #911 #### 测试与质量保障 - **测试资产整理**:完成社区开源测试用例整理、开发者贡献用例归档、QA仓库目录与文件整理。 #227 #233 - **冒烟测试流水线对接**:支持冒烟测试用例流水线对接社区每日构建流水线,自动完成冒烟测试并输出结果报告。 #243 - **IT测试资源树接口覆盖率提升**:补充开发者IT测试用例,增加资源树接口覆盖率。 #213 * * * ## 源代码 26.09版本源代码已发布至社区网站:https://openubmc.cn/download * * * ## 版本兼容说明 | openUBMC/BMC_SDK | 5.15.0 | 5.14.0 | 5.13.0 | 5.12.0 | 5.11.0 | | --- | --- | --- | --- | --- | --- | | 26.09 | Y | N | N | N | N | | 26.06 | Y | Y | Y | N | N | | 26.03 | N | Y | Y | Y | N | | 25.12 | N | N | N | Y | Y | | 25.09 | N | N | N | N | Y | 备注:SDK中的部分二进制以源码形式开放到社区,`openUBMC 26.09` 与 `5.14.0 SDK` 配套时无法做到完全兼容。在该配套场景下,社区对 `libmgmt_protocol`、`compute` 组件的修改将无法生效。详见论坛 Topic 《openUBMC 26.09 与 SDK 配套兼容性说明》。 * * * ## 已知问题 本版本问题清单: | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 4104349 | 使用redfish接口设置自定义用户权限失败 | account | * * * ## 已修复问题 本版本已修复问题清单(部分): | ISSUE ID | 问题描述 | 关联仓库 | | --- | --- | --- | | 4381659 | 一键收集日志创建/var/log/netcard目录失败 | network_adapter | | 4376537 | 先导入备用证书,再导入主证书,nginx启动失败 | nsm | | 3859066 | OCP网卡Type属性配置错误 | vpd | | 4032010 | 硬盘故障/预故障在BMC复位场景误恢复 | storage | | 3820500 | 网卡卸载时,未在stop函数里停掉相关的timer任务 | component_drivers | | 4089694 | 修复带内上报拓扑信息没有设置上限的问题 | pcie_device | | 3878208 | 解决BMC启动时网页BBU状态跳变问题 | rackmonut | | 4109892 | bmc启动时主动清除一次事件 | fructrl | | 4101747 | EXU 12V — DescArg 显示原始 ADC(如 1823 V) | libmcpp | | 4070324 | EthernetInterfaces资源Links下的Ports的@odata.id配置错误 | rackmount | | 4087729 | BMA正常运行时,redfish查询GPU信息,"GPUUsagePercent"和"MemoryUsagePercent"值一直为0 | general_hardware | | 4087729 | 修复空定制化且SystemProductName不为空时,SystemProductName变化 | frudata | | 4099359 | 解决journal_export服务在退出时崩溃问题 | rootfs_user | * * * ## CVE 漏洞 本版本已修复的CVE漏洞: | 漏洞编号 | 漏洞描述 | | --- | --- | | CVE-2026-69186 | The DNS name decompression parser of c-ares does not limit the recursion/iteration depth when processing DNS responses containing compressed pointer chains. An attacker can trigger an unbounded loop by sending a malicious DNS response, causing a CPU exhaustion denial of service. | | CVE-2026-69184 | The DNS name decompression parser of c-ares does not limit the recursion/iteration depth when processing DNS responses containing compressed pointer chains. An attacker can trigger an unbounded loop by sending a malicious DNS response, causing a CPU exhaustion denial of service. | | CVE-2026-33630 | A vulnerability was found in c-ares related to a use-after-free condition in the ares_getaddrinfo function. Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code, impacting availability. | ## OPEN SOURCE SOFTWARE NOTICE Open Source Software Notice ## 接口 API 变更 ### 资源协作接口变更 | 变更说明 | 变更详情 | | --- | --- | | 资源协作接口 bmc.kepler.Managers.SOC温度属性签名变更 | >> 变更详细说明 | ### 北向接口变更 | 变更说明 | 变更详情 | | --- | --- | | Redfish接口创建Volume请求体必选参数缺失时的响应变更 | >> 变更详细说明 | | redfish接口Drive资源patch请求取值无效时的响应变更 | >> 变更详细说明 | | redfish接口遥测资源查询响应及事件报文格式变更 | >> 变更详细说明 | | redfish接口NetworkPort和Port资源关于FC网卡WWN顺序变更 | >> 变更详细说明 | | DPU/SDI卡在WEB页面显示位置调整 | >> 变更详细说明 | | 设置延迟上电IPMI命令的配置锁定策略变更 | >> 变更详细说明 | ## 致谢 我们衷心感谢参与openUBMC项目的所有社区开发者,正是因为你们的参与才能使得此版本顺利发布,为openUBMC更好的发展迈出了第一步。 \[Copyright\] Copyright © 2026 openUBMC Community. This article was first published by the openUBMC Community. Reproduction is welcomed under CC-BY-SA 4.0. When reproducing, please prominently note the source in the text and retain the original article link and author information. \[Disclaimer\] The views expressed in this article are solely those of the author and do not represent the stance of this website. This website remains neutral regarding the statements and opinions presented and provides no express or implied warranty as to the accuracy, reliability, or completeness of the content. This article is intended for reference only, and all legal responsibilities arising therefrom shall be borne by the reader. --- https://www.openubmc.cn/zh/vulnerability-management/ --- Security Center Vulnerability Management # Vulnerability Management 2025/03/30 openUBMC # 漏洞管理 ## 1\. 漏洞响应 openUBMC 社区非常重视社区版本的安全性,openUBMC 社区安全小组(SIG Security)负责接收、调查和披露 openUBMC 社区相关的安全漏洞。我们鼓励漏洞研究人员和行业组织主动将 openUBMC 社区的疑似安全漏洞报告给 openUBMC 社区安全小组。我们会快速的响应、分析和解决上报的安全问题或安全漏洞。 ## 2\. 支持版本 漏洞响应流程主要支持 openUBMC 社区的发行版。 ## 3\. 漏洞处理流程 每一个安全漏洞都会有一个指定的人员进行跟踪和处理,协调员是 openUBMC 安全小组的成员,他将负责跟踪和推动漏洞的修复和披露。漏洞端到端的处理流程如下图。 在这里我们主要介绍流程中漏洞上报、漏洞评估和漏洞披露这三部分内容。 ### 3.1 漏洞上报 如果您认为 openUBMC 产品存在一个疑似安全漏洞,我们希望您将漏洞上报给 openUBMC 社区,并与我们配合以负责任的方式修复和披露该问题。 #### 3.1.1 漏洞上报方式 您可以通过 email 将 openUBMC 产品的潜在安全漏洞发送到 openUBMC 安全小组邮箱(securities@public.openubmc.cn)。因为漏洞信息比较敏感,为确保机密性,建议您使用安全团队邮箱PGP 公钥对邮件信息进行加密。我们能够收到使用 OpenPGP 加密的电子邮件。安全小组成员信息如下: - 张超\[@TacoJay\],zhangchao60@huawei.com - 鄢川杰\[@loopvoid\],yanchuanjie@huawei.com - 彭祥麟\[@Free\_Tomato\],pengxianglin2@huawei.com - 任山\[@Renyqing\],renshan2@huawei.com #### 3.1.2 漏洞上报内容 为了便于快速的确认和验证疑似漏洞,请在漏洞上报邮件中包含但不限于以下内容: - 基本信息:包括漏洞影响的模块、漏洞的触发条件和成功利用后对系统的影响等。 - 技术细节:包括系统配置、定位方法、Exploit 的描述、POC、问题重现方法和步骤等。 - 修复方案建议。 - 上报者的组织和联系方式。 - 上报者可能的漏洞披露计划。 #### 3.1.3 邮件响应时间 我们将在 5 天内响应通过邮箱上报的疑似安全漏洞,并向上报者反馈漏洞处理的进展。 ### 3.2 漏洞严重性评估 业界普遍使用 CVSS 标准评估漏洞的严重性,openUBMC 在使用 CVSSv3 进行漏洞评估时,需要设定漏洞攻击场景,基于在该攻击场景下的实际影响进行评估。漏洞严重等级评估是指针对漏洞利用难易程度,以及利用后对机密性、完整性、可用性的影响进行评估,并生成一个评分值。 #### 3.2.1 评估标准 openUBMC 社区采用 CVSS v3 对漏洞进行评估,CVSS V3 由通过对以下向量来评估一个漏洞的影响: - 攻击向量(AV)-表示攻击的“远程性”以及如何利用此漏洞。 - 攻击复杂性(AC)-讲述攻击执行的难度以及成功进行攻击需要哪些因素。 - 用户交互(UI)-确定攻击是否需要用户参与。 - 所需的权限(PR)-记录成功进行攻击所需的用户身份验证级别。 - 范围(S)-确定攻击者是否可以影响具有不同权限级别的组件。 - 机密性(C)-衡量信息泄露给非授权方后导致的影响程度。 - 完整性(I)-衡量信息被篡改后导致的影响程度。 - 可用性(A)-衡量用户在需要访问数据或服务时受影响的程度。 #### 3.2.2 评估原则 - 评估漏洞的严重等级,不是评估风险。 - 评估时必须基于攻击场景,且保证在该场景下,攻击者成功攻击后能对系统造成机密性、完整性、可用性影响。 - 当安全漏洞有多个攻击场景时,应以造成最大的影响,即 CVSS 评分最高的攻击场景为依据。 - 被嵌入调用的库存在漏洞,要根据该库在产品中的使用方式,确定漏洞的攻击场景后进行评估。 - 安全缺陷不能被触发或不影响 CIA(机密性/完整性/可用性),CVSS 评分为 0 分。 #### 3.2.3 评估步骤 对漏洞进行评估时,可根据下述步骤进行操作: - 设定可能的攻击场景,基于攻击场景评分。 - 确定漏洞组件(Vulnerable Component)和受影响组件(Impact Component)。 - 选择基础评估指标的值:通过对可利用指标(攻击向量/攻击复杂度/所需权限/用户交互/范围)和受影响指标(机密性/完整性/可用性)给出漏洞影响评估。 #### 3.2.4 严重等级划分 | 严重等级(Severity Rating) | CVSS评分(Score) | | --- | --- | | 致命(Critical) | 9.0 - 10.0 | | 高(High) | 7.0 - 8.9 | | 中(Medium) | 4.0 - 6.9 | | 低(Low) | 0.1 - 3.9 | | 无(None) | 0.0 | ### 3.3 漏洞披露 为了保护 openUBMC 用户的安全,在进行调查、修复和发布安全公告之前,openUBMC 社区会严格控制漏洞信息的范围,将之限制在仅处理漏洞的相关人员之间传递,不会公开披露、讨论或确认 openUBMC 产品的安全问题,同时也要求漏洞上报者对此漏洞进行保密,直到对外公开披露。安全漏洞修复后 openUBMC 社区会发布安全公告,安全公告内容包括该漏洞的技术细节、CVE 编号、CVSS 安全评分、严重性等级以及受到该漏洞影响的版本和修复版本等信息。安全公告提供邮件订阅功能,您可以通过“security”链接订阅 openUBMC 社区的安全公告。 Content on This Page --- https://www.openubmc.cn/zh/whitepapers/ --- # 白皮书 了解openUBMC技术详情及行业生态现状、业务场景的应用 Coming soon # openUBMC — Full Documentation > openUBMC 是一款架构领先、开发友好、遵循开放标准的算力设备开源管理软件。 > openUBMC is an open-source BMC management software with leading architecture, developer-friendly design, and open standard compliance. --- # 下层平台依赖管理方案 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/Lower_level_platform_management.html > Language: zh # 下层平台依赖管理方案 本文记录外部依赖管理的思路。 ## 1. 问题 openUBMC的构建依赖各种外部制品,常见方式是CMC依赖下层平台制品和构建工具,在日常过程中会遇到下层平台版本号未变更但制品变更的场景。 外部制品不可控带来如下影响: 1. 下层平台不可控 2. 下层平台变更低感知 3. 版本处于一种不确定状态,可能影响重复构建 ## 2. 思路 下层平台管理生成的制品需要有文件指纹校验,在构建系统中使用文件清单记录文件SHA256值,只有经过文件清单校验的外部制品才能进入构建系统,不能通过检查的将报告失败。 上述思路的好处在于外部的依赖在代码仓中可管控、能记录,降低外部变更的影响。 ## 3. 实现方案 借助ArtGet定义的XML文件,将需要校验的文件SHA256值写入对应XML文件中。当通过XML文件下载依赖制品后,根据XML文件中的文件SHA256值与实际的文件SHA256值进行对比,当有文件SHA256值对比不一致时,报告失败并终止构建。 对于需要校验的制品,在XML的对应`copy`标签下新增`verifyFiles`标签,其中包含1~N个`file`标签,`file`标签内容包括文件名和SHA256值。 XML文件中hash值示例: ```xml /foo/bar/file.zip foo/bar/ file.zip xxxxx ... /foo / file.zip xxxxx file.tar.gz xxxxx ``` ## 4. 影响 1. 按上述思路整改后,引入新的平台版本时不仅是修改版本号,还需要申明或修改下载的文件SHA256值,如引入的平台制品变更将因文件校验失败而构建失败。 2. 当将XML文件归档到构建的制品包中时,需要先删除XML文件中的自定义`verifyFiles`标签。 --- # 构建制品定制化方案 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/build_customized_products.html > Language: zh 构建采用 **组件自申明、集成时赋权** 策略管理组件生成的文件,该策略要求组件生成的文件都由一个permissions.ini文件申明需要的权限,由构建系统在组件集成环节解析permissions.ini文件完成文件赋权。 ## 为什么要使用组件自申明、集成时赋权策略 一个产品往往包含开源、平台、芯片、自研软件等各种软件,实践表明产品权限管理存在漏赋权、重复赋权、管理困难等,为此产生了“赋权不一定要准确,可以忽略错误”的做法,最终导致很多漏到后端测试。 Openubmc所有权限由组件自主申明,赋权文件会强制检查所有赋权操作是否正确执行,按错误即失败原则处理,实现**左移**。 > [!WARNING] > openubmc要求赋权100%准确,会检测每一条命令执行结果,如遇失败即报错退出。 > 有授权记录但无被授权文件的会报构建失败;对有文件但无授权记录的由测试团队的脚本检查并提单。 ## 如何操作 组件的制品权限管理包含四种方式: 1. 静态配置权限:构建任意场景都会生成的文件由代码仓打包的permissions.ini文件描述。 2. 动态配置权限:构建时按特性选项生成的文件由conanfile.py动态生成permissions.ini文件。 3. 组件定制化配置权限:组件构建时不生成,产品集成时由组件定制化脚本生成的文件由定制化脚本赋权。 4. 产品定制化配置权限:产品对通用权限有不同要求的由产品定制化脚本赋权。 ### 静态配置权限 组件源码目录存储一个静态permissions.ini文件,每一行记录一个文件/文件夹权限,格式要求为`name type mode uid gid`,支持对指定文件、指定目录、递归指定目录下的文件、递归指定目录下的目录赋权,下面是iam模块的示例。 ```yaml # syntax documentation # format: name type mode uid gid # name is the path to the file you want to create/modify # type is the type of the file, being one of: # f: a regular file # d: a directory # r: a directory recursively # rd: a directory recursively, only subdirectory effectivity # mode are the usual permissions settings (only numerical values are allowed) # name is the path to the file you want to create/modify opt/bmc/apps/iam rd 550 0 0 opt/bmc/apps/iam r 440 0 0 etc/systemd/system/iam.service f 640 0 0 etc/rc.d/rc.start/init_user.sh f 550 0 0 etc/weakdictionary f 640 0 0 ``` > [!TIP] > 组件构建时打包源码目录下的permissions.ini文件至打包目录。 ### 动态配置权限 静态配置的permissions.ini文件只适配于必然会生成和打包的文件,实际应用中可能因为特性开关状态产生不同的文件,此时就需要动态生成permissions.ini文件。 conan的特性控制是由options完成,一个典型的应用示例是在组件的conanfile.py的build方法中判断是否使能或关闭某个特性并将动态赋权内容追加到permissions.ini文件。 以下示例演示了gcov选项未使能时向permissions.ini文件追加了`opt/bmc/apps/example/yy f 550 0 0`赋权内容。 ```python class IamConan(ConanBase): def build(self): super().build() if not self.options.gcov: with open("permissions.ini", "a+") as fp: fp.write("\nopt/bmc/apps/example/yy f 550 0 0") ``` > [!TIP] > 示例仅演进功能,赋权内容要跟构建制品逻辑100%匹配,请以实际特性状态和文件生成逻辑为准。 ### 组件定制化配置 某些场景组件对其它组件/平台提供的文件有权限诉求的,如果这种诉求与组件存在100%关联,即组件存在,该文件必须存在且权限满足要求的,可以使用组件定制化配置权限。 该方式依赖组件定制化功能,该功能为组件提供了在特定阶段注入一段python代码的能力,其基础原理是由组件管理一个`build/customization.py`文件,构建时打包到include目录,产品构建时会搜索该文件并执行。 当前支持组件在三个阶段进行定制化,按照执行阶段顺序分为`post_image` -> `post_rootfs` -> `post_hpm`,组件按需配置各个阶段的定制化。 - `post_image` - 所有组件合并为组件镜像后执行,其中定制化脚本类`rootfs_path`参数为组件镜像目录。使用场景:对组件镜像的文件进行软链接、权限设置或其他定制化操作。 - `post_rootfs` - 组件镜像和rtos、sdk合并为rootfs镜像后执行,其中定制化脚本类`rootfs_path`参数为rootfs镜像目录。使用场景:对非组件的文件(rtos自带文件)进行定制化操作(软链接、权限设置、删除、更改内容等)。 - `post_hpm` - 制作hpm前执行,其中定制化脚本类`rootfs_path`参数为hpm包制作目录。一般组件不涉及,属于特殊场景。 以下示例用于演示了一种场景:某一组件要求/etc/passwd文件权限必须为600,该文件实际由rtos带入,为确保权限正确性,需要组件在post_rootfs(rootfs制作完成后)执行一段定制化脚本完成赋权。 ```python import subprocess # 定制化脚本,由manifest构建时调用 class Customization(object): def __init__(self, board_name, rootfs_path): self.board_name = board_name self.rootfs_path = rootfs_path def post_rootfs(self): subprocess.run(['/usr/bin/sudo', '/usr/bin/chmod', '600', '/etc/passwd'], check=True) ``` > [!attention] > > 1. 定制化配置请一定集成到版本构建中验证完成再上库。 > 2. 在`build/customization.py`脚本中不要import bmcgo相关代码,避免引起依赖。 ### 产品定制化配置 如果组件提供的默认权限不符合极个别产品定制化要求,可以由产品定制化脚本自主完成权限控制。 该方式依赖产品manifest.yml文件记录的customization定制化脚本,该脚本会在多个阶段执行,一般权限定制放在rootfs_cust阶段即可,以下示例为产品定制化脚本动态创建`data/opt/bmc/web/custom`目录并赋权的示例: ```python class Customization(BaseCustomization): def rootfs_cust(self, rootfs_path): self.work.run_command("mkdir -p data/opt/bmc/web/custom", sudo=True) self.work.run_command("sudo chmod 750 data/opt/bmc/web/custom", sudo=True) ``` > [!attention] 定制化配置请一定验证存在性及权限正确后再上库 定制化验证步骤: * 初步验证:构建`hpm`包完成后,在`temp`目录下,使用`find`命令去查找对应`build_type`和`stage`目录生成的文件或者修改权限的文件,如下: ```shell [11:28:08 root(1110):/home/workspace/codehome/manifest]# find . -name custom | grep extern ./temp/build_Openubmc_debug_dev/tmp_root/opt/bmc/web/htdocs/extern/custom ./temp/build_Openubmc_debug_dev/buildimg/rtos_with_driver/rootfs/opt/bmc/web/htdocs/extern/custom [11:28:12 root(1110):/home/workspace/codehome/manifest]# find . -name custom | grep extern | xargs ls -la lrwxrwxrwx 1 root root 24 4月 1 10:47 ./temp/build_Openubmc_debug_dev/buildimg/rtos_with_driver/rootfs/opt/bmc/web/htdocs/extern/custom -> /data/opt/bmc/web/custom lrwxrwxrwx 1 root root 24 4月 1 10:47 ./temp/build_Openubmc_debug_dev/tmp_root/opt/bmc/web/htdocs/extern/custom -> /data/opt/bmc/web/custom [11:47:52 root(1110):/home/workspace/codehome/manifest]# ``` * 环境验证(开发者自行验证,不做示例):在初步验证成功后,将`hpm`包升级到环境中,检查对应路径下的文件是否存在或符合预期权限要求 * 版本验证(开发者自行验证,不做示例):需求完成后,上库并出版本以后,将版本包升级到环境,再次检查对应路径下文件是否存在或者符合预期权限要求 --- # 组件的构建与发布 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/build_process.html > Language: zh openUBMC采用`Conan`包管理器与`CMake`构建系统集成的方式,实现组件的独立构建和发布。`Conan`是一个`C`/`C++`构建框架,由命令、属性和方法构成,主要负责封装并对外提供一致的接口,并基于`Conan`仓库完成组件交付。`CMake`定义了如何从源代码生成可执行文件或库,主要任务是负责项目的构建过程。关于`CMake`的详细介绍请参考[Cmake官方文档](https://cmake.org/documentation/);`Conan`的详细介绍请参考[Conan官方文档](https://docs.conan.io/en/1.6/introduction.html)。 openUBMC组件构建由`CMake`脚本`cmakelists.txt`和`Conan`脚本`conaninfo.py`、`conanfile.py`以及`conanbase.py`组成: 1. `cmakelists.txt`:`CMake`构建配置文件,用于定义项目的构建规则、依赖关系、编译选项等,简化项目的编译和构建过程。 2. `conaninfo.py`:定义了`Conan`基本信息,包括包名,版本号和git仓。 3. `conanbase.py`:定义了统一的`Conan`构建脚本。 4. `conanfile.py`:`Conan`脚本,继承自`conanbase.py`,可以重写`conanbase`的方法。 # CMake基本使用 `CMake`是一个开源的跨平台自动化建构系统,用来管理软件构建的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个函数库。 `CMake`的所有语句都写在一个`CMakeLists.txt`的文件中。`CMakeLists.txt`文件确定后,直接使用Cmake命令运行`CMakeLists.txt`所在的目录,CMake之后就会自动生成makefile文件,然后再直接make就可以编译出构建结果。 更简单的解释就是`CMake`是为了生成`Makefile`而存在,开发者不需要自己去写`Makefile`,只需要写简单的`CMakeLists.txt`即可。开发者可以在`CMakeLists.txt`中添加引用所需的`C`/`C++`库。 这里,以组件`new_app`的`CMakeLists.txt`为例,简单介绍openUBMC中用到的`CMake`指令: ```cmake -- cmake最低版本需求 cmake_minimum_required(VERSION 3.14) -- 设置项目名称,后面可添加支持的语言,默认是C和C++ project(new_app) -- 查找PkgConfig模块,通过PkgConfig模块找到你想要找到的第三方库 find_package(PkgConfig REQUIRED) -- 用于查找PkgConfig格式的库信息 pkg_search_module(GLIB REQUIRED glib-2.0) ... -- 设置变量的值 set(TARGET_LIB ${PROJECT_NAME}) ... -- 指定安装时运行规则 install(DIRECTORY src/lualib DESTINATION ${APP_INSTALL_DIR} OPTIONAL) ... ``` 若为定制组件,则在通用组件配置的基础上,新增定制组件构建项 ```cmake ## customized resource deployment options set(CUSTOMER new_app) set(CUSTOM_INSTALL_DIR opt/bmc/extend/${CUSTOMER}) -- 定制仓所需的sr等文件/目录 install(DIRECTORY sr DESTINATION ${CUSTOM_INSTALL_DIR} OPTIONAL) ... message(STATUS "new_app customized resource deployment is completed.") ``` # Conan基本介绍 `Conan`是一个开源的`C/C++`包管理器,用于下载、管理和构建项目所需的依赖库。简单来说,`Conan`可以作为包的使用者和包的创建者,它使用`conanfile.py`文件自动化实现构建出包。在openUBMC中,`Conan`与`CMake`构建工具集成实现项目的编译和构建。 `conanfile.py`文件需定义一个继承自`ConanFile`的类。这个类包括两个部分:属性和方法。属性用于设置一些只读信息而方法用于自动化打包的逻辑。在编写完`conanfile.py`文件之后,执行`Conan`工具的`conan create`命令会默认按照以下顺序自动执行conanfile类的方法: ```python 1. export() 2. export_sources() 3. config_options() 4. configure() 5. layout() 6. requirements() 7. package_id() 8. validate() 9. validate_build() 10. build_requirements() 11. build_id() 12. system_requirements() 13. source() 14. generate() 15. imports() 16. build() 17. package() 18. package_info() ``` 这里简单介绍`conanbase`中定义的`export`、`generate`、`build`和`package`等方法。各方法的函数体功能简要介绍如下 ```python import os import stat import urllib3 from conans import ConanFile, CMake from bingo.component.gen import GenComp urllib3.disable_warnings() class ConanBase(ConanFile): name = "new_app" #定义包名 version = "0.0.1" url = "https://www.huawei.com" settings = "os", "compiler", "build_type", "arch" # 定义不同二进制包的配置。对操作系统、编译器、构建类型或架构定义的任何修改都将生成不同的二进制包。 generators = "cmake" language = "lua" _cmake = None _codegen_version = 14 scm = { "type": "git", "url": "", "revision": "auto" } options = { # 包特定的配置,可以在default_options中定义默认值 "asan": [True, False], "gcov": [True, False], "manufacture": [True, False], } default_options = { "asan": False, "gcov": False, "manufacture": False, } def generate(self): # 执行将创建一个映射Conan和CMake语法的conan_toolchain.cmake文件 ... # 构建时,此方法会自动生成export目录 def export(self): # 此方法定义拷贝文件到export目录 ... def requirements(self): # 引用组件的依赖包 ... # 构建时,此方法会自动生成build目录 def build(self): # 主要调用了cmake下的build方法,相当于执行了cmake build命令,完成从预处理到链接的全部过程 ... cmake = self._configure_cmake() cmake.build() # 构建时,此方法会自动生成package目录 def package(self): # 执行了cmake install命令,根据cmakelists.txt文件当中的install命令将编译生成后的文件移动到指定位置 cmake = self._configure_cmake() cmake.install() ... ``` openUBMC的工程工具`bingo`在构建命令`bingo build`中集成了自动生成`conanbase.py`的功能。此文件定义了继承自`ConanFile`的类`conanbase`,并在此类中已实现基本的构建方法。因此,在各组件的conanfile.py文件中,只需定义继承自conanbase的类即可。若开发者需要自定义构建出包文件,可在`conanfile.py`文件定义的类中重写相关方法。 `conanfile.py`文件的`settings`字段定义了不同二进制包的配置。在此示例中,对操作系统、编译器、构建类型或架构定义的任何修改都将生成不同的二进制包。这些配置信息的值都统一存放于`profile`文件中。在执行构建时,`Conan`工具会根据设置的`–profile`参数获取配置文件中的所有信息,并应用于要构建或安装的软件包。如果没有指定该参数,相当于使用`–profile=default`进行调用。 在组件目录下执行命令构建包时,会生成以`<包名>/<版本>@<用户>/<渠道>`格式命名的`Conan`包。 可通过`conan cache path <组件名>`获取`Conan`生成的包所存在的具体目录,构建生成的每一个`Conan`包都会包含五个重要文件夹,每个文件夹都在`confile`类中有对应同名的方法。 - `e`: 用于存储包的文件夹,`export`方法的默认目标文件夹。 - `es`: 在`conanfile.py`文件定义的类中,使用`exports_sources`方法`copy`的文件默认存放于此文件夹中。 - `s`: 存储源码文件,`source`方法的默认目标文件夹。 - `b`: 完成实际源代码编译的文件夹,`build`方法的默认目标文件夹。 - `p`: 最终构建生成的包所在的文件夹,每个不同的二进制配置将有一个子文件夹。`package`方法的默认目标文件夹。 # 构建、发布 openUBMC的工程工具实现了`CMake`和`Conan`工具的相关文件自动生成。同时,支持CLI命令一键完成组件的构建,运行`bingo build`命令所执行的整个构建流程可以描述为: 1. 主动生成`conanbase.py`文件。组件的`conanfile.py`文件继承自`conanbase.py`定义的类`conanbase`。 2. 根据命令参数获取交叉编译所需的配置信息。 3. 清除组件锁文件,对于组件在`service.json`文件中未指明特定版本的依赖,使用最新版本的依赖包。 4. 执行`conan create`命令,依据`conanfile.py`文件实现构组件定制化构建出包。 `bingo build`命令的相关参数如下: ```shell Build conan optional arguments: -h, --help show this help message and exit -bt BUILD_TYPE, --build_type BUILD_TYPE 构建类型,可选:dt,debug,release 默认:debug --stage STAGE 组件包发布阶段, 可选: dev(developer), pre, rc, stable 默认:dev -r REMOTE, --remote REMOTE conan仓别名,请检查conan remote list查看已配置的conan仓 默认: openUBMC_dev -nc, --no_cache 不使用~/.conan/data目录下的缓存包(构建前删除缓存) -o OPTIONS, --options OPTIONS Define options values (host machine), e.g.: -o Pkg:with_qt=true --user USER 指定conan包的user字段,尝试从/etc/bingo.conf文件读取conan.user字段,否则由程序管理 -as, --asan Enable address sanitizer ``` `bingo build`命令集成了`Conan`和`CMake`工具的使用,实现组件自动化编译出包。 开发者进行个人开发时,使用此命令生成的组件`Conan`包,将会发布并存放于本地的`root/.conan2/p`目录下。 --- # 构建工具管理 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/build_tools.html > Language: zh 本文用于指导开发者管理组件特有的构建工具。 目前openubmc有特殊构建工具的组件主要是ai_engine(依赖flatbuffers) ## 说明 部分组件构建时需要使用特殊的构建工具,这些工具可能不在构建OS中并且一般针对专用场景,考虑到工具管理方式归一、持续演进(适配编译器、OS、芯片等),所有特有的构建工具请使用conan管理,原则上产品构工程和manifest仓将不再为特定app添加构建依赖。 ## 基本逻辑 首先我们需要将工具conan化,在依赖工具的组件`conanfile.py`中添加`build_requirements`方法引入构建时的工具依赖。 ai_engine组件改造示例: ### STEP1: flatbuffers构建工具conan化 创建工具的conan包,这一步需要在`conan_index`仓中添加flatbuffers构建脚本, 工具一般需要对外呈现一个或一组命令,因此工具conan包最显著的特征是要在`package_info`方法中管理好自己的PATH环境变量,当构建依赖此工具的组件时(如ai_engine组件构建时)该变量会注入PATH环境变量以正确查找到需要的工具。 除此之外,工具包跟开源软件、平台软件等conan包没有区别,就是添加一个普通的conan组件,flatbuffers完整的conanfile.py示例。 ```python # Copyright © Huawei Technologies Co., Ltd. 2022-2025. All rights reserved. from conans import ConanFile, tools, CMake from conans.errors import ConanInvalidConfiguration import os required_conan_version = ">=1.42.0" class FlatbuffersConan(ConanFile): generators = "cmake" homepage = "https://google.github.io/flatbuffers/" description = "FlatBuffers is an efficient cross platform serialization library. " chost = None settings = "os", "compiler", "build_type", "arch" exports_sources=["permissions.ini"] _cmake = None @property def _source_subfolder(self): return "source_subfolder" def validate(self): if self.settings.arch != "x86_64": raise ConanInvalidConfiguration("Only x86_64 supported") def source(self): git = tools.Git(verify_ssl=False) git.clone(**self.conan_data["sources"][self.version]) def _configure_cmake(self): if self._cmake: return self._cmake self._cmake = CMake(self) os.environ['CFLAGS'] = os.getenv('CFLAGS') + " -D_FORTIFY_SOURCE=2" os.environ['CXXFLAGS'] = os.getenv('CXXFLAGS') + " -D_FORTIFY_SOURCE=2" if self.settings.arch == "armv8" or self.settings.arch == "x86_64": self._cmake.definitions["CMAKE_INSTALL_LIBDIR"] = "usr/lib64" else: self._cmake.definitions["CMAKE_INSTALL_LIBDIR"] = "usr/lib" self._cmake.definitions["CMAKE_INSTALL_BINDIR"] = "usr/bin" self._cmake.configure(args=["--no-warn-unused-cli"]) return self._cmake def build(self): cmake = self._configure_cmake() cmake.build() cmake.install() def package_info(self): self.env_info.PATH.append(os.path.join(self.package_folder, "usr", "bin")) ``` > [!NOTE] > 上述示例最重要的是package_info方法将打包目录追加到PATH环境变量。 ### STEP2:构建工具包 可以用`bmcgo build -t dependencies -cp flatbuffers/2.0.0 --verbose`命令构建出可用的版本。 正式发布需要使用CI工程 ### STEP3:引入工具 conan提供了`build_requirements`方法管理构建依赖,我们只需要将需要的工具添加到依赖清单即可。 ```python import subprocess class AppConan(ConanBase): def build_requirements(self): super(ConanBase, self).build() # 由build_requires引入工具依赖 self.build_requires("flatbuffers/2.0.0@openubmc.dev/dev") # 启动构建示例 def build(self): # .... other 代码 # 调用flatc,此时会去flatbuffers设置的PATH环境变量中查找flatc可执行程序 subprocess.run(f"flatc -o {cml_save_path} -b {self.fbs_path}/CML.fbs {json_path}", shell=True) ``` ### STEP4:构建 随后只需要构建出包(如ai_engine)即可,构建工具会自动下载,conan会自动设置工具带入的PATH环境变量。 --- # 调试工具管理 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/debug_tools.html > Language: zh 在开发调试过程中预置一些调试功能和工具通常是有意义的,如预置telnet、gdb等,本文描述openubmc如何管理这些功能。 ## 一个组件化的构建架构需要考虑扩展性,能够轻松适配不同OS、不同编译器甚至不同的芯片。采用二进制引入工具绝对不是一个明智的选择,所有非产品类的调试功能或工具建议按如下方式管理。 ### 工具也是一个组件 调试工具应该以可源码构建的conan组件形式引入,支持可源码构建、支持交叉编译、自动依赖管理、构建工具(make/cmake/gcc等知名且通用的除外)自管理特性,这样做可以明显的好处包括: 1. 可追溯、可升级、支持交叉编译,为openubmc提供长期支持,广泛适用于各种场景,持续产生收益; 2. 维护openubmc组件化通用的和解耦的架构,维护扩展性和灵活性。 ### 功能有开关 融入业务组件中的调试功能应该以特性形式控制可见范围,控制方式一般是构建类型(debug/release),也可以根据需要扩展,不管如何都需要由conan包对外呈现特性开关,实现可控。 ## 构建工程实现 构建工程已支持软件包(supportE发布包、toGDP生产装备包)级实现组件裁剪和特性裁剪。 同时,考虑调试功能、工具的可见范围需要基于 **某些条件**,只有满足特殊条件的软件包或特性才会引入工具或组件,构建工程为此需要扩展支持条件引入功能,并预置常用条件,如根据build_type要求控制引入条件,具体条件可以扩展。 以下是manifest.yml中编写条件引入 组件 和 特性 的示例: ```yaml dependencies: - conan: "ssdp" condition: build_type: release - conan: "muparser" options: shared: true condition: build_type: debug - conan: "muparser" options: shared: false condition: build_type: release ``` 上述示例演示了: 1. ssdp组件只在release条件下引入 2. muparser组件在debug条件下使用shared动态库 3. muparser组件在release条件下使用静态库 ## 责任与分工 调试功能和工具的引入涉及构建工程和业务述求方,相关责任与分工: 1. 构建工程提供扩展条件检查设计和实现,可为具体工具和功能编译构建提供指示。 2. 调试工具和调试功能引入按谁痛谁主动原则确定,一般为业务述求方,需要完成组件的源码引入和功能实现。 --- # Hi1712 芯片构建指导 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/hi1712_chip_build.html > Language: zh # 概述 本文档指导开发者完成 Hi1712 芯片的构建与整机集成,涵盖环境准备、配置说明、构建流程、整机集成、执行构建和产物验证。 # 第一步:环境准备 ## 1.1 开发环境要求 开发环境准备请参考:[环境介绍](../../../getting_started/quick_start/env_introduction.md) ## 1.2 安装构建工具 ```bash # 克隆 manifest 仓库 git clone https://gitcode.com/openUBMC/manifest.git cd manifest # 执行环境初始化脚本 python3 init.py ``` 初始化脚本参数说明: | 参数 | 说明 | |------|------| | `-b BOARD_NAME` | 构建类型,支持 openUBMC 或 oee,默认为 openUBMC | | `-user OPENUBMC_USER` | openUBMC 社区用户名 | | `-psw OPENUBMC_PASSWORD` | openUBMC 社区密码,推荐使用交互式输入 | | `--no_build` | 不进行 SDK 初始化 | 使用示例: ```bash # 默认初始化(openUBMC) python3 init.py # 带全部选项初始化 python3 init.py -b openUBMC -user <用户名> -psw <密码> ``` 初始化脚本会自动安装: - bingo 构建工具 - Conan 2.x 包管理器 - Node.js 运行环境 - 其他依赖工具 ## 1.3 配置 Conan 远程仓库 ```bash # 查看已配置的 remote conan remote list # 输出示例: # openubmc_opensource: https://conan.openubmc.cn/openubmc_opensource [Verify SSL: False, Enabled: True] ``` 默认存在 `openubmc_opensource` remote,用于开源组件发布的 conan 包。 如需添加其他 remote: ```bash # 添加 Conan 远程仓库 conan remote add # 认证(以 openubmc_opensource 为例) conan remote login openubmc_opensource ``` ## 1.4 bingo 安装 ```bash # 检查 bingo 版本 bingo -v ``` 初始化脚本默认安装 bingo 工具。 也可以手动安装: ```bash # 克隆 bingo 仓库 git clone https://gitcode.com/openUBMC/bingo.git cd bingo # 执行安装脚本 sh install_local.sh . ``` # 第二步:构建配置说明 Hi1712 已有默认产品配置 `openUBMC_1712`,可直接使用: ```bash cd /path/to/manifest/build/product/BMC/openUBMC_1712 ``` ## 2.1 产品配置文件 查看产品配置: ```bash # 查看 manifest.yml 配置 cat manifest.yml # 查看辅助配置文件 ls -la # 输出: # -rw-r--r-- 1 root root 4871 Aug 11 20:00 manifest.yml # -rw-r--r-- 1 root root 256 Aug 11 20:00 archive.ini # -rw-r--r-- 1 root root 2100 Aug 11 20:00 version.xml # -rw-r--r-- 1 root root 500 Aug 11 20:00 update_ext4.cfg ``` ## 2.2 SDK 配置 ```yaml bmc_sdk_download: url: https://repo.openubmc.cn/26.06/sdk/bmc_sdk_1712.tar.gz sha256: c3f3b7c51ca503b40ac090b7e773aae2798f2652fc1f5f006c769d0c7bf5d8ea ``` **说明**: - Hi1712 使用专用 SDK:`bmc_sdk_1712.tar.gz` - SHA256 校验值确保下载完整性 - SDK 包含平台组件的 Conan 包,以及配套的 RTOS、SDK、编译器、构建工具 - 是整包构建方案的关键配置,简化依赖管理 ## 2.3 平台配置 ```yaml platform: conan: "ibmc_sdk/5.14.00.01.b001@openubmc/stable" options: rtos_version: rtos_v2_1712 # Hi1712 专用标识 enable_haf: false package: community_unsign_webvnc_1712 ``` **关键参数**(1712 平台组件专用 option): - `rtos_version: rtos_v2_1712`:Hi1712 专用 RTOS 版本标识(不能使用 rtos_v2) - `enable_haf: false`:平台是否支持高可用特性 - `package: community_unsign_webvnc_1712`:默认使用的整包方案 ## 2.4 签名配置 Hi1712 支持 RSA4096 和 SM2 国密双签名: ```yaml base: signature: files: - file: ${product}/ca/rootca.crl dst: cms.crl - file: ${product}/ca/rootca.der dst: rootca.der # RSA4096 签名 - file: ${product}/ca/rsa_rootca.crt dst: rootca.crt condition: signature_type: rsa4096 # SM2 国密签名 - file: ${product}/ca/sm2_rootca.crt dst: rootca.crt condition: signature_type: sm2 # RSA 签名密钥 rsa_sign_key: UBMCCMSEE rsa_ts_key: UBMCTS rsa_rootca_crl_download: url: https://openubmc-certs.obs.cn-north-4.myhuaweicloud.com/bb7d00fb-5ca5-476b-bc1a-258105fa0b8f.crl rsa_ica_crl_download: url: https://openubmc-certs.obs.cn-north-4.myhuaweicloud.com/4277907e-3a28-41e9-b58d-8f54f741dedf.crl rsa_ica_download: url: https://openubmc-certs.obs.cn-north-4.myhuaweicloud.com/openUBMC-RSA-PSS-Integrity-CA-1_certificate.pem # SM2 签名密钥 sm2_sign_key: testsm2ee sm2_ts_key: testsm2tsa sm2_crl_download: url: https://cert-b07f.obs.cn-north-4.myhuaweicloud.com/sm2ca.crl sm2_ica_download: url: https://cert-b07f.obs.cn-north-4.myhuaweicloud.com/sm2ica.pem ``` **说明**: - 支持 RSA4096 和 SM2 双签名 - 构建时通过 `--signature-type` 参数选择签名方式 - 需要配置对应的密钥标识和证书下载地址 ## 2.5 Linx 配置 ```yaml skip_linx: true linx: files: - file: ${product}/ca/rootca.der dst: host_cms_root_cert_g2.bin ``` **说明**: - `skip_linx: true`:跳过 Linx 构建(Hi1712 必配) - `linx.files`:Linx 包文件列表 ## 2.6 gpp 分区配置 ```yaml gpp: files: - file: ${work_out}/rootfs_BMC.img - file: ${work_out}/rootfs_BMC.tar.gz - file: ${work_out}/rootfs_BMC.img.cms - file: ${board_path}/cms.crl dst: cms.crl - file: ${board_path}/rootca.der dst: rootca.der - file: ${sdk_path}/Hi1711_boot_4096_debug.bin dst: Hi1711_boot_4096.bin condition: build_type: debug - file: ${sdk_path}/Hi1711_boot_4096.bin dst: Hi1711_boot_4096.bin condition: build_type: release - file: ${linx_build_dir}/out/LiteOS_M.bin dst: LiteOS_M.bin # Hi1712 专用分区头部配置 pkg_headers: gpp_header: dst: emmc_header.config file: /usr/share/bingo/emmc_uboot_header_1712.config hpm_header: dst: hpm_header.config file: /usr/share/bingo/hpm_header_1712.config uboot_header: dst: emmc_uboot_header.config file: /usr/share/bingo/emmc_uboot_header_1712.config ``` **说明**: - `pkg_headers`:eMMC/HPM 分区头部配置(Hi1712 必配) - 使用 `/usr/share/bingo/emmc_uboot_header_1712.config` 等专用配置文件 ## 2.7 组件依赖 ```yaml dependencies: - conan: iam - conan: vpd options: board_name: openUBMC - conan: hica - conan: observability - conan: fluent-bit - conan: libyaml - conan: opentelemetry - conan: abseil - conan: grpc - conan: protobuf - conan: re2 - conan: c_ares - conan: opentelemetry-proto - conan: webui options: energy_enabled: false webvnc_enabled: true - conan: help options: board_name: openUBMC - conan: libspdm - conan: spdm - conan: dcmid - conan: vnc_proxy ``` # 第三步:构建流程说明 执行 `bingo build` 后,bingo 会按依赖关系自动编排构建任务。完整的任务编排定义在 `bmcgo/target/personal.yml`(个人构建)和 `publish.yml`(发布构建)中,其中涉及 Hi1712 的 5 个关键任务以下文「3.1 ~ 3.5」详述(图中以 ★ 标注),其余为通用辅助任务(组件编译、WBD、元数据打包、HPM 打包签名、QEMU 仿真、接口配置生成等)。 下图依据 `personal.yml` 描述了 Hi1712 构建的核心流水线(箭头表示等待依赖,并行分支在同层展开): ```python prepare_env │ ▼ ┌─ download_buildtools download ──┤ └─ download_dependency ★ 3.1 │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ oct_rtos ★ build_linxbin ★ build_conan(组件编译) 3.2 3.3 │ │ │ ┌──────┴──────┐ │ │ ▼ ▼ │ │ build_wbd_up package_metadata │ │ └──────┬──────┘ └───────────────┼────────────────┘ ▼ build_rootfs_img ★ 3.4 │ ┌────────────┼─────────────┐ ▼ ▼ ▼ buildgppbin ★ qemu_rootfs run_qemu_bmc 3.5(wait (可选,ignore_not_exist) linxbin) │ ▼ buildhpm_ext4 ──► sign_and_pack_hpm │ ▼ create_interface_config ``` ## 3.1 下载并解压 SDK 依赖(task_download_dependency) 对应源码:`bmcgo/tasks/task_download_dependency.py`,编排节点 `work.build.download`。 本步骤负责将整包 SDK 中的平台二进制文件安装到本地,是后续所有构建步骤的基础。 **主要动作**: 1. 从缓存目录(`~/sdk`)复制 SDK 到构建临时目录 2. 解压 `Hi1712_SDK*.tar.gz`,提取以下关键文件: - `drivers/Module.symvers`:内核模块符号表 - `drivers/sdk_initrd.tar.gz`:initrd 根文件系统 - `drivers/sdk_rootfs.tar.gz`:rootfs 根文件系统 - `boot/packeted/hibmc_core_sec_boot*.bin`:安全启动镜像(按签名类型和构建类型选取) 3. 安装到 `/opt/hi1711sdk` 并建立软链接,记录 SHA256 用于增量判断 **Hi1712 特有逻辑**: - 根据 `build_type`(debug/release)选择 `_debug` 后缀的 boot 镜像 - 根据 `signature_type`(sm2/rsa)选择对应签名的 boot 镜像 - 当 SDK SHA256 匹配时跳过安装,加速增量构建 ## 3.2 裁剪 RTOS(task_oct_rtos) 对应源码:`bmcgo/tasks/task_oct_rtos.py`,编排节点 `work.oct_rtos`(等待 `work.build.download`)。 本步骤基于 OCT(Output Configuration Trim)策略裁剪 RTOS,生成精简的 `rtos_with_ko.tar.gz`,供后续构建 rootfs 使用。 **主要动作**: 1. 准备 RTOS 编译环境,加载 `dlsetenv.sh` 工具链环境变量 2. 若配置了 `base/rtos_oct`,下载并安装 `rtos_dist` 裁剪工具 3. 分别裁剪 initrd 和 rootfs: - 依据 `policy.yml` 策略删除无用文件(`nouse_files`、`rm_exclude_files`) - 清理 initrd 中非 busybox 相关文件以压缩体积 - 复制编译链的 `libstdc++.so`、`libgcc_s.so` 到镜像 - 对镜像执行 strip 精简 4. 生成 `initrd_boot.cpio.gz`(≤5MB)、`uImage` 和 `rtos_with_ko.tar.gz` **Hi1712 特有逻辑**: - initrd 镜像大小限制为 5MB,超出将报错 - 通过 SHA256 缓存机制判断是否需要重新裁剪 ## 3.3 编译灵犀核固件(task_build_linxbin) 对应源码:`bmcgo/tasks/task_build_linxbin.py`,编排节点 `work.build.linxbin`(等待 `work.build.download`)。 本步骤构建并签名灵犀(Linx)协处理器固件 `LiteOS_M.bin`。该步骤仅对 `1712` 和 `oee_3095` 芯片执行,与裁剪 RTOS、组件编译**并行执行**。 **主要动作**: 1. 下载灵犀核源码(非伙伴模式) 2. 构建 `origin_LiteOS_M.bin` 固件 3. 对固件进行加密和 RSA 签名(执行 `01_prepare_build.sh` ~ `05_build_header.sh` 系列脚本) 4. 生成 `LiteOS_M.bin`(协处理器固件)和 `gpp4_top_hdr.bin`(分区头部) **Hi1712 特有逻辑**: - 当 `skip_linx: true` 时,跳过构建并生成空文件占位(兼容升级模块) - 自签名模式仅支持 RSA 算法 - 产出的 `LiteOS_M.bin` 会在 3.5 中打包进 GPP 镜像的 linx 分区 ## 3.4 构建 rootfs 镜像(task_build_rootfs_img) 对应源码:`bmcgo/tasks/task_build_rootfs_img.py`,编排节点 `work.task_build_rootfs_img`(等待 `work.build.conan`、`work.oct_rtos`、`work.build_wbd_up`、`work.task_package_metadata`、`task_download_dependency`)。 本步骤将组件产物、RTOS 裁剪结果整合为完整的 rootfs 根文件系统,并制作 ext4 镜像。该步骤等待**裁剪 RTOS**、**组件编译**及其衍生任务(WBD、元数据打包)全部完成后执行。 **主要动作**: 1. 解压 `rtos_with_ko.tar.gz`,组装 rootfs 基础目录 2. 拷贝组件构建产物到 rootfs,执行 strip 精简二进制体积 3. 记录代码分支和提交信息到 `/etc/bmc-release` 4. 执行产品定制化脚本(`rootfs_cust`) 5. 配置导入导出 schema 整合(`CombineJsonSchemas`) 6. 接口映射配置打补丁(Redfish / Web-backend / CLI / SNMP) 7. 合并硬件 SR 与软件 SR,生成 `csr_version.json` 8. 精简 MDS 和 SR 的 JSON 文件(删除 `description`、`required` 字段并压缩) 9. 制作 `rootfs_BMC.img`(ext4 格式)和 `rootfs_BMC.tar.gz` ## 3.5 构建 GPP 整包镜像(task_buildgppbin) 对应源码:`bmcgo/tasks/task_buildgppbin.py`,编排节点 `work.task_buildgppbin`(`work.task_hpm_envir_prepare` 的子任务,等待 `work.build.linxbin`)。 本步骤将 boot、rootfs、灵犀核固件等分区文件打包成 GPP(General Purpose Package)整包二进制镜像。该步骤嵌套在构建 rootfs 镜像的子任务中,并等待**灵犀核固件**构建完成。 **主要动作**: 1. 准备 boot 镜像(`Hi1711_boot_4096.bin`),自签名模式下对 uboot 重新签名 2. 复制 `gpp/files` 和 `gpp/pkg_headers` 配置的分区文件和头部配置 3. 调用 `gpp_header hpm` 生成 HPM 顶层和子头部 4. 拼接生成 `{board_name}_gpp.bin`,包含以下分区: - `hpm_top_header`:HPM 顶层头部 - `Hi1711_boot_4096.bin`:boot 启动镜像 - `LiteOS_M.bin`:灵犀核固件(来自 3.3) - `hpm_sub_header`:HPM 子头部 - `rootca.der`:根证书 - `rootfs_BMC.img.cms`:签名后的 rootfs 镜像 - `cms.crl`:吊销列表 - `rootfs_BMC.tar.gz`:rootfs 压缩包 **Hi1712 特有逻辑**: - 必须配置 `gpp/pkg_headers`,使用 `/usr/share/bingo/emmc_uboot_header_1712.config`、`hpm_header_1712.config` 等专用分区头部配置文件 - 后续会继续执行 `buildhpm_ext4`(制作 HPM 升级包)和 `sign_and_pack_hpm`(签名打包) # 第四步:集成到整机 整机产品(如服务器)基于 Hi1712 芯片构建时,需在产品 `manifest.yml` 中引用 Hi1712 的平台配置与整包 SDK,并按整机形态定制组件依赖。本步骤说明集成步骤和注意事项。 > 若仅进行 Hi1712 默认产品(`openUBMC_1712`)的独立构建,可跳过本步,直接进入第五步。 ## 4.1 集成步骤 整机产品集成 Hi1712 时,在产品 `manifest.yml` 中按以下步骤完成配置。产品目录及 `manifest.yml`、辅助文件的完整说明请参考[新增产品](../../../integration/system_config/add_new_product.md)。 **步骤 1:引用 Hi1712 整包 SDK** 通过 `bmc_sdk_download` 引用 Hi1712 专用整包 SDK,构建时自动下载并解压到本地: ```yaml bmc_sdk_download: url: https://repo.openubmc.cn/26.06/sdk/bmc_sdk_1712.tar.gz sha256: c3f3b7c51ca503b40ac090b7e773aae2798f2652fc1f5f006c769d0c7bf5d8ea ``` **步骤 2:引用 Hi1712 平台组件** 通过 `platform` 引用 Hi1712 平台组件,`rtos_version` 必须使用 1712 专用标识 `rtos_v2_1712`: ```yaml platform: conan: "ibmc_sdk/5.14.00.01.b001@openubmc/stable" options: rtos_version: rtos_v2_1712 enable_haf: false package: community_unsign_webvnc_1712 ``` **步骤 3:配置签名证书** 按整机签名方式(RSA4096 / SM2)在产品 `ca` 目录准备对应证书文件,并在 `base.signature` 中配置证书引用,证书文件按签名类型二选一生效,配置方法详见 2.4 签名配置。 **步骤 4:跳过 Linx 构建并配置 gpp 分区头部** 设置 `skip_linx: true` 跳过灵犀核固件构建(Hi1712 必配),并在 `gpp.pkg_headers` 中配置 1712 专用分区头部,确保 GPP 镜像分区布局正确,配置方法详见 2.5 Linx 配置和 2.6 gpp 分区配置: ```yaml skip_linx: true ``` **步骤 5:定制整机组件依赖** 在 `dependencies` 中按整机需求添加或定制组件。整包内的平台组件默认继承整包配置,无需重复声明;如需替换或定制某个平台组件,对同名组件写出版本/options 即可覆盖(同名即覆盖),覆盖时构建日志会打印告警: ```yaml dependencies: - conan: vpd options: board_name: MyProduct - conan: my_product_specific_component/1.0.0@openubmc/stable ``` **步骤 6:执行整机构建验证** ```bash cd /path/to/manifest export OPENUBMC_LICENSE=true # 首次构建需同意《BMC软件许可协议》 bingo build -b MyProduct -bt release --stage dev ``` 构建完成后按第六步验证构建产物,确认 HPM 包完整可升级。若需构建发布包,还需在 `tosupporte` 中同步配置 `platform` 引用。整包引用方式的更多说明可参考[平台整包集成指导](../build_guide/platform_full_package_integration_guide.md)。 ## 4.2 注意事项 集成 Hi1712 到整机时需注意以下关键约束: 1. **RTOS 版本标识**:必须使用 `rtos_v2_1712`,不能使用 `rtos_v2`,否则 RTOS 无法正确安装 2. **SDK 包名**:使用 `bmc_sdk_1712.tar.gz`,不能使用通用 `bmc_sdk.tar.gz`;`sha256` 校验值必须与文件服务器提供的一致,否则下载失败 3. **整包配置**:`platform.package` 使用 `community_unsign_webvnc_1712`;更新整包版本时需同步修改该配置 4. **Linx 配置**:必须设置 `skip_linx: true`,否则会触发灵犀核固件构建流程 5. **分区头部**:必须配置 `gpp.pkg_headers`,使用 `emmc_uboot_header_1712.config`、`hpm_header_1712.config` 等 1712 专用配置文件,否则 GPP 镜像分区布局错误,导致固件无法启动 6. **签名类型**:构建时通过 `--signature-type` 指定签名方式(rsa4096 / sm2),并确保 `ca` 目录下存在对应证书文件 7. **网络与协议**:`bmc_sdk_download` 下载需网络可访问 `repo.openubmc.cn`,且需同意《BMC软件许可协议》 8. **组件覆盖**:产品对整包同名组件写出版本/options 即覆盖整包默认配置,覆盖行为会在构建日志打印告警;仅在确需替换时才写,避免无意覆盖整包默认配置 9. **构建类型匹配**:`tosupporte` 中配置的 `build_type` 必须与构建命令 `-bt` 指定的类型一致,否则构建直接报错 # 第五步:执行构建 ## 5.1 同意许可协议 首次构建需要同意《BMC软件许可协议》: ```bash # 设置环境变量自动同意 export OPENUBMC_LICENSE=true ``` ## 5.2 执行构建 ```bash # 进入 manifest 目录 cd /path/to/manifest # 使用现有产品配置构建 # Debug 版本构建 bingo build -b openUBMC_1712 -bt debug --stage dev # Release 版本构建 bingo build -b openUBMC_1712 -bt release --stage dev ``` ## 5.3 构建参数说明 | 参数 | 说明 | 值 | |------|------|------| | `-b BOARD_NAME` | 单板名称(对应产品目录名) | openUBMC_1712 | | `-bt BUILD_TYPE` | 构建类型 | debug / release | | `--stage STAGE` | 包类型 | dev / rc / stable | | `--signature-type` | 签名类型 | rsa4096 / sm2 | ## 5.4 查看构建产物 ```bash # 查看构建产物 ls -lh output/ # 输出示例: # -rw------- 1 root root 70M Aug 11 20:00 rootfs_openUBMC_1712.hpm # -rw------- 1 root root 68M Aug 11 20:00 rootfs_BMC.img # -rw------- 1 root root 65M Aug 11 20:00 rootfs_BMC.tar.gz # -rw------- 1 root root 70M Aug 11 20:00 rootfs_openUBMC_1712.hpm.signed ``` 构建产物包括: - `rootfs_openUBMC_1712.hpm`: HPM 固件包 - `rootfs_BMC.img`: rootfs 镜像文件 - `rootfs_BMC.tar.gz`: rootfs 压缩文件 - `rootfs_openUBMC_1712.hpm.signed`: 已签名 HPM 包 # 第六步:验证构建产物 ## 6.1 检查构建日志 ```bash # 查看整体日志 cat temp/log/task.log # 查看组件构建日志 cat temp/log/conan_Build_*.log ``` ## 6.2 检查 HPM 包头部 ```bash # 查看 HPM 包头部 hexdump -C output/rootfs_openUBMC_1712.hpm | head -20 ``` # 参考资料 - [manifest 配置指南](../../../feature_dev/component_interface_spec/manifest.md) - [新增产品](../../../integration/system_config/add_new_product.md) - [整包构建指导](../build_guide/platform_full_package_integration_guide.md) - [SM2 国密签名规范](https://www.oscca.gov.cn/) --- # 如何构建组件以及查找生成文件 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/how_to_build_app.html > Language: zh ## 组件构建与发布 在构建组件时,我们需要切换到组件目录,执行`bingo`命令,否则`bingo`命令不生效,这里以组件`iam`组件来作为示例,演示组件的构建流程。 ### 一、简述 进入到`iam`的源码目录,执行如下命令来查看支持的构建参数 ```shell [07:16:31 root(1110):/home/workspace/codehome/iam]# bingo --help Component commands build 构建出包 analysis BMC product or package analysis, including build dependency analysis, interface dependency analysis, etc deploy 将组件及其依赖部署至temp/rootfs目录 test 构建DT. gen 代码自动生成,支持Lua和C语言,C组件需要在service.json中添加`"language": "c",`配置. Misc commands help 获取命令帮助 upgrade 升级bingo版本 输入"bingo -h"获取子命令帮助 [07:16:33 root(1110):/home/workspace/codehome/iam]# ``` 在上面返回的结果中,我们只使用到部分,`build`,`gen`为主要使用的命令,下面主要介绍这两条命令 ### 二、自动生成命令 `gen`命令用来自动生成代码,现在组件的代码都是使用此工具来自动生成,自动生成后才能进行构建,所以这里先讲`gen`命令,查看`gen`命令的help菜单 ```shell [07:28:19 root(1110):/home/workspace/codehome/iam]# bingo gen --help usage: bingo gen/当前只支持C和lua语言代码生成 [-h] [-v VERSION] [-w] 代码自动生成. options: -h, --help show this help message and exit -v VERSION, --version VERSION use specified version -w, --with_template generate with template [07:33:21 root(1110):/home/workspace/codehome/iam]# ``` 从返回结果,可以看到这个参数结构相对比较简单,建立好模板文件,使用如下命令即可生成代码 ```shell # -bt debug: 构建类型 # --stage rc: 预发布包 # 如果在mds目录下配置了model.json,则带上-w参数来进行模板生成 bingo gen -bt debug --stage rc # 日志截取,没有发生报错,则表示自动生成成功 python3 /home/workspace/codehome/iam/temp/lua_codegen/script/template.py -d /home/workspace/codehome/iam/proto -j /home/workspace/codehome/iam/temp/lua_codegen/temp/iam/ -n iam -i /home/workspace/codehome/iam/temp/lua_codegen/temp/iam/db_json.json -f /home/workspace/codehome/iam/temp/lua_codegen/script/lua_format.py -t orm_classes.lua.mako -o /home/workspace/codehome/iam/gen/iam/orm_classes.lua make[3]: Leaving directory '/home/workspace/codehome/iam/temp/lua_codegen/templates/apps' make[2]: Leaving directory '/home/workspace/codehome/iam/temp/lua_codegen/templates' make[1]: Leaving directory '/home/workspace/codehome/iam/temp/lua_codegen' ``` ### 三、构建命令 `build`命令用来构建组件的版本包,使用`help`命令来看下`build`命令的帮助文档 ```shell [07:16:33 root(1110):/home/workspace/codehome/iam]# bingo build --help usage: bingo [-h] [-b BOARD_NAME] [-bt BUILD_TYPE] [--stage STAGE] [-u] [-r REMOTE] [-s] [-nc] [-o OPTIONS] [--user USER] [--summary] [--minimum] [--package_info PACKAGE_INFO] component dt different version options: -h, --help show this help message and exit -b BOARD_NAME, --board_name BOARD_NAME 支持的单板名,请参考manifest/build/product目录 -bt BUILD_TYPE, --build_type BUILD_TYPE 构建类型,可选:dt,debug,release 默认:debug --stage STAGE 组件包发布阶段, 可选: dev(developer), pre, rc, stable 默认:dev -u, --upload 上传组件包到conan仓 -r REMOTE, --remote REMOTE conan仓别名,请检查conan remote list查看已配置的conan仓 默认: openubmc_dev -s, --from_source Build from source, include dependency component -nc, --no_cache 不使用~/.conan/data目录下的缓存包(构建前删除缓存) -o OPTIONS, --options OPTIONS Define options values (host machine), e.g.: -o Pkg:with_qt=true --user USER 指定conan包的user字段,尝试从/etc/bingo.conf文件读取conan.user字段,否则由程序管理 --summary 打印conan构建详细日志,默认:打印简要信息 --minimum, -m 获取 dt 构建的最小版本 --package_info PACKAGE_INFO, -pi PACKAGE_INFO package_info 文件路径, 此文件在 manifest 构建时会在 inner 目录生成 [07:20:03 root(1110):/home/workspace/codehome/iam]# ``` 根据上面的返回结果,需要使用的参数只有其中几个,以具体实例来讲解 ```shell # -b Openubmc: 指定单板名,某些组件和单板名挂钩,需要指定单板名来打入某些文件,如果组件和单板无关,不带此参数 # -bt debug: 构建类型,调试包 # --stage rc: 预发布包 bingo build -b Openubmc -bt debug --stage rc # 截取部分日志放在这里 Downloading conanmanifest.txt completed [17.89k] Downloading conaninfo.txt completed [2.97k] Downloading conan_package.tgz completed [543.98k] Decompressing conan_package.tgz completed [0.00k] iam/1.20.31@hw.ibmc.release/rc: Package installed cb9794cb17b2f104bdddb1803a0104b29d12d75c iam/1.20.31@hw.ibmc.release/rc: Downloaded package revision 35401b8fc57f5024055b6203bbd5abfe Build successfully [07:28:19 root(1110):/home/workspace/codehome/iam]# ``` 在Build successfully上方,能看到编译完成的版本号,这个版本号就是生成的组件版本 ### 四、构建生成文件 conan2: 组件下执行bingo build默认发布阶段为dev,此时通过cd ~/.conan2/p可进入到生成组件文件夹。 - 示例: - 通过输入conan cache path vpd/1.80.18@openubmc/stable可以查看组件配方文件路径 /root/.conan2/p/vpd264d23efe75e8/e - 通过输入conan cache path vpd/1.80.18@openubmc/stable:582e093ee6c9a154a84fdfd89574d24b71441f47可进入制品文件夹 /root/.conan2/p/b/vpd6d29851846626/p bingo会根据组件的conanfile.py或者conanbase.py文件,会构建生成对应的conan文件,其中: - e文件夹中是构建的配方文件,在文件的export()方法中定义。 - s文件夹中是构建的源代码文件,在文件的source()方法中定义。 - es文件夹是导出的source中的文件,在文件的exports_sources中配置相关信息。 - b文件夹是构建源代码生成的文件,是根据文件中build方法配置构建信息 - p文件夹中是打包构建后的代码,在文件的package方法中配置打包信息。 - 在metadata.json文件中,可以查看生成文件的recipe哈希值、包的唯一标志符以及包的修订哈希值,它用于跟踪包的变化。可通过此编号在conan仓中找到上传组件信息。 conan1(后续将不再维护): 组件下执行bingo build默认发布阶段为dev,此时通过cd ~/.conan/data/<组件名>/<版本号>/hw.ibmc.dev/dev可进入到生成组件文件夹。 bingo会根据组件的conanfile.py或者conanbase.py文件,会构建生成对应的conan文件,其中: - source文件夹中是构建的源代码文件,在文件的source()方法中定义,如果没有定义,会默认复制文件同层文件和文件夹。 - export_source文件夹是导出的source中的文件,在文件的exports_sources中配置相关信息。 - build文件夹是构建源代码生成的文件,是根据文件中build方法配置构建信息 - package文件夹中是打包构建后的代码,在文件的package方法中配置打包信息。 - 在metadata.json文件中,可以查看生成文件的recipe哈希值、包的唯一标志符以及包的修订哈希值,它用于跟踪包的变化。可通过此编号在conan仓中找到上传组件信息。 --- # maint及conan_index说明 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/maint_and_conan_index.html > Language: zh ## 方案概述 组件只有一个开发分支,所有代码都在主干修复和演进,转维版本的缺陷或特性需要由子系统完成上库和测试。组件按需发布补丁,由组件转维版本集成补丁,发布新的构建版本。 整体动作的基本原则:谁需要谁触发,责任owner负责发布补丁。 ## 关键功能 组件转维patch方案主要是完成 **组件无分支条件下修改代码并构建发布版本** ,其核心功能包括: 1. 支持基于组件转维源码重复发布组件。 2. 支持在组件转维源码基础上追加补丁patch文件,管理多个patch文件和patch顺序。 3. 提供工程工具简化操作。 ## 基本思路 [conan官方仓库](https://github.com/conan-io/conan-center-index) 中存储约1600+开源软件构建脚本,大部分都没有侵入式修改开源软件仓代码,对外体现就是开源软件本身没有适配任何conan构建代码。少部分开源软件无法直接使用conan构建的一般采用 **拉取到原生代码后应用patch方案** 修改构建脚本,最终完成构建。 openubmc的path方案采用conan的包管理方式完成,组件主干代码采用conanfile构建脚本与组件源码共仓管理模式(构建和发布),转维组件采用conanfile构建脚本和组件源码分仓管理模式。 ## 实现方案 构建工程的bingo工具新增manitain辅助命令,帮助开发者生成维护版本构建脚本,支持从主干cherry-pick特定的commit提交或者人工指定patch文件。 openubmc使用conan-index管理开源软件、平台软件和芯片软件管理中,这种方式可以在免修改组件源码条件下实现组件的编译和发布。转维版本也借鉴该方式,由maintain命令在conan-index仓中生成构建脚本和patch文件,编译方式和发布流程与开源软件发布完全一样。 具体的转维组件生成、构建、发布和引用流程为: 1. 参与下面的场景完成转维版本conan_index代码生成 2. 构建出包`bingo build -cp /`,其它参数详见命令帮助 3. 完成转维版本功能验证 4. 完成conan_index代码上库 5. 完成转维版本发布 6. 在产品引入新发布的转维组件,可能涉及manifest.yml修改和代码上库 ## maintain子命令说明 maintain子命令了4个参数用于辅助开发者使用: ```shell root@DESKTOP-M0FU0HP:/home/xuhj/workspace/openubmc300/manifest# bingo maint --help usage: bingo maintain [-h] -cp CONAN_PACKAGE [-p PATCH_FILE] [-b BRANCH] [-c COMMIT_ID] BMC组件的维护管理工具 optional arguments: -h, --help show this help message and exit -cp CONAN_PACKAGE, --conan_package CONAN_PACKAGE 指定需要维护的组件版本,示例:iam/1.2.3 -p PATCH_FILE, --patch_file PATCH_FILE 添加patch文件,可指定多个,顺序追加到代码中 -b BRANCH, --branch BRANCH 用于提取patch的分支,与commit_id配合使用 -c COMMIT_ID, --commit_id COMMIT_ID 需要生成patch的提交节点,长度不低于8个字符,可指定多个,顺序追加到代码中。【不推荐使用】生成的patch文件可能存在冲突、功能验证不充分,建议使用-p参数使用人工生成的补丁。 ``` 具体实现的基本逻辑为: ![image](../../images/build/build_guide/maint_and_conan_index/maint_command_execution_flow.png) 1. 从组件中心仓查找`-cp`参数指定组件的源码仓`url`和`tag` 2. 自动生成或开发者指定待生成的组件版本号,生成的版本号格式必须为a.b.c-build.x,其中a.b.c是三段式版本号,一般与-cp指定的基础版本保持一致,x为补丁版本号,使用数字。 3. (如果有)`-c`参数指定提交id的,需要切换到用于提取patch的分支并提取差异生成patch文件,此过程使用到的命令为`git format-patch -1 {commit_id} --numbered-files -- ':!mds/service.json' ':!CHANGELOG'`,其中`{commit_id}`需要替换成真实的提交id,生成的patch文件将以数字命名并会被复制到组件recipes的`patches`子目录,`':!mds/service.json'`用于忽略文件名以`mds/service.json`文件的提交差异,`':!CHANGELOG*'`用于忽略文件名以`CHANGELOG`开头的提交差异。 4. (如果有)`-p`参数指定的独立patch文件,工具会从源路径复制到组件recipes的`patches`子目录。 > [!WARNING] > 生成patch文件时已忽略了`mds/service.json`和`CHANGELOG*`文件变更,如果需要该文件内容,请手工生成patch文件。 ## 使用示例 ### 指定patch文件创建转维版本 `bingo maint`功能可以人工指定patch,需要人工修改源码后再发布版本,执行的流程为“编辑源码 -> 验证功能 -> git提交 -> 生成补丁 -> 创建转维版本”,操作步骤: 1. 本地代码切换到`-cp`指定的基础版本。 2. 执行`git cherry-pick`提取需要的代码,本地提交解决冲突并验证功能 3. 执行`git format-patch -1 --numbered-files -- ':!mds/service.json' ':!CHANGELOG*' ':!ChangeLog*'`命令生成新的patch文件`1`。注意,其中`':!mds/service.json'` `':!CHANGELOG*'` `':!ChangeLog*'`是需要排除的文件,**建议认真审视,减少非必要的修改** 。 4. 自动生成的补丁文件名为`1`,需要重命名为`.patch`。 在manifest或conan_index仓操作步骤: 1. 执行`bingo maint -cp / -p .patch`命令追加patch文件。 ### 转维版本基础再次发布新的转维版本 如果要在一个patch方案发布的转维组件基础上再次使用cherry-pick生成补丁文件时,cherry-pick的基础源码需要打上补丁文件,一般的操作是: 1. 从conandata.yml中找到patch方案发布的转维组件的tag标签 2. 下载源码 3. 从conandata.yml中找到patch方案发布的转维组件的patch补丁,使用git am命令按顺序打上补丁,部分patch可能会报`trailing whitespace`错误,错误非常困难 上述操作很复杂且可能无法处理异常,bingo fetch命令适配了此场景,建议的完整操作逻辑是: 1. 执行`bingo fetch --package_info=/@hw.openubmc.release/stable`命令拉取组件源码并自动打补丁,其中`/@hw.openubmc.release/stable`是基础转维组件包。 2. 执行`git cherry-pick`提取需要的代码,本地提交解决冲突并验证功能 3. 执行`git format-patch -1 --numbered-files -- ':!mds/service.json' ':!CHANGELOG*' ':!ChangeLog*'`命令生成新的patch文件`1` 4. 自动生成的补丁文件名为`1`,需要重命名为`.patch`。 在manifest或conan_index仓操作步骤: 1. 执行`bingo maint -cp / -p .patch`命令追加patch文件。 ## bingo fetch拉取源码 - 自动打补丁 采用 **指定patch文件追加新版本** 方案,建议在已打补丁的源代码基础上执行发布流程。 其中 **已打补丁的源代码** 是指在组件代码仓基础代码打上转维版本的全量补丁之后的源码,考虑到人工打补丁比较麻烦,操作易出错,将相关流程集成到`bingo fetch`命令,实现了拉取源码自动打补丁功能。 命令需要在manifest仓中执行(后续可能会切换到conan_index仓),命令格式为`bingo fetch --package_info /@/`,其中`/@/`为需要维护的组件。 完整的命令示例: ```shell xuhj@DESKTOP:~/workspace/openubmc300/manifest$ bingo fetch --package_info skynet/1.7.0.B004@hw.openubmc.release/stable ====== 开始获取组件包信息: skynet/1.7.0.B004@hw.openubmc.release/stable ====== 创建 1 个进程拉取代码 开始运行命令: /usr/local/bin/conan download skynet/1.7.0.B004@hw.openubmc.release/stable -r openubmc_dev -re Downloading conanmanifest.txt completed [0.42k] Downloading conanfile.py completed [8.07k] Downloading conan_export.tgz completed [0.52k] Decompressing conan_export.tgz completed [0.00k] Downloading conan_sources.tgz completed [23.22k] Decompressing conan_sources.tgz completed [0.00k] 更新 skynet 组件代码到 skynet/1.7.0.B004@hw.openubmc.release/stable 开始 更新代码(组件: skynet, 地址: https://szv-open.codehub.huawei.com/OpenSourceCenter/cloudwu/skynet.git, 分支: 1.7.0-htrunk1) 开始运行命令: git am /home/xuhj/.conan/data/skynet/1.7.0.B004/hw.openubmc.release/stable/export_source/patches/0001-Huawei-Replace-lua5.4-to-luajit.patch Applying: Replace lua5.4 to luajit Offering: openubmc skynet 应用源码补丁patches/0001-Huawei-Replace-lua5.4-to-luajit.patch ``` `bingo fetch`命令默认会将代码生成在source_code目录,如果需要生成到其它目录,可以使用`-p PATH, --path PATH 指定拉取源代码的存放路径`参数指定目标目录。 ## ChangeLog 2024/12/10:转维版本号格式只允许a.b.c-build.x样式,其中a.b.c是三段式版本号,一般与-cp指定的基础版本保持一致,x为补丁版本号,使用数字。 --- # OEE+AST2600构建指南 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/oee_ast2600.html > Language: zh ## 1. 概述 本文档介绍如何使用 bingo 工具构建基于 OEE (OpenEuler Embedded) 和 AST2600 芯片的 BMC 固件。 SDK 工具包(`oee_sdk.zip`)由 Yocto 源码构建产出,包含交叉编译器、bootloader、kernel 和 rootfs 等文件。bingo 基于这份 SDK 进行 HPM 升级包和 EMMC 烧片包的组装。 ### 1.1 前置条件 - **操作系统**:推荐 Ubuntu 22.04+ 或兼容 Linux 发行版 - **bingo 工具**:尚未安装时,参考 [bingo 构建系统文档](https://gitcode.com/openUBMC/bingo) 了解安装方式 > bingo 默认已预装在 openUBMC 开发环境中,可跳过安装步骤直接使用;如使用自定义环境则需自行安装。 ### 1.2 架构对比 | 对比项 | 1711/1712 (RTOS) | OEE+AST2600 (OEE) | |--------|------------------|---------------------| | 系统架构 | RTOS | Linux (OpenEuler Embedded) | | 源码构建工具 | 内部构建系统 | oebuild + bitbake (Yocto) | | 打包工具 | gpp_header + cat | FirmwarePackager (Python) | | 配置格式 | hpm_header.config | hpm_layout.yml (YAML) | | Boot文件 | Hi1711_boot系列 | u-boot-spl + u-boot (组合为 mmc-bootarea.img) | | Rootfs | RTOS文件系统 | OEE Linux rootfs (core-image-tiny-initramfs) | | 签名方式 | 打包进固件 | 外部 CMS 签名 | ### 1.3 SDK工具包结构 社区归档的SDK工具包由 Yocto 构建产物打包而成,结构如下: ```text oee_sdk.zip ├── oee_sdk/ # Yocto 构建产物 │ ├── u-boot-spl.bin # SPL bootloader │ ├── u-boot.bin # U-Boot │ ├── u-boot-env.bin # U-Boot环境配置(原始) │ ├── u-boot-env.img # U-Boot环境镜像(2M,由 u-boot-env.bin 制作) │ ├── fitImage-obmc-phosphor-initramfs-evb-ast2600-evb-ast2600 # Linux kernel + initramfs (raw fitImage) │ ├── fitImage.img # ext4 格式的 boot 分区镜像(内含 fitImage) │ └── oee_rootfs.tar.gz # OEE rootfs 压缩包 └── oee_compiler/ # OEE专用编译器 └── openeuler-x86_64-obmc-armv7a-ast2600-toolchain-24.03-LTS.sh ``` **文件说明:** | 文件 | 来源 | 用途 | |------|------|------| | `u-boot-spl.bin` | Yocto 构建产物 | SPL bootloader | | `u-boot.bin` | Yocto 构建产物 | U-Boot | | `u-boot-env.bin` | Yocto 构建产物 | U-Boot 环境配置(原始) | | `u-boot-env.img` | 由 `u-boot-env.bin` 通过 truncate+dd 制作 | 2M 固定大小,烧入 emmc 的 u-boot-env 分区 | | `fitImage-obmc-phosphor-initramfs-${board}-${machine}` | Yocto 构建产物(raw fitImage) | 用于制作 boot 分区镜像 `fitImage.img` | | `fitImage.img` | 由 `mkfs.ext4` 将 raw fitImage 封装为 ext4 格式 | 写入 emmc boot-a/boot-b 分区 | | `oee_rootfs.tar.gz` | Yocto 构建产物(rootfs) | 作为 HPM 升级包的 ROOTFS 分区 | | `openeuler-x86_64-obmc-armv7a-ast2600-toolchain-24.03-LTS.sh` | 预编译 OEE 交叉编译器 | 安装到 `/opt/oee-sdk` | ### 1.4 分区配置文件 构建过程涉及分区配置文件: | 配置文件 | 用途 | 位置 | |----------|------|------| | hpm_layout.yml | HPM升级包分区布局 | `${board_path}/hpm_layout.yml` | | emmc_layout.yml | 真机烧片包GPT分区布局 | `${board_path}/emmc_layout.yml` | **配置文件差异:** | 特性 | hpm_layout.yml | emmc_layout.yml | |------|----------------|-----------------| | 格式 | YAML列表结构 | YAML字典结构 | | 分区设计 | 简化分区(3个) | 双备份分区(7个) | | 用途 | HPM在线升级包 | EMMC真机烧片包 | | 分区类型 | type编号(0,32,1) | 类型字符串(raw, ext4) | ### 1.5 产品仓说明 产品仓(Product Repository)是存放产品配置的 Git 仓库,包含 `manifest.yml` 等配置文件,地址为: - **GitCode**: [https://gitcode.com/openUBMC/manifest](https://gitcode.com/openUBMC/manifest) 仓库目录结构如下(以 openUBMC_ast2600 产品为例): ```text manifest/ ├── build/ │ ├── product/ │ │ └── BMC/ │ │ └── openUBMC_ast2600/ # 产品目录,即 ${product}/${board_path} │ │ ├── hpm_layout.yml │ │ ├── emmc_layout.yml │ │ ├── ca/ # 签名证书目录 │ │ │ ├── rootca.crl │ │ │ └── rootca.der │ │ └── ... │ └── ... └── manifest.yml # 产品顶层配置文件 ``` - **`manifest.yml`**:产品顶层配置文件,位于仓库根目录 - **`${product}`**:指向 `manifest/build/product/BMC/openUBMC_ast2600/` - **`${board_path}`**:与 `${product}` 相同,指向板级配置目录 ## 2. 工具链安装 ### 2.1 manifest.yml 配置 #### 2.1.1 SDK下载配置 在产品仓 `manifest.yml`(参见 1.5 节)中配置 SDK 和工具包下载: ```yaml bmc_sdk_download: url: "https://repo.openubmc.cn/26.03/oee_sdk/oee_sdk.zip" sha256: "b6b870d973e5a94625daf1947df228c184ad43d391b226f53be26535416c4a48" packages_download: url: "https://repo.openubmc.cn/26.03/oee_sdk/packages.tar.xz" sha256: "" ``` #### 2.1.2 工具安装配置 ```yaml tools_install: build_tool: label: "local" work_path: "~/oee_compiler" verify: true install: mode: "oee" path: "/opt/oee-sdk" sdk_tool: label: "local" work_path: "~/oee_sdk" verify: true install: mode: "default" path: "${sdk_path}" ``` **配置说明:** | 配置项 | 说明 | |--------|------| | `label: "local"` | 使用本地已下载的工具,不执行远程下载 | | `work_path` | 工具存放路径,支持 `~` 路径 | | `mode: "oee"` | OEE模式,安装到 `/opt/oee-sdk` | | `mode: "default"` | 默认模式,直接复制到目标路径 | #### 2.1.3 平台配置 ```yaml platform: conan: "oee_sdk/0.0.1@openubmc.dev/dev" options: rtos_version: "oee_ast2600" enable_haf: false ``` ### 2.2 安装命令 执行以下命令安装工具链: ```bash bingo build -t install_sdk -b openUBMC_ast2600 ``` **安装内容:** | 内容 | 安装位置 | 说明 | |------|----------|------| | OEE编译器 | `/opt/oee-sdk` | arm-openeuler-linux-gnueabi交叉编译工具链 | | SDK文件 | `${sdk_path}` | u-boot、kernel、rootfs等 | | Conan制品缓存 | conan缓存目录 | 平台组件编译包 | | Profile | `~/.conan2/profiles/profile_oee.ini` | 构建配置文件 | ### 2.3 安装验证 ```bash # 查看编译器版本 arm-openeuler-linux-gnueabi-gcc --version # 查看SDK文件 ls ~/oee_sdk/ ``` --- ## 3. 组件适配 openUBMC 平台相关的 BMC 组件(如 `libmcpp/1.2.128@openubmc/stable`)支持使用 OEE 交叉编译工具链进行编译。以下说明组件适配流程。 ### 3.1 Profile配置 OEE构建使用专用profile文件 `profile_oee.ini`(存放于产品仓根目录,参见 1.5 节),关键配置: ```ini [settings] os=Linux arch=armv7hf compiler=gcc compiler.version=12.3 compiler.libcxx=libstdc++11 build_type=Release [buildenv] # 编译器路径 CC=arm-openeuler-linux-gnueabi-gcc CXX=arm-openeuler-linux-gnueabi-g++ # Sysroot路径 CONAN_CMAKE_SYSROOT=/opt/oee-sdk/sysroots/armv7a-vfp-openeuler-linux-gnueabi/ ``` ### 3.2 构建命令 ```bash # 需在组件仓根目录(conanfile.py 所在目录)下执行 bingo build -pr profile_oee.ini ``` ### 3.3 构件适配要点 以下编译参数需在 `profile_oee.ini` 中配置: | 要点 | 说明 | profile_oee.ini 配置示例 | |------|------|-------------------------| | 编译器 | 使用 `arm-openeuler-linux-gnueabi-gcc` | `CC=arm-openeuler-linux-gnueabi-gcc` | | Sysroot | 链接OEE sysroot库 | `CONAN_CMAKE_SYSROOT=/opt/oee-sdk/sysroots/armv7a-vfp-openeuler-linux-gnueabi/` | | C标准 | 使用 `-std=gnu11` | `CFLAGS=-std=gnu11` | | C++标准 | 使用 `-std=c++17` | `CXXFLAGS=-std=c++17` | | ABI | `_GLIBCXX_USE_CXX11_ABI=0` | `CXXFLAGS=-D_GLIBCXX_USE_CXX11_ABI=0` | --- ## 4. 产品构建 ### 4.1 manifest.yml 完整配置 以下为构建配置中使用的变量说明: | 变量 | 含义 | 默认值/示例 | |------|------|-------------| | `${sdk_path}` | SDK工具包安装路径 | `~/oee_sdk`(由 `tools_install.sdk_tool.work_path` 指定) | | `${work_out}` | 构建输出目录 | 由 bingo 自动设置,通常为构建工作区下的 `output/` 目录 | | `${product}` | 产品配置目录 | `manifest/build/product/BMC/openUBMC_ast2600/` | | `${board_path}` | 板级配置目录 | `${product}`(与 product 相同) | ```yaml schema: /usr/share/bingo/schema/manifest.schema.json platform: conan: "oee_sdk/0.0.1@openubmc.dev/dev" options: rtos_version: "oee_ast2600" base: version: "26.06.00.01" customization: "customization/prototype.py" signature: files: - file: ${product}/ca/rootca.crl dst: cms.crl profile: "profile_oee.ini" bmc_sdk_download: url: "https://repo.openubmc.cn/26.03/oee_sdk/oee_sdk.zip" sha256: "" tools_install: build_tool: label: "local" work_path: "~/oee_compiler" install: mode: "oee" path: "/opt/oee-sdk" sdk_tool: label: "local" work_path: "~/oee_sdk" install: mode: "default" path: "${sdk_path}" gpp: gpt_config: "${board_path}/emmc_layout.yml" files: - file: ${sdk_path}/oee_rootfs.tar.gz - file: ${sdk_path}/fitImage-obmc-phosphor-initramfs-${board}-${machine} dst: kernel.bin - file: ${sdk_path}/u-boot-spl.bin - file: ${sdk_path}/u-boot.bin - file: ${sdk_path}/u-boot-env.img - file: ${sdk_path}/fitImage.img - file: ${work_out}/rootfs_BMC.img - file: ${work_out}/rootfs_BMC.tar.gz - file: ${work_out}/rootfs_BMC.img.cms - file: ${product}/ca/rootca.crl dst: cms.crl - file: ${product}/ca/rootca.der dst: rootca.der dependencies: - conan: help ``` > `kernel.bin` 使用 SDK 中的 raw fitImage 文件重命名而来,而非 `fitImage.img`。 ### 4.2 HPM包分区配置 (hpm_layout.yml) HPM升级包的分区布局配置,位于 `${board_path}/hpm_layout.yml`: ```yaml firmwares: type: "hpm" top_header: size: 512 # Top Header大小(字节) reserved: "" # 预留字段,最多15字节字符串 partitions: - partition: BOOT file: mmc-bootarea.img type: 0 # 分区类型编号 site: 0 # 分区偏移,0表示自动计算 size: 0 # 分区大小,0表示按文件实际大小 - partition: KERNEL file: kernel.bin type: 32 site: 0 size: 0 - partition: ROOTFS file: rootfs_BMC.tar.gz type: 1 site: 0 size: 0 ``` **配置说明:** | 字段 | 说明 | 备注 | |------|------|------| | `type: "hpm"` | 固件类型标识 | 用于区分固件类型 | | `top_header.size` | Top Header大小 | 固定512字节 | | `top_header.reserved` | 预留字符串 | 最多15字节,用于标识固件信息 | | `partition` | 分区名称 | 用于日志和调试 | | `file` | 分区文件名 | 相对于构建目录 | | `type` | 分区类型编号 | 用于区分分区类型(BOOT=0, ROOTFS=1, KERNEL=32等) | | `site` | 分区偏移(字节) | 0表示自动计算,强制512字节对齐 | | `size` | 分区大小(字节) | 0表示按文件实际大小 | **分区说明:** | 分区 | 文件 | 类型编号 | 说明 | |------|------|----------|------| | BOOT | mmc-bootarea.img | 0 | u-boot组合镜像(SPL + u-boot) | | KERNEL | kernel.bin | 32 | Linux kernel + initramfs | | ROOTFS | rootfs_BMC.tar.gz | 1 | BMC rootfs压缩包 | ### 4.3 真机烧片包分区配置 (emmc_layout.yml) 真机EMMC烧片包的GPT分区布局配置,位于 `${board_path}/emmc_layout.yml`: ```yaml partitions: settings: sector_size: 512 # 扇区大小(字节),可选值: 512, 4096 gpt_header_sectors: 34 # GPT头占用扇区数 header_offset: 0x5000 # 数据头偏移(字节),首个分区起始位置 alignment: 1 # 分区对齐(扇区数),1表示不强制对齐 total_size: auto # 镜像总大小,auto自动计算,可指定如 512M power_of_two_align: true # 镜像大小2次幂对齐 partition: u-boot-env: size: 2M # 分区大小 type: raw # 类型: raw, ext4 file: u-boot-env.img # 分区镜像文件名 boot-a: size: 32M type: ext4 file: fitImage.img label: boot-a # 文件系统标签(可选) boot-b: size: 32M type: ext4 file: fitImage.img rofs-a: size: 385028KB type: ext4 file: rootfs_BMC.img rofs-b: size: 385028KB type: ext4 file: rootfs_BMC.img rwfs: size: 200M type: ext4 file: datafs.img pflash: size: 2M type: raw ``` **Settings配置说明:** | 字段 | 说明 | 默认值 | |------|------|--------| | `sector_size` | 扇区大小(字节) | 512 | | `gpt_header_sectors` | GPT头占用扇区数 | 34 | | `header_offset` | 数据区起始偏移(字节) | 0(从GPT头后开始) | | `alignment` | 分区对齐(扇区数) | 1(不强制对齐) | | `total_size` | 镜像总大小 | auto(自动计算) | | `power_of_two_align` | 镜像大小2次幂对齐 | true | **分区说明:** | 分区 | 大小 | 类型 | 文件 | 说明 | |------|------|------|------|------| | u-boot-env | 2M | raw | u-boot-env.img | U-Boot环境变量分区 | | boot-a | 32M | ext4 | fitImage.img | A分区kernel镜像 | | boot-b | 32M | ext4 | fitImage.img | B分区kernel镜像(双备份) | | rofs-a | 385028KB | ext4 | rootfs_BMC.img | A分区rootfs镜像 | | rofs-b | 385028KB | ext4 | rootfs_BMC.img | B分区rootfs镜像(双备份) | | rwfs | 200M | ext4 | datafs.img | 可读写数据分区 | | pflash | 2M | raw | - | 保留分区(无文件) | ### 4.4 构建命令 ```bash # 默认构建,生成 HPM 升级包、真机 emmc 烧片包 (.wic) 和 qemu 仿真包 (.img) bingo build -b openUBMC_ast2600 ``` ### 4.5 构建产物 | 产物文件 | 说明 | |----------|------| | `rootfs_openUBMC_ast2600.hpm` | HPM升级包 | | `openUBMC_ast2600_real.wic` | 真机emmc烧片包 | | `openUBMC_ast2600_real.img` | qemu仿真包 | --- ## 5. 其他配置 ### 5.1 签名配置 OEE 固件包支持 CMS 签名,用于升级包的完整性校验。签名流程由 bingo 自动完成:构建时若环境存在 `signatrust-client`,则根据 `manifest.yml` 中配置的签名策略自动调用签名服务,对 `rootfs_BMC.img` 进行 CMS 分离签名,生成 `rootfs_BMC.img.cms`。 产品仓中 `base.signature` 仅配置证书吊销列表的分发: ```yaml base: signature: files: - file: ${product}/ca/rootca.crl dst: cms.crl ``` 证书文件(`rootca.der`、`rootca.crl`)通过 `gpp.files` 打包进固件: ```yaml gpp: files: # rootfs_BMC.img的cms签名文件 - file: ${work_out}/rootfs_BMC.img.cms # 签名文件的证书吊销列表 - file: ${product}/ca/rootca.crl dst: cms.crl # 签名的根证书 - file: ${product}/ca/rootca.der dst: rootca.der ``` **签名相关文件说明:** | 文件 | 格式 | 用途 | |------|------|------| | `rootfs_BMC.img.cms` | CMS | rootfs 签名文件(由 bingo 自动生成) | | `rootca.der` | DER | 根证书,用于验签 | | `rootca.crl` | DER | 证书吊销列表 | 更详细的签名说明参考: - [bingo支持固件完整性保护签名能力](https://gitcode.com/openUBMC/bingo/blob/main/docs/26.06/bingo%E6%94%AF%E6%8C%81%E5%9B%BA%E4%BB%B6%E5%AE%8C%E6%95%B4%E6%80%A7%E4%BF%9D%E6%8A%A4%E7%AD%BE%E5%90%8D%E8%83%BD%E5%8A%9B.md) - [cms_sign Demo](https://gitcode.com/openUBMC/bingo/blob/main/demo/cms_sign/README.md) — 包含自制签名证书链、签名服务器搭建、`bingo simple_sign` 签名验证等完整流程 --- ## 6. 常见问题 ### 6.1 SDK下载许可协议 首次下载SDK需要同意许可协议: ```bash # 设置环境变量自动同意 export OPENUBMC_LICENSE=true # 或交互式确认 bingo build -t install_sdk -b openUBMC_ast2600 # 输入 Y 同意协议 ``` ### 6.2 编译器路径问题 如果 `~/oee_compiler` 路径不正确,检查: ```bash # 确认编译器位置 ls ~/oee_compiler/ ``` ### 6.3 GPT镜像文件大小不足 GPT镜像构建时,文件小于分区大小会自动补0填充: ```text 分区 ROOTFS 文件大小不足,补0填充: 实际 50000000 字节 -> 目标 134217728 字节 ``` ### 6.4 分区配置文件位置 分区配置文件默认位置: | 配置文件 | 默认位置 | 说明 | |----------|----------|------| | hpm_layout.yml | `${board_path}/hpm_layout.yml` | HPM升级包分区配置 | | emmc_layout.yml | `${board_path}/emmc_layout.yml` | 真机烧片包分区配置 | `${board_path}` 变量指向产品仓(参见 1.5 节)内的板级配置目录。 ### 6.5 自定义分区配置 如需自定义分区配置: 1. **HPM包分区**:复制并修改 `hpm_layout.yml` 2. **真机烧片包**:复制并修改 `emmc_layout.yml`,并通过 `gpt_config` 指定新路径 ```yaml gpp: gpt_config: "${board_path}/custom_emmc_layout.yml" ``` ### 6.6 分区偏移自动计算 HPM包和真机烧片包的分区偏移均可自动计算: - **HPM包**:在 `hpm_layout.yml` 中设置 `site: 0`,系统自动计算并强制512字节对齐 - **真机烧片包**:在 `emmc_layout.yml` 中设置 `start: null` 或不配置,系统自动计算偏移 --- ## 7. QEMU 仿真验证 ### 7.1 安装 QEMU ```bash wget https://download.qemu.org/qemu-11.0.0.tar.xz tar xvJf qemu-11.0.0.tar.xz cd qemu-11.0.0 ./configure make -j8 make install ``` ### 7.2 启动仿真 ```bash cd manifest/output qemu-system-arm -M ast2600-evb,boot-emmc=true \ -drive file=openUBMC_ast2600_real.img,format=raw,if=sd,index=2 \ -nographic ``` --- ## 8. 参考文档 - [bingo支持基于OEE和ast2600芯片配置构建hpm包](https://gitcode.com/openUBMC/bingo/blob/main/docs/26.06/bingo%E6%94%AF%E6%8C%81%E5%9F%BA%E4%BA%8EOEE%E5%92%8Cast2600%E8%8A%AF%E7%89%87%E9%85%8D%E7%BD%AE%E6%9E%84%E5%BB%BAhpm%E5%8C%85.md) - [bingo支持OEE产品策略配置](https://gitcode.com/openUBMC/bingo/blob/main/docs/26.06/bingo%E6%94%AF%E6%8C%81OEE%E4%BA%A7%E5%93%81%E7%AD%96%E7%95%A5%E9%85%8D%E7%BD%AE.md) - [manifest.schema.json](https://gitcode.com/openUBMC/bingo/blob/main/tools/payload/usr/share/bingo/schema/manifest.schema.json) --- # 平台整包集成指导 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/platform_full_package_integration_guide.html > Language: zh ## 背景介绍 平台整包将平台组件预先打包,提供统一的依赖版本和配置。相比传统的逐个引用组件方式,具有以下优势: - 简化产品配置,无需单独管理多个平台组件 - 避免组件版本冲突,提升构建稳定性, 削减多个conan中心仓 - 缩短依赖下载时间,加快构建速度 ## 适用范围 ibmc_sdk>=5.14 ## 整包结构介绍 整包存在形式: 单独文件,tar压缩包 整包解压后目录结构: ```shell full_package/ ├── conan_cache/ conan缓存合集 ├── community_webvnc_1711_manifest.yml 整包配置文件1 ├── community_webvnc_manufacture_1711_manifest.yml 整包配置文件2 └── ... ``` ### 配置说明 #### manifest.yml 文件说明 manifest.yml 文件定义了整包的基本信息,包括版本、描述和组件依赖关系: ```yaml base: version: 5.14.00.01.B001 description: 社区1711支持webvnc整包,组件开启options:firmware_mgmt:community_enable=True remote_console:webvnc_supported=True nsm:webvnc_supported=True, 可用于社区webvnc整包构建 dependencies: - conan: firmware_mgmt/1.0.0@openubmc/stable options: community_enable: true ``` 字段说明: - `base.version`: 整包版本号 - `description`: 整包描述信息,包含支持的特性和组件配置说明 - `build_type`: 整包构建类型,必须和构建匹配,否则会直接失败 - `dependencies`: 组件依赖列表 - `conan`: 组件名称及版本 - `options`: 组件配置选项 ## 如何合并Debug/Release整包 在下载过程中,往往伴随着Debug和Release整包文件是单独存在的,在实际过程中需要进行合并。支持两种不同的方式合并,分别对应整包不同的使用方案。 ### 1. 整包方案 合并流程: 1. 分别下载debug/release压缩包文件 2. 将文件迁移到linux系统进行解压 3. 参考[bingo脚本](https://gitcode.com/openUBMC/bingo/blob/main/bmcgo/utils/merge_conan2.py) 4. 执行脚本 ```python python3 merge_conan2.py --base_dir=debug_path/conan_cache --merge_dir=release_path/conan_cache ``` 5. 将合并后的debug文件夹单独压缩为一个整体的tar包,支持.tar.gz和.tar.xz格式,参考命令: ```shell cd debug_path tar -czf bmc_sdk.tar.gz * sha256sum bmc_sdk.tar.gz ``` 6. 将sha256文件和bmc_sdk.tar.gz整体上传到文件服务器,供后续整包方案下载使用 ### 2. 传统方案 将debug和release缓存分别上传conan中心仓 ```shell rm -rf ~/.conan2/p mv conan_cache ~/.conan2/p conan upload * -r conan远程仓 -c ``` ## 产品引用整包 产品通过在manifest仓库的manifest.yml文件中配置`bmc_sdk_download`和`platform`字段来引用整包。 ### bmc_sdk_download配置 `bmc_sdk_download`用于配置整包文件的下载信息: ```yaml bmc_sdk_download: url: https://example.com/full_package.tar.gz sha256: xxxxxx ``` 具体整包的sha256值在下载链接文件夹有文本承载,复制即可。 配置说明: - `url`: 整包文件的下载地址 - `sha256`: 整包文件的SHA256校验值,用于验证文件完整性 下载流程: 1. 构建时会自动下载整包文件到`~/bmc_sdk_download`目录 2. 使用sha256校验文件完整性 3. 解压整包文件(tar.gz格式) 4. 需要同意《BMC软件许可协议》才能下载 ### platform配置 在产品的manifest.yml文件中添加以下配置: ```yaml platform: conan: ibmc_sdk/5.14.00.01.b001@openubmc/stable options: rtos_version: rtos_v2 enable_haf: false package: "community_webvnc_1711" #无需配置文件名最后一段_manifest.yml ``` 默认情况下,整包内的平台组件以整包配置为准,产品 manifest 中无需再重复描述这些组件;若确需替换或定制某个平台组件的版本/options,可按"覆盖平台组件"一节的写法直接在 `dependencies` 中写出,无需额外声明。 ### 配置说明 - `platform.conan`: 指定要使用的ibmc_sdk版本 - `platform.options`: 整包配置选项 - `rtos_version`: RTOS版本,可选 rtos_v2 等 - `platform.package`: 指定要使用的整包配置,对应整包目录下的manifest.yml ### 完整示例 以下是一个完整的产品manifest.yml配置示例。整包内部组件(如 firmware_mgmt)的版本/options 默认以整包为准,产品端不必再写一遍;如确需覆盖整包内部组件,参见下文"覆盖平台组件"一节: ```yaml bmc_sdk_download: url: https://example.com/full_package.tar.gz sha256: xxxxxx platform: conan: ibmc_sdk/5.14.00.01.b001@openubmc/stable options: rtos_version: rtos_v2 enable_haf: false package: "community_webvnc_1711" openubmc_sdk: conan: "openubmc_sdk/latest@openubmc/stable" base: version: "26.06.00.01" customization: "customization/prototype.py" dependency_buildtools: dependency/dependency_buildtools.xml signature: files: - file: ${product}/ca/rootca.crl dst: cms.crl - file: ${product}/ca/rootca.der dst: rootca.der dependencies: # - conan: firmware_mgmt # options: # community_enable: true - conan: vpd options: board_name: openUBMC # ... 其他依赖组件 ``` ### 覆盖平台组件(产品同名组件即覆盖) > 自 openUBMC 26.09 起新增(对应 bingo ≥ 0.7.67 版本)。早期版本在使用整包配置(`platform.package`)时,会拦截产品对平台同名组件的版本/options 定制(报错"不允许对平台组件进行定制"),现已放开为"同名即覆盖"。 整包将平台组件预先打包,提供统一的版本与配置。但在紧急采纳上游修复版本、适配产品专有分支、或仅调整某个组件编译选项等场景下,产品可能需要替换或定制整包中的某个平台组件。bingo 现支持**同名即覆盖**:产品只需在 `manifest.yml` 的 `dependencies` 中对同名组件写出版本/options,即覆盖整包(以及 `openubmc_sdk`)中的定义,无需任何额外声明。 > 上文"完整示例"中被注释掉的 `firmware_mgmt` 即属于整包内部组件:默认不写、继承整包配置即可;确需覆盖时,按下文写法在产品 `dependencies` 中写明。 #### 层间优先级 构建时,产品 manifest 与下层 manifest 按以下优先级合并(高 → 低): **产品 > openubmc_sdk > platform** - 产品优先级始终最高,对同名组件写出版本/options 即生效。 - 产品未写时,`openubmc_sdk` 的同名组件优先级高于 `platform`(整包),即上游基线可盖过整包中的旧版本定制。 > "同名"按组件名判断,例如 `firmware_mgmt/1.0` 与 `firmware_mgmt/1.1` 视为同名,生效方以高优先级层的版本为准。 #### 替换整包组件版本 直接在产品 `dependencies` 中对整包同名组件写出新版本,整包钦定的版本即被产品版本覆盖: ```yaml dependencies: - conan: firmware_mgmt/1.1.0 # 整包中的版本被产品版本覆盖;整包中该组件的 options 被清空为 None ``` > **注意**:覆盖按"整条目替换"生效,整包中该组件原有的 `options` 不会自动继承。只写版本、不带 `options` 时,产品侧未写的 `options` 会被清空(置为 None,即恢复默认)。因此若整包原本带了 `options`,仅按上例替换版本会一并丢掉这些 `options`;需要保留时,请在产品条目中把 `options` 显式写回(见下文「同时覆盖版本与 options」)。 #### 定制 options(版本沿用整包) 若只想调整某个组件的编译选项、版本仍沿用整包默认,省略版本号即可,版本由整包补齐: ```yaml dependencies: - conan: firmware_mgmt # 无版本号 → 版本由整包补齐 options: community_enable: true ``` #### 同时覆盖版本与 options 版本与 options 也可在同一组件上同时写明,二者都按产品侧覆盖整包(最常用的覆盖方式): ```yaml dependencies: - conan: firmware_mgmt/1.1.0 # 版本覆盖整包 options: community_enable: true # options 同时覆盖整包 ``` #### 清空整包组件 options 若整包中某组件带了 options,而产品侧希望清空这些 options(恢复默认),对该组件**仅写名字、不带 options** 即可,整包中的 options 会被清空(置为 None): ```yaml dependencies: - conan: firmware_mgmt # 版本由整包补齐;整包中该组件的 options 被清空为 None ``` #### 覆盖告警 为便于平台/SDK维护者审计,`bingo build`(出包阶段)在同名组件的版本/options发生覆盖时,会在构建日志中打印告警。分别对应"替换版本"、"定制options""清空options"三种场景各自输出的告警;当同一组件的版本与options同时变化时,二者会合并为一条告警(以`;`连接)输出: ```shell WARN: 组件 firmware_mgmt 被覆盖: 版本 firmware_mgmt/1.0.0 → firmware_mgmt/1.1.0; options {'community_enable': True} → None WARN: 组件 firmware_mgmt 被覆盖: options {'community_enable': False} → {'community_enable': True} WARN: 组件 firmware_mgmt 被覆盖: options {'community_enable': True} → None WARN: 组件 firmware_mgmt 被覆盖: 版本 firmware_mgmt/1.0.0 → firmware_mgmt/1.1.0; options {'community_enable': False} → {'community_enable': True} ``` 覆盖行为一览: | 产品对整包同名组件的写法 | 生效版本 | 生效 options | 是否告警 | | ---- | ---- | ---- | ---- | | 仅写名字,整包无 options | 整包版本补齐 | 无 | 否 | | 仅写名字,整包带 options | 整包版本补齐 | 清空(None) | 是 | | 写出新版本(与整包不同,可同时写 options) | 产品版本 | 产品 options | 是 | | 版本相同,options 不同 | 整包版本 | 产品 options | 是 | | 版本与 options 与整包完全一致 | 不变 | 不变 | 否 | > 当版本与 options 与整包完全一致(或仅写名字且整包本身也无 options)时,不触发告警。 ### 发布包配置 在构建发布包时,需要在tosupporte/manufacture配置中添加对应的platform配置: ```yaml tosupporte: default: platform: conan: ibmc_sdk/5.14.00.01.b001@openubmc/stable options: rtos_version: rtos_v2 enable_haf: false package: "community_webvnc_1711" package_name: "openUBMC/openUBMC-CMT_${version}.zip" build_type: release ``` ### 三种引用方式的区别 产品引用整包有三种方式: #### 1. 使用整包文件(推荐) 通过`bmc_sdk_download`下载bmc_sdk整包文件,然后通过`platform.package`引用: ```yaml bmc_sdk_download: url: https://example.com/full_package.tar.gz sha256: xxxxxx platform: conan: ibmc_sdk/5.14.00.01.b001@openubmc/stable options: rtos_version: rtos_v2 enable_haf: false package: "community_webvnc_1711" ``` 特点: - 需要将整包上传到文件服务器,校验sha256值 - 整包文件自动下载并解压到`~/bmc_sdk_download`目录 - 适合社区统一发布的整包 - 需要同意许可协议才能下载 #### 2. 使用本地整包目录 手动指定参数--debug_platform_path,适用于手动指定整包路径联调 直接通过`platform.package`引用本地整包目录配置: ```yaml platform: conan: ibmc_sdk/5.14.00.01.b001@openubmc/stable options: rtos_version: rtos_v2 enable_haf: false package: "community_webvnc_1711" ``` 特点: - 需要手动将整包解压到指定目录 - 适合本地开发或自定义整包 #### 3. 使用Conan包(传统方式) 通过`platform.conan`引用Conan包: ```yaml platform: conan: "ibmc_sdk/5.13.00.01.b002@openubmc/stable" options: rtos_version: rtos_v2_1712 enable_haf: false ``` 特点: - 不需要整包文件 - 通过Conan仓库管理SDK版本 - 适合传统SDK管理方式 ## 使用流程 ### 使用bmc_sdk_download自动下载 1. **配置引用**:在产品manifest.yml中配置bmc_sdk_download和platform字段 2. **构建产品**:使用bingo工具构建产品包,构建时会自动下载并解压整包 ```bash bingo build -b openUBMC ``` 3. **同意协议**:下载时需要同意《BMC软件许可协议》 - 可设置环境变量自动同意:`export OPENUBMC_LICENSE=true` - 或在构建时手动输入Y同意 4. **验证下载**:整包文件会下载到`~/bmc_sdk_download`目录,并使用sha256校验 ### 手动使用整包目录 1. **获取整包**:从发布渠道获取整包文件(tar.gz格式) 2. **解压整包**:使用`tar -xzf <整包文件名>.tar.gz`解压到指定目录 3. **配置引用**:在产品manifest.yml中配置platform字段,指向解压后的整包目录 4. **构建产品**:使用bingo工具构建产品包 ```bash bingo build -b openUBMC --debug_platform_path=/test/full_packages ``` ## 注意事项 1. 整包配置名称需与产品需求匹配 2. platform.package配置将直接引入产品manifest.yml 3. 更新整包版本时,需同步修改platform.package配置为新的整包名称 4. 使用bmc_sdk_download下载整包时: - 确保网络可访问下载地址 - sha256校验值必须正确,否则下载会失败 - 下载需要同意许可协议 - 整包会下载到`~/bmc_sdk_download`目录并自动解压 5. 本地已有整包目录时,可直接使用platform.package引用,使用参数--debug_platform_path指定整包路径 6. 使用platform.conan方式时,需要确保Conan仓库中有对应的SDK包版本 7. 产品对整包同名组件写出版本/options 即覆盖整包默认配置(同名即覆盖,无需额外声明,详见"覆盖平台组件"一节)。覆盖发生时构建日志会打印告警以便审计;仅在确需替换时才写,避免无意覆盖整包默认配置。 --- # 产品构建 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/product_build.html > Language: zh - openUBMC各个组件有其独立的构建代码以及代码仓,在manifest仓中会对所有参与构建的代码进行整合,通过拉起一个主组件解析依赖(conan内置解析逻辑),然后由依赖逻辑进行并发构建 - 构建以manifest仓作为总入口,且将所有的构建能力都集成在`bingo`命令中以供开发者便捷使用 # 构建命令总览 - 以下为`bingo`的帮助文档,这个帮助文档在`manifest`仓路径(也就是产品路径)和组件仓路径下显示内容不同,在产品构建时只需关注在manifest仓下的行为 ```shell # 在manifest路径下执行命令 [04:51:58 root(1110):/home/workspace/codehome/manifest]# bingo --help Integrated commands build 构建出包 publish 构建版本发布包,-sc参数指定ToSupportE编码,-z参数指定ToGPD生产装备编码 qemu 创建仿真环境,运行构建的产品包 fetch 基于参数指定的组件版本拉取全量代码 Misc commands help 获取命令帮助 输入"bingo -h"获取子命令帮助 [04:52:01 root(1110):/home/workspace/codehome/manifest]# ``` - 从上面返回的信息,可以看到我们能够使用的命令,构建产品以及发布包只使用到其中一个命令,当前`build`命令与`publish`效果相同。 ```shell [04:52:01 root(1110):/home/workspace/codehome/manifest]# bingo build --help 构建BMC options: -h, --help show this help message and exit -b BOARD_NAME, --board_name BOARD_NAME 单板包,可选值为build/product/|...>/下的目录名 -bt BUILD_TYPE, --build_type BUILD_TYPE 构建类型,可选:debug(调试包), release(正式包), dt(开发者测试包) --stage STAGE 包类型,可选值为: dev(调试包), rc(预发布包), stable(发布包) 默认:dev --verbose 使能conan构建详细日志打印 -ucc, --update_conan_cache 全量更新本地conan缓存 -r REMOTE, --remote REMOTE conan仓别名,请检查conan remote list查看已配置的conan仓 默认: openUBMC_dev -sc SUPPORTE_CODE, --supporte_code SUPPORTE_CODE 待发布的SupportE编码,可选值参考单板manifest.yml/tosupporte 默认:default -q, --enable_qemu QEMU打包使能 -qi, --qemu_in QEMU使能,自动拉起qemu环境 -as, --asan Enable address sanitizer -v VERSION, --version VERSION 构建版本号,不指定时从manifest.yml读取 -t TARGET, --target TARGET 构建目标,请查看build/target目录, 支持的目标: personal publish [04:59:33 root(1110):/home/workspace/codehome/manifest]# ``` ## 一、构建产品包命令 1. 直接构建`hpm`包 - 现在,开始构建一个`hpm`包,查看上面的`help`文档,可分析其具体含义,命令执行结束后,可在`manifest`目录下的`output`目录下找到构建出来的`hpm`包 ```shell # 进入到集成构建环境 cd manifest # -t personal: 构建目标,个人构建指 hpm 包 # -b openUBMC: 单板名,查看帮助文档,可以看到支持哪些单板 # -bt release: 构建类型,release正式包 # --stage rc: 包类型,预发布包 bingo build -t personal -b openUBMC -bt release --stage rc ``` - 以下为列出的生成件目录下文件,其中`rootfs_openUBMC.hpm`即为产品包 ```shell [05:22:48 root(1110):/home/workspace/codehome/manifest/output]# ls -la total 70172 -rw-r--r-- 1 root root 1349 Mar 12 17:22 openubmc.perf -rw-r--r-- 1 root root 54813 Mar 12 17:22 package.lock drwxr-xr-x 5 root root 4096 Mar 7 14:32 packet -rw-r--r-- 1 root root 0 Mar 12 17:20 prof.perf.lock -rw-r--r-- 2 root root 70144173 Mar 12 17:22 rootfs_openUBMC.hpm [05:23:04 root(1110):/home/workspace/codehome/manifest/output]# ``` 2. 集成发布的组件场景:在组件发布以后,我们需要将其版本集成到产品包中,具体修改方法如下: - 我们需要在`subsys`目录下添加新增的组件,组件属于什么类型,则添加到相应类型下,`subsys`目录下有`rc`和`stable`区分,组件发布对应的类型并在`rc`和`stable`目录下同时更改,这里的示例为`rc`版本,`stable`版本后缀要更新为`stable` ```yaml # yaml-language-server: $schema=../../schema/subsys.rc.schema.json dependencies: - conan: "rackmount/1.20.97@openUBMC.release/rc" - conan: "Kunpeng/1.10.2@openUBMC.release/rc" ``` - 在`manifest.yml`文件中配置添加的组件 新引入的组件,要在产品目录下配置相应的依赖,否则不会集成到产品包当中,`dependencies` 字段中,每配置一个组件,则集成进一个组件,这里不要去填版本号,填入版本号后,更新组件版本时,则需要变更多个文件 ```yaml dependencies: - conan: "huawei_secure_c" - conan: "kmc" - conan: "Signature_Verify_CBB_Library" - conan: "sqlite3" - conan: "openssh" ``` ## 二、构建发布包命令 - 构建发布包命令与上面的命令稍有差异,如下所示 ```shell # 进入到集成构建环境 cd manifest # -t publish: 构建目标,发布包 # -sc default: 发布包编码,这个编码可以在manifest.yml文件中的 tosupporte 字段中查询 # -b openUBMC: 单板名,查看帮助文档,可以看到支持哪些单板 # -bt release: 构建类型,release正式包 # --stage stable: 包类型,发布包 bingo build -t publish -sc default -b openUBMC -bt release --stage stable ``` - 执行完成以后,在`output`目录下会生成文件,如下为`output`树(仅供参考) ```shell [07:05:30 root(1110):/home/workspace/codehome/manifest/output]# tree . |-- openUBMC.perf |-- package.lock |-- packet | |-- openUBMC | | |-- openUBMC-CMT_1.00.00.00.zip | `-- inner | |-- release | | |-- package_openUBMC.lock |-- prof.perf.lock `-- rootfs_openUBMC.hpm 4 directories, 6 files [07:05:31 root(1110):/home/workspace/codehome/manifest/output]# ``` --- # 如何使用schema文件描述规范 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_guide/schema.html > Language: zh 本文讲解openubmc构建工程如何管理自己的配置文件。 ## 背景 openubmc构建工程广泛采用机制和策略解耦,构建代码和产品配置划分出明确的业务边界,两者使用manifest.yml、subsys等配置文件互动。 1. 构建工具与代码分离会产生版本匹配。 2. 功能引入和变更如何赋能和指导开发者配置。 一般的做法是在设计文件或更新wiki中描述需要配置什么属性、这些属性需要什么样的值、哪些是必须哪些是可选等要求。 文档传递在实践过程效果不明显,定义和使用之间脱节,开发者感知低,无法高效传递,容易导致不正确的配置上库,降低了整体效率。 ## 流程 openubmc的构建工程采用自动化的工程和工具解决,构建工程提供的每个json/yaml文件的格式都使用json schema描述,通过schema文件自动传递规范和要求,看护配置文件正确性,构建过程会提前检查配置正确性,提前配置,并且schema校验一般不接受。 openubmc要求构建机制影响策略配置的都需要按如下流程完成设计和开发: 1. 设计新机制、新功能时优先完成配置项值类型、可选值、可选必选定义,分析兼容性影响。 2. 分配配置项兼容性,一般按兼容处理,不影响既有配置。如果的确存在影响的,需要协同产品共同完成配置适配。 > [!WARNING] >构建工程会独立演进,维护工具的兼容性是非常重要,一个完全兼容的工具可以减少大量的适配成本,广泛适用于伙伴构建。 ### yaml文件schema标注 yaml文件标注使用`yaml-language-server: $schema=`格式,其中url支持本地文件或远程文件,示例: ```yaml # yaml-language-server: $schema=../../../schema/manifest.schema.json base: version: "5.01.00.01.B004" customization: "customization/prototype.py" ``` ### json文件schema标注 json文件标注需要在顶层对象中添加`$schema`配置项指定schema文件路径,示例: ```yaml { "$schema": "http://json-schema.org/draft-07/schema#", } ``` ## 开发者使用 开发者需要在vscode中安装`redhat.vscode-yaml`插件,该插件提供了格式提醒功能,辅助开发者正确配置。 schema校验只在版本构建场景开启,开发者修改manifest以及subsys配置时,建议执行一次`bmcgo build -t publish`命令。 > [!TIP] > schema校验计划在所有场景默认开启。 --- # 构建常见问题 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/build_project.html > Language: zh # 构建时提示输入git的账号密码,出现Username for xxx Password for xxx,或提示权限403 错误 报错原因是使用https访问代码仓,未正确配置git凭证导致需要用账号密码鉴权,请参考以下步骤设置git凭证: 1. 首先参考gitcode文档 [创建token](https://docs.gitcode.com/docs/help/home/user_center/security_management/user_pat)。 2. 创建 `~/.git-credentials文件`,添加 `https://token:token@gitcode.com`,其中token是第一步创建的凭证。 3. 使能配置:`git config --global credential.helper 'store --file ~/.git-credentials'`。 * 备注:不同git平台创建凭证的方式有差异,请参考官方文档 # 产包出包build时卡在mount阶段一直失败 1. 使用的镜像权限不足,mount失败,此时使用的是旧版bingo,需要在运行镜像 `docker run`的时候加上`--privileged=true`参数。 2. 升级bingo版本,使用最新bingo,优化了mount的权限逻辑。 # 构建时报错:`No remote 'openubmc_dev' defined in remote` 请参考[openUBMC社区conan仓使用指导](https://discuss.openubmc.cn/t/topic/186)。 # 构建时报进程异常退出,报错:`internal compiler error: Killed (program cciplus)` 请参考[openUBMC构建运行内存不足问题解决说明](https://discuss.openubmc.cn/t/topic/239)。 # manifest仓出包失败,报错:组件 `was not found in remote 'openubmc_dev'` 1. 原因是conan仓中不存在指定版本的组件,可使用`conan search 'name/*' -r openubmc_dev`获取`openubmc_dev`组件仓已发布的`name`组件版本清单,选择正确的组件版本,如果组件未发布的请发布后使用。 2. 在manifest中引入了错误的组件名包,检查build/subsys下的组件的版本配置。 # 构建组件失败,报错:`CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage` 1. 在编译环境查看`/opt/RTOS`和`/opt/hcc_arm64le`文件夹是否存在。若不存在,则环境缺少编译需要的依赖组件。 2. 通过初始化本地环境 `bingo build -t install_sdk`解决。 # 本地出组件dev包测试时,在manifest执行 bingo build出现报错:`下载组件(xxx/xxx.dev/dev)的构建配方(recipe)失败,退出码:1` 本地缓存被 `rm -rf ~/.conan/data`(conan1)或`rm -rf ~/.conan2/p`(conan2)删除,重新在组件仓执行 `bingo build`。 # 本地出组件构建,bingo build出现报错:具体错误为闭源组件触发源码构建,类似错误为`ERROR in xx Method` `ERROR XX pwd`等 这种问题一般为开发者本地bmc_sdk和当前版本依赖不配套: 1. 切换到对应版本构建时,应使用官网相应版本bmc_sdk初始环境,如:切换到2509版本构建时,应使用官网2509版本bmc_sdk初始环境。 2. 简易操作为:下载官网bmc_sdk,替换本地~/sdk、~/rtos_compiler文件夹(先删除本地再复制) # conan升级2.0后,本地出现组件构建bingo build出现报错:具体错误为`ERROR: luajit/xx@openubmc/stable: Error in source() method` 这种问题一般为开发者本地环境不匹配: 1. 升级最新bingo工具。 2. 切换到对应版本的manifest,执行一次bingo build -t install_sdk # conan升级2.0后,本地出组件构建bingo test出现报错:具体错误为闭源组件缺包触发源码构建,类似错误为`ERROR in xx Method` 短期内bingo test应更改为bingo test -jit,附加-jit参数即可运行 # 构建时出现`Couldn't checkout xx git -c xx checkout 'xxxxxx' returned non-zero exit status 128, reference is not a tree` 应排查是否在组件发布后又变更了git信息,如删除了commit,强推送了git提交? 开发者应遵守社区规范,版本发布后不应修改git信息树,如发生变更应重新推送组件版本。 # 整包构建时出现长时间等待,排查log后发现是卡在conan认证失效 1. 升级最新bingo,版本做了优化,如认证失效会提示重新登录。 2. 如老版本想解决此问题,可进入task.log文件按提示输入账号密码也可。 # 自签名报错问题,具体错误:`ERROR: 任务 work.task_buildgppbin 执行失败,打开了自签名模式但未找到待签名的uboot文件,构建失败` 1. 排查本机是否存在待签名的uboot,ls -al ~/sdk,如不存在文件hi1711_xxx(带时间戳结尾的文件), 需要官网下载bmc_sdk。 2. 下载官网bmc_sdk,替换本地~/sdk, 确保带时间戳结尾的文件存在。 # Linux下执行 `docker` 命令提示 "permission denied" 或 "connect to the Docker daemon socket" **原因:** Docker守护进程默认绑定Unix socket而不是TCP端口,该socket默认属于`root`用户。普通用户执行命令需要`sudo`权限,或者需要被加入到`docker`用户组。 **解决方案:** 1. 创建docker用户组(如果不存在): ```bash sudo groupadd docker ``` 2. 将当前用户加入docker组: ```bash sudo usermod -aG docker $USER ``` 3. **重要:** 执行完上述命令后,需要注销并重新登录系统(或重启)才能生效。 # 运行构建脚本 `build.py` 时报错 "FileNotFoundError: 找不到 SDK 文件" **原因:** 传入的SDK路径不正确,或者使用了脚本无法识别的相对路径。 **解决方案:** 请在 `-s` 参数中使用**绝对路径**。 例如: ```bash python3 build.py -s /home/user/downloads/bmc_sdk.zip ... ``` # 构建时报错 "failed to solve with frontend dockerfile.v0" 或语法错误 **原因:** 您的Docker版本过低,或者未启用BuildKit构建引擎(新方案依赖BuildKit特性)。 **解决方案:** 1. 确保Docker版本 \>= 18.09。 2. 尝试手动开启BuildKit环境变量后再次运行: ```bash export DOCKER_BUILDKIT=1 python3 build.py ... ``` # 容器启动后立即退出 (Exited) **原因:** Docker容器必须有一个前台进程在运行,否则会自动退出。 **解决方案:** 请确保在 `docker run` 命令中加入了 `-itd` 参数,或者在命令末尾指定了保持运行的指令(如 `sleep infinity` 或 `/bin/bash`)。使用 `sleep infinity` 保持容器常驻时,建议同时配置 `--init`,避免构建异常中断后子进程无法被可靠回收。 如果是使用本地构建的镜像,推荐命令: ```bash docker run -itd --init --pids-limit=32768 --name openubmc openubmc/dev:latest sleep infinity ``` # 容器内 `apt-get update` 或 `conan` 连接失败 **原因:** 宿主机的网络环境存在DNS污染或需要代理才能访问外网。 **解决方案:** 1. **DNS问题**:尝试重启Docker服务。 ```bash # Linux sudo systemctl restart docker ``` 2. **代理问题**:如果宿主机配置了VPN或代理,容器内默认不会自动继承。需要在 `docker run` 时通过环境变量传入代理配置: ```bash docker run -e http_proxy=http://your_proxy:port -e https_proxy=http://your_proxy:port ... ``` --- # 构建目标描述文件管理 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/concept_principle/Build_Target_Description.html > Language: zh `bingo build`命令支持基于任务的多进程并行调度,其`-t`参数依赖一个目标描述文件,该文件是yml格式,具体参考 [构建框架-目标描述文件](./build.md#目标描述文件) 或者参考已实现的目标,代码位置 `bingo/target` 目标描述文件原本由产品管理,考虑其中的目标为多个产品共用,当前已提取至bingo管理。 ## 产品目标描述文件定制 产品可以继承或重写目标描述文件,bingo构建时会优先查询当前目录(build/target)是否存在`-t`指定的目标描述文件,如果文件存在则会使用产品自定义的目标描述文件。 只有产品未定制目标描述文件时才会使用bingo定义的目标描述文件。 > [!TIP] > 示例: > `bingo build -t publish`用于XX产品版本发布,如果XX产品需要自定义发布流程,可在manifest/build/target目录下新增`publish.yml`文件并编写目标实现逻辑,bingo构建时检查到XX产品有自定义的`publish`目标,则会直接加载,此时不会加载bingo定义的`publish`目标。 > 如果YY产品没有自定义`publish`目标,则会使用bingo定义的`publish`目标描述文件。 ## 防冲突机制 目标描述文件的文件名代表了目标的功能和应用,如果产品在build/target目录新增了目标描述文件且该目标在bingo中不存在,需要在bingo的target目录中创建一个文件名相同的文件,内部增加注释注意(什么产品使用此目标完成了什么功能)。 上述防冲突机制用于产品向bingo申明某一名称的目标已被占用,避免bingo新增功能占用产品已经实现的目标,防止目标名称冲突。 对于产品未申明目标,bingo有优先使用权。 > [!TIP] > 示例: > bingo新增一个无任何产品申明的`test_target`这一目标实现某种公共能力。XX产品报告因产品自定义了`test_target`目标导致无法使用公共能力的,需要产品修改自己的目标描述文件的文件名。 --- # 构建策略 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build/concept_principle/build.html > Language: zh # 装配式构建架构 为满足构建场景和目标,实现构建系统的灵活定制和可扩展能力,openUBMC重构了构建框架,形成一套任务编排框架,其核心是任务标准化、目标可描述和自动化调度。 - 任务标准化:框架提供了一个任务基类,所有任务都继承该基类,具有相同的参数传递方式、任务创建逻辑,统一任务执行和产物收集,为调度核心提供统一的调度范式; - 目标可描述:使用文本文件描述完成构建目标所需要的任务拓扑,包括需要执行任务类、依赖的任务、子任务等。 - 自动化调度:调度器会分析目标描述文件得到完整的任务拓扑,依据任务间依赖关系和任务状态,创建多进程实例化任务类,实现并行构建。 装配式构建框架由全局配置、基础任务类、任务实现、目标描述文件、多进程调度框架、性能测试工具、全局状态管理进程功能。 ## 全局配置 - 为了在装配式方案调用任务时传递参数,我们定义了一个Config对象,该对象记录了公共配置清单。 ## 基础Work类 - Work类定义了run和install方法,还提供了一些具体任务实现需要的基础能力,基础类初始化需要还会传入一个全局配置对象,为后续任务执行提供输入。 ```python import sys import os import logging from colorama import Fore, Back, Style from iutils.config import Config from multiprocessing import Process cwd = os.path.join(os.getcwd(), os.path.dirname(__file__)) sys.path.append(f"{cwd}/../") class Work(Process): name = "WorkBase" description="基础类" work_name = "" def __init__(self, config: Config, work_name=""): Process.__init__(self) self.config = config self.work_name = work_name # 子类必须实现run方法,未实现时异常 def run(self): logging.info(f"{__file__} error") raise Exception # 安装函数,将各work的产出安装到config.rootfs目录中 def install(self): pass # 命令执行标准接口,具体实现已省略 def run_command(self, command, ignore_error=False, show_log=False, sudo=False, command_echo=True, timeout=600, command_key = None): pass # 带颜色的错误日志,具体实现已省略 def log_error(self, msg, frame_cnt=1): pass # 带颜色的告警日志,具体实现已省略 def log_warn(self, msg, frame_cnt=1): pass ``` ## 任务实现 - 任务的实现需要从Work类继承,从Work类定义可知任务类从Process类继承了多进程执行能力,调度框架正式基于Proess的能力实现了多进程调度执行。 - 如下是简单的环境初始化文件示例。 ```python #!/usr/bin/env python # coding:utf-8 import os import sys import subprocess import jsonschema import json import yaml import logging cwd = os.path.join(os.getcwd(), os.path.dirname(__file__)) sys.path.append(f"{cwd}/../") sys.path.append(f"{cwd}/../../") sys.path.append(f"{cwd}/../../../") from works.work import Work from iutils.config import Config class WorkPrepare(Work): def __init__(self, config: Config, work_name = ""): """ 任务初始化,会传入一个Config全局配置对象,实现全局配置归一 """ super(WorkBuildCommon, self).__init__(config, work_name) def run(self): # 任务执行,此处实现任务逻辑 def install(self): # 安装阶段 # 提供脚本单独调试运行能力 if __name__ == "__main__": cfg = Config() cfg.parse_args() wk = WorkEnvirPrepare(cfg) wk.run() ``` - 所有任务都有if __name__ == "__main__":的代码,所有脚本都可以单独调用,调用时需要进入build目录,再执行python3 works/work_prepare.py ## 目标描述文件 - 目标描述文件采用yaml格式,描述内容有任务名、任务类、子任务和依赖任务等。 ```yml # 任务示例,当任务被依赖时需要 - name: work.prepare_env # 任务python类,由独立进程执行 klass: works.work_prepare.WorkPrepare # 子任务列表,当klass执行完成后递归执行子系统,执行逻辑完全相同 subworks: - name: work.dependency.bison klass: works.dependency.work_install_bison.WorkInstallBison - name: work.dependency.flatbuffers klass: works.dependency.work_install_flatbuffers.WorkInstallflatbuffers - name: work.build.conan_debug_rc klass: works.build.work_build_conan.WorkBuildConan # 任务的依赖列表,可以等待多个任务,只有当所有依赖都执行完成后当前任务才会执行 wait: - work.prepare_env # 任务私有配置,构建框架会查询任务是否有set_xxx方法(以下示例则是查询set_stage(self, value)方法是否存在) # 随后调用set_xxx方法配置任务。 work_config: stage: rc # 全局任务配置,不同于任务私有配置,该配置会作用于全局配置对象,调用配置对象的set_xxx方法变更全局配置对象的值 target_config: build_type: release ``` - 如示例注释,任务目录为扩展框架的配置能力,我们定义了target_config和work_config配置能力,前者配置Config对象,后者配置Work对象。在调度框架中会解释两者的作用。 ## 多进程调度框架 - 我们采用了多进程调度方案,每个任务都是在独立进程中执行,每一个任务(包括子系统)都有创建任务、等待依赖、执行任务和创建子进程4个运行阶段,以及运行、完成、错误3种状态。 1. 创建任务:创建一个任务进程, 2. 等待依赖:多进程意味着不能直接共享状态,为此我们创建了一个全局状态管理进程,任务会向全局状态管理进程轮询被依赖任务的状态。 3. 执行任务:依赖任务都已完成后开始执行任务的run方法。当任一依赖任务失败时当前任务报错并退出执行; 4. 创建子进程:每个子进程重复父进程的4个阶段,周而复始,直至所有任务执行完成,构建目标也就达成了。 - 在创建子进程阶段会将任务自己的Config对象传递给子进程,这就是target_config类存在的意义,这个对象会由调度框架在任务的调度链往子进程方向传递。 work_config只是配置任务,可以修改也可以不修改Config对象,这完全是任务自己的行为,不受框架限制。 - 任务状态 - 任务可能执行成功也可能失败,每个进程都会对外报告自己的状态,当前的机制要求任一任务失败则会终止其它任务,整体报错退出。 - 各任务处于不同的进程中,任务状态同步需要借助进程间通信完成,为此我们创建了一个全局状态管理进程用于进程间状态同步,该进程会在TCP:23456上接收任务上报的执行状态报文并记录在全局任务状态表中,也能接收任务状态查询报文并返回指定任务的运行状态。 任务等待过程就是向全局状态管理进程发送TCP报文轮询状态。 ![image](../../images/build/concept_principle/build/task_status.png) --- # 概述 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/build_overview.html > Language: zh 欢迎来到openUBMC构建升级,本文档将介绍openUBMC的构建和升级概念原理、具体操作、常见问题,以及调测环境准备事项,方便开发者快速了解构建升级基本概念,以及完成相关操作。 [**构建**](./build/concept_principle/build.md) 介绍openUBMC构建相关概念原理,以及具体操作指导和常见问题。 [**升级**](./upgrade/concept_principle/upgrade_principle.md) 介绍openUBMC升级相关概念原理,以及具体操作指导和常见问题。 --- # 整机环境搭建 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/debug_env_setup/system_env_setup.html > Language: zh iBMC 与 openUBMC 均为 BMC 固件。iBMCv2、iBMCv3 是 iBMC 的不同代际版本,openUBMC 为社区版本。当需要在 iBMC 整机环境上开展 openUBMC 的构建、部署和调测时,需要将整机升级到 openUBMC。整机升级分为两种场景:iBMCv3 升级到 openUBMC 和 iBMCv2 升级到 openUBMC。两种场景都需要先升级过渡包,再升级 openUBMC 社区包。升级完成后,整机环境可用于后续的构建、部署和调测。 # 升级前准备 - 确认整机设备型号,记录当前 BMC 版本号 ```shell ipmcget -d version ``` - 准备串口线(RJ45 或 USB 转串口),连接 BMC 串口用于调试 - 准备网线连接 BMC 管理口,确保可 SSH 登录 - 准备 SSH/SFTP 客户端工具,用于登录 BMC 和上传升级包 - 准备过渡 HPM 包(联系 PAE 获取) - 准备 openUBMC 社区包 `rootfs_openUBMC.hpm`:可从 [openUBMC 官网](https://www.openubmc.cn/zh/download) 下载社区发行版,或参考[一键出包](https://www.openubmc.cn/docs/zh/development/quick_start/build_your_own_bmc.html) 本地构建 - 确保服务器供电稳定,升级过程中不可断电 - 确保 BMC 上 `/tmp` 目录至少预留 100MB 空间 ```shell du -sh /tmp ``` - 确保 BMC 空闲内存不低于 100MB,CPU 空闲率不低于 20% ```shell free -m top ``` # iBMCv3 升级到 openUBMC iBMCv3 无法直接升级到 openUBMC 社区包,需要先升级过渡包,再升级社区包。与 iBMCv2 升级相比,iBMCv3 无伙伴根证书兼容问题,且 26.03 及之后版本支持 SSL 证书内置。 ## 出包 ### 咨询 PAE 获取过渡包 联系 PAE 获取用于过渡升级的 HPM 包。 ### 获取 openUBMC 社区包 从社区获取 `rootfs_openUBMC.hpm` 包,或本地构建 hpm 包。 ## 升级 ### 确认当前 V3 环境 ```shell ipmcget -d version # 记录当前 Active 和 Available 分区版本号 ``` ### 上传过渡包并升级 通过 SFTP 将 HPM 包上传到 BMC 的 `/tmp` 目录: ```shell scp transition.hpm Administrator@:/tmp/ ``` 也可通过 Web 界面“系统管理 → 固件升级”上传。上传前确保 `/tmp` 空间充足: ```shell rm -rf /tmp/*.hpm /tmp/*.tmp ``` 执行升级: ```shell ipmcset -d upgrade -v /tmp/transition.hpm ``` BMC 固件升级完成后,默认自动重启使新版本生效。如未自动重启,请手动重启 BMC 使新版本生效。重启后执行 `ipmcget -d version`,预期 Active 分区版本号变为过渡包版本号。 ### 确认过渡包升级成功 ```shell ipmcget -d version ``` ### 上传 openUBMC 社区包并升级 ```shell scp rootfs_openUBMC.hpm Administrator@:/tmp/ ipmcset -d upgrade -v /tmp/rootfs_openUBMC.hpm ``` 升级完成后 BMC 自动重启使新版本生效。重启后执行 `ipmcget -d version`,预期 Active 分区版本号变为 openUBMC 社区包版本号,Available 分区为升级前版本。 ## 升级后操作 ### 导入 SSL 证书(26.03 之前版本需要) ```shell # 通过 SSH 登录 BMC # 导入 SSL 证书(文件名和密码按自己生成的证书为准) ipmcset -t certificate -d import -v /tmp/server.p12 1 123456 ``` 26.03 及之后版本支持 SSL 内置,在 `manifest 目录/build/product/BMC/openUBMC/rootfs/opt/bmc/trust/partner/ssl` 下放置密码为空的 SSL 证书文件出包即可,无需手动导入。 ### 自签名(可选) 如果选择使用自签名固件包,则后续只能升级该签名证书生成的 HPM 包。使用 `bingo` 进行自签名构建。 ## 升级后验证 1. 查看版本号确认升级成功 ```shell ipmcget -d version # Active 分区版本号应等于升级包版本号 # Available 分区版本号为升级前的旧版本 ``` 2. 验证 Web 界面可正常访问 3. 验证 SSH/串口登录正常 4. 验证基本命令可用 ```shell ipmcget -d ipinfo ipmcget -d powerstatus ``` 5. 验证网络连通性 ```shell ping ``` ## V3 升级常见问题 以下为 V3 升级过程中的高频问题,更多问题可参考[升级常见问题](../upgrade/upgrade_faq.md)。 ### 升级卡住显示“请等待” 上一次升级被中断后触发了自愈机制,此时 app.log 中会出现 `resume files(%s) exist and will be upgraded again` 日志,表示检测到上次未完成的升级任务,系统会自动再次执行升级。解决方法: ```shell systemctl restart bmc_core rm -rf /data/upgrade_resume/reset/ systemctl restart bmc_core ``` ### 升级成功但版本号未变 升级实际成功,但新版本启动失败后自动回切到原分区。排查步骤: 1. 通过串口查看启动日志,确认失败原因 2. 查看 app.log,搜索 `get current nvm_active`,如果分区从 `nvm_temp` 变为 `nvm_active` 则说明升级失败回滚 3. 常见原因: - 组件服务启动检查失败 → 查看串口日志定位具体组件 - 安全启动拦截 → 需要清根操作 - 内存不足 → 清理文件后重启 ### 升级报错:机型不匹配 日志显示 `sys-uid not in update.cfg's ProductUIDList`,说明升级包与当前环境机型不匹配。解决方法: 1. 先尝试回滚:`ipmcset -d rollback` 2. 构建过渡版本:修改 manifest 中 update.cfg 的 ProductID 为 65535(匹配所有机型),出包后先升级过渡包,再升级目标版本 ### 升级包过旧 1. **DowngradeAllowed=false**:不允许降级 ```shell busctl --user set-property bmc.kepler.bmc_upgrade \ /bmc/kepler/UpdateService/UpdateMgmt \ bmc.kepler.UpdateService.UpdateMgmt DowngradeAllowed b true ``` 2. **RevisionNumber 过大**:日志显示 `base version is not matched and cannot be allowed to upgrade` ### 传包失败导致签名校验失败 `/tmp` 目录空间不足导致上传的包不完整: ```shell rm -rf /tmp/*.hpm /tmp/*.tmp # 重新上传升级包 ``` ### 升级后网络不通 1. 检查 IP,若不符合预期重新配置: ```shell ipmcset -d ipaddr -v ``` 2. 检查路由和防火墙规则: ```shell route -n iptables -t filter -nvL ``` # iBMCv2 升级到 openUBMC iBMCv2 无法直接升级到 openUBMC,需要先升级过渡包,再升级社区包。整体流程与 V3 升级类似,但 V2 有额外的签名兼容性问题需注意。 ## 出包 出包步骤与“iBMCv3 升级到 openUBMC”的出包步骤相同,包括过渡包获取和社区包制作。 ## 升级 升级流程与“iBMCv3 升级到 openUBMC”相同,分四步: 1. 确认当前 V2 环境:执行 `ipmcget -d version`,记录当前 Active 和 Available 分区版本号 2. 上传过渡包并升级:执行 `ipmcset -d upgrade -v /tmp/transition.hpm`,升级完成后 BMC 自动重启,重启后执行 `ipmcget -d version`,预期 Active 分区版本号变为过渡包版本号 3. 确认过渡包升级成功:执行 `ipmcget -d version`,确认 Active 分区版本号已更新为过渡包版本号 4. 上传 openUBMC 社区包并升级:执行 `ipmcset -d upgrade -v /tmp/rootfs_openUBMC.hpm`,升级完成后 BMC 自动重启,重启后预期 Active 分区版本号变为 openUBMC 社区包版本号 V2 特有的伙伴根证书、签名格式等注意事项见本文档“V2 升级常见问题”章节。 ## 升级后操作 与“iBMCv3 升级到 openUBMC”的升级后操作相同,包括 SSL 证书导入和自签名配置。 ## 升级后验证 与“iBMCv3 升级到 openUBMC”的升级后验证相同。 ## V2 升级常见问题 V2 升级除可能遇到 V3 的常见问题外,还有以下特有问题: ### 缺乏伙伴根证书导致签名校验失败 日志显示 `partner_cert is NULL`,当前版本无法升级。解决方法:使用镜像倒换功能切换到另一个分区版本,然后尝试升级。 ```shell ipmcset -d rollback ``` ### 老版本签名仅支持 PKCS 不支持 PSS 较老的 V2 版本签名只支持 PKCS 格式,不支持 PSS。需先升级到一个支持 PSS 的较新 V2 中间版本,再升级过渡包到 openUBMC。 --- # 固件升级机制 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/upgrade/concept_principle/upgrade_principle.html > Language: zh # 固件升级整体描述 固件升级动作主要包含启动固件升级和升级进度查询,其中启动固件升级分为两个场景,即本地升级和远程升级,实际的升级动作由实际的固件子模块完成,固件管理模块驱动完成整个固件升级流程,因此固件管理模块需要与固件子模块机型交互: ![alt text](../../images/upgrade/concept_principle/upgrade_principle/image-1.png) # 固件升级具体实现 固件升级阶段分为Initialize,prepare,process,和finish四个阶段,在两个阶段间插入公共处理动作,每个固件子模块包含prepare,process,和finish三个特有动作。 ## prepare 在接收到固件管理组件发送的prepare消息后,确认收到的消息是当前子模块的升级消息,判断是否允许升级,回复prepare结果。 ## process - 升级包数据预处理。通过AES,CBC,128算法加密,解密并将升级数据写入bin文件; - 写升级数据到flash。将bin文件打包写入flash,并最终输出到对应的分区; - 设置M3标志位。设置BMC升级标志位。 ## finish - 判断若first boot脚本存在,则执行该脚本; - 给固件管理组件注册生效模式,生效动作由固件管理组件统一管理。 固件升级时序流程如下: ![alt text](../../images/upgrade/concept_principle/upgrade_principle/image-2.png) 三个阶段都通过之后则升级成功,中间任意一个阶段收到固件子系统”升级失败“的结果,则认为此次升级失败,或者在规定时间段内固件子系统未回复固件管理阶段性结果,则认为超时失败。 # 固件生效 固件子模块感知到生效条件满足后,找固件管理模块进行裁决,由固件管理模块决定其是否能执行生效动作。基础的处理流程如下: ![alt text](../../images/upgrade/concept_principle/upgrade_principle/image-3.png) # 并行升级 ## 并行升级流程 iBMC除了常用的升级方式单独升级固件以外,还配置了并行升级方式,具体的升级流程如下: ![alt text](../../images/upgrade/concept_principle/upgrade_principle/image-4.png) ## 互斥处理 ### 并行升级与串行升级互斥 升级流程(如固件生效)需串行执行,避免并发冲突。生效接口调用时,若已经在生效流程中,直接报错。 ### 固件互斥规则 - 相同ComponentID和ComponentIDEx的固件不支持并行升级; - 不同ComponentIDEx的固件可能支持并行,但需要业务组件在prepare阶段返回错误码; - 硬件对象间(如管理板与接口卡)禁止并行升级;BMC必须优先升级且独立。 ### 互斥处理 互斥场景(如加锁失败或者下游组件判断不支持并行升级)时,任务移动至队尾等待,不记录重试次数,相同ComponentID和ComponentIDEx的固件在升级时,新任务排队等待重试。 ## 资源限制 - 并行任务上限:同时升级的固件数量通过CSR配置,默认上限为5;等待队列任务数默认任务上限为10,超限后新掉用报错。 - 存储队列管理:本地升级需要先缓存固件包,优先处理本地任务以释放资源。 --- # 升级常见问题 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/upgrade/upgrade_faq.html > Language: zh # 【Q1】升级成功但是版本号没变化 版本号没变化请直接咨询子固件组件,版本号更新由子固件组件自行管理,固件管理仅为外部提供版本号展示,不修改版本号内容 # 【Q2】升级框架问题与各固件组件问题快速定位 升级非bmc固件的时候,有时候会升级失败,通过 /var/log/app_debug_log_all(最新版的日志已经移到/var/log/app.log) 有时候可以快速定界是firmware_mgmt升级框架问题还是各固件组件升级生效导致的固件失败(cpld、bios、vrd等)。firmware_mgmt解包成功并识别到是什么固件之后,会发送信号通知多样硬件触发升级,多样硬件收到信息进行升级,然后把升级结果返回给firmware_mgmt。所以当出现以下日志,就可以确认多样硬件给firmware_mgmt返回了升级失败信号。 **关键日志:Upgrade <某固件> process failed, ret=<非0返回值>** 有这条打印说明firmware明确收到了来自多样硬件的升级失败信息。 ![alt text](../images/upgrade/upgrade_faq/image.png) # 【Q3】升级BIOS升级完成,上电后发现未生效 1.查看BIOS升级完是否注册到了firmware_mgmt: 查看firmware_mgmt资源树,若存在以下字段,则已注册到firmware_mgmt;若无以下字段,优先找Bios组件定位 ![alt text](../images/upgrade/upgrade_faq/image-1.png) 2. 若已注册到firmware_mgmt,自查未生效方式如下: 查找关键词“PowerState changed to xxx”,若不存在**PowerState changed to OFF**,则有可能是下电失败,只有完全下电,即OFF状态才会触发生效 以下图片即为无OFF的情况 ![alt text](../images/upgrade/upgrade_faq/image-2.png) 本问题经过上下电组件定位: 下电超时了,可能环境逻辑版本有误 ![alt text](../images/upgrade/upgrade_faq/image-3.png) # 【Q4】上电升级CPLD,下电后未生效 场景:上电情况下升级了CPLD,下电后CPLD未触发生效,环境没AC,CPLD版本没变 定位(三板斧)Q: 1、查看操作日志,找到对应操作的时间 ![alt text](../images/upgrade/upgrade_faq/image-4.png) 2、搜索app日志对应时间点,查看详细升级日志 ![alt text](../images/upgrade/upgrade_faq/image-5.png) 3、在相关事件点附近查看日志,观察CPLD升级生效流程日志是否按照正常预期执行: (1)CPLD上电升级,向firmware_mgmt注册生效item ![alt text](../images/upgrade/upgrade_faq/image-6.png) (2)环境下电 (3)firmware_mgmt监听到下电,触发生效 ![alt text](../images/upgrade/upgrade_faq/image-7.png) 在步骤(1)中,我们(敏锐地)看到CPLD注册的生效条件是PowerCycle,说明跑了CPLD生效定制化(BMCSet_CPLD_UpgradeActiveCondition),此定制项定制之后,下电和强制下电将不会生效CPLD,只有PowerCycle才会生效CPLD。 所以本次CPLD没生效的原因是环境被人跑了定制化,firmware_mgmt的mdb_info.log资源树可以佐证: ![alt text](../images/upgrade/upgrade_faq/image-8.png) 消除此定制化: `busctl --user call bmc.kepler.general_hardware /bmc/kepler/general_hardware/MicroComponent bmc.kepler.MicroComponent.ConfigManage Import a{ss}ss 0 {\"ConfigData\":{\"CustomSettings\":{\"BMCSet_CPLD_UpgradeActiveCondition\":{\"Import\":true,\"Value\":\"PowerOff\"}}}} custom` 或 执行一次空定制 若以上三个步骤均没问题,general_hardware与firmware_mgmt均不存在报错信息,查看fructrl是否有以下日志重复打印,以下日志表明AC失败了 此时需咨询上下电,即fructrl组件责任人 ![alt text](../images/upgrade/upgrade_faq/image-9.png) 如有关键字“refresh the cache, and then execute ac down”打印,表示写寄存器触发ac成功了,但是硬件没有做对应的ac动作,需咨询相关硬件负责人 注:使用上述的定位三板斧,已经能够定位出大部分的升级问题。 # 【Q5】cli升级期间,cli连接突然断开 现象:用例执行cli升级期间,查询升级进度突然无响应 ![alt text](../images/upgrade/upgrade_faq/image-10.png) 正常的升级进度应该是这样的: ![alt text](../images/upgrade/upgrade_faq/image-11.png) 问题根因:Administrator用户信息被改,导致Administrator的连接断开,所以cli突然登出,导致突然查不到升级进度 操作日志如下:一个IP使用Administrator登录cli触发升级,升级期间,另一个IP也登录了Administrator,并修改了用户信息。修改用户信息将导致Administrator用户登出,导致升级的那个cli会话直接断开,最终升级进度回显被中断 ![alt text](../images/upgrade/upgrade_faq/image-12.png) # 【Q6】升级报错:无效升级包/FirmwareType is nil 日志如下:"get obj nil for Id=" ![alt text](../images/upgrade/upgrade_faq/image-13.png) 新日志如下:"FirmwareType is nil, invalid package config" ![alt text](../images/upgrade/upgrade_faq/image-14.png) firmware_mgmt版本>=1.10.50之后,固件类型的定义被外置,详情参考V3固件管理一本通文档 遇到这种报错,就是因为**没有在vpd仓定义需要升级的固件类型**,自发现没分发此固件的对象给firmware_mgmt,导致firmware_mgmt无法识别此固件。 新增固件对象的方法:vpd仓中对应的机型的platform.sr中新增对象, `"FirmwareComponentInfo_BMC": { "ComponentID": 2, "ComponentIDEx": 131, "Name": "Bios", "RevisionNumber": 0 }` ComponentID与ComponentIDEx数据需与update.cfg内数据保持一致 # 【Q7】升级失败报错:升级文件与机型不匹配 关键字update.cfg app日志:sys-uid(1030abf00) not in update.cfg's ProductUIDList 等几条日志 ![alt text](../images/upgrade/upgrade_faq/image-15.png) 原因:就是升级的包,与当前环境的机型信息不匹配。不允许升级 想要强行升级的办法: 1、ipmcset -d rollback尝试回滚,使用另一个看能否升级 2、如果另一个分区也报机型不匹配,自己通过本地manifest构建出一个过渡版本,先升级到过渡版本,然后在升级到预期版本。 以DA123C举例,想要把当前 非DA123C机型 升级到 DA123C,按以下步骤操作: (1)在manifest仓找到DA123C机型的BMC固件的update.cfg文件 ![alt text](../images/upgrade/upgrade_faq/image-16.png) (2)修改ProductID字段,改成65535,表示匹配所有的产品系列 3、个人构建出包:python3 frame.py -t target_personal --stage=dev -b TaiShan200_DA123C 把此包升级到环境上,然后就可以升级到目标DA123C版本了 # 【Q8】升级超时失败 三个现象代表三个阶段的超时失败: (1)prepare阶段超时失败。现象:升级进度在5%持续一分钟,然后升级失败,app.log存在以下打印: ![alt text](../images/upgrade/upgrade_faq/image-19.png) 说明子固件在prepare阶段没有在一分钟内响应firmware_mgmt,导致超时失败。 关键日志:Wait message reply timeout (2)process阶段超时失败。现象:升级进度在>=15%持续一小时,然后升级失败,app.log存在Wait message reply timeout相关打印 (3)finish阶段超时失败。现象:升级进度在99%持续一分钟,然后升级失败,app.log存在Wait message reply timeout相关打印。 # 【Q9】升级iBMC成功,复位起来之后iBMC当前版本号没变 烧片了2023.5的烧片包,升级最新版本BMC,升级成功后BMC起不来。 环境烧片了23年5月份的BMC包,然后升级当前较新的版本(TR5-1以后的版本),能够升级成功,但是发现BMC多次起不来,然后自动回退成原来5月份的版本。 观察到串口日志有如下打印: ![alt text](../images/upgrade/upgrade_faq/image-20.png) 从上述串口打印发现,每次到启动Rsyslog服务时,反复启动几次失败,紧接着BMC就挂了,说明Rsyslog启动失败与BMC服务起不来强相关。 (找相关专家询问后,基本确认就是Rsyslog起不来导致BMC无法启动) 解决方案:烧片一个TR5的BMC 注:iBMC升级成功之后,多次启动失败然后切分区到原来的版本,导致的一个直接现象就是 升级之后版本号不变。 ![alt text](../images/upgrade/upgrade_faq/image-21.png) 这一类的问题,共性情况如下: 现象:升级成功之后,主分区版本号没变,可用分区版本号变了。 原因:升级实际上是成功的,升级成功后复位iBMC,iBMC系统启动失败,三次未启动成功之后触发分区切换,切回了原版本。 根因:定位根因需要进一步查看串口日志,串口日志 dump_info\OSDump\uart2com.dat 举例一:串口打印内核异常日志,说明rtos内核crash,问题出在RTOS或SDK,应当找相关领域定位 ![alt text](../images/upgrade/upgrade_faq/image-22.png) 举例二:查看framework.log,看是否有组件启动异常,连续两次启动检查失败会触发切分区 ![alt text](../images/upgrade/upgrade_faq/image-23.png) 如上日志发现确实有组件服务异常,启动检查失败,找对应领域责任人定位 # 【Q10】传包失败导致签名校验失败 1、app日志看firmware_mgmt错误打印,发现是签名校验失败 ![alt text](../images/upgrade/upgrade_faq/image-26.png) 2、 分析用例发现传包阶段失败 ![alt text](../images/upgrade/upgrade_faq/image-27.png) 3、查看/tmp空间使用情况 ![alt text](../images/upgrade/upgrade_faq/image-28.png) 原因是/tmp目录存在一些临时文件,导致空间被占用了60M,而/tmp目录容量只有100M,再次上传一个升级包的时候,由于/tmp目录容量不够,导致传了一个不完整的hpm上去,导致签名校验失败。 建议:(1)优化脚本,触发升级之前先清理/tmp目录。(2)提需求,通过手动或自动方式清理tmp目录 # 【Q11】网络波动导致传包中断,升级失败 同上一个传包失败导致升级失败的问题,从日志看还是签名校验失败, 但是这一次导致传包失败的不是/tmp目录满了,而是BMC突然断开连接。 ![alt text](../images/upgrade/upgrade_faq/image-29.png) 问题原因可能是 网络波动 或 当时BMC突然复位 或 部分服务重启 导致BMC不可达。 此类问题具体问题具体分析,非升级问题。 # 【Q12】升级过程中bmc_core重启导致升级失败 升级过程中升级失败,观察bmc_core启动日志发现当时bmc_core刚好重启过。 重启原因是bmc_core中的event组件存在内存泄漏,导致bmc_core达到512M内存使用阈值,触发重启。 当时刚好正在进行升级。 措施(已执行):从bmc_core中分离event组件的服务。 # 【Q13】升级密钥解密失败导致升级失败 升级失败,查看app日志存在如下解密密钥失败打印 ![alt text](../images/upgrade/upgrade_faq/image-30.png) 说明是升级需要的密钥解密失败,可能原因是key_mgmt更新密钥之后,ksf密钥与升级密钥不匹配,导致升级密钥无法解密。这部分有可能是key_mgmt存在缺陷。 当前firmware版本 >=1.0.30 已经从firmware角度增强健壮性解决了这个问题。 规避措施: 1、 删除环境密钥 ``` rm /data/opt/bmc/upgrade/profile_en rm /data/opt/bmc/upgrade/profile_en.bak ``` 2、 重启bmc_core服务 ``` systemctl restart bmc_core ``` 3、 等firmware服务起来之后,重新升级即可 # 【Q14】升级卡住不想等两小时或无法平滑重启 急需重启一下恢复环境 **!!慎用** 方法有以下两类 【强制重启】 1.telnet下执行 systemctl reboot 若无法进入telnet 2.clp调试命令:reboot -f --》进入clp:输入clp_commands ![alt text](../images/upgrade/upgrade_faq/image-33.png) 【AC】 cli命令:ipmcset -t maintenance -d accycle AC约等于拔电源,没有什么能阻止AC,fructrl组件起不来除外 # 【Q15】升级包版本太低/过旧的升级包 ![alt text](../images/upgrade/upgrade_faq/image-34.png) **情况1** 环境上允许降级升级属性DowngradeAllowed可能被置成了false 查询方式: ``` busctl --user get-property bmc.kepler.bmc_upgrade /bmc/kepler/UpdateService/UpdateMgmt bmc.kepler.UpdateService.UpdateMgmt DowngradeAllowed ``` 值为false则不允许降级升级,即不允许升比当前环境版本低的升级包 恢复方式 ``` busctl --user set-property bmc.kepler.bmc_upgrade /bmc/kepler/UpdateService/UpdateMgmt bmc.kepler.UpdateService.UpdateMgmt DowngradeAllowed b true ``` **情况2** RevisionNumber值大于升级包中配置的Revision值 查看RevisionNumber: ``` ipmitool -H *bmc_ip* -I lanplus -p 623 -U *用户名* -P *密码* -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x5b 0x2d 0x00 0x06 0x00 0xc0 *0x19*(ComponentId) *0xff 0xff 0xff 0xff*(ComponentIdEx) ``` RevisionNumber设置成0: ``` ipmitool -H *bmc_ip* -I lanplus -p 623 -U *用户名* -P *密码* -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x5a 0x2d 0x00 0x07 0x00 0xc0 *0x19*(ComponentId) *0xff 0xff 0xff 0xff*(ComponentIdEx) *0x00*(RevisionNumber) ``` # 【Q16】升级报错:无效升级包/FirmwareType is nil 日志报错如下: ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-8.png) 固件类型的定位被外置,遇到这种报错就是因为没有在VPD仓定义需要升级的固件类型,自发现没分发此固件的对象给固件管理组件,导致固件管理组件无法识别此固件。新增固件对象的方法:VPD仓中对应的机型的platform.sr中新增对象,如下如所示,且ComponentID与ComponentIDEx数据需与update.cfg内数据保持一致。 ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-23.png) # 【Q17】 密钥解密失败导致升级失败 ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-9.png) 如上图日志打印说明是升级需要的密钥解密失败,可能原因是key_mgmt更新密钥后,ksf密钥与升级密钥不匹配,导致升级密钥无法解密,当前固件版本大于等于1.0.30,已经从firmware角度增强健壮性,解决了整个问题。如果遇到该问题规避措施如下: - 删除环境密钥 ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-14.png) - 重启bmc_core服务; ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-15.png) - 组件服务起来之后,重新升级。 # 【Q18】 升级白牌包时报"p12 parse fail" ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-10.png) 白牌包在制作的过程中涉及到ssl证书,证书分为加密和不加密两种,该日志对应的是加密证书,加密证书的制作分为四个步骤,分别为原始加密.pxf证书制作,确认加密密码,去密码,设置加密密码,而该报错是因为在制作证书的时候未按照要求去密码设置,导致在解密的时候系统解密密钥与加密密钥不匹配。 # 【Q19】 保留配置升级和不保留配置升级BIOS均失败 ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-11.png) 日志上显示get snaphot failed,尝试下发如下图命令,确实是否有返回: ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-16.png) 返回报错,此时根本原因是上图中的BIOS资源树未成功加载,从而生成快照失败。沟通后发现,环境为天池模组环境,无bcu,导致bcu中涉及bios升级的资源树全部未加载,解决方案是将bcu中涉及bios的资源树部分功能进行迁移,最好跟着产品走。 # 【Q20】 V2无法升级V3 ipmcget -d v 获取V2版本信息 ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-12.png) 收集日志或重启触发升级,分析升级相关日志: ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-13.png) 从日志可以看到此版本BMC缺乏或缺少根证书,导致签名校验失败,当前版本的BMC不但无法从V2升级到V3,也无法升级V2,需要先解决证书问题。解决办法:使用镜像倒换功能切换到另一个分区的BMC版本,然后再尝试升级。 # 【Q21】 烧片包的V2无法升级V3 环境上的BMC是一个较老的V2烧片BMC,V2升级V3日志报错如下: ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-17.png) 原因是V2较老版本的签名只支持PKCS,不支持PSS,需要升级到中间版本作预埋,然后B版本就可以同时校验PKCS和PSS,此时再升级V3的BMC就可以成功。 # 【Q22】 上电升级CPLD,下电后未生效 现象:上电情况下升级了CPLD,下电后CPLD未触发生效,环境没AC,CPLD版本未变化。 定位步骤: - 查看操作日志,确定操作时间: ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-18.png) - 搜索app.log日志对应时间点,查看详细升级日志: ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-19.png) - 在相关事件点附近查看日志,管擦和CPLD生效流程日志是否按照正常预期执行: 1. CPLD上电升级,向固件管理组件注册生效item; ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-20.png) 2. 环境下电; 3. 固件管理组件监听到下电,触发生效 ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-21.png) 在步骤(1)中,看到CPLD注册的生效条件是PowerCycle,说明跑了CPLD生效定制化,此定制项定制之后,下电和强制下电将不会生效CPLD,此时只需要消除此定制化即可。 # 【Q23】 升级超时失败 升级的三个现象代表三个阶段的超时失败: - prepare阶段超时失败: 现象:升级进度在5%持续一分钟,然后升级失败,app.log存在如下打印: ![alt text](../images/upgrade/upgrade_faq/firmware_upgrade-22.png) 说明子固件在prepare阶段没有在一分钟之内响应固件管理组件,导致超时失败。 - process阶段超时失败 现象:升级进度在大于等于15%持续一小时,然后升级失败,app.log存在超时相关日志打印 - finish阶段超时失败 现象:升级进度在99%持续一分钟,然后升级失败,app.log存在超时相关日志打印 # MCU升级 ## 【Q1】 VRD正在升级,无法升级MCU 上电升级VRD,下电后升级MCU返回失败: * 当前MCU和VRD走的是一个升级通道,做了互斥限制 * VRD作为二级电源,只能在下电情况下进行升级,在os上电时缓存升级文件,返回升级成功,下电取升级文件,开始生效 需要等VRD下电生效后升级MCU,才能返回成功。 5.2最新版本更新了错误码,在VRD生效期间升级MCU返回特殊的失败提示: ![alt text](../images/upgrade/upgrade_faq/mcu_image.png) ## 【Q2】 升级riser卡MCU升级失败 storage组件使用插件式访问调用I2C,如果没有加载raid卡,在获取不到预期信息时会长时间独占总线,导致命令阻塞 ## 【Q3】 如何查询BCU的MCU和VRD的版本号 命令查询版本号: mcu: busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018500 7 VRD: busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018501 7 busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018502 7 busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018503 7 busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018504 7 busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018505 7 busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018506 7 busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018507 7 busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_010101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018508 7 # VRD升级 ## 【Q1】 没有找到对应的升级文件 日志打印如下:对应的bin文件规则为VRD_厂商_SKU_NO.bin ![alt text](../images/upgrade/upgrade_faq/vrd_image-1.png) 厂商和SKU如下(当前B830版本只支持00_00和01_00): ![alt text](../images/upgrade/upgrade_faq/vrd_image-2.png) # CSR升级 ## 【Q1】 BC83PRUU(蝴蝶卡)CSR为1.17之前的版本升级出现升级失败 1.17版本CSR的port配置有问题,会导致raid卡无法正常加载,BMC会占用总线通道一直访问Raid,导致CSR升级时总线被占用,访问超时,会出现概率性升级失败的情况,需要重试几次 # CPLD升级 ## 【Q1】 获取厂商信息 下一步是获取芯片的厂商信息,根据厂商选择升级方式,在/logDump/app.log中筛选general_hardware: ![alt text](../images/upgrade/upgrade_faq/cpld_image-3.png) 大概率是ChipInfo无法获取,该Chip是挂在Jtag链路上的,有三种情况: 1、jtag链路没有切过去,在BMC中输入一下命令,看看是否可以获取到版本信息: busctl --user set-property bmc.kepler.hwproxy /bmc/kepler/Accessor/Accessor\_JtagSwitch\_010101 bmc.kepler.Accessor Value t \_( \_ 为对应的链路,当前EXU为0,BCU为1,具体查看CSR的FirmwareRoute属性) 设置后查看信息,value是否改变: ![alt text](../images/upgrade/upgrade_faq/cpld_image-4.png) busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Cpld/Cpld\_1\_0101 bmc.kepler.Chip.JtagTarget GetChipIdcode a{ss} 0(0101为EXU,010101为BCU,具体查看板卡的position) 以基础板为例子,正常获取到chip信息: ![alt text](../images/upgrade/upgrade_faq/cpld_image-5.png) 2、cpld扫链失败,输入dmesg驱动日志查看,可能是扩展板CPLD的版本问题,或者BMC测链路未通,未将CPLD和1711选通 ![alt text](../images/upgrade/upgrade_faq/cpld_image-6.png) 3、jtag链路异常,测波形排查Jtag链路 ## 【Q2】紫光CPLD的IIC升级失败(二盘背板) 在驱动日志中出现如下打印: ![alt text](../images/upgrade/upgrade_faq/cpld_image-7.png) 传输数据时出现丢失的情况,大概率是有毛刺影响,建议更换线缆 ## 【Q3】 主板SVF格式升级成功后版本不变 1. 查看升级的framework.log日志,发现升级时间很短就返回send data成功 ![alt text](../images/upgrade/upgrade_faq/cpld_image-8.png) 2. 查看linux_kenl日志(环境上输入dmesg),发现文件校验失败 ![alt text](../images/upgrade/upgrade_faq/cpld_image-9.png) --- # 整包升级指导 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/upgrade/upgrade_guide/Firmware_Packaging_Guide.html > Language: zh # 1. 概述 针对产品整机固件升级场景,为解决固件包数量多,固件下载效率低,版本配套管理困难问题,BMC提供产品级固件整包升级能力,避免运维人员由于误操作导致版本不匹配问题,同时提升整机升级效率。 # 2. 压缩包格式 * **文件格式**:`zip` * **压缩包大小限制**: * **压缩前**:≤ 110 MB * **压缩后**:≤ 150 MB * **推荐压缩方式**: * **windows**:7zip * **linux**:zip命令 # 3. 压缩包内容 压缩包内应包含以下内容: |类型|数量|说明| | --- | --- | --- | |`.hpm` 文件|≥1 个,最多支持并行升级最大数量|固件升级包(HPM: Huawei Package Module)| |`full_image_profile.json`|≤1 个|用于描述包内各模块信息,不包含该配置文件则默认并行升级所有hpm包| > ✅ **示例结构**: ``` fullimage.zip ├── a.hpm ├── b.hpm └── full_image_profile.json ``` > ⚠️ **注意**: > * 仅允许包含 `.hpm` 和 `full_image_profile.json` 文件。 > * 禁止包含其他无关文件(如 `.txt`, `.log`, `.tmp` 等)。 > * 禁止包含隐藏文件或目录。 # 4. 文件命名规范 |项目|规则| | --- | --- | |**压缩包文件名**|不超过 **128 字节**
不包含非法字符(如:`< > : " / \)| |**.hpm 文件名**| 与 `full_image_profile.json` 中 `FileName` 字段一致| |所有文件名|可由数字、大小写英文字母、空格、圆括号()、点号(.)、下划线(_)和连接号(-)组成| |**full_image_profile.json**|遵循所有文件名规范| # 5. `full_image_profile.json` 格式说明 ## 5.1 基本结构 ```json { "Packages": [ { "Module": "CPLD_EXU", "FileName": "a.hpm", "Priority": 1 }, { "Module": "BMC", "FileName": "b.hpm", "Priority": 2 } ] } ``` ## 5.2 字段说明 |字段名|类型|必填|说明| | --- | --- | --- | --- | |`Module`|string|是|模块标识符,如 `BMC`, `CPLD_EXU` 等| |`FileName`|string|是|对应 `.hpm` 文件的文件名,必须与压缩包中一致| |`Priority`|number|否|优先级数值,范围:`1` ~ `16` 数值越小,优先级越高 **未配置时默认为 `16`**| > ✅ **优先级示例**: > * `Priority: 1` → 最高优先级,最先升级 > * `Priority: 16` → 最低优先级,最后升级 > ⚠️ **注意事项**: > * 所有 `Priority` 必须为整数,非数字将导致解析失败。 > * 若多个模块优先级相同,则它们同时执行并行升级。 # 6. 并行升级数量限制 * 固件包中 `.hpm` 文件数量应**不超过系统支持的并行升级最大数量**(可CSR配置,默认为20个)。 * 超出数量将导致升级失败。 * 建议:使用 `Packages` 列表中 `Priority` 字段合理调度升级顺序。 # 7. 注意事项 * 使用Redfish进行整包升级时,由于涉及远程升级,为保证接口响应时间,需要提前创建最大并行升级个数的子任务。在获取到具体固件后,再将子任务与对应固件匹配,多余的子任务状态标记为"exception",多余子任务不影响主任务的升级状态及进度。 # 8. 接口使用说明 ## 8.1. Redfish接口升级 - URL POST ```text https:///redfish/v1/UpdateService/Actions/Oem/{OemIdentifier}/UpdateService.FullImageUpdate ``` - 请求头: ``` X-Auth-Token : auth_value Content-Type : header_type ``` - 请求消息体: ```json { "ImageURI": image_uri, "TransferProtocol": transfer_protocol, "ForceUpdate": force_update } ``` |参数|参数说明|取值| | --- | --- | --- | |device_ip|登录设备的IP地址|IPv4或IPv6地址| |auth_value|请求消息的鉴权参数|可通过/redfish/v1/SessionService/Sessions创建会话时获得| |header_type|请求消息的格式|支持的消息格式包括:`application/json`或者`application/json;charset=utf-8`| |transfer_protocol|BMC从远程服务器下载升级包时使用的协议|取值:HTTPS、SCP、SFTP、CIFS、NFS。本地升级不需要该字段| |image_uri|升级包所在路径,文件为zip格式|升级包的URL(支持本地tmp目录升级
例如:“sftp://username:password@10.10.10.191/tmp/package.zip”
本地升级:“/tmp/cpldimage.zip”| |force_update|固件是否强制升级|true:版本号一致的固件升级
false:版本号一致的固件不升级
可选参数,如果不加该参数。默认为版本号一致的固件升级| ## 8.2 IPMI接口升级 ### 8.2.1 触发固件整机升级 **命令权限:** BasicSetting **是否锁定之后可以访问:** 是 **命令样式:** * 请求:`ipmitool raw 0x30 ` * 响应:`` **命令请求参数:** |字节顺序|域取值说明| | --- | --- | |NetFn|30h| |Cmd|93h| |1:3|Manufacturer ID,LB Byte first。长度固定 3 个字节,例如,某厂家ID时 2011,对应十六进制为0x0007DB,则字节序为第1个字节为 DBh,第二个字节为 07h,第三个字节为 00h。| |4|94h| |5|Operation type:
AA initiate upgrade| |6|Reserved,当前统一填0,为后续可能添加的参数做预留| |7|Reserved,当前统一填0,为后续可能添加的参数做预留| |8|Length:路径名长度,大小不超过128字节| |9:N|Filename:绝对路径名| **命令响应参数:** |字节顺序|域取值说明| | --- | --- | |1|Completion Code| |2:4|Manufacturer ID,LB Byte first。长度固定 3 个字节,例如,某厂家ID时 2011,对应十六进制为0x0007DB,则字节序为第1个字节为 DBh,第二个字节为 07h,第三个字节为 00h。| **命令示例:** **样例:开始升级整包/tmp/fullimage.zip** * 请求:`ipmitool raw 0x30 0x93 0xdb 0x07 0x00 0x94 0xaa 0x00 0x00 0x00 0x12 0x2F 0x74 0x6D 0x70 0x2F 0x66 0x75 0x6C 0x6C 0x69 0x6D 0x61 0x67 0x65 0x2E 0x7A 0x69 0x70` * 响应:`0xdb 0x07 0x00` ### 8.2.2 查询整包升级进度 **命令权限:** ReadOnly **是否锁定之后可以访问:** 是 **命令样式:** * 请求:`ipmitool raw 0x30 ` * 响应:` ` **命令请求参数:** |字节顺序|域取值说明| | --- | --- | |NetFn|30h| |Cmd|93h| |1:3|Manufacturer ID,LB Byte first。长度固定 3 个字节,例如,某厂家ID时 2011,对应十六进制为0x0007DB,则字节序为第1个字节为 DBh,第二个字节为 07h,第三个字节为 00h。| |4|95h| |5|Reserved,当前统一填0,为后续可能添加的参数做预留| |6|Reserved,当前统一填0,为后续可能添加的参数做预留| **命令响应参数:** |字节顺序|域取值说明| | --- | --- | |1|Completion Code| |2:4|Manufacturer ID,LB Byte first。长度固定 3 个字节,例如,某厂家ID时 2011,对应十六进制为0x0007DB,则字节序为第1个字节为 DBh,第二个字节为 07h,第三个字节为 00h。| |5|Length,返回数据长度| |6:N|整包中各固件升级进度和状态,每两个字节描述一个固件,其中进度百分比使用低字节,升级状态码使用高字节的低4bit,高字节的高4bit预留,状态码定义如下:
0:正常
1:升级失败
2:未匹配到具体板卡而未升级
如:0x00 0x50固件升级进度为80%,当前状态码为0
0x01 0x00固件升级进度为0%,当前状态码为1| **命令示例:** **样例1:查询整包升级进度及状态** * 请求:`ipmitool raw 0x30 0x93 0xdb 0x07 0x00 0x95 0x00 0x00` * 响应:`0xdb 0x07 0x00 0x0a 0x00 0x50 0x00 0x53 0x01 0x00 0x00 0x64 0x02 0x00` * 固件1、2升级到80%,固件3升级失败,固件4升级到100%,固件5未匹配到具体板卡而未升级 ## 8.3 Web Rest接口升级 ### 8.3.1 整包上传接口 **uri**: ```text /UI/Rest/BMCSettings/UpdateService/Actions/UpdateService.FullImageUnpack ``` **操作类型**: POST **请求参数**: |参数|参数说明|取值| | --- | --- | --- | |FilePath|升级包所在路径|string| **操作权限**:BasicSetting **样例展示:** 请求参数: ```json { "FilePath": "/tmp/fullimage.zip", } ``` 响应消息体举例: ```json { "url":"/UI/Rest/Task/1" } ``` ### 8.3.2 整包升级下发二次确认 **uri**: ```text /UI/Rest/BMCSettings/UpdateService/ParallelUpdate ``` **操作类型**: POST **请求参数**: |参数|参数说明|取值| | --- | --- | --- | |ImageType|固件升级的类型|“SingleImage”
“FullImage”|“SingleImage”| |FullImageNames|string数组,ImageType为FullImage时不允许为null|整包升级各固件名称| ### 8.3.3 获取并行升级各固件信息 **uri**: ```text /UI/Rest/BMCSettings/UpdateService/UpdateProgress ``` **操作类型**: GET **响应参数**: |参数|参数说明|取值| | --- | --- | --- | |UpgradeMode|表明当前升级模式|“Serial”:串行升级中
“Parallel”:并行升级中
“FullImageUnpacking”:整包解包中| |UpgradeTasks|升级任务的进度信息对象|属性包括:
TaskName:升级任务名
Component:升级固件描述
FileName:升级包名称
Percentage:升级进度
TaskState:升级状态
ErrorCode:升级任务错误码
EstimatedRemainingTime:固件预计升级的剩余时间
FirmwareId:固件ID| ### 8.4 相关资源协作接口 **interface:** `bmc.kepler.UpdateService` **path:** `/bmc/kepler/UpdateService` |方法名称|请求签名|请求参数描述|响应签名|响应参数描述|方法描述|访问权限| |---|---|---|---|---|---|---| |FullImageUnpack|s|整包路径|u|任务id|将整包进行解析、校验|BasicSetting| --- # 固件验签、拆包解析定制要求及使用指导 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/upgrade/upgrade_guide/Firmware_Signature_Verification_Guide.html > Language: zh ## 1. 固件验签、拆包解析定制要求 定制固件验签、拆包解析需要配置CSR,需要在FirmwareCustomConfig对象中配置CustomVerifyEnabled、CustomVerifyLibraryName、CustomParseEnabled、CustomParseLibraryName属性。属性说明见下表: | 属性名 | 属性类型 | 取值说明 | | ----------------------- | -------- | -------------------------------------------------------------------- | | CustomVerifyEnabled | Boolean | 客户验签流程定制使能,true:使能;false:禁用,默认值为false | | CustomVerifyLibraryName | String | 客户验签流程定制库名称,默认值为"hpm_parser" | | CustomParseEnabled | Boolean | 客户拆包解析流程定制使能,true:使能;false:禁用,默认值为false | | CustomParseLibraryName | String | 客户拆包解析流程定制库名称,默认值为"hpm_parser",字符串长度约束1~32 | ## 2. 流程 ### 固件验签 1. 客户新增 `/opt/bmc/luaclib/xxx.so`,作为定制hpm解析的接口库(xxx为定制so名称,下同) 2. 客户自行实现 `xxx.so`内容,需要提供方法 `parse_hpm_file`供lua接口调用,入参file_path为hpm包路径;响应为状态码,通过约定返回的状态码标识,确定解析状态。当前实现返回状态码如下: - 正数表示解析成功,负数表示失败,返回负数则直接退出升级流程; - 返回状态码为1:解析验证固件成功,需要继续openUBMC的验签+解析+升级; - 返回状态码为2:解析验证固件成功,需要继续openUBMC的解析+升级; - 返回状态码为3:解析验证固件成功,直接结束固件解析,跳到后续升级 ### 拆包解析 1. 客户新增 `/opt/bmc/luaclib/xxx.so`,作为定制hpm解析的接口库(xxx为定制so名称,下同) 2. 客户自行实现 `xxx.so`内容,需要提供方法 `custom_parse_pkg`供lua接口调用,入参file_path为hpm包路径,output_dir为拆包解析后数据存放目录;响应为true(解析成功)/false(解析失败),且在output_dir下存放必带文件。 ## 3. 配置示例: ### 固件验签 ```json "FirmwareCustomConfig": { "CustomVerifyEnabled": true, //客户签名定制使能 "CustomVerifyLibraryName": "sign_verify" //客户签名定制库为sign_verify.so } ``` ### 拆包解析 ```json "FirmwareCustomConfig": { "CustomParseEnabled": true, //客户拆包解析定制使能 "CustomParseLibraryName": "hpm_parser" //客户拆包解析定制库为hpm_parser.so } ``` ## 4. 客户定制仓自行实现要求 ### 固件验签定制库内容流程图 ![image](../../images/upgrade/upgrade_guide/Firmware_Signature_Verification_Guide/firmware_signature_verification.png) ### 拆包解析定制库输入输出要求 固件管理标准流程调用客户定制库时,会传入file_path(hpm包路径),output_dir(拆包解析后数据存放目录),定制库自行对hpm包进行拆包解析,并将解析内容存放在output_dir下,output_dir必带数据如下: - beforeaction.sh(升级前自定义动作,内容可为空) - afteraction.sh(升级后自定义动作,内容可为空) - update.cfg(参考update.cfg规范) - 解压后的各个固件镜像的二进制数据(命名为FirmwareX,X为固件索引,起始值为1,随着固件数量递增,如Firmware1、Firmware2...,Firmware0用于将update.cfg这个文件作为固件进行描述) ## 5. update.cfg 规范 ### Basic 基础信息域 | 字段名称 | 说明 | 必选(M/O) | 约束 | 样例 | | -------- | -------- | --------- | -------- | -------- | | Version | 固件的内部版本号 | M | 按照各个不同的固件的版本规范进行定义。比如:BMC固件内部采用4段式版本号 | `[Basic]`
`Version=X.XX.XX.XX` | | Revision | 固件的防回退登记号 | O | 当前固件配置了Revision并且是大于0的则生效。每个固件都可以定义自己的Revision,分为两种:
- RevisionNumber:硬件确定的防回退标记
- RevisionNumber4User:软件确定的防回退标记当固件配置的任何一个Revision小于待升级固件的Revision则不允许升级 | `[Basic]`
`Revision=20` | ### Firmware 固件描述域 | 字段名称 | 说明 | 必选(M/O) | 约束 | 样例 | | -------- | -------- | --------- | -------- | -------- | | FileNum | 固件由多少个部分的子固件组成 | M | 最大32个 | `[Firmware]`
`FileNum=2` | | FirmwareMode | 固件升级模式 | O | 取值:Multiple/Single 表示多firmware升级/单firmware升级 | `[Firmware]`
`FirmwareMode=Multiple` | ### FirmwareX 固件描述详细域 当前域会分为多个域进行描述。 | 字段名称 | 说明 | 必选(M/O) | 约束 | 样例 | 补充说明 | | -------- | -------- | -------- | -------- | -------- | -------- | | ProductID | 固件适用的产品标识 | M | 2字节的数字,配置必须是10进制,默认是65535。如果不为默认值并且和当前product的低字节不匹配或者完全不匹配则阻止升级 | `[Firmware1]`
`ProductID=65535` | | | BoardID | 固件适用的单板标识 | M | 2字节的数字,配置必须是10进制,默认是65535。如果不为默认值并且和当前product的低字节不匹配或者完全不匹配则阻止升级 | `[Firmware1]`
`BoardID=65535` | | | Model | 固件适用的硬盘型号列表 | O | 字符串,用英文逗号(,)分隔的多个硬盘型号元素,每个元素是具体的硬盘型号 | `[Firmware1]`
`Model=XXX,YYY,ZZZ` | | | ComponentID | 固件适用的固件类型标识 | M | 1字节的数字,配置必须是10进制,通配是255。根据 ComponentID 和 ComponentIDEx 共同确认一个具体的固件类型。具体参考《IPMI接口说明》附录《固件ID管理》 | `[Firmware1]`
`ComponentID=0` | IPMI接口说明 | | ComponentIDEx | 固件适用的固件扩展标识 | O | 4字节的数字,配置必须是10进制,通配是4,294,967,295(0xFFFFFFFF)。根据 ComponentID 和 ComponentIDEx 共同确认一个具体的固件类型。如果 ComponentIDEx 是通配则仅由 ComponentID 确认具体的固件类型。具体参考《IPMI接口说明》附录《固件ID管理》 | `[Firmware1]`
`ComponentIDEx=0` | IPMI接口说明 | | Uid | 固件适用的UID | O | 24字节的字符串,由 Vendor(8) + Type(2) + ComponentID(14) 组成。仅天池机型固件使用 | | | | UID | DPU固件的UID | O | 仅DPU使用 | | | | ProductUIDList | 固件适用的产品UID列表 | O | 字符串,用英文逗号(,)分隔的多个 ProductUID 元素,每个元素是4字节的16进制数字,默认为空。如果产品 Product 配置中 ProductVendorID 不为 0xFFFFFFFF 则联合 ProductUniqueID 判定固件的匹配;否则单独采用ProductUniqueID 判定固件的匹配,不匹配则阻止升级。和下文中的 BoardIDList 作用同样,优先判定 ProductUIDList | `[Firmware1]`
`ProductUIDList=0xXXXXXXXX,0xXXXXXXXX,...` | | | BoardIDList | 固件适用的单板UID列表 | O | 字符串,用英文逗号(,)分隔的多个 BoardID 元素,每个元素是2字节的数字,配置为10进制。如果上文中 BoardID 配置不为 65535 则优先匹配FRU0的 BoardId,不匹配则阻止升级。然后遍历当前 BoardIDList,如果元素不为65535 则匹配FRU0的 BoardId,不匹配则阻止升级 | `[Firmware1]`
`BoardIDList=XXX,XXX` | | | Version | 当前固件包此Firmware的内部版本号 | O | 按照各个不同的固件的版本规范进行定义。比如:BMC固件内部采用4段式版本号 | `[Firmware1]`
`Version=X.XX.XX.XX` | 2026/1/8新增,用于版本一致则跳过升级的特性 | | SubComponentNum | 当前固件下对应的Firmware适用的子固件 | O | 仅openUBMC升级使用,compute和bios使用 | | | | CPLDChipNummbers | 多供应商模式下的CPLD芯片数量 | O | 仅cpld升级使用,和MultipleSuppliersMode配套使用 | | | | ColdValidList | 固件适用的冷升级片选标识 | O | 仅cpld升级使用 | | | | HotValidList | 固件适用的热升级片选标识 | O | 仅cpld升级使用 | | | | MultipleSuppliersMode | 多供应商模式 | O | 仅cpld升级使用 | | | | UpdateLink | CPLD升级的链路 | O | 仅cpld升级使用 | | | | UpdateFileType | CPLD升级的格式 | O | 仅cpld升级使用 | | | ### Custom 自定义域 可选域,对于固件的自定义描述,如果固件不涉及自定义可不写。 | 字段名称 | 说明 | 必选(M/O) | 约束 | 样例 | | -------- | -------- | -------- | -------- | -------- | | VersionXXX | 自定义对外版本号,其中 XXX 是具体的客户标识,不同的客户可以有多个 | | 1、Version之后的描述产品包构建时根据不同的客户动态写入,必须和定制化客户保持一致
2、该属性如果没有则认为不需要自定义对外版本号,默认采用BMC的内部版本号,取自Basic域的Version属性 | `[Custom]`
`VersionCustomerA=X.X.X`
`VersionCustomerB=X.XX` | ### BMC固件升级update.cfg示例 升级时默认从Firmware1开始读取除update.cfg文件之外的固件相关信息 ```ini [Basic] Version=X.XX.XX.XX Revision=31 [Firmware] FileNum=2 [Firmware0] ProductID=0 # 天池机型的productId为0 ComponentID=0 BoardID=255 ProductUIDList=0xXXXXXXXX,0xXXXXXXXX [Firmware1] ProductID=0 ComponentID=25 BoardID=255 ProductUIDList=0xXXXXXXXX,0xXXXXXXXX [Custom] VersionCustomerA=X.XX.XX VersionCustomerB=X.XX.XXXXXXXX ``` --- # 固件升级指导 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/upgrade/upgrade_guide/upgrade.html > Language: zh 固件升级接口由多个,其中包括web页面升级,cli命令升级,Redfish接口升级,snmp接口升级及ipmi命令升级等,但是常用的有web页面升级及cli升级,下文将分别介绍。 # web页面升级 操作位置:iBMC管理>>固件升级>>固件更新 ![alt text](../../images/upgrade/upgrade_guide/upgrade/image-5.png) # cli命令升级 xshell登录后,下发如下命令即可升级: ![alt text](../../images/upgrade/upgrade_guide/upgrade/image-6.png) # Redfish命令升级 - URL POST `https:///redfish/v1/UpdateService/Actions/Oem/{{OemIdentifier}}/UpdateService.ParallelUpdate` - 请求头: ``` X-Auth-Token : auth_value Content-Type : header_type ``` - 请求消息体: ```json { "Packages": packages_value, "Stage": true } ``` |参数|参数说明|取值| | --- | --- | --- | |device_ip|登录设备的IP地址|IPv4或IPv6地址| |auth_value|请求消息的鉴权参数|可通过/redfish/v1/SessionService/Sessions创建会话时获得| |header_type|请求消息的格式|支持的消息格式包括:`application/json`或者`application/json;charset=utf-8`| |packages_value|升级参数|对象数组,内容如下:
SystemId
TransferProtocol
ImageURI
ForceUpdate
Stage| |SystemId|Multi-Host场景(一个BMC管理多个host主机)下指定升级某host的固件|字符串[1~N]:表示升级第[1~N]个host上的固件,要求对应的host在位| |TransferProtocol|BMC从远程服务器下载升级包时使用的协议|取值:HTTPS、SCP、SFTP、CIFS、NFS。本地升级不需要该字段| |ImageURI|升级包所在路径|升级包的URL(支持本地tmp目录升级),本地tmp目录支持的最大长度为255个字符,远程目录支持的最大长度为1004个字符(传输协议长度不计算在内,如"**sftp://**")| |ForceUpdate|固件是否强制升级|true:版本号一致的固件升级
false:版本号一致的固件不升级
可选参数,如果不加该参数,默认为版本号一致的固件升级| |Stage|固件是否暂存|true:暂存
false:不暂存
可选参数,不加该参数默认为不暂存| # SNMP接口升级 **启动升级** ``` snmpset -t 10 -v3 -l priv -a -X -u -A -X 1.3.6.1.4.1.{SnmpOemIdentifier}.30.1.0 s ``` **查看升级状态** ``` snmpget -t 10 -v3 -l priv -a -X -u -A -X 1.3.6.1.4.1.{SnmpOemIdentifier}.30.2.0 ``` # IPMI命令升级 **启动升级** ``` ipmitool -H -I lanplus -p 623 -U -P -C 17 raw 0x30 0x91 0x06 0xaa 0x00 0x00 ``` - `flag` :[0-6]:offset [7]级联标志,0=最后一帧数据 1=后面还有数据 - `length`:本帧数据的长度 - `filepath`:路径名,单帧请求不超过16个字节 例: ``` ipmitool -H -I lanplus -p 623 -U -P -C 17 raw 0x30 0x91 0x06 0xaa 0x00 0x00 0x00(flag) 0x0c(length,此处为/tmp/BMC.hpm的长度,即12个字节) 0x2f 0x74 0x6d 0x70 0x2f 0x42 0x4d 0x43 0x2e 0x68 0x70 0x6d(filepath,此处为/tmp/BMC.hpm) ``` --- # SVF文件介绍 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/upgrade/upgrade_guide/upgrade_svf_file.html > Language: zh ## 1. SVF基本概述 SVF 是 `Serial Vector Format` 的缩写,常用于 `JTAG (IEEE 1149.1)` 场景。 它本质上是**可读文本脚本**,用于描述测试/烧录时序与向量数据,通常由开发工具生成,再由烧录或边界扫描工具执行。 在硬件升级流程中,SVF 常用于 FPGA/CPLD 等可编程器件的下载与验证,也可用于产线测试和板级调试。 > 说明:`SVF` 在不同领域有同名含义。本文默认指 JTAG 的 `Serial Vector Format`,不是 Autodesk 生态中的 `Streaming Vector Format`。 ### 1.1 缩写与术语表 | 缩写或写法 | 英文全称 / 含义 | 说明 | |------------|-----------------|------| | **SVF** | Serial Vector Format | 串行向量格式,JTAG 场景下为文本化向量脚本(勿与 Autodesk 的 Streaming Vector Format 混淆) | | **JTAG** | Joint Test Action Group | 业界通称;对应标准为 **IEEE 1149.1**,边界扫描 / 在线测试常用接口 | | **IEEE** | Institute of Electrical and Electronics Engineers | 电气电子工程师学会;文中 **IEEE Std 1149.1** 即 JTAG 边界扫描标准 | | **TAP** | Test Access Port | 测试访问端口;芯片内 JTAG 控制器对外接口,含状态机与 `TCK`/`TMS`/`TDI`/`TDO` 等信号 | | **IR** | Instruction Register | 指令寄存器;`SIR` 扫描的对象,用于选择器件当前执行的 JTAG 指令 | | **DR** | Data Register | 数据寄存器;`SDR` 扫描的对象,用于读写数据或配置位流 | | **TCK** | Test Clock | JTAG 测试时钟 | | **TMS** | Test Mode Select | 模式选择,配合 `TCK` 驱动 TAP 状态迁移 | | **TDI** | Test Data In | 测试数据输入(移位链输入侧) | | **TDO** | Test Data Out | 测试数据输出(移位链输出侧);可与期望值比对做校验 | | **TRST** / **TRST#** | Test Reset(低有效常写作 `#`) | 可选硬件复位脚;未引出时可用 `TMS` 序列使 TAP 进入复位类状态 | | **LSB** | Least Significant Bit | 最低有效位;本文约定扫描数据常从 LSB 一侧先移入/移出 | | **ASCII** | American Standard Code for Information Interchange | 美国信息交换标准代码;SVF 文件为可读文本编码 | | **Hz** | Hertz | 赫兹;`FREQUENCY` 中声明的时钟频率单位 | | **SEC** / **TCK**(`RUNTEST` 参数) | Second / Test Clock | `RUNTEST` 可按秒(`SEC`)或按 `TCK` 周期数等待 | | **BMC** | Baseboard Management Controller | 基板管理控制器;可运行 SVF 解析并通过 GPIO 或专用硬件驱动 JTAG | | **CPLD** | Complex Programmable Logic Device | 复杂可编程逻辑器件;文中为 SVF/JTAG 升级的典型目标之一 | | **FPGA** | Field-Programmable Gate Array | 现场可编程门阵列;亦常用 SVF/JTAG 下载配置 | | **PC** | Personal Computer | 个人计算机;可连接下载器运行 SVF | | **ATE** | Automatic Test Equipment | 自动测试设备;产线或实验室批量执行 SVF 的常见宿主 | | **MCU** | Microcontroller Unit | 单片机 / 微控制器;可作嵌入式 SVF 解析与 bit-bang JTAG 宿主 | | **GPIO** | General-Purpose Input/Output | 通用输入输出;软件模拟 JTAG 时常用 GPIO 连接 `TCK`/`TMS`/`TDI`/`TDO` | | **IDCODE** | Identification Code(Device ID) | 器件标识寄存器读回值;用于确认 JTAG 链路与器件型号 | | **UID** | Unique Identifier | 唯一标识;升级包与固件对象匹配时常用 | | **HIR / HDR** | Header Instruction / Data Register | 头部位:正式 `SIR`/`SDR` 前附加的移位前缀 | | **TIR / TDR** | Trailer Instruction / Data Register | 尾部位:正式 `SIR`/`SDR` 后附加的移位后缀 | | **PIO** | Parallel I/O | 并行 I/O;SVF 扩展指令,非所有工具实现 | | **PATHDATA** | (扩展指令名) | 部分工具链扩展;非核心 JTAG/SVF 必备 | | **SVF_MISMATCH** | (实现侧错误码示例) | 表示 TDO 等回读与期望不一致导致中止 | ## 2. SVF文件结构与常见指令 SVF 文件由一系列指令组成,每条指令以分号结尾,常见内容包括: - `SIR`:Shift Instruction Register,向 IR 移位指令 - `SDR`:Shift Data Register,向 DR 移位数据 - `RUNTEST`:保持一定时钟周期或时间,用于等待器件内部操作完成 - `STATE`:切换 TAP 状态机状态 - `TRST`:复位测试逻辑(按平台支持情况使用) - `ENDIR` / `ENDDR`:设置 IR/DR 移位结束后的目标状态 SVF 语法规则补充说明: - **文件形式**:SVF 文件是由多条 SVF 语句构成的 ASCII 文本文件 - **语句结构**:一条 SVF 语句由“指令 + 参数”组成,以 `;` 作为结束标记 - **多行支持**:单条 SVF 语句可跨多行书写;单行最大长度通常为 256 个字符 - **大小写规则**:SVF 关键字大小写不敏感 - **注释规则**:支持行内注释,以 `!` 或 `//` 起始,起始符之后本行剩余内容视为注释(部分工具仅支持整行注释,不支持行尾注释,需以实际工具手册为准) - **扫描数据表示**:扫描类语句的数据写在圆括号内,使用十六进制表示 - **位宽约束**:扫描数据长度不能超过语句声明的比特长度;若超过,超出部分的高位会被丢弃 - **位序约定**:扫描数据按最低有效位(最右侧)优先的顺序处理,适用于 `TDI`、`TDO` 和 `MASK` 示例(简化): ```svf TRST OFF; // 关闭可选 TRST#,仅用 TMS 序列控制 TAP ENDIR IDLE; // IR 扫描结束后进入 Run-Test/Idle(IDLE) ENDDR IDLE; // DR 扫描结束后进入 Run-Test/Idle(IDLE) SIR 8 TDI (AB); // 向指令寄存器移入 8 位指令 0xAB SDR 32 TDI (12345678) TDO (XXXXXXXX) MASK (00000000); // 向数据寄存器移入 32 位;TDO/MASK 为占位示例(MASK 全 0 表示不校验 TDO) RUNTEST 100 TCK; // 在 Run-Test/Idle 下输出 100 个 TCK 周期 ``` ## 3. SVF核心指令介绍(按功能分组) 根据常见实践(含 IEEE Std 1149.1 相关约定与行业工具通用用法),可将 SVF 指令按功能分组理解为“状态控制、扫描执行、时序复位、扩展指令”四大类。 ### 3.1 状态控制类(让 TAP 停在哪、走哪条路) | 指令 | 作用(通俗版) | 常见示例 | |------|----------------|----------| | `ENDDR` | DR 扫描结束后,TAP 回到什么状态(常见 `IDLE` 或 `PAUSE`) | `ENDDR IDLE;` | | `ENDIR` | IR 扫描结束后,TAP 回到什么状态 | `ENDIR IDLE;` | | `STATE` | 让 TAP 进入指定状态(如复位、空闲) | `STATE RESET;` / `STATE IDLE;` | | `RUNTEST` | 在 `Run-Test/Idle` 保持一段时间或一定时钟周期 | `RUNTEST 5000E-6 SEC;` / `RUNTEST 100 TCK;` | 通俗理解: - `ENDDR`/`ENDIR` 是“扫完后去哪里” - `STATE` 是“立刻去哪里” - `RUNTEST` 是“在空闲区等待多久” ### 3.2 扫描操作类(真正移位与校验) | 指令 | 作用(通俗版) | 典型格式 | 格式解释 | |------|----------------|----------|----------| | `SIR` | 扫描 IR,选择待执行 JTAG 指令 | `SIR 8 TDI (55);` | `8` 表示扫描位宽为 8 bit;`TDI(55)` 表示移入的 IR 数据为 `0x55`。 | | `SDR` | 扫描 DR,执行读写数据与可选回读校验 | `SDR 16 TDI (1234) TDO (ABCD) MASK (FFFF);` | `16` 为 DR 位宽;`TDI` 为移入值;`TDO` 为期望回读值;`MASK` 指定参与比较的位(`1` 参与,`0` 忽略)。 | | `HIR` / `HDR` | 在正式扫描前追加前导位(链路对齐/绕过) | `HIR 4 TDI (0);` | `HIR` 作用于 IR 链,`HDR` 作用于 DR 链;示例表示在正式扫描前先追加 4 bit 前导数据。 | | `TIR` / `TDR` | 在正式扫描后追加尾随位 | `TDR 4 TDI (0);` | `TIR` 作用于 IR 链,`TDR` 作用于 DR 链;示例表示在正式扫描后追加 4 bit 尾随数据。 | 通俗理解: - `SIR` 负责“选命令” - `SDR` 负责“传数据 + 可选验证” - `HDR/HIR` 与 `TDR/TIR` 主要用于链路对齐与多器件场景 ### 3.3 时序与复位控制类(速度与复位信号) | 指令 | 作用(通俗版) | 示例 | 示例解释 | |------|----------------|------|----------| | `FREQUENCY` | 声明可用的 JTAG 时钟上限(Hz) | `FREQUENCY 10E6 HZ;` | 声明后续操作可使用不高于 10 MHz 的 TCK 频率(`10E6` 即 `10,000,000 Hz`)。 | | `TRST` | 控制可选 `TRST#` 复位信号 | `TRST ON;` / `TRST OFF;` | `TRST ON` 表示使能复位(通常将低有效 `TRST#` 拉低);`TRST OFF` 表示释放复位。 | 注意: - `FREQUENCY` 常用于约束或提示执行工具按该上限工作 - `TRST` 依赖硬件是否提供该引脚 ### 3.4 扩展/并行类指令(工具相关,较少使用) | 指令 | 说明 | |------|------| | `PIO` | 并行读写一组引脚(非 JTAG 核心指令) | | `PIOMAP` | 将 PIO 通道映射到物理引脚 | 说明:`PIO`/`PIOMAP` 不属于通用 JTAG/SVF 核心流程,常见于特定测试平台。若目标是常规烧录/调试,可暂不使用。 ### 3.5 简化片段示例(按执行顺序理解) ```svf ENDDR IDLE; // 设置 DR 扫描结束行为 ENDIR IDLE; // 设置 IR 扫描结束行为 FREQUENCY 10E6 HZ; // 最高频率 10MHz STATE RESET; // 进入复位状态 STATE IDLE; // 转入空闲状态 SIR 8 TDI (FF); // 扫描指令:示例值 SDR 16 TDI (1234) TDO (5678) MASK (FFFF); // 扫描数据:写入并校验返回值 RUNTEST 1E-3 SEC; // 等待 1ms STATE IDLE; // 结束状态 ``` ### 3.6 两个易混淆点 1. `HDR/HIR` 与 `TDR/TIR` 不是必须项 在简单单器件场景中,常仅使用 `SIR`/`SDR`;多器件链路或需要填充位时再引入头尾位。 2. `ENDDR`/`ENDIR` 只定义扫描后的目标状态 它们不改变当前扫描的数据本身,而是影响扫描结束时 TAP 停留位置。 ## 4. 在升级流程中的使用方式 BMC 支持通过 SVF 对 CPLD 进行升级。其本质是:解析 SVF 中的扫描数据与控制指令(如 `TDI` 数据字段、`SIR`、`SDR` 等语句),并通过 JTAG 链路驱动 `TDI`、`TMS`、`TCK` 等信号,按既定时序将配置数据下发到目标 CPLD,最终完成升级。 是否需要控制 `TRST` 信号取决于硬件设计:若板级已引出并接入该引脚,可在流程中使用;若未引出,则通常通过 `TMS` 序列完成 TAP 复位。 典型流程如下: 1. 由原厂工具或工程工具链导出 SVF 文件 2. 使用支持 JTAG/SVF 的执行工具加载该文件 3. 连接目标板卡并校验 JTAG 链路(器件顺序、IDCODE) 4. 执行 SVF,完成烧录/配置 5. 读取状态或回读关键寄存器进行结果确认 注意事项: - **版本匹配**:SVF 与目标器件型号、工程版本需严格一致 - **链路一致性**:JTAG 链顺序变化会导致向量错位 - **时序要求**:某些器件对 `RUNTEST` 等等待时长敏感 - **供电与复位**:升级前应确认电源、时钟、复位状态稳定 ### 4.1 参考实现补充(general_hardware) 结合 `general_hardware` 的实现,BMC 侧基于 SVF 升级 CPLD 的工程化流程可进一步归纳为: 1. **升级包匹配与解包** - 根据 `Firmware` 包名匹配配置项(`update.cfg`),再按 `uid/system_id` 过滤目标 CPLD 对象 - 升级前先安全解包到临时目录,再按文件命名规则装载 2. **文件组织与命名约定** - 单厂商常见命名:`cpld.svf` + `valid.svf` + `bypass.svf` - 多器件/多厂商常见命名:`cpld01.svf`、`valid01.svf`、`bypass01.svf`(按 `file_id` 递增) - `valid` 文件用于后续生效阶段,`bypass` 文件用于链路偏移/对齐场景 3. **链路准备与串行执行** - 升级前切换到 firmware route(`switch_to_firmware_route`) - 按需使能 bypass 模式,并通过 `set_upg_cpld_chip` 选中目标链上器件 - 逐片执行升级,单片完成后短暂等待,再继续下一片 4. **总线锁与并发保护** - 升级与校验前尝试获取芯片锁(带重试和超时),避免并发访问同一硬件通道 - 成功后执行 SVF 写入流程,结束后立即解锁 5. **校验与生效管理** - 升级成功后保存 `valid_*`(及 `bypass_*`)文件,供后续生效任务使用 - 冷生效路径通常由系统在后续阶段统一执行;热生效路径可按 chip 粒度快速生效 - 失败场景应删除残留生效文件并清理标志,避免下次误生效 ### 4.2 安全自检场景(verify.svf) CPLD 通过 `verify.svf` 实现安全自检流程: - 升级后可加载 `verify.svf`(或 `verify01.svf` 等)进行 JTAG 侧回归校验 - 多厂商场景下,按 chip 信息映射到对应 `verifyXX.svf`,逐片校验 - 若校验失败或锁获取失败,流程应立即返回错误并记录审计日志 上述做法可显著提升 SVF 升级在量产环境下的可追踪性、并发安全性与生效可靠性。 ## 5. 常见问题与排查建议 ### 5.1 扫链失败(扫链结果为空) 现象: - BMC `app.log` 中出现:`[cpld]get cpld device info failed` - 同时 `framework.log` 中出现:`get cpld id:[] success` - `id` 数组为空,表示业务流程成功调用了扫链接口,但返回的链路扫描结果为空 定位思路: 1. 排查 CSR 中配置的硬件链路是否正确 2. 排查实际硬件链路是否正常(连接、供电、时钟、复位、信号完整性等) 验证命令: `mdbctl call Cpld_1_010101 bmc.kepler.Chip.JtagTarget GetChipIdcode 0` ### 5.2 升级失败(TDO 校验不通过) 现象: - `linuxkernel_log` 中出现日志:`verify TDO [0] expect:03b, mask: 0xff, sample:0x0` 含义: - 升级使用的 SVF 文件中,期望值(`expect`)是 `0x3b` - 实际从 CPLD 链路读到的 TDO 采样值(`sample`)是 `0x0` 定位思路: 1. 先排查 CSR 配置的链路是否符合预期(例如应使用 `jtag0` 还是 `jtag1`) 2. 若日志中 `sample` 值**非 0**,优先排查 SVF 文件本身是否有问题(指令/位宽/掩码/目标器件不匹配) 3. 若 `sample` 值为 **0**,通常表示链路基本未读到有效值,需要从硬件侧观察 CPLD 的 TDO 波形 ## 6. SVF文件加载与执行流程(深入) SVF 的加载过程可以理解为:**SVF 解析器(运行在 PC、ATE 或嵌入式 MCU)逐行读取文本指令,并翻译为 JTAG 硬件接口上的精确时序波形。** 核心逻辑如下: ```mermaid flowchart TD A[开始加载SVF文件] --> B[初始化JTAG硬件
设置TCK等参数] B --> C[逐行读取SVF语句] C --> D{解析命令类型} D -- FREQUENCY --> E[重新配置TCK时钟频率] D -- STATE --> F[驱动TAP状态机到指定状态] D -- SIR/指令扫描 --> G[执行指令寄存器扫描
移入特定指令] D -- SDR/数据扫描 --> H[执行数据寄存器扫描
移入/移出数据并校验TDO] D -- RUNTEST --> I[保持Run-Test/Idle状态
等待固定时间或时钟周期] D -- HDR/HIR/TDR/TIR --> J[设置头部/尾部数据
用于后续扫描] D -- ENDDR/ENDIR --> K[设置扫描结束后的 TAP 状态] D -- TRST --> L[控制可选复位信号] D -- 其他 --> M[处理PIO、PATHDATA等扩展命令] G & H --> N{TDO校验是否通过?} N -- 否 --> O[报告错误,停止加载] N -- 是 --> P{是否还有更多语句?} E & F & I & J & K & L & M --> P P -- 是 --> C P -- 否 --> Q[加载完成,成功] O --> R[加载失败] ``` 下面详细拆解关键步骤。 ### 6.1 初始化阶段 在解析任何 SVF 命令之前,解析器需完成以下基础设置: - **硬件接口初始化**:配置 JTAG 引脚(`TCK`、`TMS`、`TDI`、`TDO`),设置初始 TCK 频率(常见默认 1MHz 或更低,再由 `FREQUENCY` 动态调整) - **状态机复位**:通过 TMS 序列将 TAP 强制复位到 `Test-Logic-Reset`,确保链上器件处于已知初态 - **参数初始化**:清空内部上下文,如 `HDR`/`HIR`/`TDR`/`TIR` 缓存与默认 `ENDDR`/`ENDIR` 状态 ### 6.2 逐行解析与执行(核心循环) 解析器按顺序读取每条语句,忽略注释,识别命令与参数,调用底层 JTAG 驱动完成执行。 常见命令执行逻辑示例: - **`FREQUENCY 10000000 HZ;`** - 重新配置 TCK 频率 - 后续 `SIR`/`SDR` 在新频率下执行 - **`STATE RESET;`** - 通过 TMS 输出特定序列(例如保持高电平并给出 5 个 TCK)进入 `Test-Logic-Reset` - **`SIR 6 TDI(09);`** - 进入 `Shift-IR` - 按位序串行移入 6 位指令数据 - 退出到 `Update-IR` 使指令生效 - 根据 `ENDIR` 停留到目标状态(默认常见为 `Run-Test/Idle`) - **`SDR 32 TDI(00000000) TDO(0484a093) MASK(0fffffff);`** - 进入 `Shift-DR` - 在移入 `TDI` 同时采集 `TDO` - 按 `MASK` 指定位对比采样值与期望 `TDO` - 不匹配则立即报错并停止(`SDR` 既传输也验证) - 根据 `ENDDR` 退出到目标状态 - **`RUNTEST 10000 TCK;`** - 保持 `Run-Test/Idle` 状态,输出指定数量 TCK 周期 ### 6.3 错误处理与流程控制 - **TDO 校验失败**:`SIR`/`SDR` 期望值与实测值不一致时立即中止,并返回错误码(如 `SVF_MISMATCH`) - **语法错误**:命令无法识别、参数格式非法(如错误十六进制字符)时停止加载 - **超时/资源错误**:`RUNTEST` 超出平台限制、内存分配失败等均可触发终止 ### 6.4 实现注意事项(常见坑点) 1. **TAP 状态迁移精确性** `STATE` 可指定中间态(如 `SELECT-DR-SCAN`),解析器需从当前态计算合法路径并输出正确 TMS 序列。 2. **`HDR`/`HIR` 与 `TDR`/`TIR` 的拼接处理** 这些前后缀会影响后续 `SIR`/`SDR` 的实际移位位流;若拼接错误会导致链路对齐失败。 3. **`RUNTEST` 时间精度** 使用 `SEC` 时需结合当前频率准确换算时钟数,并明确取整策略,避免累积时序偏差。 4. **长位流命令的内存管理** 超长 `SDR`(如 FPGA 配置位流)建议流式处理,边解析边下发,避免一次性分配大缓冲。 ### 6.5 小结 SVF 加载本质是一个**解释执行**过程,关键在于: - 正确实现 JTAG 底层时序与 TAP 状态机控制 - 稳健地解析文本命令并执行校验、错误中止与资源管理策略 这些细节处理到位,SVF 解析器才能稳定完成器件编程与测试任务。 --- # 升级生效管理指导 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/upgrade/upgrade_guide/upgrade_task_management_guide.html > Language: zh # 1 升级生效单任务管理机制 **升级生效单任务管理**将升级和生效操作为一个连续的单一任务进行管理。在任务创建并且满足**生效**条件后,系统会自动执行升级动作,升级完成后自动触发生效动作。 # 2 升级生效分别管理机制 **升级生效分别管理**将升级和生效操作分为两个独立的任务进行管理。首先创建并执行升级任务,升级完成后,创建生效任务,然后再判断是否满足**生效**条件,满足条件则自动立即生效,不满足生效条件时等待满足条件后再生效。两个任务可独立监控状态和进度。 # 3 定制化方法 ### 3.1 定制是否采用异步升级策略 **定制化项** |项目|值| | --- | --- | |定制化项|Custom_AsyncFirmwareUpdate定制项| |定制化接口名称|Custom_AsyncFirmwareUpdate| |取值类型|string| |取值范围|“on” 或 “off”| |默认值|“off”| |处理逻辑|if (Custom_AsyncFirmwareUpdate== “on”)
 redfish标准升级接口采用异步升级策略,待生效条件满足后再开始升级
else
 redfish标准升级接口采用原有的升级与生效分离策略| **定制化流程** ![image](../../images/upgrade/upgrade_guide/upgrade_task_management_guide/Custom_AsyncFirmwareUpdate.png) # 4. 导入导出方法 ## 4.1 是否采用异步升级策略 |项目|值| | --- | --- | |导出项|UpgradeService| |导出子项|AsyncFirmwareUpdate| |取值类型|string| |属性类型|ImportAndExport| |取值范围|“on” 或 “off”| |含义说明|是否采用异步升级策略| |导出后是否可以直接导入|是| # 5. 资源协作接口 **path:** `/bmc/kepler/UpdateService/FirmwareInventory/:Id` **资源interface:** `bmc.kepler.UpdateService.FirmwareInfo` **变化类型:** 新增资源协作接口属性 **属性:** |属性名称|签名|只读|变化通知|属性描述|取值范围|访问权限|属性来源|持久化类型|易变属性| | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | |ActiveCondition|as|true|false|属性描述:固件的生效条件|None、PowerOff、PowerOn、ResetBMC、ResetTargetDevice|R:ReadOnly|各固件下游组件启动时注册|无需持久化|false| --- # VME文件介绍与CPLD升级实践指南 > URL: https://openubmc.cn/docs/zh/latest/build_upgrade/upgrade/upgrade_guide/upgrade_vme_file.html > Language: zh ## 1. VME基本概述 VME 文件(Virtual Machine Environment file)是莱迪思半导体(Lattice Semiconductor)在 `ispVM Embedded` 体系中定义并推广的专有文件格式。 从工程实现角度看,VME 可理解为将 SVF(Serial Vector Format,串行向量格式)中的文本指令与数据转换为面向执行侧的紧凑表示(常见为二进制化/编码化,并支持可选压缩)的结果文件,用于嵌入式处理器高效解析与执行 JTAG 编程流程。 因此,相比标准 SVF 文本,VME 的核心价值在于在资源受限场景下兼顾存储效率与执行效率。 在 `general_hardware` 代码中,如果 CPLD 升级需要使用 VME 文件,需要在 HPM 升级包的 `update.cfg` 配置文件中设置 `UpdateFileType=vme`。 该配置用于告知升级框架按 VME 路径解析与执行后续流程。 VME 文件在本项目中主要用于 CPLD 固件升级场景,可理解为一类用于 JTAG 升级流程的向量文件格式。 在工程实现上,BMC 会将 VME 文件封装后下发给底层驱动,由驱动执行实际链路操作与数据写入。 ### 1.1 缩略语表 | 缩略语 | 英文全称 | 解释 | |--------|----------|------| | `VME` | Virtual Machine Environment | Lattice `ispVM Embedded` 体系中的专有升级文件格式。 | | `SVF` | Serial Vector Format | 文本化 JTAG 向量脚本格式,常作为 VME 的输入来源。 | | `JTAG` | Joint Test Action Group | IEEE 1149.1 边界扫描接口,用于器件编程与测试。 | | `BMC` | Baseboard Management Controller | 服务器板级管理控制器,可执行固件升级流程。 | | `CPLD` | Complex Programmable Logic Device | 复杂可编程逻辑器件,本文主要升级对象。 | | `FPGA` | Field-Programmable Gate Array | 现场可编程门阵列,常与 CPLD 同属可编程逻辑器件。 | | `ASCII` | American Standard Code for Information Interchange | 文本编码标准,SVF 通常以 ASCII 文本形式存在。 | | `ATE` | Automatic Test Equipment | 自动测试设备,常用于生产测试与烧录。 | | `MCU` | Microcontroller Unit | 微控制器,常作为嵌入式执行 VME 的处理器。 | | `DSP` | Digital Signal Processor | 数字信号处理器,部分嵌入式编程场景会使用。 | | `HPM` | Hardware Platform Management | 服务器固件升级常用封装格式(`.hpm`)。 | | `ISP` | In-System Programming | 在系统编程,指器件在板内完成下载/升级。 | | `TMS/TCK/TDI/TDO` | JTAG Signals | JTAG 四个核心信号:模式、时钟、数据输入、数据输出。 | | `UID` | Unique Identifier | 升级对象唯一标识,用于匹配固件与目标器件。 | ## 2. VME与SVF的关系 VME 文件的主要用途之一是对 SVF 文件进行简化与优化:SVF 通常是包含算法与数据的 ASCII 文本格式,而 VME 可视为其面向执行侧的二进制优化版本。 与 SVF 相比,VME 通常占用更少的存储空间用于保存码流文件,并对编码长度进行了优化,更适合资源受限场景。 简单来说,你可以把 SVF 想象成一份文本格式的说明书(人可读,但体积大),而 VME 文件则是这份说明书被编译成二进制代码后的版本(机器更易执行)。二者都能用于 JTAG 升级流程。 进一步对比如下表所示: | 对比维度 | SVF文件 | VME文件 | |----------|---------|---------| | 文件格式 | 文本(ASCII),人类可读 | 二进制,机器可读 | | 文件体积 | 大(文本描述冗长) | 小(二进制 + 压缩) | | 解析方式 | 需逐行解析文本指令 | 直接按二进制结构执行 | | 处理效率 | 需要文本解析,执行开销较高 | 可按预定义结构快速解析与执行 | | 主要用途 | PC 端 ATE/调试器 | 嵌入式微处理器编程 | | 可移植性 | 通常跨工具可读性更好 | 往往与具体平台/工具链绑定更紧 | | 形态定位 | 更偏标准化文本脚本 | 更偏工程工具链产物 | ## 3. 文件格式与结构 从工程视角看,VME 文件可理解为“结构化执行载体 + 两类效率优化”的组合: 1. **存储形式** VME 常以机器高效解析为目标,实际交付中可表现为二进制文件或十六进制编码载体(取决于工具链与发布方式)。 2. **数据结构** - **算法部分(Algo)**:描述编程控制流程(如进入编程模式、擦除、校验) - **数据部分(Data)**:承载实际待烧录数据(例如由设计文件转换得到的器件配置数据) 3. **内容来源** 通常由上位机工具结合 JTAG 链路拓扑信息、器件信息与用户设计数据打包生成。 ### 3.1 压缩格式与循环格式 “压缩格式”和“循环格式”的 VME 文件,是 Lattice 为提升 `ispVM Embedded` 编程效率而设计的两种优化策略。 简单理解:**压缩格式**主要优化文件“体积”,**循环格式**主要优化执行“流程”。 #### 3.1.1 压缩格式(Compressed VME) 核心目标是**最小化文件体积**。 - **特点与原理**:将标准 SVF 指令/数据转换为更紧凑表示,并结合压缩算法(如游程编码)减少冗余;对大量重复数据场景效果明显。 - **应用场景**:适用于存储资源紧张的嵌入式设备(如 MCU Flash 空间有限)。 - **差异点**:执行前或执行时通常需要解压步骤,会带来一定 CPU/RAM 开销,属于“以算力换空间”的策略。 #### 3.1.2 循环格式(Looped VME) 核心目标是**优化执行效率**。 - **特点与原理**:通过可重复执行的块结构(循环/子流程)描述高重复操作,避免把同类指令逐条展开。 - **应用场景**:适用于对编程速度敏感,或处理器主频/RAM 受限但需高效执行的场景。 - **差异点**:要求执行引擎支持循环控制码解析,属于“以结构换速度”的策略。 #### 3.1.3 选型建议 在实际应用中两者通常可组合使用: - **追求最小体积**:优先压缩格式 - **追求最快编程速度**:优先循环格式 - **通用嵌入式场景**:建议“压缩 + 循环”组合,通常能在体积与效率间取得更好平衡 ## 4. VME命令集 SVF 的 `SIR`、`SDR`、`RUNTEST` 等命令是文本可读的;VME 侧通常不是以同样的文本命令直接呈现。 在嵌入式场景中,更常见做法是由配套解析器/库读取 VME 内部算法与数据,再翻译为底层 JTAG 信号序列(`TMS`、`TCK`、`TDI`、`TDO`)执行。 可简化理解为:**SVF 更偏“人可读脚本”,VME 更偏“机器可执行载荷”。** VME 在指令组织上还引入了一些用于减少重复结构的机制(如 `BEGIN_REPEAT`、`CONTINUE`、`END_FRAME`、`END_REPEAT`、`DATA`、`PROGRAM`、`VERIFY`、`ENDVME`、`DTDI`、`DTDO`)。 这类结构化能力在标准 SVF 文本中通常没有一一对应的同名特性。 其中: - `CONTINUE` 常出现在每个 `SIR`/`SDR` 逻辑段之后,用于标识该段结束并继续后续流程 - `END_FRAME` 常出现在每个 VME 数据帧之后,用于标识当前数据帧结束 ### 4.1 指令映射汇总表 | 指令 | 指令码 | 指令说明 | |------|--------|----------| | `STATE` | `0x10` | 控制 TAP 状态机跳转到目标状态(如 `RESET`、`IDLE`)。 | | `SIR` | `0x11` | 执行 IR 扫描,向指令寄存器移入指令位流。 | | `SDR` | `0x12` | 执行 DR 扫描,进行数据移入/移出与可选校验。 | | `TCK` | `0x1B` | 产生指定数量的测试时钟脉冲。 | | `WAIT` | `0x1A` | 执行等待动作(按时间或时钟周期等待)。 | | `ENDDR` | `0x02` | 指定 DR 扫描结束后 TAP 停留状态。 | | `ENDIR` | `0x03` | 指定 IR 扫描结束后 TAP 停留状态。 | | `HIR` | `0x06` | 定义 IR 扫描前导位(Header-IR)。 | | `TIR` | `0x07` | 定义 IR 扫描尾随位(Trailer-IR)。 | | `HDR` | `0x08` | 定义 DR 扫描前导位(Header-DR)。 | | `TDR` | `0x09` | 定义 DR 扫描尾随位(Trailer-DR)。 | | `BEGIN_REPEAT` | `0xA0` | 重复块起始标记,用于压缩重复执行结构。 | | `TDI` | `0x13` | 指定移入链路的测试数据(Test Data In)。 | | `CONTINUE` | `0x70` | 当前 `SIR`/`SDR` 逻辑段结束并继续后续流程。 | | `END_FRAME` | `0xA2` | 当前 VME 数据帧结束标记。 | | `TDO` | `0x14` | 指定期望回读数据(Test Data Out)用于比对。 | | `MASK` | `0x15` | 指定回读校验掩码位(`1` 参与比较,`0` 忽略)。 | | `END_REPEAT` | `0xA1` | 重复块结束标记。 | | `DATA` | `0xA3` | 数据段标记,表示后续为待处理数据载荷。 | | `PROGRAM` | `0xA4` | 进入或执行编程动作流程。 | | `VERIFY` | `0xA5` | 进入或执行校验动作流程。 | | `ENDVME` | `0x7F` | VME 文件/流程结束标记。 | | `DTDI` | `0xA6` | 压缩/差分 TDI 数据段(用于减少重复编码)。 | | `DTDO` | `0xA7` | 压缩/差分 TDO 数据段(用于减少重复编码)。 | 从 SVF 文件到 VME 文件的翻译通常按“逐条指令映射”的方式进行。示例如下: - SVF 指令:`SIR 8 TDI (16)` - 翻译后的 VME 字节序列:`0x02 0x08 0x0E 0x68` ## 5. 工程中的 VME 文件组织方式 结合现网实现,VME 相关文件通常按以下命名组织: ### 5.1 单文件(单厂商)模式 - `cpld.vme`:升级主文件 - `valid.vme`:后续生效文件 - `bypass.vme`:链路偏移/对齐相关辅助文件 ### 5.2 多文件(多器件/多厂商)模式 - `cpld01.vme`、`cpld02.vme` ... - `valid01.vme`、`valid02.vme` ... - `bypass01.vme`、`bypass02.vme` ... 其中 `XX` 文件序号可由链路设备信息与芯片映射规则计算得到,用于多器件按片升级。 ## 6. BMC侧VME升级流程 在服务器 BMC 领域,VME 文件是用于升级 CPLD(复杂可编程逻辑器件)的核心文件格式。为更好理解其应用位置,可先看端到端流程: ```mermaid flowchart TD A[开发人员生成VME文件] --> B[打包VME文件为HPM固件包] B --> C[管理员通过BMC Web界面上传HPM包] C --> D[BMC解析HPM包并提取VME文件] D --> E[BMC通过JTAG接口烧录CPLD] E --> F{烧录方式} F -->|后台模式| G[先写入Flash
不影响CPLD当前运行] F -->|直接模式| H[直接编程CPLD
期间CPLD逻辑失效] G --> I[等待业务空闲
加载新固件并复位] H --> J[CPLD复位后新固件生效] I --> J ``` ### 6.1 HPM包:VME文件的标准包装形态 服务器场景中的 VME 文件通常不会以“裸文件”直接交付,而是作为 HPM 包中的组成部分。 - **是什么**:HPM 是标准化固件升级容器,可理解为服务器固件升级“安装包” - **为什么需要它**:可统一封装 CPLD/BIOS/BMC 等多类固件,并提供版本管理、签名校验等机制 - **怎么做**:研发阶段通常使用 `hpmimage` 等工具,将 `.vme`、配置与脚本打包为 `.hpm` ### 6.2 BMC如何执行VME升级 当通过 Web 或 CLI 上传包含 VME 的 HPM 包后,BMC 内部流程通常包括: 1. **解析与验证**:解包并校验签名/完整性,确认来源可信且未被篡改 2. **驱动 JTAG**:BMC 作为 JTAG 控制端,通过 `TMS/TCK/TDI/TDO` 与 CPLD 交互 3. **执行 VME**:升级引擎按 VME 内容执行擦除、编程、校验等步骤 ### 6.3 平滑升级(无感升级)机制 为降低业务影响,工程上常采用“两阶段”策略: - **阶段一:后台烧录** 将新固件写入 CPLD 外挂/片上 Flash,不立即切换运行镜像,业务侧通常无感知。 - **阶段二:择机生效** 在业务低峰、计划维护窗或受控重启时执行加载生效。必要时先锁定输出,再完成固件加载与复位,最后释放输出。 这种“后台烧录 + 择机生效”模式可显著降低在线升级风险。 ### 6.4 行业实践(简要) - **openUBMC 场景**:支持 VME 相关升级能力,并可通过 API 形式对接上层管理系统 - **主流服务器平台**:普遍采用 “BMC + JTAG + VME/HPM” 的 CPLD 升级技术路线 - **平台差异**:早期平台可能采用 I2C 流程,现有主流多收敛到 JTAG 方案 ### 6.5 常见风险点(服务器场景) - **文件兼容性**:不同 BMC 版本/硬件平台对 VME 支持可能存在差异 - **升级中断**:升级过程掉电或链路中断可能导致器件状态异常 - **方案代际差异**:老平台与新平台在链路和生效策略上可能不同,需按平台文档确认 ### 6.6 与当前项目实现的流程映射 结合当前项目(`general_hardware`)实现,VME 升级可映射为以下工程步骤: 1. 解析升级包(`update.cfg` + 固件包)并匹配目标组件(`uid/system_id`) 2. 根据配置确定 `file_type=vme`,选择对应 `cpld*.vme` 文件 3. 切换固件路由(firmware route),必要时使能 bypass 并选中目标 chip 4. 获取芯片锁(带重试和超时)后执行升级写入 5. 升级成功后保存 `valid*.vme` / `bypass*.vme` 供后续生效 6. 解锁并恢复默认路由,进入生效或校验阶段 说明:升级写入阶段本质是将文件描述信息(文件类型、路径、长度等)按约定结构打包并传给底层接口执行;成功后进入 `valid/bypass` 生效链路。 ## 7. 总结 VME 在本项目中是 CPLD 升级链路的核心输入格式,重点价值在于面向嵌入式执行场景的效率优化。 从工程落地看,应同时关注格式理解(SVF 关系、指令与结构)与流程闭环(打包、执行、生效、回归校验),以确保升级过程稳定可控。 --- # openUBMC Studio CLI (bingo) > URL: https://openubmc.cn/docs/zh/latest/common_tools/bingo/cli_tool.html > Language: zh openUBMC Studio CLI (bingo) 是BMC Studio的CLI命令行,常用于组件构建、产品构建等命令执行。本文档介绍bingo的具体使用方式。 # 构建产品包与发布包 我们构建命令目前已经集成到`bingo`命令中,这个命令在环境中已安装,只需要执行命令即可,我们先来看下`bingo`的帮助文档,这个帮助文档会在`manifest`仓路径(也就是产品路径)和组件仓路径显示不同,此节只讨论产品构建。 ```shell # 在manifest路径下执行命令 [04:51:58 root(1110):/home/workspace/codehome/manifest]# bingo --help >> whoami root conan版本: 2.23.0 Integrated commands build 构建出包 publish 构建版本发布包,-sc参数指定ToSupportE编码 Misc commands help 获取命令帮助 new 创建组件 diff 获取两个产品版本间, 组件版本变更时的合并记录 fetch 基于参数指定的单个、部分、全量组件版本拉取源代码 config bingo参数配置 upgrade 升级 bingo 版本 analysis 依赖和接口分析 json_check json 文件检查 hpm_signer HPM 文件重签名 Studio commands studio 执行bmc studio启动停止操作 check BMC Studio语法正确性与模型一致性检查 输入 "bingo -h" 获取子命令帮助 [04:52:01 root(1110):/home/workspace/codehome/manifest]# ``` 从上面返回的日志,可以看到我们能够使用的命令,构建产品以及发布包只使用到其中一个命令,当前`build`命令与`publish`效果相同,其余命令后续自行深入学习,输入`build`的`help`命令,可以看到这个命令有很多的内容,部分版本有些命令没有,但是可以构建出`hpm`包,对出包没有影响 ```shell [04:52:01 root(1110):/home/workspace/codehome/manifest]# bingo build --help >> whoami root conan版本: 2.23.0 usage: bingo [-h] [-b BOARD_NAME] [-bt BUILD_TYPE] [--stage STAGE] [--verbose] [-ucc] [-r REMOTE] [-sc SUPPORTE_CODE] [-v VERSION] [-t TARGET] [--deploy] 构建openUBMC options: -h, --help show this help message and exit -b BOARD_NAME, --board_name BOARD_NAME 单板包,可选值为build/product//下的目录名 默认:openUBMC 支持的单板列表: openUBMC -bt BUILD_TYPE, --build_type BUILD_TYPE 构建类型,可选:debug(调试包), release(正式包) --stage STAGE 包类型,可选值为: dev(调试包), rc(预发布包), stable(发布包) 默认:dev --verbose 使能conan构建详细日志打印 -ucc, --update_conan_cache 全量更新本地conan缓存 -r REMOTE, --remote REMOTE conan仓别名,请检查conan remote list查看已配置的conan仓 -sc SUPPORTE_CODE, --supporte_code SUPPORTE_CODE 待发布的SupportE编码,可选值参考单板manifest.yml/tosupporte 默认:default -v VERSION, --version VERSION 构建版本号,不指定时从manifest.yml读取 -t TARGET, --target TARGET 构建目标,请查看build/target目录, 支持的目标: install_sdk publish personal app --deploy 将hpm包部署至bmc设备 ``` ## 构建产品包 1. 构建`hpm`包 现在,开始构建一个`hpm`包,查看上面的`help`文档,可分析其具体含义,命令执行结束后,可在`manifest`目录下的`output`目录下找到构建出来的`hpm`包 ```shell # 进入到集成构建环境 cd manifest # -t personal: 构建目标,个人构建指 hpm 包 # -b openUBMC: 单板名,执行bingo build -h,可以看到支持哪些单板 # -bt release: 构建类型,release正式包 # --stage rc: 包类型,预发布包 bingo build -t personal -b openUBMC -bt release --stage rc ``` 以下为列出的生成件目录下文件,其中`rootfs_openUBMC.hpm`即为产品包 ```shell [05:22:48 root(1110):/home/workspace/codehome/manifest/output]# ls -l total 70172 -rw-r--r-- 1 root root 1349 Mar 12 17:22 openubmc.perf -rw-r--r-- 1 root root 54813 Mar 12 17:22 package.lock drwxr-xr-x 5 root root 4096 Mar 7 14:32 packet -rw-r--r-- 1 root root 0 Mar 12 17:20 prof.perf.lock -rw-r--r-- 2 root root 70144173 Mar 12 17:22 rootfs_openUBMC.hpm [05:23:04 root(1110):/home/workspace/codehome/manifest/output]# ``` 2. 集成发布的组件 根据章节的流程,已经了解了组件的发布,组件发布以后,我们需要集成到产品包中,具体修改方法如下 * 第一步: 构建组件发布版本 在流程中,已经有组件的构建方法与发布方法,如果不清楚,请查看[组件构建与发布](../../build_upgrade/build/build_guide/build_process.md) * 第二步: 在`subsys`目录下配置发布的组件版本 我们需要在`subsys`目录下添加新增的组件,当前组件发布只有`stable`版本,但仍需在`rc`和 `stable`目录下同时更改,这里的示例为`rc`版本,`stable`版本的修改同样如此 ```yaml # yaml-language-server: $schema=../../schema/subsys.rc.schema.json dependencies: - conan: "rackmount/1.90.198@openubmc/stable" ``` * 第三步: 在`manifest.yml`文件中配置添加的组件 新引入的组件,要在产品目录下配置相应的依赖,否则不会集成到产品包当中,`dependencies`字段中,每配置一个组件,则集成进一个组件,这里不要去填版本号,填入版本号后,更新组件版本时,则需要变更多个文件 ```yaml dependencies: - conan: "huawei_secure_c" - conan: "kmc" - conan: "Signature_Verify_CBB_Library" - conan: "sqlite3" - conan: "openssh" ``` * 第四步: 构建产品包 使用第1小节的构建命令,则可以构建出产品包`hpm` ## 构建发布包 构建发布包命令与上面的命令稍有差异,如下所示 ```shell # 进入到集成构建环境 cd manifest # -t publish: 构建目标,发布包 # -sc default: 发布包编码,这个编码可以在manifest.yml文件中的 tosupporte 字段中查询 # -b openUBMC: 单板名,查看帮助文档,可以看到支持哪些单板 # -bt release: 构建类型,release正式包 # --stage stable: 包类型,发布包 bingo build -t publish -sc default -b openUBMC -bt release --stage stable ``` 执行完成以后,在`output`目录下会生成文件,如下为`output`树 ```shell [07:05:30 root(1110):/home/workspace/codehome/manifest/output]# tree . |-- openUBMC.perf |-- package.lock |-- packet | |-- openUBMC | | |-- openUBMC-CMT_1.00.00.00.zip | `-- inner | |-- release | | |-- package_openUBMC.lock |-- prof.perf.lock `-- rootfs_openUBMC.hpm 4 directories, 6 files [07:05:31 root(1110):/home/workspace/codehome/manifest/output]# ``` --- # 组件构建与发布 在构建组件时,我们需要切换到组件目录,执行`bingo`命令,否则`bingo`命令不生效,这里以组件`iam`组件来作为示例,演示组件的构建流程。 进入到`iam`的源码目录,执行如下命令来查看支持的构建参数 ```shell [07:16:31 root(1110):/home/workspace/codehome/iam]# bingo --help >> whoami root conan版本: 2.13.0 Component commands build 构建出包 deploy 将组件及其依赖部署至temp/rootfs目录 test 构建DT. gen 代码自动生成,支持Lua和C语言,C组件需要在service.json中添加`"language": "c",`配置. git_history 获取指定开始时间与结束时间之间提交信息,并生成release note Misc commands help 获取命令帮助 new 创建组件 config bingo参数配置 upgrade 升级 bingo 版本 analysis 依赖和接口分析 json_check json 文件检查 hpm_signer HPM 文件重签名 Studio commands studio 执行bmc studio启动停止操作 check BMC Studio语法正确性与模型一致性检查 输入 "bingo -h" 获取子命令帮助 [07:16:33 root(1110):/home/workspace/codehome/iam]# ``` 在上面返回的结果中,我们只使用到部分,`build`,`gen`为主要使用的命令,下面主要介绍这两条命令 ## 代码自动生成 `gen`命令用来自动生成代码,现在组件的代码都是使用此工具来自动生成,自动生成后才能进行构建,所以这里先讲`gen`命令,查看`gen`命令的help菜单 ```shell [07:28:19 root(1110):/home/workspace/codehome/iam]# bingo gen --help >> whoami root conan版本: 2.13.0 usage: bingo gen/当前只支持C和lua语言代码生成 [-h] [-v VERSION] [-r REMOTE] [-s SERVICE_FILE] [-w] 代码自动生成. options: -h, --help show this help message and exit -v VERSION, --version VERSION use specified version -r REMOTE, --remote REMOTE conan remote, 如不设置则默认读取本地conan配置 -s SERVICE_FILE, --service_file SERVICE_FILE Service file -w, --with_template generate with template [07:33:21 root(1110):/home/workspace/codehome/iam]# ``` 从返回结果,可以看到这个参数结构相对比较简单,建立好模板文件,使用如下命令即可生成代码 ```shell # -bt debug: 构建类型 # --stage rc: 预发布包 # 如果在mds目录下配置了model.json,则带上-w参数来进行模板生成 bingo gen -bt debug --stage rc # 日志截取,没有发生报错,则表示自动生成成功 python3 /home/workspace/codehome/iam/temp/lua_codegen/script/template.py -d /home/workspace/codehome/iam/proto -j /home/workspace/codehome/iam/temp/lua_codegen/temp/iam/ -n iam -i /home/workspace/codehome/iam/temp/lua_codegen/temp/iam/db_json.json -f /home/workspace/codehome/iam/temp/lua_codegen/script/lua_format.py -t orm_classes.lua.mako -o /home/workspace/codehome/iam/gen/iam/orm_classes.lua make[3]: Leaving directory '/home/workspace/codehome/iam/temp/lua_codegen/templates/apps' make[2]: Leaving directory '/home/workspace/codehome/iam/temp/lua_codegen/templates' make[1]: Leaving directory '/home/workspace/codehome/iam/temp/lua_codegen' ``` ## 组件构建 `build`命令用来构建组件的版本包,使用`help`命令来看下`build`命令的帮助文档 ```shell [07:16:33 root(1110):/home/workspace/codehome/iam]# bingo build --help >> whoami root conan版本: 2.13.0 usage: bingo build [-h] [-bt BUILD_TYPE] [--stage STAGE] [-u] [-r REMOTE] [--conan2] [-nc] [-o OPTIONS] [--user USER] [-wb] Build conan options: -h, --help show this help message and exit -bt BUILD_TYPE, --build_type BUILD_TYPE 构建类型,可选:debug, release 默认:debug --stage STAGE 组件包发布阶段, 可选: ['dev', 'pre', 'rc', 'stable'] 默认:dev -u, --upload 上传组件包到conan仓 -r REMOTE, --remote REMOTE conan仓别名,请检查conan remote list查看已配置的conan仓 --conan2 强制使用conan2构建组件,此参数仅用于临时兼容组件conan1和conan2构建场景 -nc, --no_cache 不使用~/.conan/data目录下的缓存包(构建前删除缓存) -o OPTIONS, --options OPTIONS Define options values (host machine), e.g.: -o Pkg/*:with_qt=True --user USER 指定conan包的user字段,未指定时依次尝试读取mds/service.json的user字段,都未指定时使用'openubmc' -wb, --without_build 不强制源码构建组件自身 [07:20:03 root(1110):/home/workspace/codehome/iam]# ``` 根据上面的返回结果,需要使用的参数只有其中几个,以具体实例来讲解 ```shell # -b Board_A: 指定单板名,某些组件和单板名挂钩,需要指定单板名来打入某些文件,如果组件和单板无关,不带此参数 # -bt debug: 构建类型,调试包 # --stage rc: 预发布包 bingo build -b Board_A -bt debug --stage rc # 截取部分日志放在这里 Downloading conanmanifest.txt completed [17.89k] Downloading conaninfo.txt completed [2.97k] Downloading conan_package.tgz completed [543.98k] Decompressing conan_package.tgz completed [0.00k] iam/1.20.31@openUBMC.release/rc: Package installed cb9794cb17b2f104bdddb1803a0104b29d12d75c iam/1.20.31@openUBMC.release/rc: Downloaded package revision 35401b8fc57f5024055b6203bbd5abfe Build successfully [07:28:19 root(1110):/home/workspace/codehome/iam]# ``` 在Build successfully上方,能看到编译完成的版本号,这个版本号就是生成的组件版本 ## 组件测试 `test`命令用来执行组件的集成测试,单元测试,压力测试,使用`help`命令来看下`test`命令的帮助文档 ```shell [07:25:33 root(1110):/home/workspace/codehome/iam]# bingo test --help >> whoami root conan版本: 2.13.0 usage: bingo [-h] [-bt BUILD_TYPE] [--stage STAGE] [-r REMOTE] [--conan2] [-s] [-nc] [-o OPTIONS] [--user USER] [-as] [-wb] [-pr PROFILE] [-jit] [-ut] [-it] [-ft] [-fg] [-mt] [-mg] [-lf LOG_FILE] [-cnt FUZZ_COUNT] [-f TEST_FILTER] [-a APP] [--coverage_exclude COVERAGE_EXCLUDE] [--minimum] [--package_info PACKAGE_INFO] Test component options: -h, --help show this help message and exit -bt BUILD_TYPE, --build_type BUILD_TYPE 构建类型,可选:debug, release 默认:debug --stage STAGE 组件包发布阶段, 可选: ['dev', 'pre', 'rc', 'stable'] 默认:dev -r REMOTE, --remote REMOTE conan仓别名,请检查conan remote list查看已配置的conan仓 --conan2 强制使用conan2构建组件,此参数仅用于临时兼容组件conan1和conan2构建场景 -s, --from_source Build from source, include dependency component -nc, --no_cache 不使用~/.conan/data目录下的缓存包(构建前删除缓存) -o OPTIONS, --options OPTIONS Define options values (host machine), e.g.: -o Pkg/*:with_qt=True --user USER 指定conan包的user字段,未指定时依次尝试读取mds/service.json的user字段,都未指定时使用'openubmc' -as, --asan Enable address sanitizer -wb, --without_build 不强制源码构建组件自身 -pr PROFILE, --profile PROFILE 显式指定conan构建使用的profile文件 (~/.conan/profiles目录下)别名, 默认为: 空 可选值: profile.ini, profile.dt.ini, profile.luajit.ini, armv8_release, default -jit, --enable_luajit Enable luajit -ut, --unit_test Enable unit test -it, --integration_test Enable integration test -ft, --fuzz_test Enable fuzz test -fg, --fuzz_gen Generate fuzz case -mt, --mock_test Enable mock test -mg, --mock_gen Generate mock case -lf LOG_FILE, --log_file LOG_FILE Monitor log file directory path -cnt FUZZ_COUNT, --fuzz_count FUZZ_COUNT Fuzz count -f TEST_FILTER, --test_filter TEST_FILTER Run unit test with a filter -a APP, --app APP App in hica --coverage_exclude COVERAGE_EXCLUDE Specify coverage exclude file path of whitelist --minimum, -m 获取dt构建的最小版本 --package_info PACKAGE_INFO, -pi PACKAGE_INFO package_info 文件路径, 使用manifest配套版本dt构建, 此文件在manifest构建时会在inner目录生成 ``` 从返回结果,可以看到这个参数结构相对比较简单,使用如下命令即可执行组件测试 ```shell # 集成测试 bingo test -it # 单元测试 bingo test -ut # 日志截取,没有发生报错,则表示测试通过 ================ 开发者测试开始 ================ ================ 测试 bmc_time 开始 ================ 1..1 # Started on Thu Dec 12 10:24:16 2024 # Starting class: TestTimeCfg ok 1 TestTimeCfg.test_time_intf # Ran 1 tests in 0.005 seconds, 1 success, 0 failures Dt 报告结果输出到 /root/bmc_time/temp/coverage/dt_result.json ================================ 构建菜单 ================================ 单元测试(ut): True 集成测试(it): False 自动测试(rt): False 覆盖率: False 地址消毒: False ============================================================================ ===>>>> 测试: bmc_time/1.60.1@openubmc.dev/dev 完成 ``` --- # openUBMC Studio常见问题 > URL: https://openubmc.cn/docs/zh/latest/common_tools/bmc_studio/bmc_studio.html > Language: zh # 2026版本openUBMC Studio FAQ ## Q1:登录到社区时提示无法识别OS keyring,登录保持功能无法正常生效 **问题现象:** 登录到社区时,右下角弹窗提示`An OS keyring couldn't be identified for storing the encryption related data in your current desktop environment.`,登录保持功能无法正常生效,开启新页面或重启openUBMC Studio时仍为未登录状态 **问题原因:** 该问题可能与主机的凭证管理服务无法正常工作有关,请确认当前使用的主机是否支持凭证管理 首先确保Windows凭据管理器服务正在运行: 1. 按下`Win + R`,输入`services.msc`并回车。 2. 在服务列表中找到`Credential Manager`(凭据管理器),确保其状态为“正在运行”,启动类型建议为“手动”或“自动”。 3. 如果服务未运行,右键单击选择“启动”。 如果服务是启动的,则有可能当前主机没有权限管理凭证,请确认是否能够管理凭据: 1. 打开“控制面板”>“用户账户”>“凭据管理器”>“Windows 凭据”。 2. 确认是否能够正常打开,少数场景下,打开会报错,此时当前用户无权限管理凭据,请尝试提升用户权限 --- # 2025版本BMC Studio FAQ ## Q1:通过apt源安装仓颉工具链时,执行apt install cangjie-runtime命令报错trying to overwrite '/usr/share/bmc_studio/server/libsecurec.so', which is also in package bmc-studio 1.1.95.250628 **问题现象:**运行`apt install cangjie-runtime`安装仓颉工具链时报错,报错信息如下 ```bash dpkg: error processing archive /var/cache/apt/archives/cangjie-runtime_1.0.0_amd64.deb (--unpack): trying to overwrite '/usr/share/bmc_studio/server/libsecurec.so', which is also in package bmc-studio 1.1.95.250628 Errors were encountered during processing: /var/cache/apt/archives/cangjie-runtime_1.0.0_amd64.deb E: Sub-process /usr/bin/dpkg returned an error code (1) ``` ![安装仓颉失败](../images/bmc_studio/bmc_studio/install_cangjie_failed.png) **可能原因:**安装仓颉工具时,旧版本 BMC Studio (1.1.95.250628版本)未卸载。 **处理建议:**请先运行代码 ```bash apt update apt install bmc-studio ``` 安装最新BMC Studio,然后再执行 ```bash apt install cangjie-runtime ``` ## Q2:安装完成后,运行提示error while loading shared libraries: libcangjie-std-ast\.so: cannot open shared object file: No such file or directory **问题现象:**安装完成后,提示 error while loading shared libraries: libcangjie-std-ast\.so: cannot open shared object file: No such file or directory ![缺少仓颉依赖](../images/bmc_studio/bmc_studio/missing_cangjie_dependency.png) **可能原因:**未安装 cangjie-runtime **处理建议:**参考[安装方式3](./installation_guide/bmc_studio_installation.md)配置 apt 源,然后在命令行输入命令: ```bash apt install cangjie-runtime ``` 然后重新启动 BMC Studio 即可。 ## Q3:安装完成后,使用`bingo studio`命令无法正常拉起BMC Studio窗口 **问题现象1:**安装完成后,使用`bingo studio`命令,但是没有界面被唤起。 **可能原因1:**您使用的 linux 环境并非 wsl **处理建议:**非 wsl 环境需要手动输入地址打开。 在 windows 中的 web 浏览器中(edge、Internet Explorer、chrome 任意均可)输入图中所示位置的地址,即可打开 BMC Studio 前端页面。 ![手动拉起BMC Studio web窗口](../images/bmc_studio/bmc_studio/manually_start_bmc_studio_web.png) **问题现象2:**日志无异常,有浏览器窗口被打开,但窗口白屏,一段时间后显示无连接。 **可能原因2:**您曾经在配置过 netsh 转发规则 **处理建议:**打开管理员权限的 powershell ,输入命令 ```bash netsh interface portproxy show all ``` 如果发现有您的端口号相关的设置,请清除它。 ```powershell netsh interface portproxy delete v4tov4 listenport=10000 listenaddress=x.x.x.x ``` 请自行替换命令中的listenaddresss **问题现象3:**现象同问题现象2,但`netsh interface portproxy show all`没有发现回显 **可能原因3:**有进程在占用您的端口号 **处理建议:** ```bash # 在wsl终端里输入以下命令查找是否有进程在占用10000端口 sudo netstat -tlnp | grep :10000 # 如果发现占用进程,结束它 sudo kill -9 ``` 请自行替换命令中的端口号和 pid 此外,windows 端中也有可能有进程占用 10000 端口。 您可以使用命令: ```powershell netstat -ano | findstr :10000 ``` 如果看到如下回显: ![查找占用端口windows进程](../images/bmc_studio/bmc_studio/find_windows_port_process.png) 请在任务管理器中使用回显中最后的数字查找该进程,如果您认识且认为不重要,您可以在任务管理器中右键点击这个进程并点击"结束进程" ![任务管理器](../images/bmc_studio/bmc_studio/task_manager.png) 如果该应用对您很重要,可以修改我们的脚本,将/usr/share/bmc_studio/load_nginx.sh中的第46行从 ```bash FRONTEND_PORT=$((10000 + USER_ID % 10000)) ``` 修改为 ```bash FRONTEND_PORT=$((10001 + USER_ID % 10000)) ``` **问题现象4:**日志报错"Failed to auto-open in WSL" **可能原因4:**您在 `/etc/wsl.conf` 这个文件中配置了 `default=root` ,wslu 的 bug 会将这个配置误识别为 windows 挂载点配置,导致无法获取到正确的 windows 目录地址。 **处理建议:**打开文件 `/usr/bin/wslview`,删除114~119行内容: ```bash if [ -f /etc/wsl.conf ]; then tmp="$(awk -F '=' '/root/ {print $2}' /etc/wsl.conf | awk '{$1=$1;print}')" [ "$tmp" == "" ] || win_location="$tmp" [[ "$win_location" =~ ^.*/$ ]] || win_location="$win_location/" # make sure it always end with slash unset tmp fi ``` 删除完成后,重新打开 BMC Studio 。 ## Q4:BMC Studio 上传文件/文件夹报错 fail to post /studio-tool/csr/folder **问题现象:** 在 csr 页面选择导入代码仓或导入单个 csr 报错,信息为 ```bash fail to post /studio-tool/csr/folder ``` **可能原因:** 您的系统磁盘剩余空间不足 **处理建议:** 清理您的系统,获得更多的磁盘剩余空间。 ## Q5:BMC Studio 一键仓库部署超时 **问题现象:** 使用 manifest 创建完工作空间后,按照文档流程在仓库管理页面点击一键仓库部署,然而超时失败 **可能原因:** 您没有登录 conan 账号 **处理建议:** 在命令行输入命令 ```bash conan remote login openubmc_dev 您的账号 -p 您的密码 ``` 登录 conan 账号后,重新一键仓库部署即可。 ## Q6:BMC Studio 的 QEMU 在线调试过程中,资源协作接口获取不全 **问题现象:** 拉起 QEMU 后,使用 BMC Studio 连接上 QEMU ,点开在线调试的资源协作接口窗口后,接口显示很少。 **可能原因:** QEMU 性能较慢,获取全量接口需要时间。 **处理建议:** 请耐心等待,并通过刷新按钮查看新增接口。 ## Q7:BMC Studio 连接真机后,无法进行在线调试 **问题现象:** BMC Studio 连接真机后,无法进行在线调试。 **可能原因:** BMC Studio 的在线调试能力尚未支持真机,存在破坏环境的风险,目前暂时仅支持基于 QEMU 的调试。 **处理建议:** 建议使用 QEMU 进行替代。QEMU 每次启动都会重置,调试导致环境出现问题后只需要重启 QEMU 即可。 ## Q8:无法使用插件进行调试文件 **问题现象:** 使用 VsCode 修改文件后,无法进行调试或右上角没有调试图标 **可能原因:** 不是所有文件都支持调试,支持的文件主要是 `/opt/bmc/apps/` 组件名路径下的 lua 文件、北向接口配置文件以及 `/opt/bmc/sr` 路径下的内置CSR文件。且 mdb_interface 这种模型定义仓暂时也不支持直接通过 VsCode 调试。 **处理建议:** 使用出整包的方式调试。 ## Q9:运行 BMC Studio 时闪退 **问题现象:** 运行 BMC Studio 时闪退,报错信息为 ```bash xxxxxx E Thread "bmc_studio_serv" catched unhandled SIGILL /(Illegal instruction) from managed frame. signal pc: 0xxxxxxxxxxxxx /usr/share/bmc_studio/bmc_studio.sh: line 96: xxxxxx Segmentation fault ./bmc_studio_server "$1" Failed to start foreground service ``` **可能原因:** BMC Studio 使用仓颉语言开发,目前仓颉语言依赖 avx2 指令集。您使用的电脑 CPU 可能不支持 avx2 指令集。可以通过在 linux 命令行中执行命令 ```bash lscpu | grep avx2 ``` 来进行判断。如果没有出现结果,那么您的 cpu 可能就不支持 avx2 指令集。 **解决方案:** 如果您的 cpu 不支持 avx2 指令集,可能暂时无法使用 BMC Studio。请期待未来仓颉更新后解除对 avx2 指令集的依赖。 ## Q10:运行 BMC Studio 的终端被关闭了,如何查看日志? **问题现象:** 在命令行唤起 BMC Studio 后,终端被误关闭,导致没法看日志。 **解决方案:** BMC Studio 的日志会保存在 `~/bmc_studio/var/log/debug.log` 中,可以手动打开这个文件进行查看。 --- # openUBMC Studio 安装指南 > URL: https://openubmc.cn/docs/zh/latest/common_tools/bmc_studio/installation_guide/bmc_studio_installation.html > Language: zh # openUBMC Studio 开发平台 openUBMC Studio 是 openUBMC 社区推出的集成化开发平台,专为 BMC 固件开发打造,提供代码编辑、项目构建、设备仿真、自动化检查等一站式开发体验。**推荐**所有开发者安装使用;首次体验时,可以暂不安装。 本文档主要介绍 openUBMC Studio 的环境搭建以及安装指导。 openUBMC Studio可以通过[openUBMC应用市场](https://www.openubmc.cn/marketplace)获取 # 安装openUBMC Studio ## 下载安装包 1. 访问openUBMC Studio下载链接 2. 下载安装包到本地 > **说明**:
> 建议从官方渠道下载安装包,以确保软件的安全性和完整性。 ## 执行安装程序 1. 双击打开下载的exe安装包 2. 根据安装向导提示进行操作: - 同意许可协议 - 选择是否从vscode迁移插件(如果之前安装过VSCode,可选择迁移已有插件) 3. 点击“安装”按钮,等待安装完成 4. 安装完成后,点击"完成"退出安装向导 ![安装完成界面](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_finish_install.png) > **说明**:
> 安装过程中如果遇到杀毒软件拦截,请选择允许或添加到信任列表。 ## 环境初始化配置 首次启动 openUBMC Studio 时,需要完成社区登录、BMC 开发环境部署和规则集配置。您可以使用 AI Agent 按当前环境状态自动引导,也可以按照引导页面手动完成配置。 ### 使用 AI 引导初始化 如果已安装并能正常使用 AI Agent(例如 opencode、Claude Code 或 Cursor),建议使用 AI 引导完成初始化: 1. 启动 openUBMC Studio,在欢迎页面中单击“配置引导”。 2. 在配置引导窗口中找到“AI 引导初始化”卡片。 ![AI 引导初始化卡片](../../images/bmc_studio/installation_guide/bmc_studio_installation/ai_env_init_wizard.png) 3. 单击“复制指令”,再单击“复制到 AI Agent”。 4. 将复制的 Prompt 粘贴到 AI Agent 并发送。AI Agent 会查询当前配置进度,依次引导完成 GitCode 登录认证、开发环境部署和规则集配置;已经完成的步骤会自动跳过。 5. AI Agent 执行完成后,确认配置引导窗口显示初始化已完成,并检查状态栏中的登录状态、机型和规则集信息。 初始化中断后,可以重新发送 Prompt 继续执行。完整操作和问题排查请参见[AI 引导环境初始化](#使用-ai-引导初始化)。 ### 手动完成初始化配置 如果暂不使用 AI Agent,可以按照以下步骤手动完成初始化: 1. 首次启动openUBMC Studio,界面将显示初始化引导页面。 2. 根据引导页面的提示,逐步完成以下配置。 ![引导页面](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_guide.png) - 登录到社区 1. 点击IDE右下角状态栏中的登录图标 2. 在弹出的登录页面中输入您的openUBMC社区账号和密码 3. 点击“登录”按钮完成登录 ![登录到社区](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_login.png) - 配置BMC开发环境 1. 关闭新功能展示页面 ![新功能展示页面](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_feature_panel.png) 2. 根据[环境准备](../../../getting_started/quick_start/env_introduction.md)配置环境 - 配置conan 在 Linux 中运行 manifest 仓库中的初始化脚本 `init.py`,脚本会自动完成配置。 如果在 Windows 中,则需前往 [Conan 官方下载页面](https://conan.org.cn/downloads)下载安装包,手动安装 Conan 后通过 openUBMC Studio 登录到社区。 ![登录到社区](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_login2.png) - 配置检查规则集 点击Web版Studio状态栏中的"未选择机型"按钮,按以下步骤操作: 1. 在模型配置页面中,选择对应的产品和规则集。 ![模型配置步骤1](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_model_config_step1.png) 2. 确认产品信息后,选择需要配置的模型文件。 ![模型配置步骤2](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_model_config_step2.png) 3. 配置模型文件对应的代码仓和分支信息。 ![模型配置步骤3](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_model_config_step3.png) 4. 完成配置后,点击"确定"保存配置。模型配置完成后,规则检查、拓扑配置等功能即可正常使用。 ![模型配置步骤4](../../images/bmc_studio/installation_guide/bmc_studio_installation/studio_model_config_step4.png) 3. 点击“完成”按钮,完成初始化配置。 > **说明**:
> 初始化配置完成后,如果完成过一次完整配置则不再弹出,可随时通过欢迎页面重新触发。
> 环境初始化完成后,一般不需要频繁配置。 --- # openUBMC Studio适配指南 > URL: https://openubmc.cn/docs/zh/latest/common_tools/bmc_studio/user_guide/bmc_studio_adapt_guide.html > Language: zh openUBMC 采用组件化架构,需与板卡、传感器、电源、RAID/GPU/NPU 网卡等部件完成适配后方能在产品中落地。openUBMC Studio 适配指南包括板卡适配与部件驱动适配,介绍如何借助 Studio 的可视化拓扑配置、参数配置等能力,以拖拽替代手工编写配置文件,降低适配门槛、减少出错概率,帮助开发者快速交付可运行的 BMC 固件。 [**openUBMC Studio整机适配指南**](../../../hardware/system_adapt/quick_start/board_integration_guide.md) 介绍如何使用 BMC Studio 的可视化能力完成板卡 CSR 拓扑配置与器件参数适配。 --- # openUBMC Studio 用户指南 > URL: https://openubmc.cn/docs/zh/latest/common_tools/bmc_studio/user_guide/bmc_studio_tool.html > Language: zh # 一、简介 openUBMC Studio 是一款基于 Code - OSS 的 openUBMC 集成开发环境,面向 openUBMC 开发、调试和构建场景。 ## 最近版本新增功能 下表按发布时间倒序汇总 openUBMC Studio 最近三个版本的新增功能,单击功能名称可跳转到对应章节。当前收录 2026 年 8 月和 9 月发布的版本;后续发布新版本时,仅保留最近三个版本。 | 版本 | 新增功能 | | --- | --- | | **2.1.1(2026 年 9 月 1 日)** | [AI 引导环境初始化](#ai-env-init):通过预置 Prompt 引导 AI Agent 完成 GitCode 登录、开发环境部署和规则集配置。
[CSR 拓扑插件 0.3.7](#bmc-csr-topo):提供本地、日志和远程三种整机拓扑模式,支持总线异常检测、单板卡配置、日志包离线还原和真机在位调试。
[事件管理](#event-management):可视化管理事件字典、描述模板和 CSR 事件绑定,并导出事件字典及机型支持清单。
[日志诊断、Agent 日志体检与告警链条分析](#log-diagnosis):导入 BMC 一键日志压缩包或 dump 目录,结合本地证据和 openUBMC RAG 生成问题清单、导出 PDF 报告,并分析指定告警的触发链条。
[C/C++、Lua 与北向接口快速调试](#quick-debug):根据组件 Git 变更生成调试计划,直接部署 Lua 和运行时配置,按需构建 C/C++ 与生成型北向配置,并完成服务重启、结果校验和环境恢复。
[BMC 远程 GDB 调试](#remote-gdb-debug):支持附加板端 systemd 服务,或部署并启动独立程序进行源码级调试。
[出包签名配置](#sign-config):可视化管理 HPM 和 EEPROM 签名档案,生成本地自签名证书并吊销签名者证书。 | | **2026 年 8 月 1 日版本** | [BMC 环境管理插件](#bmc-env-management):集中管理多台 BMC,支持连接与分组、命令宏、SFTP/HPM 升级、日志监控和 MCP 工具。
[白牌包定制](#white-brand):可视化定制 Web 风格、Logo、图片和产品信息,并构建白牌包或清白牌包。
[Manifest 配置与一键出包](#manifest-package):可视化编辑 `manifest.yml` 出包配置,并按机型和包型构建固件包。
[组件与固件联合构建](#joint-build):从业务组件仓构建本地组件包,在隔离 Manifest 中验证选包并转入固件出包。 | ## 主要特性 openUBMC Studio 的主要特性包括: - **智能代码辅助**:提供代码跳转、定义预览和引用查找等功能。 - **实时错误检查**:基于规则集检测代码错误和潜在问题。 - **表达式计算器**:支持 CSR 表达式的编写、调试和批量测试。 - **SMC 命令字配置**:提供可视化的 SMC 命令字解析和配置工具。 - **模型配置**:支持产品和规则集的选择与配置。 - **CSR 拓扑可视化与调试**:支持本地、日志和远程三种整机拓扑模式,提供总线异常检测、单板卡配置、日志包离线还原和真机在位调试。 - **事件管理**:支持查看和编辑事件字典、描述模板及 CSR 事件绑定。 - **能效调速配置**:支持通过 Excel 导入热设计表格并生成 CSR 调速曲线代码。 - **Manifest 可视化配置**:支持配置构建变体、组件依赖、默认特性和组件特性,并提供配置诊断。 - **组件与固件联合构建**:支持从业务组件仓构建本地组件包,在隔离 Manifest 中验证选包并转入固件出包。 - **一键出包**:支持选择机型和包型,完成出包预检、固件构建、日志查看和产物下载。 - **签名配置**:支持管理 HPM 和 EEPROM 签名档案,并生成或吊销本地自签名证书。 - **AI 引导环境初始化**:支持通过 AI Agent 完成社区开发环境初始化。 - **日志诊断与告警链条分析**:支持导入 BMC 一键日志进行可视化诊断、Agent 日志体检和告警链条分析。 - **C/C++、Lua 与北向接口快速调试**:支持按照 Git 变更规划直接部署或隔离构建,将最小替换集部署到 BMC 并验证结果。 - **BMC 远程 GDB 调试**:支持附加板端服务,或部署独立程序进行源码级调试。 - **BMC 环境管理插件**:集中管理多台 BMC,支持连接与分组、命令宏、SFTP/HPM 升级和日志监控。 - **白牌包定制**:支持可视化定制 Web 风格、Logo、图片和产品信息,并构建白牌包或清白牌包。 - **社区集成**:对接 openUBMC 社区资源和服务。 # 二、AI 引导环境初始化 openUBMC Studio 提供 AI 引导环境初始化能力。将预置 Prompt 发送给 AI Agent(例如 opencode、Claude Code 或 Cursor)后,AI Agent 会检测当前状态、诊断问题,并按顺序引导用户完成社区开发环境初始化。 ## 使用前准备 - 已安装并能正常使用 AI Agent,例如 opencode、Claude Code 或 Cursor。 ## 打开配置引导 1. 在欢迎页面中单击“配置引导”入口。 ![欢迎页面配置引导入口](../../images/bmc_studio/user_guide/bmc_studio_tool/ai_env_init_statusbar.png) 2. 在打开的配置引导窗口中找到“AI 引导初始化”卡片。 ![AI 引导初始化卡片](../../images/bmc_studio/user_guide/bmc_studio_tool/ai_env_init_wizard.png) ## 复制引导指令 1. 单击“复制指令”卡片,打开 Prompt 对话框。 2. 单击“复制到 AI Agent”,将 Prompt 复制到剪贴板。 ![复制 AI 引导 Prompt](../../images/bmc_studio/user_guide/bmc_studio_tool/ai_env_init_prompt.png) 3. 切换到 AI Agent,粘贴并发送 Prompt。 ![AI Agent 执行环境初始化](../../images/bmc_studio/user_guide/bmc_studio_tool/ai_env_init_agent.png) ## 了解 AI 引导流程 AI Agent 接收到 Prompt 后,会按以下流程引导用户完成环境初始化: 1. **GitCode 登录认证**:AI Agent 打开 OAuth 登录窗口,并在用户授权后检测登录状态。 2. **环境检测与部署**:AI Agent 检测操作系统。Windows 用户可以选择 Docker(约 5 分钟)或 WSL(约 30 分钟)部署方式,Linux 用户直接进入环境配置。 3. **规则集配置**:AI Agent 引导用户在 openUBMC Studio 界面中选择机型和规则集,并通过 `localview_get_data_source` 验证配置是否生效。 4. **状态写回**:每个步骤完成后,AI Agent 会回写向导状态;全部步骤完成后,向导状态变为“已完成”。 > [!NOTE]说明:
> AI Agent 在每个步骤开始前会查询当前配置进度,并自动跳过已完成的步骤。初始化中断后,可以重新发送 Prompt 继续执行。 ## 验证初始化结果 1. 确认配置引导窗口显示初始化已完成。 ![环境初始化完成状态](../../images/bmc_studio/user_guide/bmc_studio_tool/ai_env_init_complete.png) 2. 返回欢迎页面,确认状态栏中的登录状态、机型和规则集信息已更新。 ## 常见问题 - **Docker SSH 连接失败**:检查容器内 `sshd` 是否启动、`10022` 端口是否开放,以及密钥认证是否配置正确。 - **Conan 鉴权失败**:检查 GitCode 登录状态是否有效,重新登录后重试。 - **规则集未生效**:在 openUBMC Studio 状态栏中确认是否已选择机型和规则集,必要时重新配置。 # 三、登录到社区 openUBMC Studio提供了便捷的社区登录功能,通过社区登录可以获取更多资源和服务支持。 ## 登录步骤 1. 点击IDE右下角状态栏中的登录图标 2. 在弹出的登录页面中输入您的openUBMC社区账号和密码 3. 点击“登录”按钮完成登录 ![登录到社区](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_login.png) ## 登录状态保持 登录成功后,IDE会自动保持和刷新登录状态: - **自动刷新**:IDE会定期刷新登录状态,确保持续有效 - **状态保持**:退出IDE后,登录状态会继续保持一段时间 - **自动重连**:重新打开IDE时,会自动尝试使用上一次的登录状态重新登录 ## Conan中心仓集成 登录社区后,IDE会自动同步登录到Conan中心仓: - 登录状态自动保持并刷新 - 只要IDE处于登录状态,Conan就处于登录状态 - 在执行出包等操作时不会因为认证问题而超时 > [!NOTE]说明:
> 建议在开始开发工作前先完成社区登录,以确保能够正常访问所有资源和服务。 # 四、openUBMC 远程连接 openUBMC 远程连接插件用于在 openUBMC Studio 中接入远程开发环境。通过该插件,用户可以在 IDE 内管理本地 Docker 镜像并一键连接容器开发环境,也可以直接打开 SSH 远程主机或 WSL 发行版中的目标工作目录,无需在多个工具之间切换。 插件提供以下两类核心能力: | 能力 | 说明 | 典型场景 | | --- | --- | --- | | 管理与连接 Docker 镜像 | 查看本地 Docker 镜像,基于镜像启动、停止、删除容器,并一键连接容器内的开发环境 | 在 Windows 下使用 openUBMC 开发镜像快速搭建开发环境 | | 打开 SSH 或 WSL 目标工作目录 | 通过 SSH 连接远程主机,或打开本机 WSL 发行版中的目录作为工作空间 | 代码位于远程服务器或 WSL 中,需要在 IDE 内直接编辑和调试 | ## 管理与连接 Docker 镜像 1. 在远程连接插件视图中查看本地已有镜像,包括镜像名称、标签、大小等信息。 ![Docker 镜像列表](../../images/bmc_studio/user_guide/bmc_studio_tool/remote_docker_images.png) 2. 通过镜像条目上的操作按钮管理镜像: - **连接到该镜像**:基于选中的镜像创建并启动容器。 - **拉取镜像文件**:将选中的镜像文件拉取到本地用于后续的容器创建与连接。 - **创建容器**:为选中的镜像选取工作目录并以该目录创建容器。 ### 连接容器开发环境 1. 在镜像中点击连接到该镜像,或者找到镜像列表下的已创建容器,选择“连接到容器”。 2. 连接成功后,左下角状态栏显示当前连接的容器名称,后续的编码辅助、构建和调试功能均在该容器内执行。 ![连接容器开发环境](../../images/bmc_studio/user_guide/bmc_studio_tool/remote_docker_connect.png) ## 打开 SSH/WSL 目标工作目录 1. 通过远程连接插件最上方的选项选择SSH Targets或者WSL Targets。 2. 在当前已检测到的WSL目标或已创建的SSH目标中,选择要打开的目标WSL distro或SSH。 3. 选择WSL目录或SSH中的特定文件夹作为目标工作目录打开。 4. 等待连接建立后,WSL/SSH 目录会作为工作空间打开,左下角状态栏显示当前发行版名称。 ![打开 WSL 工作目录](../../images/bmc_studio/user_guide/bmc_studio_tool/remote_open_wsl_folder.png) > [!NOTE]说明:
> 通过 Docker、SSH 或 WSL 方式打开工作空间后,CSR 编码辅助、组件构建、一键出包等功能均可正常使用。组件构建与一键出包要求使用 Linux 本地、WSL 或 SSH Remote 工作空间。 ## 常见问题 - **Docker 连接失败**:确认 Docker 服务已启动,Docker Desktop 处于运行状态。 # 五、CSR 编码辅助 openUBMC Studio提供了强大的CSR编码辅助功能,包括引用跳转、规则检查、表达式计算器和SMC计算器等,帮助开发者快速定位代码、发现问题并提高开发效率。 ## 模型配置 使用CSR编码辅助功能前,需要先完成模型配置。登录IDE后,点击Web版Studio状态栏中的"未选择机型"按钮,按以下步骤操作: 1. 在模型配置页面中,选择对应的产品和规则集。 ![模型配置步骤1](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_model_config_step1.png) 2. 确认产品信息后,选择需要配置的模型文件。 ![模型配置步骤2](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_model_config_step2.png) 3. 配置模型文件对应的代码仓和分支信息。 ![模型配置步骤3](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_model_config_step3.png) 4. 完成配置后,点击"确定"保存配置。模型配置完成后,规则检查、拓扑配置等功能即可正常使用。 ![模型配置步骤4](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_model_config_step4.png) > [!NOTE]说明:
> 模型配置完成后即可使用以下CSR编码辅助功能。后续如需切换产品或规则集,可重新进行模型配置。 ## 引用跳转功能 引用跳转功能可以帮助开发者快速定位代码定义和引用位置,支持多种跳转方式,大幅提高代码阅读和导航效率。 ### 转到定义 1. 在代码编辑器中,将光标定位到需要查看定义的符号上。 2. 使用以下任一方式跳转到定义: - 右键点击符号,选择“转到定义” - 按住 `Ctrl` 键,点击符号 ![转到定义](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_go_to_def.png) 3. 编辑器将自动跳转到符号的定义位置。 ### 转到引用 1. 在代码编辑器中,将光标定位到需要查看引用的符号上。 2. 使用以下任一方式查看引用: - 按下 `Shift + F12` 键 - 右键点击符号,选择“转到引用” ![转到引用](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_go_to_ref.png) 3. 在侧边栏将显示所有引用该符号的位置列表。 4. 点击列表中的项可跳转到对应的引用位置。 ### 鼠标悬停预览定义 1. 在代码编辑器中,将鼠标悬停在符号上。 2. 等待片刻,将显示符号的定义预览窗口。 ![悬停预览](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_hover_def.png) ## 基本规则错误检查功能 openUBMC Studio内置了CSR规则检查功能,模型配置完成后即可支持CSR语法与配置约束的实时检查。该功能支持错误位置高亮和规则自动更新,帮助开发者在编码阶段就发现潜在问题。 ### 实时检查 模型配置后,在openUBMC Studio中打开任意CSR文件,检查自动生效: ![规则检查概览](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_rule_check_overview.png) 页面中的类型错误和格式错误都会被实时拦截: ![类型错误拦截](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_rule_check_type_error.png) 表达式中的语法错误也可以被实时拦截: ![表达式错误拦截](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_rule_check_expr_error.png) ### 查看检查结果 1. 错误和警告会以波浪线形式标注在代码中: - 红色波浪线:表示错误(Error) - 黄色波浪线:表示警告(Warning) ![错误标注](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_error_marks.png) 2. 查看"问题"面板: - 点击底部"问题"标签页 - 查看所有错误和警告列表 - 点击列表项可快速定位到对应代码位置 ![问题面板](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_error_panel.png) ### 复杂规则校验 openUBMC Studio已建立复杂规则校验能力,可以在社区代码仓 [openubmc_dsl_rulepack](https://gitcode.com/openUBMC/openubmc_dsl_rulepack) 中开发业务相关的检查规则,自定义规则同样支持实时检查功能。 ![复杂规则检查](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_rule_check_complex.png) ## 表达式计算器功能 表达式计算器是openUBMC Studio提供的强大工具,用于编写、调试和测试CSR表达式,帮助开发者快速验证表达式的正确性。 ### 打开表达式计算器 1. 打开CSR文件,在表达式上方将显示“计算表达式”按钮 2. 点击“计算表达式”按钮,表达式计算器窗口将在右侧打开 ![打开表达式计算器](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_open_expr_calc.png) ### 表达式计算器界面 表达式计算器界面包含以下部分: - **表达式编辑区**:显示和编辑当前选中的表达式 - **模式切换按钮**:可以在“调试模式”和“用例模式”之间切换 - **变量面板**:显示当前表达式中可用的变量及其值 - **结果面板**:显示表达式计算结果和各级管道的计算过程 ### 修改表达式 1. 在表达式编辑区查看或修改表达式 2. 修改完成后,点击“保存到文件”按钮保存修改 3. 保存后,表达式计算器会自动重新加载表达式 4. 源文件中的表达式修改并保存后,表达式编辑页面也会自动重新加载 ![修改表达式](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_edit_expr.png) ### 调试表达式 1. 在表达式编辑区查看表达式内容 2. 在变量面板中输入或修改变量值 3. 完成输入后,系统将自动计算: - 各级管道的中间结果 - 最终表达式结果 ![表达式计算结果](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_expr_result.png) > [!NOTE]说明:
> 调试功能可以帮助您逐步查看表达式的计算过程,快速定位问题。 ### 表达式批量用例测试 1. 在表达式计算器中, 点击“用例模式”按钮切换到批量测试模式 ![用例模式](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_expr_batch.png) 2. 创建测试用例: - 按照要求输入测试用例名称和参数值以及结果值 3. 执行批量测试: - 点击“加载用例”加载所有测试用例 - 点击“Execute all”执行所有测试用例 - 查看验证报告,显示每个用例的执行结果 ![运行批量测试](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_expr_batch_result.png) > [!NOTE]说明:
> 测试用例可以导出为文件,方便团队共享和版本管理。
> 建议为复杂表达式编写多个测试用例,确保表达式在各种情况下都能正确工作。
## SMC计算器功能 SMC计算器用于解析和配置SMC命令字,帮助开发者快速理解和生成SMC命令,简化SMC相关的开发工作。 ### 打开SMC计算器 1. 打开CSR文件,定位到Scanner或Accessor的offset字段 2. 点击offset字段上方显示的"计算偏移量"按钮 ![打开SMC计算器](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_offset_calc.png) 3. SMC计算器窗口将在右侧打开 ### SMC命令字解析 SMC计算器提供了强大的命令字解析功能: 1. **自动解析**:当前偏移量会被自动解析,显示各字段的含义 2. **实时计算**:修改下方输入框的数据内容将自动更新和计算偏移量 3. **应用到文件**:点击“应用”按钮可以将计算结果写入到CSR文件 4. **字段提示**:鼠标悬停在字段上方可以显示具体的字段含义和说明 ### SMC命令字可视化辅助 openUBMC Studio提供了直观的SMC命令字可视化功能: 1. **水印显示**:SMC命令字将在CSR中以水印形式显示字段内容,方便查看 2. **悬停详情**:鼠标悬停在offset字段上将显示偏移量的详细信息,包括: - 各字段的值 - 字段的含义 - 完整的偏移量计算结果 ![SMC悬停显示](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_smc_hover_view.png) > [!NOTE]说明:
> 可视化辅助功能可以帮助您快速理解复杂的SMC命令字结构,减少配置错误。 # 六、拓扑与 CSR 可视化配置 CSR 拓扑插件提供整机和单板卡两个维度的总线及器件拓扑可视化。0.3.7 版本新增本地、日志和远程三种整机拓扑模式,并支持总线异常检测、日志包离线还原、真机在位调试以及单板卡可视化配置。 ## 创建拓扑配置 1. 单击 openUBMC Studio 左侧的拓扑十字形侧边栏图标。 2. 单击“创建配置”。 ![创建拓扑配置](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_create.png) 3. 单击“添加仓库”,选择 CSR 文件夹,即可在该机型配置中使用来自该文件夹的 CSR。可以添加多个 CSR 代码仓,单击右下角的“确定”即可创建项目。 ![添加仓库](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_add_repo.png) 4. 创建完成后,拓扑起点为 `root.sr`。 ![拓扑起点](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_root.png) ## CSR 整机拓扑 CSR 整机拓扑图提供整机维度与单 CSR 维度的总线及器件拓扑可视化:以板卡为节点展示整机的层级结构、Connector 连接关系与总线连线,支持双击板卡下钻到单板视图、从器件库拖拽器件完成配置。根据数据来源不同,拓扑图分为三种使用模式:**本地模式**、**日志模式**与**远程模式**。 ### 三种模式对比与选择 | 对比项 | 本地模式 | 日志模式 | 远程模式 | |--------|---------|---------|---------| | 数据来源 | 模型配置的本地 CSR 代码仓 | 日志压缩包(`connectors.txt` + `.sr`) | 真机运行时(`mdbctl` + `framework.log`) | | 依赖模型配置 | 是 | 否 | 否 | | 在位状态 | 静态配置,可切换(在位/不在位/天池加载/动态加载) | 收集时刻快照,只读 | 运行时实际值,可切换开关模拟拔插 | | 典型场景 | 日常开发、搭建整机拓扑、板卡适配 | 现场日志离线分析、问题回溯 | 真机调试、在位异常定位 | 根据手头资源选择: - 有整机 CSR 代码仓,需要搭建或修改拓扑配置 → **本地模式**(见下文「本地模式」)。 - 只有现场日志压缩包,需要还原收集时刻的整机拓扑 → **日志模式**(完整指南见[导入 BMC 日志压缩包查看 CSR 拓扑](#bmc-log-import))。 - 有可达真机 BMC,需要查看实时在位或调试板卡加载 → **远程模式**(完整指南见[远程模式连接 BMC 环境](#remote-csr-debug))。 模式切换:日志模式与远程模式均为临时查看模式,重新从侧边栏加载本地拓扑(如切换机型或点击侧边栏文件节点)即恢复本地模式,导入日志产生的临时解压目录会自动清理。 ### 界面说明 拓扑图中的主要元素如下: - **板卡节点**:每个节点代表一块板卡,显示板卡类型、SR 文件名与对应的板型示意图;根节点为 `root.sr`(BMC 主板)。 - **在位状态**:节点左上角显示在位标签或开关,含义与可操作性随模式不同,详见各模式说明。 - **板卡选择器**:本地模式下,尚未确定 SR 的节点提供候选板卡列表与数量选择器,用于配置下游板卡。 - **总线连线与连接桩**:连线表示**上游 Connector 传入的总线**,由上游板卡的连接桩连向下游板卡;总线配置不一致时会出现红色连线或异常标志。 - **单板下钻**:双击整机拓扑页面的任意板卡,或点击左侧 CSR 列表中的文件,即可打开单 CSR 配置页面,查看该板卡 SR 的板内拓扑与详情。 - **工具栏**:配置选择框与「导出配置」按钮用于整机拓扑的多配置管理,仅本地模式可用。 ### 本地模式 本地模式是默认模式,数据来自模型配置的本地 CSR 代码仓,用于日常开发中搭建与修改整机拓扑。 #### 查看整机拓扑 点击侧边栏拓扑插件图标,进入整机拓扑图页面,显示如下: ![拓扑起点](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_overview.png) 1. **总线连线**:板卡之间的连线为上游 Connector 传入的总线,将鼠标悬停在总线上可显示总线名称。 ![总线名称查看](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_bus_hover.png) 2. **总线异常检测**:自动检测上游 Connector 传入总线与下游板卡 Anchor 中定义总线的一致性。 1. 总线类型不匹配 当上游 Connector 的 Buses 和下游板卡 Anchor 的 Buses 同一索引位置的总线类型不一致时,总线显示为红色,将鼠标悬停在图标上可查看具体信息。 总线类型判断逻辑:取总线名称前缀,若前缀相同,则认为类型匹配。 ![总线类型不匹配](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_bus_error_1.png) 2. 上游多传入总线 当上游 Connector 的 Buses 数量大于下游板卡 Anchor 的 Buses 数量时,Connector 的 Buses 数组中多出的总线会被识别为上游多传入总线。板卡左下角会显示红色异常标志,将鼠标悬停在标志上可查看具体信息。 ![总线多传入](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_bus_error_2.png) 3. 下游板卡多出总线 当上游 Connector 的 Buses 数量小于下游板卡 Anchor 的 Buses 数量时,下游板卡 Anchor 的 Buses 数组中多出的总线会被识别为下游多定义总线。板卡左下角会显示红色异常标志,将鼠标悬停在标志上可查看具体信息。 ![总线多定义](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_bus_error_3.png) 3. **板卡合并**:SR 文件中的不同 Connector 加载同一个文件时,拓扑图会将其合并为一张板卡。 ![板卡合并](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_node_merge.png) #### 配置整机拓扑 1. 可通过板卡上方选项在整机拓扑中选择对应板卡,各板卡可选下游板卡数量和类型由该板卡的 Connector 配置决定;尚未确定 SR 的节点通过板卡选择器从候选列表中指定 SR 文件。所有配置信息会自动在本地持久化。 2. 双击整机拓扑页面的任意板卡,或点击左侧 CSR 列表中的文件,即可打开单 CSR 配置页面。 3. 通过工具栏的配置选择框可在多套整机配置之间切换,点击「导出配置」可导出当前配置。 ![本地模式工具栏](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_local_config_toolbar.png) #### 在位状态 本地模式根据 SR 文件中上游 Connector 的 `IdentifyMode` 和 `Presence` 值显示在位状态,单击开关可切换: | 显示 | 含义 | |------|------| | 天池加载 | `IdentifyMode` 为 3,由天池配置加载 | | 在位 / 不在位 | `IdentifyMode` 为 2,`Presence` 为固定值 1 / 0 | | 动态加载 | `IdentifyMode` 为 2,`Presence` 为表达式,按表达式动态计算 | 1. 板卡在位状态 ![板卡在位状态](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_local_status.png) 2. 切换在位状态:单击开关可同步修改上游 Connector 中 `Presence` 的值。 ![在位状态切换](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_local_status_switch.gif) ### CSR 单板卡配置 双击整机拓扑页面的任意板卡,或单击左侧 CSR 列表中的文件,即可打开单 CSR 配置页面。单板卡视图支持新增、删除总线或器件,以及修改 Mux 总线的 `ChannelId`。也可以按 `Ctrl + Z` 撤销、按 `Ctrl + Y` 恢复。 ![单CSR配置页面](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_sr_view.png) #### 定位器件 单击器件,右侧 SR 文件会自动定位到该器件对象所在的位置。 ![器件单击](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_single_csr_click.png) #### 修改 ChannelId 单击器件上方的 `ChannelId` 数字方块,可修改其值。 ![修改 ChannelId](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_single_csr_edit_channelId.png) #### 新增总线 单击 `+` 图标,选择总线类型并填写总线后缀,然后单击“确定”新增总线。 ![新增总线](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_csr_add_bus.gif) #### 删除器件、总线 将鼠标悬停在器件或总线上,单击鼠标右键并选择“删除”。 ![删除总线器件](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_csr_delete_bus.gif) #### 拖拽器件 打开器件库,将器件拖拽到总线上即可将器件挂载到总线,同时自动修改对应 CSR 文件内容。也可以拖拽器件到可下连的器件卡片上进行挂载。 ![拖拽器件](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_drag_device.gif) ## 导入 BMC 日志压缩包查看 CSR 拓扑 openUBMC Studio 支持导入 BMC 一键收集的日志压缩包,在离线环境下还原当前整机加载的 CSR 及其拓扑关系。适用于现场问题定位与离线日志分析:拿到日志包即可查看板卡层级结构、连接关系与在位情况,无需连接真机。 ### 使用前准备 - 已安装 openUBMC Studio 并启用 CSR 拓扑插件(随主插件提供)。 - 准备 BMC 一键收集的日志压缩包,支持 `zip`、`tar`、`tgz`、`gz`(含 `.tar.gz`)格式。 - 本机需可执行 `tar` 命令(日志包解压依赖系统 tar)。 > [!NOTE]说明:
> 导入日志模式不依赖模型配置,也无需预先创建拓扑项目,可直接使用。 ### 导入日志压缩包 1. 在 openUBMC Studio 左侧 CSR 拓扑侧边栏视图标题栏,点击「导入日志包」按钮。 ![导入日志包入口](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_import_entry.png) 2. 在弹出的文件选择框中,选择 BMC 日志压缩包并点击「选择日志压缩包」确认。 ![选择日志压缩包](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_import_file_picker.png) 3. 工具自动解压并解析日志包中的 `connectors.txt`,随后在主编辑区渲染整机 CSR 拓扑图。导入成功后右下角提示「成功导入: 文件路径」。 ![导入后的整机拓扑](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_imported_topology.png) ### 查看导入的拓扑 - **板卡层级与连接关系**:拓扑图展示整机各板卡的层级结构与总线连接,查看能力与本地整机拓扑页面一致,但不支持切换板卡配置(配置选择框与导出配置按钮为禁用状态)。 - **在位状态**:每块板卡以只读标签显示在位状态(在位/不在位),状态取自日志包记录。 ![在位状态标签](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_import_presence.png) ### 实现原理 #### 数据来源 导入模式的拓扑数据全部来自日志压缩包内部,不访问真机,各数据项来源如下: | 数据项 | 来源 | 用途 | |--------|------|------| | 板卡层级结构 | `connectors.txt` 的树形拓扑部分 | 构建整机拓扑树(板卡父子关系) | | Connector 详情(`Buses`、`Type`、`Presence`、`IdentifyMode` 等) | `connectors.txt` 的 Connector 详情段 | 总线连线、连接器类型、在位状态 | | 板卡类型与名称(`Unit.Type` / `Unit.Name`) | 日志包内的 `.sr` 文件 | 拓扑节点显示的板卡类型与名称 | | 下游总线(`ManagementTopology.Anchor.Buses`) | 日志包内的 `.sr` 文件 | 总线一致性检测的下游锚点 | | 板卡 SR 详情 | 日志包内的 `.sr` 文件 | 双击板卡下钻查看的自描述内容 | `connectors.txt` 通常位于日志包的 `dump_info/AppDump/hwdiscovery/` 目录下;工具同时支持在解压根目录及任意子目录中递归查找。`.sr` 文件从 `connectors.txt` 所在目录及其子目录中递归收集。 #### connectors.txt 格式示例 `connectors.txt` 由 BMC 硬件自发现流程生成,前半部分是板卡树形结构,后半部分是每个 Connector 的属性详情: ```text root ├─Connector_BMC │├─Connector_PCPU_1 │└─Connector_PCPU_2 └─Connector_PSU_1 Connector_BMC: .Buses: ["I2c_1","I2c_2"] .Type: BMC .Presence: 1 .IdentifyMode: 2 Connector_PSU_1: .Buses: ["I2c_3"] .Type: PSU .Presence: 0 .IdentifyMode: 2 ``` - **树形部分**:通过行首的 `├─`、`└─`、`│` 符号表达层级,每个节点即一块板卡的 Connector,对应 SR 文件名为 `节点名.sr`(如 `Connector_PCPU_1.sr`)。 - **详情部分**:`Connector_XXX:` 开启一个 Connector 段,其下以 `.属性: 值` 逐行列出属性。其中 `Presence` 决定在位标签(1=在位,0=不在位),`Buses` 决定上游总线连线。 ![connectors.txt 内容示例](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_import_connectors_file.png) #### 处理流程 1. **解压**:调用系统 `tar`(zip 在 Linux 下用 `unzip`)将日志包解压到固定临时目录。 2. **查找 connectors.txt**:按「解压根目录 → `dump_info/AppDump/hwdiscovery/` → 递归子目录」的顺序查找。 3. **解析**:拆分树形结构与 Connector 详情段,得到拓扑树骨架与各 Connector 属性。 4. **收集 SR 文件**:递归收集同目录下全部 `.sr` 文件并解析缓存到内存。 5. **构建拓扑**:将 Connector 属性与 SR 文件按名称(去除末尾 `_序号` 后缀)匹配,生成前端拓扑树并渲染。 > [!NOTE]说明:
> 在位状态反映的是**收集日志时刻**的整机状态,非实时数据。 ### 功能验证 导入完成后,可按以下检查项验证功能是否正常: | 验证项 | 操作步骤 | 预期结果 | |--------|----------|----------| | 导入解析 | 选择 BMC 一键收集日志压缩包导入 | 右下角提示「成功导入: 文件路径」,主编辑区渲染整机拓扑 | | 板卡层级 | 对比拓扑树与日志包 `connectors.txt` 的树形结构 | 板卡父子层级一致,无遗漏板卡 | | 在位状态 | 查看板卡节点标签,与 `connectors.txt` 中对应 Connector 的 `Presence` 值比对 | 标签显示与记录一致(1=在位,0=不在位) | | 板卡详情下钻 | 双击拓扑中的板卡节点 | 编辑器第二列打开该板卡 SR 文件内容 | ### 常见问题 | 现象 | 处理建议 | |------|----------| | 提示「未找到 connectors.txt 文件」 | 请确认导入的是 BMC 一键收集日志压缩包(内含 `connectors.txt`) | | 导入会占用/残留磁盘空间吗 | 日志包解压到固定临时目录(`系统临时目录/bmc-log-import`),每次导入前自动清理旧数据,无需手动维护 | | 能否修改在位状态或板卡配置 | 导入模式为只读查看,不支持修改在位状态与 CSR 配置;配置选择与导出按钮为禁用状态 | ## 远程模式连接 BMC 环境 远程模式支持连接真机 BMC 环境,自动从运行时数据(`mdbctl` 调试命令 + 框架日志)构建整机 CSR 拓扑,实时展示板卡实际在位情况。无需从 BMC 手动导出数据再导入,选择环境即可出图,适用于真机调试、板卡适配验证与在位异常定位。 ### 使用前准备 - 已安装并启用 **BMC环境管理** 插件(`openubmc.bmcstudio-bmc-remote`),并添加至少一条 BMC 连接。连接的添加方法参见 [BMC环境管理插件](#bmc-env-management) 章节。 - 目标 BMC 运行 openUBMC 固件,开放 Telnet 调试通道(23 端口免认证调试 shell),且板上具备 `mdbctl` 调试命令。 - 开发机无需安装 telnet 客户端,扩展使用内置连接直连。 > [!NOTE]说明:
> 远程模式不依赖模型配置,选中环境后自动跳过机型配置流程,直接加载拓扑。 ### 连接 BMC 环境 1. 在 CSR 拓扑侧边栏视图标题栏,点击「远程调试」按钮。 ![远程调试入口](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_topo_remote_entry.png) 2. 在顶部弹出的环境选择框中,选择目标 BMC 环境。列表展示全部已配置连接,并实时探测在线状态(在线/离线图标 + 账号信息)。 3. 选择后显示「正在加载 xx 环境的 CSR 拓扑」进度通知,工具自动读取真机运行时的 Connector 对象与 SR 加载记录并构建拓扑。 4. 加载完成后,拓扑图工具栏显示当前连接的环境名称与 IP,主编辑区渲染整机实时拓扑。 ### 查看实时拓扑 - **真实在位状态**:拓扑以真机运行时数据为准(而非静态 root.sr 配置),每块板卡显示实际在位/不在位状态。 - **EEPROM 板卡**:CSR 烧录在 EEPROM(而非 .sr 文件)的板卡会被自动解码,与文件板卡同等展示,双击同样可查看内容。 - **板卡 SR 下钻**:双击板卡即可进入单板视图查看该板卡的 SR 内容。 - **在位调试**:板卡节点上的在位开关可点击切换,模拟板卡拔插,详见下文「在位调试」。 ### 在位调试 远程模式下,点击板卡节点上的在位开关即可**模拟板卡拔插**,验证下级板卡的加载逻辑,无需物理操作真机。 > [!NOTE]说明:
> 切换在位状态**不是卸载板卡**:该板卡已加载的 SR 不受影响,只影响**下级板卡的加载判断**——下级板卡检测到上游 Connector 的 Presence 为 0 时不会加载。 #### 普通在位属性 Presence 为固定值(1/0)的板卡,节点上显示单个在位开关。点击开关后: 1. 工具通过 `mdbctl setprop` 向真机下发修改,更新该 Connector 的 Presence 值; 2. 重新读取运行时在位状态并重建拓扑(不重新读取 SR 文件); 3. 下级板卡的加载状态随 Presence 变化体现在拓扑上。 #### 同步属性(多开关) Presence 为表达式(引用其他对象属性,如多个物理在位开关共用一个 Connector)时,节点上会按同步源渲染**多个开关**,每个开关对应一个同步源对象的属性。点击单个开关只修改对应同步源对象的属性值,适用于逐个验证各物理开关对板卡加载的影响。 > [!WARNING]注意:
> 在位调试通过 `setprop` 真实修改真机运行时属性,直接影响下级板卡的加载判断。请确认影响范围后再操作,调试完成后建议将开关切回原状态。 ### 实现原理 #### 数据来源 远程模式的拓扑数据来自真机运行时,全部通过 Telnet 调试通道(23 端口)自动采集,各数据项来源如下: | 数据项 | 来源 | 用途 | |--------|------|------| | Connector 对象清单 | 真机运行时(`mdbctl lsobj connector`) | 拓扑节点唯一来源,以实际加载为准(非静态 root.sr) | | Connector 实际在位值 | 真机运行时(`mdbctl lsprop` 读取 `Presence`) | 板卡在位/不在位状态 | | SR 文件加载记录 | 真机 `/var/log/framework.log` 中框架打印的加载日志 | 确定每个 Connector 实际加载的 SR 文件路径(含根节点) | | SR 文件内容 | 真机 `/opt/bmc/sr/*.sr` | 板卡类型/名称(`Unit` 字段)、下游总线、双击下钻内容 | | EEPROM 板卡 CSR | 板上 EEPROM(CDR 容器格式) | CSR 烧录在 EEPROM(无 .sr 文件)板卡的解码展示 | | 拓扑层级关系 | Connector 的 `GroupPosition` 属性 | 按 GroupPosition 建树(去末两位即父节点) | #### 通过日志查看 Connector 加载的文件 每个 Connector 实际加载的 SR 文件记录在 BMC 的框架日志 `/var/log/framework.log` 中,由硬件自发现流程打印,共两类记录: **记录一(init.lua,板卡加载主源)**——每个 Connector 加载 SR 时打印,`position` 即该 Connector 的 `GroupPosition`: ```text 2026-08-20 10:15:32 hwdiscovery NOTICE: init.lua(152): position: 0101011A, get csr data from /opt/bmc/sr/14100513_pcie_card.sr, ... ``` **记录二(dump.lua,根节点主源)**——根板卡的加载只出现在此类记录中: ```text 2026-08-20 10:15:30 hwdiscovery NOTICE: dump.lua(88): start to dump connector: root loading file: /opt/bmc/sr/root.sr ``` 工具解析后的对应关系示例: | 日志记录 | 解析结果 | |----------|----------| | `position: 0101011A, get csr data from /opt/bmc/sr/14100513_pcie_card.sr` | GroupPosition 为 `0101011A` 的 Connector 加载了 `14100513_pcie_card.sr` | | `start to dump connector: root loading file: /opt/bmc/sr/root.sr` | 根节点加载 `root.sr`(拓扑根板卡) | | `start to dump connector: Connector_EXU_1 loading file: Eeprom/...`(`loading file` 为 EEPROM 对象路径) | 该板卡 CSR 烧录在 EEPROM,工具改走 EEPROM 解码 | 也可以在 BMC 上手动执行以下命令核对(与工具解析使用同一数据源): ```bash grep -E "get csr data from|start to dump connector" /var/log/framework.log ``` > [!NOTE]说明:
> 同一 Connector 多次加载时取**最新一条**记录(日志按最新文件优先解析);加载失败的记录(如占位文件)会被过滤,不会体现在拓扑中。 #### 处理流程 1. **连通性自检**:通过 Telnet 23 端口连接目标 BMC,探测调试 shell 可用性。 2. **发现 Connector**:执行 `mdbctl lsobj connector` 获取运行时全量 Connector 对象,再批量 `mdbctl lsprop` 读取每个 Connector 的 `Presence` 实际值。 3. **解析加载记录**:读取 `/var/log/framework.log`(含历史 `.gz` 轮转文件),解析「position → SR 文件」与「运行时名 → 文件」两组映射。 4. **建树**:按 Connector 的 `GroupPosition` 属性构建整机层级(去掉末两位十六进制即父节点位置)。 5. **读取 SR 内容**:按映射从 `/opt/bmc/sr/` 读取 `.sr` 文件;EEPROM 板卡读取 EEPROM 二进制(CDR 容器)并本地解码出 CSR。 6. **渲染**:组装拓扑树、在位状态与 SR 数据,发送到拓扑图视图渲染。 > [!NOTE]说明:
> 在位状态以**真机运行时数据**为准(mdbctl 实时读取),而非 CSR 静态配置中的 `Presence` 表达式,可避免静态配置与实际加载不一致造成的误判。
> 所有数据仅在加载拓扑和切换在位开关时读取,不在本地持久化。 ### 功能验证 连接环境并加载拓扑后,可按以下检查项验证功能是否正常: | 验证项 | 操作步骤 | 预期结果 | |--------|----------|----------| | 环境列表 | 点击「远程调试」按钮 | 列出全部已配置 BMC 连接,并标注在线/离线状态与账号信息 | | 拓扑加载 | 选择一个在线环境 | 显示「正在加载 xx 环境的 CSR 拓扑」进度,完成后工具栏显示环境名与 IP,渲染整机拓扑 | | 在位一致性 | 将拓扑中板卡在位状态与真机实际在位比对(可对照 BMC Web 页面或板上 `mdbctl` 查询结果) | 与真机实际加载一致(以运行时数据为准) | | 加载文件一致性 | 在 BMC 上执行上文 grep 命令,比对拓扑中板卡对应的 SR 文件 | 双击下钻打开的 SR 文件与日志记录的 `get csr data from` 路径一致 | | 板卡详情下钻 | 双击拓扑中的板卡节点 | 打开单板视图,可查看该板卡 SR 内容 | | EEPROM 板卡 | 查看拓扑中无 .sr 文件的板卡 | EEPROM 板卡正常解码展示,双击同样可查看 CSR 内容 | | 在位开关切换 | 点击某板卡节点的在位开关 | 切换后拓扑自动刷新,下级板卡加载状态随之变化 | | 同步属性切换 | 点击同步属性板卡上的单个开关 | 仅对应同步源对象的属性变化,其余开关状态不变,拓扑刷新 | ### 常见问题 | 现象 | 处理建议 | |------|----------| | 提示「未配置 BMC 环境,请先添加连接」 | 先在 BMC环境管理插件中添加连接,参见 [BMC环境管理插件](#bmc-env-management) 章节 | | 提示「远程拓扑加载失败」 | 检查环境是否在线、BMC 23 端口是否开放、板上 `mdbctl` 是否可用;详细原因可查看输出通道中 RemoteTopologyLoader 的日志 | | 环境列表显示「探测中」 | 连接健康探测最长 3 秒,离线环境会标注离线状态,不影响选择其他环境 | > [!NOTE]说明:
> 远程模式下配置选择与导出配置不可用(禁用),与导入日志模式一致。
> 此外,远程拓扑支持通过 MCP 工具 `csr_topo_get_remote_topology` 供 AI Agent 查询整机 Connector 在位清单与 SR 来源。 ## 能效调速配置 能效调速配置功能提供能效调速对象的配置入口,支持通过Excel导入热设计表格解析调速曲线配置,支持对象自动关联及配置检查、CSR片段自动生成。 ### 打开配置页面 点击CSR拓扑侧边栏中的温度计图标即可开启能效调速配置页面。 ![能效调速配置入口](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_efficiency_entry.png) ### 配置能效调速对象 1. 通过该页面配置能效调速对象,以及配置对象间的关联关系。 2. 点击右上角的"导入Excel"即可导入热设计表格,当前仅支持xlsx格式,若为其他格式请通过Excel另存为xlsx格式文件。完成导入后,温度点与调速曲线等配置可以自动解析。 3. 点击右上角"生成CSR"即可根据当前配置产生CSR代码片段,可以自行填入CSR文件中。生成CSR过程支持配置语法检查,禁止出现ID冲突等问题。 ![生成CSR代码片段](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_efficiency_generate.png) # 七、事件管理 本章节介绍 openUBMC Studio 的事件管理功能。用户可以在 IDE 中查看和编辑 `event_def.json` 中的事件信息与描述模板,也可以查看、新增和保存事件与 CSR `Event_` 对象的绑定关系。 > [!NOTE]说明:
> 事件管理依赖模型配置生成的事件字典基线。如尚未配置模型,请先完成[模型配置](#模型配置)中的产品和规则集选择。 ## 功能说明 BMC 事件字典定义了整机事件的事件标识、严重级别、事件编码和描述模板等标准信息。事件管理提供以下能力: - **事件字典管理**:查看、筛选和搜索全部事件,编辑基础字段与中英文描述模板,新建自定义事件模板,以及还原或导出差量。 - **CSR 绑定管理**:查看事件在 SR 文件中绑定的 `Event_` 对象,可视化新增、编辑和删除绑定,并批量保存到 SR 文件。 根据打开入口,事件管理提供以下两种视图: | 视图 | 入口 | CSR 绑定聚合范围 | | --- | --- | --- | | 单板卡视图 | 单 SR 拓扑视图中的“事件管理” | 当前 SR 文件及其拆分文件中的 `Event_` 对象 | | 整机视图 | 总拓扑页面工具栏中的“事件管理” | 总拓扑下所有 SR 文件中的 `Event_` 对象 | 两种视图共用同一套事件字典与编辑能力,仅 CSR 绑定的聚合范围不同。 ## 使用前准备 - **模型配置**:已完成产品和规则集选择,事件字典基线来自 Conan 规则包中的 `event_def.json`。 - **拓扑项目**:已通过拓扑侧边栏创建配置并添加 CSR 仓库,当前工作区存在可用的 SR 上下文。 > [!NOTE]说明:
> 字段修改、描述模板修改和自定义事件模板会以差量形式保存在本地缓存中。编辑停止约 1 秒后,差量会自动写入缓存;关闭事件管理面板时,差量会自动落盘。原始字典文件不会被直接修改。 ## 打开事件管理 - **打开整机视图**:进入总拓扑页面,单击工具栏中的“事件管理”。 ![从总拓扑打开事件管理](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_entry_board.png) - **打开单板卡视图**:进入单 SR 拓扑视图,单击“事件管理”。此时 CSR 绑定范围限定为当前 SR 文件。 ![从单 SR 拓扑打开事件管理](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_entry_sr.png) 事件管理会在独立面板中打开,不影响原拓扑页面。 ## 查看事件管理界面 事件管理界面由工具栏、事件列表、编辑横幅、分页栏和详情面板组成。 ![事件管理界面](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_overview.png) - **工具栏**:提供新建事件模板、重新拉取、导出、清除全部筛选和搜索功能。 - **事件列表**:展示全部事件,支持列头筛选和分页。 - **编辑横幅**:存在未导出的编辑时,以黄色或绿色横幅提示导出。 - **详情面板**:单击事件行后显示在界面右侧。拖动面板左边缘可以在约 `280~700px` 范围内调整宽度,单击“×”可以关闭面板。 ## 筛选和搜索事件 ### 查看列表字段 | 列 | 说明 | | --- | --- | | 事件(`EventKeyId`/`EventName`) | 事件唯一标识与名称,内容过长时自动省略,悬停后显示全文 | | 级别 | 严重程度:提示(蓝灰)、一般(蓝)、重要(橙)或紧急(红) | | CSR 绑定 | 当前视图范围内绑定的 `Event_` 对象数量 | | 分类 | 根据事件标识推导的业务分类 | | 机型支持 | 当前机型是否支持该事件 | | `EventCode` | 事件的十六进制唯一编码 | | 恢复上报 | 是否上报恢复事件 | | `EventType` | 事件类型 | | `LifeCycleId` | 生命周期标识 | ### 设置筛选条件 1. 单击“级别”“CSR 绑定”“分类”“机型支持”或“恢复上报”列头中的筛选按钮。 2. 勾选需要保留的选项。每个选项会显示对应的事件数量。 3. 如需清空当前列的条件,再次打开筛选菜单并单击“清空筛选”。 右上角搜索框支持按 `EventKeyId`、事件名称或事件编码进行模糊搜索。存在筛选或搜索条件时,工具栏会显示“清除全部筛选(N)”,单击后可以恢复完整列表。 ![筛选和搜索事件](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_filter.png) ### 设置分页 底部分页栏支持将每页数量设置为 20、40、80 或 100 条,也支持按页码跳转。没有事件数据时,可以通过空状态入口新建事件模板;存在数据但被过滤时,可以通过空状态入口清除筛选。 ## 新建和编辑事件 ### 新建事件模板 1. 单击工具栏中的“新建事件模板”。 2. 在右侧详情面板中编辑新模板。 新建的自定义事件会置于列表顶部并自动选中。详情面板底部提供“删除该自定义事件模板”按钮。 ### 编辑基础字段 1. 在事件列表中单击目标事件。 2. 在右侧详情面板中打开“基础信息”页签。 ![编辑事件基础信息](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_basic_fields.png) 基础字段说明如下: | 字段 | 说明 | | --- | --- | | 事件名称 `EventName` | 事件短名称,通常与 `EventKeyId` 的最后一段一致 | | `SeverityId` | 严重级别:`0` 表示提示、`1` 表示一般、`2` 表示重要、`3` 表示紧急 | | 机型支持 | 标记当前机型是否支持该事件,是导出 `eventDefList.txt` 的依据 | | 恢复上报 `DeassertFlag` | 是否上报恢复事件,与 `LifeCycleId` 共同决定事件是否可恢复 | | 事件编码 `EventCode` | 十六进制唯一编码,例如 `0x0200001F` | | 旧版事件编码 `OldEventCode` | 跨版本兼容映射,没有对应关系时留空 | | 上报通道 `ReportChannel` | 目标通道位掩码,`65535` 表示向全部通道上报 | | 事件类型 `EventType` | BMC 固件定义的编号,当前字典中的常见取值为 `0` 或 `1` | | 生命周期标识 `LifeCycleId` | BMC 固件定义的编号,当前字典中的常见取值为 `0` 或 `1` | | 动作标识 `ActionId` | BMC 固件定义的编号,当前字典中的常见取值为 `0` 或 `1` | ### 编辑描述模板 “描述模板”区域提供以下四类内容的中英文编辑,单击右上角的“中”或“EN”可以切换语言: - `Description`:描述。 - `Cause`:可能原因。 - `Influence`:影响。 - `Suggestion`:处理建议。 ![编辑事件描述模板](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_desc_template.png) > [!NOTE]说明:
> > - 描述支持 `%Component`、`%DescArg1`~`%DescArg5` 占位符,依次引用 CSR 事件绑定中的 `Component` 和 `DescArg` 字段。输入占位符后,界面会显示提示。 > - 可能原因与处理建议支持多条内容,多条内容之间使用 `@#AB;` 分隔。 ### 还原事件数据 - **还原单个事件**:单击详情面板标题行中的“还原”,丢弃该事件的全部本地编辑并恢复为字典基线值。 - **重新拉取全部事件**:单击工具栏中的“重新拉取”,在确认窗口中继续操作。完成后,事件管理会丢弃全部编辑,从 Conan 包重新读取事件字典,并将筛选、搜索和分页恢复为初始状态。 ![重新拉取事件确认窗口](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_reload_confirm.png) > [!WARNING]注意:
> “重新拉取”会丢弃当前所有本地编辑。首次打开事件管理时,系统优先读取本地缓存;仅在需要放弃全部差量或重新获取 Conan 包中的最新数据时执行此操作。 ## 查看并导出修改 存在未同步的编辑时,列表上方会显示编辑横幅。 ![事件修改横幅和清单](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_banner.png) | 横幅 | 含义 | 导出文件 | | --- | --- | --- | | 黄色 | 事件字段、描述模板或自定义模板发生变化 | `event_def.json` | | 绿色 | 机型支持字段发生变化 | `eventDefList.txt` | - **查看修改**:打开变化清单后,可以单击事件标识定位到对应事件,也可以单独还原某个事件。 - **导出事件字典**:导出的 `event_def.json` 包含全部事件定义与描述模板,文件版本号末段自动加一,例如从 `1.0.0` 更新为 `1.0.1`。导出后,请将文件提交到 VPD 仓库进行同步。 - **导出机型事件清单**:导出的 `eventDefList.txt` 仅包含“机型支持”为“是”的事件标识。 > [!NOTE]说明:
> 两类横幅会根据修改内容独立显示和导出。两类内容均发生变化时,需要分别导出对应文件。 ## 管理 CSR 绑定 CSR 绑定描述事件与 SR 文件中 `Event_` 对象的对应关系。在详情面板中打开“CSR 绑定”页签,可以查看和编辑绑定。 ### 查看 CSR 绑定 页签顶部显示当前视图类型和事件的绑定总数。绑定以卡片形式展示,每张卡片会标注所属 SR 文件,悬停后可以查看完整路径。 ![查看 CSR 绑定](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_csr_binding.png) ### 新增 CSR 绑定 1. 单击详情面板底部的“CSR 绑定”。 2. 在新增卡片中填写绑定字段。 3. 如果当前处于整机视图,选择“目标 SR 文件”。整机根文件 `root.sr` 不在候选范围内;单板卡视图会自动使用当前 SR 文件。 4. 单击“确定”,批量保存本次绑定修改。 ![新增 CSR 绑定](../../images/bmc_studio/user_guide/bmc_studio_tool/event_mgmt_csr_add.png) ### 查看绑定字段 | 字段 | 说明 | | --- | --- | | 事件对象名 | 必须以 `Event_` 开头且不能只有前缀;同一拆分文件组内不得重名,不同组之间允许同名 | | 目标 SR 文件 | 仅在整机视图新增绑定时显示,用于指定绑定写入的 SR 文件 | | `Condition` | 绑定条件;清空后删除该键,纯数字内容会自动转换为数值 | | `Component` | 事件关联的器件组件,候选项按照目标 SR 文件分为“推荐”和“其他”两组 | | `OperatorId` | 操作符编号,可以留空 | | `Enabled` | 是否启用绑定,可以留空以删除该键 | ### 验证保存结果 - “确定”仅在存在修改且表单校验通过时可用;单击“取消”会放弃本次全部修改。 - 对象名为空、未以 `Event_` 开头或在组内重名时,对应输入框会显示错误。 - 保存成功后,绑定列表和绑定数量会自动刷新,事件列表会定位到当前事件。 - 在编辑器中直接保存 SR 文件后,绑定列表和绑定数量也会自动刷新。 ## 常见问题 - **事件字段是否需要手动保存?** 不需要。字段与描述模板编辑会在停止输入约 1 秒后写入本地缓存,并在关闭面板时落盘;CSR 绑定修改需要单击“确定”保存到 SR 文件。 - **重新拉取后编辑全部消失**:此行为符合预期。“重新拉取”会丢弃全部本地差量并恢复到字典基线。 - **CSR 绑定提示对象名必须以 `Event_` 开头**:事件对象名必须带有固定前缀,并且不能只有 `Event_` 前缀。 - **整机视图与单板卡视图的绑定数量不一致**:两种视图的聚合范围分别为全部 SR 文件和当前 SR 文件,因此数量可能不同。 - **还原事件后列表中的绑定数量未变化**:“还原”仅丢弃事件字典的本地差量,不修改 CSR 绑定。 - **导出的文件应提交到哪里?** `event_def.json` 与 `eventDefList.txt` 均用于提交到 VPD 仓库,具体流程遵循团队的字典变更管理规范。 - **新建的模板在筛选结果中不可见**:新建模板时会自动清空筛选。如模板仍不可见,请检查搜索词和列头筛选条件。 # 八、日志诊断与告警链条分析 一键日志解析插件(扩展 ID:`openubmc.bmcstudio-log-reviewer`)用于导入 BMC 一键日志包或 dump 目录,并通过可视化页面和 AI Agent 分析设备状态。用户可以浏览硬件、告警、传感器、性能及原始日志,也可以结合 openUBMC RAG 进行日志体检,或通过告警证据工具分析指定事件的触发链条。 ## 功能说明 日志诊断提供以下使用方式: | 使用方式 | 主要能力 | 适用场景 | | --- | --- | --- | | 一键日志解析页面 | 自动解压日志包,通过概览、硬件、告警、传感器、性能、调速、线缆和日志等视图展示 dump 日志 | 人工浏览现场、筛选日志和快速确认异常范围 | | Agent 日志体检 | 结合本地日志证据和 openUBMC RAG 生成问题清单,实时回写结果并导出 PDF 报告 | 对日志进行批量体检和问题优先级排序 | | 定向诊断与告警链条分析 | 关联事件记录、运行日志、数据库及 `CSR Event` 定义,输出告警状态、触发链、恢复或复发情况和证据位置 | 聚焦指定问题、还原告警链条和形成可复核结论 | > [!NOTE]说明:
> 可视化页面中的“智能检测”用于 Agent 日志体检。指定问题的深入诊断和告警链条分析可以在已配置 openUBMC Studio MCP 服务的 AI Agent 对话中发起。 ## 使用前准备 如果活动栏中没有“一键日志解析”图标,请先执行以下操作: 1. 在 openUBMC Studio 中打开插件市场,搜索“一键日志解析”。 2. 安装插件,并按照提示重新加载窗口。 3. 确认活动栏中出现“一键日志解析”图标。 使用 Agent 日志体检前,还需要满足以下条件: - 已登录 openUBMC 社区。 - `openubmc-rag` 扩展已启用。 - 当前网络可以访问配置的 LightRAG 服务。 - AI Agent 可以访问 openUBMC Studio MCP 工具。 AI Agent 会在读取日志前检查 RAG 状态。未登录、RAG 工具未启用、网络异常或状态响应无法解析时,日志体检会停止并显示处理建议。 > [!NOTE]说明:
> 如果所有 MCP 工具均提示网络错误,请将 `localhost`、`127.0.0.0/8` 和 `::1` 加入代理直连列表或 `NO_PROXY`,然后完全重启 openUBMC Studio 和 AI Agent。 ## 打开一键日志 一键日志解析支持 Windows、Linux、WSL、SSH 远程工作区和容器工作区。 支持导入以下内容: - `.tar.gz`、`.tgz`、`.tar` 或 `.zip` 格式的 BMC 一键日志压缩包。 - 已解压且包含 `AppDump` 子目录的 dump 文件夹。 操作步骤如下: 1. 单击活动栏中的“一键日志解析”图标。 ![一键日志解析入口](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_log_analysis_entry.png) 2. 根据日志形态,选择“打开 BMC 一键日志压缩包”或“打开 dump 目录”。 ![打开 BMC 一键日志压缩包](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_open_log_archive.png) 3. 选择日志压缩包或 dump 根目录。选择目录时,应选中包含 `AppDump` 子目录的 dump 根目录。 4. 等待解压和解析完成,确认日志页面已在编辑器区域打开。 ![BMC 一键日志解析页面](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_log_reviewer_entry.png) 也可以通过以下入口打开日志: - 在资源管理器中右键单击日志压缩包或 dump 文件夹,选择对应的一键日志解析命令。 - 单击“最近打开”中的历史记录,重新打开对应日志。 “最近打开”最多保存 30 条记录。同一日志已经打开时,再次打开只会定位到原页面。删除一条最近记录时,对应的日志页面也会关闭。 ### 查看日志包要求 日志包中必须存在名称完全匹配的 `AppDump` 目录,典型结构如下: ```text dump_info/ ├── AppDump/ ├── LogDump/ ├── RTOSDump/ └── OSDump/ ``` 插件最多向下查找 6 层目录。`AppDump` 是导入日志时的必需目录;缺少 `LogDump`、`RTOSDump` 或 `OSDump` 时,日志包仍可能打开,但对应页面会显示无数据或目录缺失。 | 项目 | 限制 | | --- | --- | | 单次选择 | 1 个日志包,可以重复导入不同日志包 | | 支持格式 | `.tar.gz`、`.tgz`、`.tar`、`.zip` | | `tar` 系列解压后总内容 | 不超过 8GiB | | `tar` 系列归档条目 | 不超过 200000 项 | | ZIP 解压 | 依赖系统中的 `tar` 或 `unzip`,单次命令最长执行 300 秒 | | `AppDump` 查找深度 | 最多递归 6 层 | > [!WARNING]注意:
> 插件不单独限制压缩文件本身的大小。处理大型日志包时,需要为远程暂存文件、中间 `.tar` 文件和解压目录预留足够空间,建议可用空间至少为解压后内容大小的两倍。 ## 查看诊断信息 日志面板按照不同领域组织现场信息,常用视图包括: - **现场概览**:查看机型、健康状态、FRU、板卡和软件版本。 - **告警与传感器**:查看告警记录、活动状态、传感器读值和门限信息。 - **运行状态**:查看性能、功率、进风温度、调速策略和 PID 配置。 - **硬件关联**:查看线缆检测、同步属性、CSR 和丝印信息。 - **日志与诊断**:查看操作日志、应用日志、框架日志、维护日志、驱动日志、串口日志、`journalctl`、一键日志原始文件和故障诊断文件。 - **智能检测**:使用 AI Agent 和 openUBMC RAG 进行日志体检。 不同页面按需解析日志文件,不会在导入时将所有文件一次性加载到内存。日志视图支持筛选、大小写匹配、全字匹配、正则表达式、匹配项跳转和保存搜索,具体可用项以当前视图为准。 ## 使用 Agent 进行日志体检 日志体检会将本地日志证据与 openUBMC RAG 检索结果关联,并按照严重程度、紧急度和置信度排列问题。故障案例库是可信度最高的知识来源,但不是唯一可用来源。 ![Agent 日志体检流程](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_log_reviewer_workflow.png) > [!NOTE]说明:
> 流程图中的问题数量和内容仅用于说明操作过程。实际问题数量、严重程度和诊断结论以导入日志中的证据及 RAG 检索结果为准。 ### 复制分析 Prompt 1. 打开日志页面顶部的“智能检测”。 2. 单击“复制 Prompt 模板”。 ![复制日志体检 Prompt](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_log_reviewer_prompt.png) 3. 将 Prompt 粘贴到能够访问 openUBMC Studio MCP 工具的 AI Agent 中。 4. 发送 Prompt,等待 AI Agent 完成 RAG 状态检查并开始分析。 Prompt 已包含以下约束,无需手动填写日志路径: - 包含当前日志包的显示名称、分析任务标识和回调地址。 - 只允许读取当前分析任务绑定的日志包。 - 必须先检查 RAG 连接和社区登录状态。 - 必须保留 RAG 引用的真实来源,其中故障案例库来源具有最高可信度。 - 每个问题必须同时提供 RAG 匹配内容和本地日志证据。 - 分析完成后,按照用户配置的 TopN 返回结果。 ### 查看实时问题 AI Agent 分析期间,每个已确认的问题会实时显示在“Agent 日志问题”区域。问题卡片包含以下内容: - 严重程度:`CRITICAL`、`HIGH`、`MEDIUM` 或 `LOW`。 - 紧急度:综合故障影响、恶化可能、冗余能力和修复窗口计算的 0~100 分。 - 置信度:本地多源证据与 RAG 知识的一致程度。 - 可能原因和处理建议。 - RAG 匹配内容、来源及可信度。 - 日志片段、日志包内相对路径和定位信息。 ![Agent 日志体检结果](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_log_reviewer_results.png) > [!NOTE]说明:
> 截图中的故障名称和日志内容仅用于演示界面结构,不代表产品预置的诊断结论。 同一根因产生的重复现象应合并为一个问题。分析完成后,插件会依次按照严重程度、紧急度和置信度排序,并展示最紧急的 TopN 问题。 ### 配置 TopN TopN 默认值为 10,可以设置为 1~50: 1. 单击“一键日志解析”侧边栏标题栏中的齿轮图标。 2. 在设置页面中修改 `bmcstudio.logReviewer.analysisTopN`。 3. 创建新的分析会话,使新设置生效。 TopN 只限制分析完成后页面和 PDF 报告中展示的问题数量。AI Agent 可以在分析过程中回写更多候选问题,插件会在完成时统一排序和截取。已经打开的分析会话继续使用创建会话时的 TopN 值;如需让同一日志使用新的 TopN,请先从“最近打开”中删除该日志,再重新导入并发起分析。 ### 导出 PDF 报告 “导出为 PDF 报告”仅在分析状态变为“已完成”后可用: 1. 确认页面显示“Agent 智能分析:已完成”。 2. 单击“导出为 PDF 报告”。 3. 选择保存路径和文件名。 4. 使用 PDF 阅读器打开报告,核对摘要、问题排序、RAG 内容、日志证据和处理建议。 报告在当前 openUBMC Studio 扩展宿主运行期间可以持续导出。完全关闭或重启 openUBMC Studio 后,内存中的分析会话不会保留,需要重新发起分析。 ### 处理会话异常 | 场景 | 预期行为 | | --- | --- | | 分析期间关闭日志页面 | AI Agent 回调可以继续写入后台会话,重新打开同一日志后恢复状态 | | 页面关闭较长时间后重新打开 | 运行中的会话按照空闲策略管理,重新打开并操作后刷新活跃状态 | | 从“最近打开”中删除日志 | 对应页面关闭,关联分析会话被清理 | | 清空“最近打开” | 所有日志页面关闭,关联分析会话被清理 | | RAG 不可用 | 分析停止并显示登录、网络或配置建议,不生成主观问题 | | 日志中没有诊断内容 | 日志包格式有效时,分析完成并显示 0 个问题,PDF 报告可以导出 | | 缺少 `AppDump` | 导入失败,并提示文件可能不是 openUBMC 一键日志包 | | 缺少 `AppDump/fault_diagnosis` | 结构化诊断失败,AI Agent 将分析任务标记为失败 | ## 使用 AI Agent 定向诊断日志 在 AI Agent 对话中提供日志路径和分析目标,例如: ```text 请打开并诊断 /path/to/bmc-log.tar.gz,先给出设备健康概览、关键异常和对应证据位置。 ``` openUBMC Studio 会打开同一份日志的可视化面板,同时将机型、健康状态、硬件清单、告警、传感器、性能、调速、线缆和 CSR 等结构化数据提供给 AI Agent。后续可以继续要求 AI Agent 聚焦某个领域,例如: ```text 继续分析当前日志中的散热异常,关联传感器、调速策略、功率和相关运行日志。 ``` ## 分析告警链条 分析单条告警时,建议提供以下任一组定位信息: - 事件码和发生时间。事件码格式为 `0x` 后接 8 位十六进制数字,时间格式为 `YYYY-MM-DD HH:mm:ss`。 - `sel.txt` 中的事件记录 ID。openUBMC Studio 可以据此解析事件码和发生时间。 - 需要区分多个告警实例时,再补充组件或实例名称。 示例: ```text 基于当前打开的一键日志,分析事件码 0x12345678、时间 2026-08-28 14:23:16 的完整告警触发链。 请说明当前告警状态、已观察到和缺失的阶段、恢复与复发情况,并在每个节点标注证据文件及行号或数据库记录位置。 ``` AI Agent 会根据日志中的实际证据按需给出以下内容: - 唯一告警锚点及其匹配方式,避免混淆相同事件码的不同告警实例。 - 告警当前状态,包括 `active`、`inactive`、`conflicted` 或 `unknown`,并分别列出状态依据。 - 已观察到的触发流程,例如采样、数值转换、门限或事件规则求值、事件存储和北向上报;未采集到的阶段会标记为缺失。 - 运行期事件与 dump 内 `.sr` 文件中 `CSR Event`/`PowerEvent` 定义、属性和直接引用关系的关联结果。 - `Assert`/`Deassert` 恢复配对、复发次数下界、历史覆盖范围和可能的时钟跳变。 - 每个关键事实对应的 dump 相对路径、行号、列号、JSON Pointer 或数据库定位信息。 > [!WARNING]注意:
> 告警链条分析仅关联 dump 中可观察到的事实,不会自动将时间相邻的事件视为因果,也不会使用静态 CSR 定义证明规则在告警时刻一定执行。日志缺失或状态冲突时,结论会保留为“证据不足”或“存在冲突”,需要结合现场信息和业务知识继续判断。 ## 了解数据范围和安全边界 - AI Agent 日志工具只能访问分析任务绑定的日志包,不会自动选择其他历史日志。 - 日志证据使用日志包内相对路径,不会向页面回写宿主绝对路径。 - 日志体检唯一允许访问的外部知识是 openUBMC RAG 状态和知识检索结果。 - `tar` 系列导入会拒绝路径逃逸、绝对路径和解压炸弹,并忽略符号链接、硬链接及设备文件。 - PDF 报告只包含当前分析会话中的摘要、TopN 问题、RAG 依据和日志证据。 # 九、BMC 环境管理 本章介绍 openUBMC Studio 的 **BMC环境管理** 插件(扩展 ID:`openubmc.bmcstudio-bmc-remote`)的功能与使用方法。该插件用于在 IDE 内集中管理多台 BMC 环境、批量下发命令、上传文件、一键升级固件、实时监控日志、自动调试组件以及远程 GDB 调试。 BMC环境管理插件在活动栏注册一个「BMC环境管理」容器,下设两个视图: - **BMC Environments**:BMC 环境连接树,按分组组织,管理连接的元数据与凭据。 - **Command Macros**:命令宏树,维护可批量下发的命令序列。 ![活动栏与两个视图](../../images/bmc_studio/user_guide/bmc_studio_tool/activity_bar.png) 插件的核心能力包括: - **连接管理**:以分组方式管理多台 BMC,单条连接可任选 SSH、Telnet 或 WebView 方式接入。 - **连通性管理**:手动或周期性探测 BMC 可达性,并在状态变化时播报。 - **命令宏**:预定义命令序列与变量,按「全部可达 / 分组 / 手动多选」批量下发,回收结构化结果。 - **SFTP 上传**:从资源管理器右键将本地文件或目录上传到 BMC。 - **HPM 一键升级**:右键 `.hpm` 固件包,并发升级多台 BMC,全程进度可视。 - **实时日志监控**:实时 `tail` 远端 `/var/log` 日志,支持日志轮转衔接、时间回绕校准与原始文件下载。 - **组件自动调试**:根据 Git 变更自动部署 Lua、C/C++ 和北向接口调试内容,详见 [C/C++、Lua 与北向接口快速调试](#quick-debug)。 - **远程 GDB 调试**:附加板端服务或部署独立程序进行源码级调试,详见 [BMC 远程 GDB 调试](#remote-gdb-debug)。 - **MCP 工具**:对外暴露 27 个 MCP 工具,供 AI Agent 调用,实现自然语言驱动的批量运维与告警证据分析。 ## 使用前准备 ### 环境要求 - **运行平台**:推荐 Linux(Ubuntu)。连接管理以 Linux 为目标平台;HPM 升级与日志监控仅依赖 Node 内置模块,三平台行为一致。 - **系统依赖**:建议预装以下工具: - `openssh-client`:SSH 接入与 SFTP 上传。 - `telnet`:Telnet 接入与实时日志监控。 - `tar`(支持 `-z`):目录上传与日志下载解压。 - `libsecret-1-0` / `gnome-keyring`:Linux 下用于安全存储密码。 ### 安装插件 1. 在 openUBMC Studio 中打开插件市场(活动栏的「扩展」图标,或按 `Ctrl+Shift+X`),搜索「BMC环境管理」,点击「安装」。 2. 安装完成后重启 IDE 生效。活动栏出现「BMC环境管理」图标即表示安装成功。 > [!NOTE]说明:
> 若已安装 openUBMC Studio 主插件,BMC环境管理作为配套扩展随其一同提供,具体获取方式请参考 [openUBMC Studio安装指南](../installation_guide/bmc_studio_installation.md)。 ## BMC 环境管理 ### 新增分组 连接以「分组」为单位组织,系统默认创建一个分组。 1. 在 **BMC Environments** 视图标题栏单击「Add Group」按钮。 2. 输入分组名称并确认。 分组的右键菜单支持「Add」「Rename Group」「Delete Group」。**分组非空时拒绝删除**(保护数据),需先清空或迁移其下连接。 ### 新增连接 1. 单击 **BMC Environments** 视图标题栏「Add BMC Environment」按钮,或在某个分组上右键选择「Add」。 2. 在弹出的表单中填写连接信息并保存。 ![新增连接表单](../../images/bmc_studio/user_guide/bmc_studio_tool/add_connection.png) 连接字段说明: | 字段 | 说明 | 备注 | | --- | --- | --- | | 名称 `name` | 连接显示名称 | 必填 | | IP 地址 `host` | BMC 的 IPv4 地址 | 必填,仅接受 IPv4,非法地址会被拒绝 | | 用户名 `username` | 登录用户名 | 必填 | | 密码 `password` | 登录密码 | 必填(新增时);密码存于操作系统级安全存储,不落配置文件、不进日志 | | 分组 `group` | 所属分组 | 不选则落入首个分组 | | 标签 `tags` | 标签数组 | 可选,用于归类 | | 描述 `description` | 连接描述 | 可选 | ### 接入 BMC 在连接上右键,选择接入方式: ![连接右键菜单](../../images/bmc_studio/user_guide/bmc_studio_tool/connection_context_menu.png) - **Connect via SSH**:使用进程内 SSH 客户端登录(兼容老款 BMC 的弱算法与 keyboard-interactive 交互),以伪终端呈现。默认在编辑器区(接近全屏)打开,由配置项 `bmc.autoMaximizeTerminal` 控制,关闭后回到底部面板。 - **Connect via Telnet**:调用系统 `telnet` 命令接入,需本机已安装 telnet。Telnet 不会自动发送密码,需手动输入。 - **Open in WebView**:使用系统浏览器打开 BMC Web UI(`https://{host}`)。 SSH 握手超时由 `bmc.connectionTimeout`(默认 30 秒)控制。 ### 编辑与删除 - **Edit Configuration / Change Password**:修改连接信息。编辑密码时留空表示保留原密码。 - **Disconnect**:发送 `exit`、关闭终端并注销会话。 - **Delete**:删除前会弹出模态确认;删除会先关闭相关终端并清理该连接的凭据。 > [!NOTE]说明:
> 删除连接会连带删除其凭据;删除分组前需先清空连接或迁移。 ## 连通性管理 插件通过 TCP 探测 SSH 22 端口判断 BMC 可达性,连接树图标实时反映状态(不可达时变红),分组徽章显示「X/Y 可达」。 - **手动探测单个**:右键连接 → 「Check Connection Health」,提示可达 / 不可达。 - **全量刷新**:单击视图标题栏「Refresh」,先把全部连接置为检测中再统一探测。 - **周期检测**:右键连接 → 「开启自动检测连通状态」/「关闭自动检测连通状态」。开启后每 **10 秒** 探测一轮,仅对开启该项的连接生效。 - **状态播报**:右键连接 → 「开启连通性变更播报」/「关闭连通性变更播报」。上线提示「{分组}/{名称} 已上电」,掉线提示「{名称} 已下电」。 探测超时由 `bmc.pingTimeout`(默认 3000 毫秒)控制。可达性 = 「TCP 22 端口通 + 已配置凭据」;运行宏、上传、升级前均以此作为就绪判据。 ## 命令宏 命令宏用于预定义「一组有序 shell 命令 + 变量 + 失败策略」,运行时按目标范围批量下发到 BMC,每台环境复用一条 SSH 连接执行完整命令集,并回收结构化的「环境 × 命令」结果矩阵。 ### 新建宏 1. 单击 **Command Macros** 视图标题栏「Add Command Macro」按钮。 2. 在表单中填写宏内容并保存。 ![新建命令宏表单](../../images/bmc_studio/user_guide/bmc_studio_tool/add_macro.png) 宏字段说明: | 字段 | 说明 | 默认值 / 范围 | | --- | --- | --- | | 名称 `name` | 宏名称 | 必填 | | 描述 `description` | 宏描述 | 可选 | | 命令 `commands` | 有序命令列表 | 至少 1 条;每条可单独设置 `description`、`timeoutMs`、`abortOnFailure`(遇错:默认 / 中断 / 继续) | | 变量 `variables` | 自定义变量(键名不含 $) | 与内置变量合并;同名时**内置优先** | | 失败策略 `onError` | 宏级策略 | `continue`(继续)/ `abort`(中断该环境后续命令);默认 `continue` | | 命令超时 `timeoutMs` | 单条命令超时(毫秒) | 默认 30000;单条命令可覆盖 | | 并发度 `concurrency` | 环境间并发度 | 1–8,默认 1 | | 标签 `tags` | 标签(表单中逗号分隔) | 可选 | ### 变量替换 命令模板支持变量占位: - 语法:`$VAR` 或 `${VAR}`;$$ 转义为字面 $。 - 内置变量(按每台环境各自替换,优先级高于自定义): | 变量 | 含义 | | --- | --- | | `$HOST` | BMC IP 地址 | | `$USER` | 登录用户名 | | `$NAME` | 连接名称 | | `$CONN_ID` | 连接 ID | | `$GROUP` | 分组名称 | > [!NOTE]说明:
> 未定义的变量**保留原样**(不会被置空),以避免因拼写错误导致类似 `rm -rf /tmp/$UNDEF/*` 的危险展开。 ### 运行宏 - **Run Macro...**:右键宏 → 选择目标范围(「所有可达且有凭据的环境」/「按分组」/「手动多选」)→ 模态确认后执行。 - **Run on Group...** / **Run on All Reachable**:右键宏快速按分组或全部可达执行;后者也可用视图标题栏的火箭图标。 运行前会弹出确认:「命令可能对 BMC 造成不可逆影响,是否继续?」。 每台环境内的命令**严格串行**(后一条常依赖前一条结果);环境间并发受 `concurrency` 限制(上限 8)。不可达或无凭据的环境自动跳过并标注,**不阻断其他环境**。每台环境的结果状态包括: | 状态 | 含义 | | --- | --- | | `ok` | 全部命令成功 | | `partial` | 部分命令失败 | | `aborted` | 该环境被中断(如命令超时) | | `unreachable` | 不可达 | | `error` | 无凭据或连接失败 | ### 注入终端 除批量执行外,宏还支持把命令注入到已打开的终端: - **Run Macro in Terminal...**:右键某连接 → 选择宏 → 命令注入该连接已打开的 SSH/Telnet 终端,复用连接与终端上下文,输出保留在终端中。 - **双击宏**:注入当前活动终端(任意终端;若该终端属于某 BMC 连接,则解析其内置变量)。 注入模式无法读回退出码,因此失败判断交由远端 shell:全部「继续」时按换行拼接逐条执行;存在「中断」时用 `&&` 串联,并把「继续」型命令包成不阻断链路的形式。 ### 筛选与结果 - **Filter by Tag**:视图标题栏按标签筛选宏(含「无 tag」选项)。 - 结果写入 **BMC Remote** 输出通道(OutputChannel),包含每条命令的退出码、stdout、stderr 与汇总。 ## SFTP 上传 1. 在资源管理器中右键本地文件或目录 → 「上传到 BMC 环境」。 2. QuickPick 列出全部连接并实时探测连通性,**仅可达环境可选**。 3. 选择目标 BMC 后,进度通知显示上传过程,完成后默认上传到远端 `/tmp`。 单文件使用 SFTP 直传;目录上传采用「本地 tar.gz 打包 → 传输 → 远端 `tar -xzf` 解压」流程。 > [!NOTE]说明:
> 目录上传需本机与远端均安装 `tar`(支持 `-z`),缺失会提示安装方式。无凭据或不可达的环境不可选。 ## HPM 一键升级 1. 在资源管理器中右键 `.hpm` 固件包 → 「一键升级到 BMC 环境」(仅 `.hpm` 文件出现该菜单项)。 2. 多选目标 BMC(实时探测连通性,不可达项自动忽略),仅保留可达且有凭据的环境。 3. 模态危险确认:「将对 N 个环境升级固件 xxx.hpm,升级期间 BMC 可能重启且不可中断,是否继续?」。 4. 进度通知显示整体进度,完成后给出成功 / 失败汇总;失败环境的右下角通知可一键打开输出查看原因。 升级按 BMC HTTPS REST 协议执行「登录 → 上传 → 触发 → 轮询 → 登出」,使用 443 端口,自签名证书自动放行。 相关配置项: | 配置项 | 默认值 | 说明 | | --- | --- | --- | | `bmc.upgradeConcurrency` | 3(1–8) | 多 BMC 并发度,重操作建议保守 | | `bmc.upgradePollDeadlineMs` | 600000 | 单台轮询整体硬超时(默认 10 分钟) | | `bmc.upgradePollErrorTolerance` | 5 | 轮询连续失败容错次数,兼容升级中途 BMC 重启 | | `bmc.upgradeUploadTimeoutMs` | 300000 | REST 上传 HTTP 超时(超时自动转 SFTP 兜底) | **BMC 重启期间**,进度条数值暂停在最后已知值,提示信息切换为「设备异常不通,正在尝试重新查询升级状态」,避免被误判为卡死或误报成功。常见失败原因:登录失败(检查账号密码与 443 端口)、触发失败、状态异常、轮询连续失败、上传失败、网络错误。 > [!WARNING]注意:
> 升级为**破坏性、不可逆**操作,一旦开始**不可取消**。请确认固件版本与目标环境正确后再执行。 ## 实时日志监控 1. 在连接树右键某连接 → 「实时日志监控」。 2. 插件通过 Telnet 列出 `/var/log`,归并出日志基名,QuickPick 选择目标日志。 3. 打开日志监控 Webview(标题「{连接名} 日志监控」),实时追加日志。 4. 顶部按钮:「日志信息下载」(可选「下载当前窗口内容」/「下载远程原始文件」)、「清空」、「停止」;滚动离开底部时出现「回到底部」。 核心能力: - **日志轮转无缝衔接**:跟随文件名 `tail`,在日志压缩切换瞬间自动重开新文件,流不中断。 - **时间回绕校准**:当系统时间回绕(年份小于 `rewindMinYear`,典型如 1970)时,自动估算并标注 `[估算]`,时间恢复后线性插值回填 `[校准]`。 - **断线自动重连**:默认开启,退避重连且不重置状态机。 - **下载双通道**:优先 SFTP 取回原始文件(含 `.gz`);SSH/SFTP 不可用时自动回退 Telnet 八进制传输。 - **下载后自动拼接**:解压所有 `.gz` 并按时间顺序拼接为完整日志。 相关配置项: | 配置项 | 默认值 | 说明 | | --- | --- | --- | | `bmc.logMonitor.maxBufferedLines` | 5000 | 后端缓冲日志行数上限(超出丢最旧) | | `bmc.logMonitor.tailInitialLines` | 200 | 启动时初始输出行数 | | `bmc.logMonitor.rewindMinYear` | 2000 | 年份小于该值视为回绕 | | `bmc.logMonitor.autoReconnect` | true | 断线是否自动重连 | | `bmc.logMonitor.reconnectAttempts` | 3 | 自动重连尝试次数 | | `bmc.logMonitor.downloadGzip` | true | 下载原始文件是否包含 `.gz` | > [!NOTE]说明:
> 仅开放 SSH(23 端口不通)的 BMC 无法使用日志监控。下载原始文件时密码可选(仅 SFTP 下载需要,缺失时自动回退 Telnet 传输)。 ## 配置项总览 除上述章节提到的配置外,所有配置集中在 `bmc.*` 命名空间。可通过侧栏视图标题栏的齿轮按钮(「Open Settings」)直接打开本扩展配置页。 | 配置项 | 类型 | 默认值 | 用途 | | --- | --- | --- | --- | | `bmc.connectionTimeout` | number | 30000 | SSH 连接超时(毫秒) | | `bmc.pingTimeout` | number | 3000 | 可达性 TCP 探测超时(毫秒) | | `bmc.autoMaximizeTerminal` | boolean | true | BMC 终端在编辑器区(而非底部面板)打开 | | `bmc.upgradeConcurrency` | number | 3 | HPM 升级并发度(1–8) | | `bmc.upgradePollDeadlineMs` | number | 600000 | 单台升级轮询整体硬超时 | | `bmc.upgradePollErrorTolerance` | number | 5 | 轮询连续失败容错次数 | | `bmc.upgradeUploadTimeoutMs` | number | 300000 | HPM 上传 HTTP 超时 | | `bmc.logMonitor.*` | — | — | 日志监控相关参数,见「实时日志监控」章节 | ## 与 AI 协作:MCP 工具 插件对外暴露 **27 个 MCP 工具**,可由 openUBMC Studio 的 MCP 宿主以鸭子类型发现,供 AI Agent 调用,实现自然语言驱动的批量运维与告警证据分析。凭据由安全存储服务端读取,**绝不进入工具的输入参数或返回结果**;连接、分组、宏均可用 ID 或名称(大小写不敏感)引用。 主要工具分类: - **查询与探测**:列出连接 / 分组、健康探测。 - **SSH 执行 / SFTP 上传**:单命令执行、单文件 / 目录上传。 - **连接与分组管理**:增删改、自动检测与播报开关。 - **命令宏**:列出(可按标签过滤)、运行、新增、删除。 - **HPM 升级**:指定固件与目标范围,返回逐环境结果与汇总。 - **告警证据分析**:按事件码/时间或记录 ID 编译告警证据、定点读取报告,并生成有界的告警链条分析流程。 连接、宏、上传和升级等运维类 UI 命令与对应 MCP 工具共用同一套执行核心;告警证据分析只读 dump,不会修改日志或目标 BMC。 ## 常见问题与注意事项 - **密码安全**:所有密码存于操作系统级安全存储,不落配置文件、不进日志、不在 MCP 输入输出中回显。 - **平台支持**:连接管理以 Linux 为目标平台;Windows / macOS 未纳入连接管理的测试范围。 - **可达性判据**:宏、上传、升级在执行前均以「TCP 22 通 + 有凭据」作为就绪判据,不可达环境自动跳过。 - **HPM 升级不可逆**:一旦开始不可取消,BMC 可能中途重启,请确认无误后再执行。 - **Telnet 依赖**:Telnet 接入与日志监控依赖系统 `telnet` 命令;目录上传与日志下载依赖 `tar`。 # 十、快速调试 C/C++、Lua 与北向接口 快速调试功能由“BMC 环境管理”插件提供。它根据组件中已保存到磁盘的 Git 变更自动生成调试计划,将必要文件部署到目标 BMC,重启受影响的服务并验证是否生效,适用于开发和自测阶段的快速迭代。 > [!NOTE]说明:
> 界面中的功能名称为“自动调试当前组件”。该功能用于快速部署和运行验证,不启动 GDB。如需使用断点、单步和变量查看,请执行“GDB 调试: 选择 BMC 连接并启动”,并参考[使用 openUBMC Studio 远程调试 BMC](#remote-gdb-debug)。 ## 支持的变更类型 | 变更类型 | 处理方式 | 是否构建 | | --- | --- | --- | | 普通组件或北向接口中的运行时 Lua | 使用已保存源码直接部署到运行时目标 | 否 | | 可证明为直接运行时文件的 JSON | 完成 JSON 语法和目标映射检查后直接部署 | 否 | | 北向接口映射 JSON 等生成型输入 | 隔离构建当前组件,仅部署该输入影响的运行时生成结果 | 是,一轮最多一次 | | C/C++ 源文件、头文件和 DMC 等编译型输入 | 隔离构建当前组件,部署本次构建产生的 ELF 或 Lua C 模块 | 是,一轮最多一次 | | Lua、北向配置和 C/C++ 混合变更 | 合并为同一调试计划,直接部署项与构建产物一并生效 | 按需构建一次 | README、设计文档和测试文件等无运行时影响的变更会被忽略;文件新增、删除、重命名、冲突或无法可靠映射的变更会被阻断,并在连接 BMC 前给出原因。 ## 使用前准备 1. 使用 openUBMC Studio 打开组件仓或 rackmount 仓。仓库中应包含 `mds/service.json`。 2. 将工作区标记为受信任,并确保组件代码由 Git 管理。自动调试可以采集已暂存、未暂存和未跟踪的修改。 3. 单击活动栏中的“BMC 环境管理”图标。 ![打开 BMC 环境管理](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_bmc_environment_entry.png) 4. 在“BMC 环境管理”中添加目标 BMC,并确认连接地址和凭据可用。 5. 仅包含可直接部署的 Lua/JSON 修改时,不依赖本地构建环境;C/C++ 和生成型北向配置的修改需要在支持 Bingo/Conan 的构建环境中调试。 6. 仅在已授权、可通过 Telnet 连接到具有 root 权限的 Shell 环境的开发板或调试环境中使用此功能。自动调试会临时替换运行时文件并重启受影响的 systemd 服务,不应直接用于生产设备。 ## 执行自动调试 1. 保存本次需要验证的修改。若组件内仍有未保存文件,openUBMC Studio 会要求保存后再继续。 2. 通过以下任一入口执行“自动调试当前组件”: - 在业务仓列表中选择组件仓的快捷操作“自动调试当前组件”或“按 Git 提交基线自动调试”。 ![业务仓自动调试操作](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_quick_debug_repository_actions.png) - 在“BMC 环境管理”的连接上右键单击,选择“自动调试当前组件”。 ![BMC 连接自动调试菜单](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_quick_debug_connection_menu.png) - 按 `Ctrl + Shift + P` 打开命令面板,执行“BMC 调试: 自动调试当前组件”。 3. 根据入口选择或确认目标 BMC。openUBMC Studio 会采集当前组件的 Git 变更并生成初步计划。 4. 检查修改文件数、处理策略、预估替换文件数和是否需要构建。若需要构建,单击“开始构建”;直接部署场景单击“继续”。 5. 构建和最终映射完成后,再次检查替换文件数及影响的逻辑应用,单击“确认自动调试”。 6. 等待 openUBMC Studio 完成文件上传、完整性校验、服务归并、运行时激活、服务重启和结果验证。 > [!NOTE]说明:
> 需要验证一段连续提交中的最终差异时,可以使用“按 Git 提交基线自动调试”,选择一个提交、标签或分支作为基线。普通“自动调试当前组件”只处理当前 Git 工作树修改。 ## 验证调试结果 自动调试完成后,按以下步骤验证结果: 1. 确认 openUBMC Studio 显示调试成功,并核对替换文件数和受影响服务数。 2. 打开“BMC GDB”输出通道,检查详细计划、构建输出、运行时目标、服务名称和校验结果。 3. 执行本次修改对应的业务操作,确认功能行为符合预期。 ## 切换默认调试目标 如需切换默认调试目标,执行以下操作: 1. 单击状态栏中的“BMC:当前环境名称”。 2. 在环境列表中选择目标 BMC。 状态栏显示所选环境名称时,表示默认调试目标已切换。 ## 调试生效与连续迭代 自动调试不会覆盖 BMC 的只读系统分区,而是在 `/data/bmc-debug` 下准备会话私有的最小替换集,通过临时挂载或服务配置让目标进程使用调试版本。openUBMC Studio 会进行以下校验: - Lua、JSON 和可执行文件的运行时目标必须来自本轮调试目录,且内容摘要一致。 - 共享库必须在服务重启后由目标进程从本轮调试目录加载。 - 多个逻辑应用属于同一个 systemd 服务时,会合并替换内容,该服务只重启和验证一次。 - 任一服务组激活失败时,后续服务停止执行,已经生效的服务组按逆序恢复。 修改代码并再次执行自动调试时,新版本会直接接管同一服务的上一轮 openUBMC Studio 调试会话,不需要每轮都先恢复环境,也不会叠加多层调试挂载。 > [!NOTE]说明:
> 自动调试仅支持替换目标环境中已存在的组件和文件。涉及文件新增或删除时,请构建并升级固件包进行验证。 ## 恢复调试环境 完成验证后,通过以下任一入口恢复目标 BMC: - 在“BMC 环境管理”的目标连接上右键单击,选择“恢复调试环境”。 - 在业务仓快捷操作中选择“恢复调试环境”。 - 打开命令面板,执行“BMC 调试: 恢复调试环境”。 openUBMC Studio 会根据板侧会话清单和实际挂载、临时服务配置及进程状态,仅清理能够证明属于 openUBMC Studio 的调试资源,并将服务恢复到首轮调试前的状态。若提示恢复不完整,请保留“BMC GDB”输出中的会话和路径信息,修复连接后再次执行恢复,不要直接批量删除 `/data/bmc-debug`。 ## 配置项 | 配置项 | 默认值 | 说明 | | --- | --- | --- | | `bmc.quickRestart.enabled` | `true` | 是否在组件工作区启用自动调试 | | `bmc.quickRestart.buildToolPath` | `bingo` | 构建型修改使用的构建工具 | | `bmc.quickRestart.buildArgs` | `["build", "-bt", "debug"]` | 隔离构建参数 | | `bmc.quickRestart.buildTimeoutMs` | `1800000` | 单次构建超时,默认 30 分钟 | | `bmc.quickRestart.maxChangedFiles` | `2000` | 单次自动调试允许采集的最大修改文件数 | > [!WARNING]注意:
> 自动调试用于临时验证,不能替代正式组件包、固件构建和升级流程。最终交付前仍需执行项目规定的构建、测试和发布检查。 # 十一、远程调试 BMC openUBMC Studio 通过 BMC 环境管理扩展(`openubmc.bmcstudio-bmc-remote`)提供远程 GDB 调试能力,用于对板端 C/C++ 组件进行源码级调试。扩展可以完成板端部署、`gdbserver` 启动、符号与源码路径解析和会话清理。 > [!WARNING]注意:
> 仅在已授权的隔离调试板上使用远程调试,不要对生产环境中的 BMC 执行调试操作。 ## 选择调试方式 | 场景 | 调试方式 | 是否进入 GDB | | --- | --- | :---: | | 调试板上正在运行的 systemd 业务服务 | Attach(附加)调试 | 是 | | 调试独立测试程序、工具或 carrier | Standalone(独立程序)调试 | 是 | | 仅验证新产物能否运行或查看日志 | Deploy & Restart(快速部署并重启) | 否 | | 组件仅输出 `.so` 库 | 编写 carrier 后使用 Standalone 调试 | 是 | 在“运行和调试(Run and Debug)”下拉列表中选择 `launch.json` 配置。`request` 为 `attach` 的配置使用 Attach 调试,`request` 为 `launch` 的配置使用 Standalone 调试。 ## 使用前准备 - **调试版产物**:执行 `bingo build -bt debug`,构建包含 DWARF 调试信息的产物。推荐使用 `-g -O0` 编译选项。 - **本机交叉 GDB**:安装 `gdb-multiarch` 或 `aarch64-linux-gnu-gdb`。 - **BMC 连接**:在“BMC 环境管理”中配置管理 IP 地址、SSH 端口和 Administrator 账号凭据。 - **板端 gdbserver**:通常无需手动安装,扩展会探测板端 `gdbserver` 或使用内置版本。 > [!NOTE]说明:
> 首次调试时,openUBMC Studio 会自动安装 Eclipse CDT GDB Adapter 扩展。离线环境需要提前安装该扩展。生产网络或非隔离网络建议将 `bmc.gdb.rspTransport` 设置为 `tunnel`,使 RSP 流量通过 SSH 隧道传输。 ## 使用 Attach 调试板上服务 Attach 调试会根据构建产物的二进制名称发现板端服务。以下 `launch.json` 配置将 `artifact` 指向构建产物目录或 ELF 文件: ```jsonc { "version": "0.2.0", "configurations": [ { "type": "bmc-gdb", "request": "attach", "name": "BMC 调试:附加板上服务", "bmcConnection": "lab-bmc-03", "artifact": "/home/dev/.conan2/p/b/xxxx/p", // 构建产物目录或 ELF 文件 "stopAtEntry": true, "buildIdCheck": "warn" } ] } ``` 操作步骤如下: 1. 执行 `bingo build -bt debug`,确认构建产物包含调试信息。 2. 确认板端目标服务处于 `active` 状态。 3. 在“运行和调试”下拉列表中选择 Attach 配置。 4. 按 `F5` 启动调试。 5. 在“BMC 调试会话”视图中确认各准备阶段均已通过。 扩展会根据 Build ID 比对结果选择执行策略: - **Build ID 匹配**:不部署、不替换且不重启服务,仅使用 `gdbserver --attach` 附加到当前进程。 - **Build ID 不匹配**:选择“准备调试版本并附加”可以部署调试产物、临时替换并重启服务,会话结束后自动恢复;也可以选择“继续仅汇编调试”或“选择其他 Artifact”。替换和重启前,openUBMC Studio 会显示影响确认窗口。 ## 使用 Standalone 调试独立程序 Standalone 调试适用于独立工具、测试程序、尚未安装的新服务,以及为纯库组件编写的 carrier。以下配置将 `artifact` 指向构建输出目录: ```jsonc { "version": "0.2.0", "configurations": [ { "type": "bmc-gdb", "request": "launch", "name": "BMC 调试:部署并启动程序", "bmcConnection": "lab-bmc-03", "artifact": "/home/dev/build/output", // 推荐使用目录,也可以直接指定 ELF 文件 "stopAtEntry": true, "buildIdCheck": "warn" } ] } ``` 使用 Standalone 调试时,请注意以下事项: - `artifact` 指向目录时,扩展会扫描其中的 AArch64 可执行 ELF。只有一个候选文件时自动选用,存在多个候选文件时需要手动选择。 - 产物包含共享库时,通过 `artifactRoots` 指定本次构建对应的 Conan package 目录,避免混用不同版本的同名库。 - 启动程序前,扩展会执行 ABI 预检,并报告缺少共享库或符号未定义等问题。 - 调试纯 `.so` 库时,需要编写调用目标库函数的最小 carrier,并在库函数中设置断点。 配置完成后,在“运行和调试”下拉列表中选择 Standalone 配置,按 `F5` 启动调试,并在“BMC 调试会话”视图中确认部署和启动阶段均已通过。 ## 快速部署并重启组件 Deploy & Restart 不进入 GDB。该功能会将产物部署到板端影子目录、重启服务,并通过 `/proc//maps` 验证目标进程是否加载新产物,适用于修改静态库后快速确认服务能否启动。 1. 按 `Ctrl + Shift + P` 打开命令面板。 2. 执行“BMC调试: 快速重拉组件(部署+重启,不调试)”。 3. 在“BMC GDB”输出通道中确认部署、服务重启和加载路径校验均已完成。 ## 执行日常调试操作 断点、条件断点、日志断点、单步、变量监视和调用栈等操作均使用 openUBMC Studio 原生调试界面。常用 GDB 控制台命令如下: | 命令 | 作用 | | --- | --- | | `bt`、`bt full` | 查看当前线程的调用栈,或包含局部变量的调用栈 | | `thread apply all bt` | 查看所有线程的调用栈,用于排查卡死或死锁 | | `info sharedlibrary` | 查看共享库加载和符号读取情况 | | `print <变量>`、`ptype <类型>` | 打印变量或查看类型定义 | | `info breakpoints` | 查看断点是否已验证或处于 pending 状态 | > [!WARNING]注意:
> Attach 会话中的进程由 systemd 和扩展管理,不要在 GDB 控制台中执行 `run`,请使用 `continue`、`next` 或 `step`。服务在断点处暂停过久可能触发上游超时或 watchdog,请控制暂停时间。 ## 排查常见问题 | 现象 | 原因与处理方法 | | --- | --- | | 提示“无 DWARF 调试信息” | 当前文件可能是 strip 后的 package 文件;使用 `bingo build -bt debug` 重新构建,并选择 build 目录中未 strip 的副本 | | 断点显示为灰色或未命中 | 检查源码映射和 Build ID,并使用 `info sharedlibrary` 确认目标库已加载 | | GDB 连接立即断开 | 检查“BMC GDB”输出中最早出现的错误,确认 `gdbserver` 能够启动且运行依赖完整 | | `libX.so => not found` | 将本次构建对应的精确 package 目录加入 `artifactRoots` | | 变量显示 `` | 使用 `-O0 -g` 重新构建调试产物 | | 服务重启后立即退出 | 查看 ABI 预检报告和 `journalctl -u `,排查缺少共享库或 ABI 不兼容问题 | | 调试结束后服务仍使用调试版本 | 执行“GDB调试: 清理板侧调试残留” | ## 结束调试并清理环境 - **正常结束**:单击调试工具栏中的“停止”。扩展会停止 `gdbserver`、撤销板端替换、恢复服务并删除调试产物。 - **异常退出后恢复**:重新启动扩展,等待扩展自动对账和恢复。如果仍有残留,在命令面板中执行“GDB调试: 清理板侧调试残留(崩溃会话对账)”。 完成远程调试时,请遵循以下原则: 1. 符号文件、运行文件和依赖库应来自同一次构建。 2. 排查故障时,优先查看“BMC 调试会话”视图中最早失败的阶段。 3. 使用 openUBMC Studio 的停止按钮或清理命令结束会话,确保扩展能够执行恢复流程。 # 十二、白牌包定制 本章介绍 openUBMC Studio 的 **白牌包定制** 能力:在 IDE 内通过可视化编辑器定制 BMC 白牌包的 Web 界面风格、Logo/图片、产品信息等,并一键调用 `bingo wbd_build` 构建出白牌固件包。 > [!NOTE]说明:
> 本能力由 openUBMC Studio CSR 拓扑插件(`bmcstudio_csr_topolopy`)提供。关于白牌包定制的官方概念与字段含义,另见 [白牌包定制官方指南](https://www.openubmc.cn/docs/zh/development/develop_guide/product_development/white_branding_customization_guide.html)。 白牌包定制用于把 BMC 从默认外观/信息改造为某品牌或客户专属形态,涵盖三类定制: - **配置定制**:产品联系信息、SSL 证书字段、软件名称、主机名、客户名等,写入 `web_custom.xml`。 - **风格定制**:Web 主界面风格(精美/简约/标准),写入 `style_config.json`。 - **图片定制**:浏览器图标、登录页 Logo、技术支持二维码、Web 界面图片等,写入 `filelist.conf` 声明并随包发布。 白牌包定制分两种模式: | 模式 | 作用 | |---|---| | **白牌包**(普通) | 把 BMC 定制为目标品牌/客户形态 | | **清白牌包** | 一种特殊白牌包,把已定制的 BMC **恢复为默认配置** | 两类模式共用同一套可视化编辑器与构建流程。 ## 使用前准备 - **构建工具**:需安装 `bmcgo` 或 `bingo`,且支持 `wbd_build` 子命令。插件会优先尝试 `bmcgo`,不可用时回退 `bingo`。 - **工作目录**:准备一个用作白牌目录的文件夹(可为空)。白牌定制涉及的核心文件会生成在该目录下,构建产物 `wbd-crypt-image-signed.hpm` 也会落回该目录。 ## 打开白牌定制编辑器 在资源管理器中**右键单击任意文件夹**,选择 **「定制白牌文件」** 即可打开白牌定制编辑器(webview)。 ![文件夹右键菜单「定制白牌文件」](../../images/bmc_studio/user_guide/bmc_studio_tool/wb_rightclick_menu.png) 打开时的行为遵循「缺哪个补哪个」: - 若目录下尚无白牌文件,会自动创建默认的 `filelist.conf`、`web_custom.xml`、`style_config.json`(默认风格 `beautiful`、版本 `2.00`);同时**扫描目录里已存在的图片**自动加入 `filelist.conf` 声明,避免「图片在但 filelist 没声明」的不一致。 - 若目录下已有白牌文件,则按现有配置加载到编辑器中。 > 编辑器为单例面板:同一文件夹重复右键打开会回到已打开的面板;不同文件夹各自打开独立面板,互不干扰。 ## 编辑器界面 编辑器顶部为模式切换与版本号,下方分为「配置定制」「风格定制」「图片定制」三个区域,底部为「保存」「构建」按钮。 ![白牌定制编辑器总览](../../images/bmc_studio/user_guide/bmc_studio_tool/wb_editor_overview.png) ### 模式与版本号 - **模式**:`白牌包` / `清白牌包` 单选。切换到清白牌模式时,会隐藏「风格定制」段、图片按 BMC 路径分组展示、构建按钮文案变为「清白牌包构建」。图片在两种模式间共享,切换不重置。 - **版本号**:格式 `x.y`(`y` 最多两位,如 `1.0`、`2.0`、`1.10`),保存后写入 `web_custom.xml` 的 `` 头部。加载时从 XML 头部解析回填。必填且需通过正则校验,否则保存/构建按钮禁用。 ### 配置定制(web_custom.xml) 可视化表单对应 `web_custom.xml` 的 17 个属性,每项带 tooltip 说明,只需填写需要的项: ![配置定制表单](../../images/bmc_studio/user_guide/bmc_studio_tool/wb_config_fields.png) | 字段 | 说明 | |---|---| | `sysContact` | 维护联系人 | | `dBannerContent` | 默认横幅内容 | | `PreSSLSeverCommonName` / `PreSSLSeverOrgName` / `PreSSLSeverCountry` | 预置 SSL 证书通用名/组织/国家 | | `OfficalWeb` / `SupportWeb` | 官网 / 技术支持网址 | | `Copyright` | 版权信息 | | `Email` / `Phone` | 邮箱 / 电话 | | `DownloadKVMLink` | KVM 下载链接 | | `DocSupportFlag` | 文档支持标记(取值 `0`/`1`) | | `SoftwareName` | 软件名称 | | `CustomAlarmName` | 自定义告警名称 | | `CustomManufacturer` | 自定义厂商 | | `HostName` | 主机名 | | `Customer` | 客户名 | 保存时只输出非空字段;`DocSupportFlag` 取值必须为 `0` 或 `1`。 ### 风格定制(style_config.json) 选择 Web 主界面风格 `pageStyle`: - `beautiful`(精美,默认) - `simple`(简约) - `standard`(标准) ![风格定制](../../images/bmc_studio/user_guide/bmc_studio_tool/wb_style.png) `pageStyle` 在白牌模式下必填(不选会校验失败,保存/构建禁用);清白牌模式下该段隐藏,`style_config.json` 强制写空对象 `{}`。 ### 图片定制(filelist.conf) 可定制 8 张图片,每张对应固定的 BMC 路径与文件名,已按类型限制只能选择对应类型图片: | 分组 | 文件名 | BMC 路径 | |---|---|---| | 浏览器图标 | `favicon.ico` | `/data/opt/pme/web/htdocs` | | 技术支持二维码 | `code1.png` | `/data/opt/pme/web/htdocs/theme/custom/img` | | Web 界面图片 | `login.png`、`login_logo.png`、`img_01.png`、`img_02.png`、`img_03.png`、`header_logo.png` | `/data/opt/pme/web/custom` | ![图片定制](../../images/bmc_studio/user_guide/bmc_studio_tool/wb_images.png) 每张图卡片支持「选择图片 / 更换 / 删除」;保存时所选图片会被复制到白牌目录(文件名与 `filelist.conf` 的声明一致)。 ## 保存 点击「保存」执行两步: 1. **同步图片**:把所选图片复制到白牌目录,文件名改为与 `filelist.conf` 声明一致; 2. **生成文件**:按当前配置写出 `filelist.conf`、`web_custom.xml`、`style_config.json`。 保存成功后右下角提示「白牌配置已保存」。 ## 构建白牌包 点击「白牌包构建」(清白牌模式为「清白牌包构建」),流程如下: 1. **校验**:`pageStyle` 必填、`DocSupportFlag` 合法、版本号格式正确(实时校验,通过后才允许构建); 2. **自动保存**:有未保存改动时先自动保存,保存成功后再构建; 3. **前置文件检查**:核对 `filelist.conf` 声明的文件是否都实际存在; - 仅图片缺失 → 自动清理 `filelist` 中缺失声明并提示重新构建; - 核心文件(`web_custom.xml`/`style_config.json`)缺失 → 报错,需手动处理; 4. **临时目录构建**:把白名单文件(`filelist.conf`、其声明的文件、可选 `beforeaction.sh`/`afteraction.sh`)复制到临时目录,在其中执行 `bingo wbd_build`,终端面板实时输出进度(可手动终止); 5. **产物落回**:构建成功后产物 `wbd-crypt-image-signed.hpm` 自动复制回原白牌目录(同名覆盖),右下角提示带完整路径; 6. **按钮状态**:构建期间按钮变为「构建中...」并禁用,结束后无论成功/失败/终止都恢复。 ![构建终端与成功提示](../../images/bmc_studio/user_guide/bmc_studio_tool/wb_build_terminal.png) > [!NOTE]说明:
> 为什么要切到临时目录:`bingo` 命令清单对当前工作目录敏感,在 manifest 项目根或组件目录下会过滤掉 `wbd_build`。因此构建一律先切到脱离任何 manifest 树的临时目录执行,跑完再把产物复制回来。 **工具回退**:优先 `bmcgo`,不可用回退 `bingo`;执行中若返回退出码 `127`(命令不存在)会自动换另一个工具重试一次,其他业务错误不重试。 **常见失败提示**: | 场景 | 提示 | |---|---| | 缺图片(可自动清理) | 已自动清理 filelist 中缺失的图片声明:xxx,请重新构建 | | 缺核心文件 | 白牌目录缺少必要文件:xxx,请重新保存完整配置 | | bingo 退出码非 0 | 白牌包构建失败(退出码 N),请查看终端输出 | | 用户 Ctrl+C | 白牌包构建已终止 | | 工具未找到 | 未找到打包工具,请先安装 | ## 清白牌包定制(恢复默认) 清白牌包用于把 BMC 从已定制状态恢复为默认配置,三类恢复默认规则: - **配置定制**:`web_custom.xml` 写默认值; - **风格定制**:`style_config.json` 写空对象 `{}`; - **图片定制**:要恢复默认的图片在 `filelist.conf` 中将 `Name=` 改为 `CLEAR_ALL`(BMC 路径不变),并在白牌目录创建一个空 `CLEAR_ALL` 文件。 切到清白牌模式后,8 张图按 BMC 路径分 3 组展示(浏览器图标 / 技术支持二维码 / Web 界面图片),每组有组级复选框可整组恢复默认。 ![清白牌模式分组与恢复默认](../../images/bmc_studio/user_guide/bmc_studio_tool/wb_clear_mode.png) > [!NOTE]说明:
> **CLEAR_ALL 按路径去重**:BMC 检测到某路径下有 `CLEAR_ALL` 文件就清空整个目录,与 filelist 中声明数量无关。因此同一 BMC 路径下多张图标记恢复默认时,`filelist.conf` 只生成一条 `Name=CLEAR_ALL`(例如 Web 界面图片组 6 张共用一个路径 → 只写 1 条)。 清白牌构建链路与白牌包完全一致(临时目录 + 白名单复制 + `bingo wbd_build` + HPM 落回原目录);`filelist.conf` 的 `Version` 为 `2.02`(白牌模式为 `2.00`)。 ## 常见问题与注意事项 - **按钮一直禁用**:检查 `pageStyle` 是否已选(白牌模式必填)、`DocSupportFlag` 是否为 `0`/`1`、版本号是否符合 `x.y`(`y` 最多两位)。 - **图片显示但构建报缺失**:以文件实际存在为准;缺图片会被自动清理,按提示重新构建即可。 - **找不到 `wbd_build` 命令**:不要在 manifest 项目根或组件目录下手动执行;编辑器的临时目录构建已规避此问题。若仍报工具未找到,请确认 `bmcgo`/`bingo` 已安装并在 PATH。 - **产物位置**:`wbd-crypt-image-signed.hpm` 总是生成并覆盖回右键打开的白牌目录,不会留在临时目录。 - **清白牌模式风格段消失**:属预期,清白牌会把 `style_config.json` 强制写为 `{}`。 # 十三、Manifest 配置与一键出包 ## Manifest 配置 Manifest 配置功能用于可视化查看和修改 `manifest.yml` 中的出包配置,包括构建变体、默认特性、组件依赖和组件特性。配置面板会结合 lockfile 显示组件的实际版本和生效配置,并在写回文件时尽量保留原有注释、缩进和其他未修改内容。 > [!NOTE]说明:
> Manifest 配置功能当前支持 Linux 环境,完整解析组件版本和特性需要安装 Conan 2.x。
> 建议将 manifest 仓根目录作为受信任的工作空间打开,并确认目标产品的配置文件位于 `build/product/<产品线>/<机型>/manifest.yml`。 ### 打开出包配置 1. 在 openUBMC Studio 中打开需要配置的 `manifest.yml` 文件。 2. 点击依赖配置上方的“打开出包配置”。也可以打开命令面板,执行“Manifest: 打开出包配置面板(变体/依赖/默认特性)”。 3. 在“出包配置”页面查看 schema 类型、平台包和 lockfile 状态,以及构建变体、默认特性、组件依赖和诊断结果。 ![Manifest 配置入口](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_manifest_config_entry.png) ![出包配置页面](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_manifest_config_panel.png) ### 配置构建变体和默认特性 1. 在“构建变体”区域选择需要配置的 `manufacture` 或 `tosupporte` 变体。未选择变体时,页面展示并修改基线配置。 2. 查看当前变体的 `build_type`、`signature_type` 和 `platform.package` 信息。选择变体后,依赖列表展示该变体与基线合并后的生效结果。 3. 在“默认特性 default_options”区域修改已有特性,或点击“新增一项”添加特性。 4. 点击“保存默认特性”,将配置写回当前基线或变体。 > [!NOTE]说明:
> 切换变体或清空默认特性前,如果存在未保存的修改,openUBMC Studio 会提示是否丢弃修改。 ### 配置组件依赖和特性 1. 在“依赖 dependencies”区域查看基础组件,`dt_dependencies`(gcov)、`debug_dependencies`(dev)、`qemu_dependencies`(qemu)分别以独立卡片展示。 2. 根据需要执行以下操作: - 点击“插入”,从候选列表中向当前依赖类型添加组件。 - 点击“特性”,展开组件的 `options` 和 `tool_options`。特性值会标识为“显式”、“继承默认”或“recipe 默认”。 - 配置变体时,点击“删除”或“取消删除”,设置或取消组件的 `action: delete` 状态。 - 点击“移除”,删除当前基线或变体中直接声明的组件。 3. 修改组件特性后,点击“保存到 manifest”。 ![构建变体和默认特性配置](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_manifest_variant_options.png) > [!NOTE]说明:
> 当 `platform.package` 已配置时,平台整包中的组件会显示“锁”标识,其版本和特性不可在产品 Manifest 中定制。
> 变体中继承自基线的组件不能直接从变体中移除,如需删除其声明,请切换到基线操作。 ### 查看 SDK 组件 1. 在 `platform.conan` 配置上方点击“查看 ibmc_sdk 组件”,或在 `openubmc_sdk.conan` 配置上方点击“查看 openubmc_sdk 组件”。 2. 在“SDK 组件”页面查看组件名称、版本或 Conan 引用,以及组件清单的来源。 3. 在搜索框中输入组件名称,可以筛选当前 SDK 中的组件。 ![SDK 组件列表](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_manifest_sdk_components.png) ## 组件与固件联合构建 组件与固件联合构建功能用于在业务组件仓中构建本地 Conan 包,并将该组件集成到目标产品的调试固件中。本章节适用于需要验证组件改动或生成联调固件的组件开发人员。 ### 准备构建环境 执行组件构建前,请准备以下环境: - 受信任的 Linux 本地、WSL 或 SSH Remote 工作空间 - 包含有效 `mds/service.json` 的业务组件仓 - 安装在 Extension Host 中的 Conan 2.x - 登录 Shell 可以执行 `bmcgo` 或 `bingo` 执行组件与固件联合构建时,还需要满足以下要求: - Extension Host 中已安装 Git - 目标 Manifest 可以从同一 Extension Host 访问 - 目标 Manifest 位于 `build/product/<产品线>/<机型>/manifest.yml` - 目标 Manifest 所在仓库具有有效的 Git HEAD - 目标 Manifest 的修改已经保存 - 目标 Manifest 未配置非空的 `include` > [!NOTE]说明:
> 如果同时检测到 `bmcgo` 和 `bingo`,openUBMC Studio 默认使用 `bmcgo`,并允许用户切换构建工具。组件构建面板与固件出包页面共用此设置。仅检测到 `bingo` 时,openUBMC Studio 直接使用 `bingo`。 ### 打开组件构建面板 1. 将包含 `mds/service.json` 的业务组件仓作为工作空间打开。 2. 在资源管理器中展开“业务组件仓快捷入口”。 3. 展开“openUBMC Studio Local View”。 4. 单击“组件构建”。 5. 等待构建计划解析完成。 通过资源管理器中的快捷入口打开组件构建面板。 ![打开组件构建快捷入口](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_component_build_shortcut.png) 组件构建面板默认进入“仅组件模式 · 不关联 Manifest”,并显示组件包、组件 options、阻断项和诊断信息。 ![查看组件构建面板](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_component_build_panel.png) 展开“运行环境与命令详情”,可以查看登录 Shell、工具路径、命令预览和目标 profile。展开“查证与会话技术详情”,可以查看组件包身份、依赖图和沙箱覆盖的证据位置。 ### 仅构建组件 仅构建组件适用于只需要生成本地组件包、不需要生成固件的场景。此模式不创建 Manifest 沙箱,也不执行 `install_sdk`、`app` 或 `publish`。 1. 确认页面处于“仅组件模式”。 2. 如果已经选择固件目标,单击“返回仅组件模式”。 3. 在“组件 options”区域选择需要的值。 4. 确认“阻断项”为空。 5. 根据需要展开“运行环境与命令详情”,检查命令预览。 6. 单击“仅构建组件”。 7. 在 Task 终端中查看构建输出。 8. 构建完成后,确认“执行状态”为“成功”。 9. 展开“查证与会话技术详情”,查看“组件独立构建包身份证明”。 只能选择当前 `mds/service.json` 中声明且类型一致的 option 值。openUBMC Studio 使用 debug build type 和 stable channel 构建组件。Task 终端会显示组件构建过程和最终结果。 Task 退出码为 0 后,openUBMC Studio 会从本地 Conan cache 验证本次组件包的 reference、RREV、package ID、PREV、settings 和 options。如果无法唯一确定本次组件包,构建结果仍会标记为失败。 ![查看组件包身份证明](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_component_build_package_identity.png) > [!WARNING]注意:
> 组件 Task 在源码仓根目录中执行,可能创建或刷新 `conanbase.py`、`temp/`、`gen/` 以及 `mds/service.json` 中声明的代码生成目录。如果其他受保护文件发生变化,openUBMC Studio 会停止后续流程,但不会自动回滚文件。执行构建前,请保存重要修改。 ### 构建组件并转到固件出包 组件与固件联合构建适用于生成包含当前组件改动的调试固件。openUBMC Studio 会在隔离的 Manifest 沙箱中应用组件包,不会修改源 Manifest、SDK 或 subsystem 文件。 #### 选择固件目标 1. 单击“选择固件目标”(已选择目标时显示为“更换固件目标”)。 2. 选择需要构建的 `tosupporte` 或 `manufacture` 包型。 3. 如果列表中没有目标文件,单击“选择其他 manifest.yml…”。 4. 选择当前 Extension Host 可以访问的 `manifest.yml`。 5. 等待构建计划刷新完成。 6. 确认页面标题下方显示正确的产品线、机型和包型。 固件目标列表显示已发现的产品、包型和 Manifest 路径。选择结果会自动缓存。 ![选择固件目标](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_component_firmware_target_selector.png) 选择固件目标后,组件 options 由目标 Manifest 的生效配置锁定,不能在面板中修改。如果源码版本不满足目标版本约束,页面会显示非阻断提示;`app` 和 `publish` 仍会验证实际选中的组件包。无法安全解析配置或 option 时,页面会阻止构建。 #### 执行联合构建 1. 确认“阻断项”为空。 2. 展开“运行环境与命令详情”。 3. 检查 `install_sdk`、组件构建、`app` 预检和 `publish` 命令。 4. 单击“构建组件并转到固件出包”。 5. 在 Task 终端中查看构建输出。 openUBMC Studio 按以下顺序执行联合构建: 1. 复制 Manifest 的 Git 源输入并创建临时沙箱。 2. 在沙箱中将所选包型的 `build_type` 设置为 `debug`。 3. 使用 stable channel 执行 `install_sdk`。 4. 使用目标 profile 构建并验证当前组件包。 5. 在沙箱当前包型的 `dependencies` 中写入组件的精确 reference、RREV 和业务 options。 6. 使用 stable channel 执行 `app` 依赖图预检。 7. 验证依赖图选择的组件 recipe、目标 profile 和业务 options。 8. 打开“固件出包”页面并自动启动 stable channel 的 `publish` 任务。 #### 验证联合构建结果 1. 在组件构建面板中确认“执行状态”为“成功”。 2. 确认“组件包证明”和“app 目标包证明”均已通过。 3. 在自动打开的“固件出包”页面中查看计划组件和本次实际组件。 4. 确认固件任务退出码为 0。 5. 在“自动发现的本次产物”区域下载需要的固件产物。 在“固件出包”页面中核对计划组件和本次实际组件,确认固件使用了本次构建的组件包。 ![核对计划组件和实际组件](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_component_firmware_package_compare.png) 在“自动发现的本次产物”区域下载需要的固件文件。 ![下载自动发现的固件产物](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_component_firmware_artifacts.png) 组件会话、固件出包交接和固件任务分别记录结果。组件页面显示成功,表示组件包身份和 `app` 选包已经验证;固件是否成功以固件出包页面中 `bmcgo` 或 `bingo` 的退出码为准。未自动发现 HPM、ZIP 或 QEMU 文件不会改变固件任务的结果,需要结合 `output` 目录和完整的 `task.log` 确认实际文件。 选择合法的 `tosupporte/qemu` 目标时,`app` 和 `publish` 会自动启用 QEMU 构建参数。固件出包页面会尝试发现 `.data.gz` 和 `.cpio.gz` 产物并提供下载入口。后续操作请参见[一键出包](#一键出包)。 ### 停止构建任务 关闭组件构建页面不会停止正在运行的任务。重新打开同一组件仓,可以继续查看当前会话。 - 组件构建阶段:单击“取消” - 固件构建阶段:在“固件出包”页面中单击“终止任务” ### 清理构建沙箱 1. 等待固件任务进入成功、失败或取消状态。 2. 下载需要保留的固件产物。 3. 返回组件构建页面。 4. 单击“清理本次沙箱”。 5. 在确认窗口中单击“清理本次沙箱”。 开始下一轮构建时,也可以在提示窗口中单击“清理并继续”。 > [!WARNING]注意:
> 清理沙箱会永久删除本次联合构建生成的临时 Manifest、日志和固件产物,且无法恢复。openUBMC Studio 重启后也不保证能够访问旧会话产物。执行清理前,请下载需要保留的产物。 ### 处理常见问题 | 诊断码或现象 | 处理建议 | |--------------|----------| | `WORKSPACE_UNTRUSTED`、`UNSUPPORTED_PLATFORM` | 在受信任的 Linux 本地、WSL 或 SSH Remote 工作空间中重新打开组件仓。 | | `BUILD_TOOL_NOT_FOUND`、`SHELL_ENV_RESOLVE_FAILED` | 确认登录 Shell 可以执行 `bmcgo` 或 `bingo`,并可以执行 Conan 2.x;也可以单击“配置工具路径”。 | | `TARGET_MANIFEST_INVALID`、`MANIFEST_GIT_CONTEXT_UNAVAILABLE` | 保存并检查目标 Manifest;确认已安装 Git,目标仓具有有效 HEAD,且没有非空 `include`。 | | `PLAN_STALE` | 组件源码、`mds/service.json`、Manifest 或相关 SDK 输入在计划生成后发生变化;保存文件并单击“刷新计划”。 | | `PROFILE_DRIFT`、共享构建资源等待 | 避免在其他 Studio 窗口或外部终端中同时修改同一 Conan profile 或 cache,等待当前任务结束后刷新计划。 | | `COMPONENT_VERSION_OUT_OF_RANGE` | 此提示不会阻止构建。确认源码版本符合本次调试目的后继续,实际选包仍由沙箱中的 `app` 和 `publish` 依赖图验证。 | | `INTEGRATION_MISMATCH` | 展开“查证与会话技术详情”,检查独立组件包、整包目标组件包、`app` 依赖图和 options 差异。 | | `MANIFEST_INPUT_LIMIT_EXCEEDED`、`INSUFFICIENT_DISK_SPACE` | 清理 Manifest 仓中未忽略的大文件或释放沙箱所在卷空间;确有需要时在“组件构建”设置中调整输入上限或最低可用空间。 | | `DEBUG_PACKAGE_SIGNING_UNAVAILABLE` | 此提示不会阻止构建。固件签名或占位行为由 `bmcgo` 或 `bingo` 决定,请以固件任务退出码和产物为准。 | | `FIRMWARE_PACKAGE_HANDOFF_FAILED` | 组件包和 `app` 预检可能已经成功;根据提示中的沙箱 Manifest 和覆盖报告,在固件出包页面检查阻断项并重试。 | ## 一键出包 一键出包功能可以根据产品 `manifest.yml` 中的 `tosupporte` 和 `manufacture` 包型生成构建命令,完成环境预检并启动固件构建。构建过程中可以查看计划组件、实际组件、构建进度和日志,构建完成后可以下载本次生成的固件产物。 > [!NOTE]说明:
> 执行一键出包需要使用受信任的 Linux 本地、WSL 或 SSH Remote 工作空间,manifest 仓及其 `output` 目录需要具备写权限。
> 用户登录 Shell 环境中需要存在 `bmcgo` 或 `bingo` 命令。检测到 `bmcgo` 时默认使用 `bmcgo` 并支持切换到 `bingo`;仅检测到 `bingo` 时直接使用 `bingo`。 ### 选择机型和包型 可以通过以下任一方式进入出包流程: - 在资源管理器的“快捷入口”中展开“openUBMC Studio Local View”,点击对应机型的出包入口,例如 `BMC/openUBMC 出包`。 - 打开产品 `manifest.yml`,点击目标 `tosupporte` 或 `manufacture` 包型上方的入口,例如 `default 出包入口`,直接进入该包型的出包页面。 ![manifest 仓一键出包快捷入口](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_manifest_package_shortcut.png) 通过“出包配置”页面或“快捷入口”进入时,按以下步骤选择包型: 1. 在“固件包类型选择”页面查看当前机型的所有包型。页面按照“To Support E”和“Manufacture”分组,显示包型名称、构建类型、包名和签名类型。 2. 可以在搜索框中按照包型名称、分类或包名筛选。 3. 在目标包型右侧点击“进入出包页”。无效包型会显示具体的配置错误,需要修改 `manifest.yml` 并刷新后再选择。 ![固件包类型选择页面](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_manifest_package_selector.png) ### 执行出包预检 1. 进入“固件出包”页面后,等待 openUBMC Studio 读取 Manifest、组件清单和构建环境。 2. 在“构建选择”区域选择构建类型。若 `manifest.yml` 已配置 `build_type`,构建类型不可修改。 3. 查看出包信息、构建命令预览和计划组件。组件来源默认折叠,可按需展开查看。 4. 如果“组件来源”中存在支持获取的缺失 SDK 制品,点击“从 Conan 获取”,完成后页面会自动重新加载出包信息。 5. 点击“一键预检”重新检查当前配置和环境。如果页面显示“预检阻断”,请根据提示保存 Manifest、信任工作空间、修复配置或补齐构建工具后再次预检。 ![固件出包预检页面](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_manifest_package_precheck.png) ### 执行出包任务 1. 预检通过后,点击页面顶部的“开始出包”。openUBMC Studio 会根据包型自动生成参数,并通过 Task 终端启动构建。 2. 任务启动后,页面会自动定位到“构建阶段”,依次展示“计划就绪”、“有效 manifest”、“依赖图就绪”和“产物就绪”状态。 3. 构建期间可以在 Task 终端查看实时输出,也可以在页面查看本次实际组件以及计划和实际配置之间的差异。 4. 如需停止构建,点击“终止任务”。关闭出包页面不会自动终止正在执行的任务,重新打开同一包型的出包入口可以继续查看当前会话。 ### 查看日志和下载产物 1. 构建成功、失败或取消后,页面会自动定位到“构建日志”,并显示 `temp/log/task.log` 末尾最多 128KiB 的内容。 2. 构建失败时,可以点击“只看异常上下文”或“跳到最近异常”辅助定位问题;点击“打开完整 task.log”可以查看完整日志。 3. 构建成功后,在“本次新产物”区域根据包型查看本次构建生成的 HPM、发布 ZIP 等文件,点击“下载”并选择保存位置。Remote 工作空间中的产物也可以下载到本机。 4. 在“最近记录”区域查看当前工作区近期出包任务的状态、执行时间和产物数量。 ![构建日志和产物下载](../../images/bmc_studio/user_guide/bmc_studio_tool/studio_manifest_package_result.png) > [!NOTE]说明:
> 日志中的异常高亮仅用于提供排查线索,不代表 openUBMC Studio 已经确定失败根因,请结合完整日志确认。
> “本次新产物”仅展示当前构建会话中新生成且校验通过的文件,不会将历史 `output` 目录中的文件作为本次结果。 # 十四、出包签名配置 openUBMC Studio 签名配置扩展(`bmcstudio_sign_config`)提供可视化的 HPM 签名档案管理、本地自签名证书生成和 EEPROM 签名配置。开发者可以在 CSR 出包和白牌包构建时复用签名档案,无需手动编辑 `.bmcgo/config` 中的 INI 配置。 ## 选择出包签名档案 CSR 出包和白牌包构建页面均支持选择已有签名档案: - **单 CSR 出包**:在出包窗口的签名档案下拉列表中选择档案。如果工作目录的 `.bmcgo/config` 中存在同名 INI 节,界面会显示配置冲突提示。 - **多 CSR 出包**:通过 QuickPick 选择签名档案。 - **白牌包构建**:在白牌定制编辑器的构建流程中选择签名档案。 ![选择 CSR 出包签名档案](../../images/bmc_studio/user_guide/bmc_studio_tool/sign_config_csr_build.png) 如果没有可用档案,单击签名档案下拉列表旁的“新增签名档案”,进入签名配置界面。 ## 管理 HPM 签名档案 HPM 签名档案用于保存签名方式、密钥路径和服务端参数,可以在多次出包任务之间复用。签名配置界面包含以下页签: | 页签 | 说明 | | --- | --- | | 签名管理 | 新增、编辑和删除签名档案 | | 证书生成 | 生成本地自签名所需的证书文件 | | 证书吊销 | 吊销签名者证书并更新 CRL | ![HPM 签名配置页签](../../images/bmc_studio/user_guide/bmc_studio_tool/sign_config_tabs.png) ### 新增 HPM 签名档案 支持以下签名方式: | 签名方式 | 说明 | 适用场景 | | --- | --- | --- | | 本地自签名 | 使用本地 OpenSSL 密钥签名 | 开发调试 | | 简易签名服务器 | 通过 HTTP 请求签名服务器 | 内部 CI | | 远程签名 | 通过 SignServer 远程签名 | 正式发布 | 不同签名方式需要配置以下字段: | 签名方式 | 配置字段 | | --- | --- | | 本地自签名 | 根证书(DER)、吊销列表(CRL)、签名证书、时间戳证书、时间戳配置 | | 简易签名服务器 | 根证书(DER)、证书标识符、签名服务器地址、TLS 验证方式 | | 远程签名 | SignServer 地址、时间戳服务器地址、根证书(DER)、吊销列表(CRL)、Worker 路由标识、签名哈希算法、TLS 验证方式、Keyfactory 模式 | 1. 打开“签名管理”页签。 2. 单击“新增签名档案”。 3. 选择签名方式。 4. 填写对应的证书路径、密钥路径或服务端参数。 5. 单击“保存”。 ![新增 HPM 签名档案](../../images/bmc_studio/user_guide/bmc_studio_tool/sign_config_add_profile.png) > [!NOTE]说明:
> 保存时会自动检查密钥和证书文件是否存在。路径无效时,界面会显示错误并阻止保存。 ### 编辑或删除 HPM 签名档案 - **编辑档案**:在档案列表中单击目标档案,修改配置后单击“保存”。 - **删除档案**:单击档案旁的“删除”,在确认窗口中继续操作。 ## 创建本地自签名证书 首次使用本地自签名方式时,可以在“证书生成”页签中生成所需文件。该功能依赖 OpenSSL,请先执行 `openssl version`,确认系统已安装 OpenSSL。 需要填写以下信息: | 字段 | 说明 | | --- | --- | | 输出目录 | 证书文件的生成目录 | | 组织名(O) | 证书中的组织名称 | | 根私钥保护密码 | PFX 根私钥的加密密码,不少于 12 个字符,可以通过“随机生成”创建 | 操作步骤如下: 1. 打开“证书生成”页签。 2. 填写输出目录、组织名和根私钥保护密码。 3. 根据需要填写国家、证书通用名称和各证书有效期。RSA 密钥长度固定为 4096 位。 4. 单击“一键生成全套证书”。 ![生成本地自签名证书](../../images/bmc_studio/user_guide/bmc_studio_tool/sign_config_cert_generate.png) 生成的文件如下: | 文件 | 说明 | | --- | --- | | `rootca.pfx` | 包含私钥的根 CA 证书,采用 PKCS#12 格式 | | `rootca.der` | DER 格式的根 CA 证书 | | `rootca.crl` | 证书吊销列表 | | `signer.pem` | 包含私钥的签名者证书 | | `ts_signer.pem` | 时间戳签名者证书 | | `tsa.cnf` | 时间戳配置文件 | 5. 将所需文件路径填写到本地自签名档案中。 > [!NOTE]说明:
> 签名档案使用 `rootca.der`、`rootca.crl`、`signer.pem`、`ts_signer.pem` 和 `tsa.cnf`。`rootca.pfx` 包含根 CA 私钥,仅在证书吊销时使用,不需要填写到签名档案中。 ## 吊销签名者证书 签名私钥泄露时,可以在“证书吊销”页签中吊销签名者证书并更新 CRL。 | 字段 | 说明 | | --- | --- | | 证书目录 | 包含 `rootca.pfx` 和 `rootca.crl` 的目录 | | 根私钥保护密码 | 生成证书时设置的 PFX 密码 | | 签名者证书 | 需要吊销的 `signer.pem` 文件路径 | 1. 打开“证书吊销”页签。 2. 填写证书目录、根私钥保护密码和签名者证书路径。 3. 单击“吊销并更新 CRL”。 ![吊销签名者证书](../../images/bmc_studio/user_guide/bmc_studio_tool/sign_config_revoke.png) > [!WARNING]注意:
> 证书吊销不可逆。吊销后,签名者证书会写入 CRL,继续使用该证书签名 HPM 包将失败。如需继续签名,请创建新的签名者证书。 ## 管理 EEPROM 签名档案 EEPROM 签名与 HPM 签名是两条独立链路。HPM 签名使用 CMS 对固件包外层进行签名,EEPROM 签名使用 ECDSA P-256/SHA-256 对写入 EEPROM 的原始二进制内容进行签名。CSR 出包时可以分别配置两类签名。 CSR 出包页面中的 HPM 签名和 EEPROM 签名分别使用独立的下拉列表。选择“使用现有配置”可以保留当前配置;单击 EEPROM 下拉列表旁的“新增签名档案”可以打开 EEPROM 签名配置页面。 ![EEPROM 签名档案列表](../../images/bmc_studio/user_guide/bmc_studio_tool/sign_config_eeprom.png) EEPROM 签名档案支持以下签名方式: | 签名方式 | 说明 | | --- | --- | | 本地自签名 | 使用本地 ECC 密钥签名 | | 简易签名服务器 | 通过 HTTP 请求签名服务器 | | 远程 ECC 签名 | 通过 SignServer 远程签名 | ![新增 EEPROM 签名档案](../../images/bmc_studio/user_guide/bmc_studio_tool/sign_config_eeprom_form.png) > [!NOTE]说明:
> EEPROM 签名档案与 HPM 签名档案独立管理,互不影响。 ## 常见问题 - **保存时提示路径不存在**:检查密钥和证书文件路径。签名配置界面会在保存时验证文件是否存在。 - **出包时提示全局配置冲突**:工作目录的 `.bmcgo/config` 中存在同名 INI 节。请确认是否使用签名档案覆盖已有配置。 - **证书生成失败**:执行 `openssl version`,确认 OpenSSL 已安装并已加入 `PATH`。 # 十五、常用操作 ## 快捷键参考 openUBMC Studio提供了丰富的快捷键支持,帮助开发者提高工作效率: | 功能 | 快捷键 | 说明 | |------|--------|------| | 转到定义 | `Ctrl + 点击` 或 `F12` | 跳转到符号的定义位置 | | 转到引用 | `Shift + F12` | 查看符号的所有引用位置 | | 查找 | `Ctrl + F` | 在当前文件中查找 | | 全局搜索 | `Ctrl + Shift + F` | 在整个项目中搜索 | | 保存 | `Ctrl + S` | 保存当前文件 | | 全部保存 | `Ctrl + Shift + S` | 保存所有打开的文件 | | 撤销 | `Ctrl + Z` | 撤销上一步操作 | | 重做 | `Ctrl + Y` | 重做上一步操作 | | 快速打开文件 | `Ctrl + P` | 快速打开项目中的文件 | | 命令面板 | `Ctrl + Shift + P` | 打开命令面板,执行各种命令 | | 切换侧边栏 | `Ctrl + B` | 显示/隐藏侧边栏 | > [!NOTE]说明:
> 可以在“文件”>“首选项”>“键盘快捷方式”中查看和自定义所有快捷键。 ## 设置与配置 ### 修改用户设置 1. 点击菜单栏“文件”>“首选项”>“设置”,或使用快捷键 `Ctrl + ,` 2. 在设置页面中,可以修改各类配置: - 编辑器设置(字体、主题、缩进等) - CSR规则检查设置 - 快捷键配置 - 扩展设置 # 十六、卸载 openUBMC Studio 如果您不再需要使用openUBMC Studio,可以通过以下步骤卸载。 ## Windows系统卸载 1. 打开“控制面板”>“程序”>“程序和功能” 2. 在程序列表中找到“openUBMC Studio” 3. 右键点击,选择“卸载” 4. 按照卸载向导提示完成卸载 ## 卸载后清理 > [!NOTE]说明:
> 卸载程序不会删除用户配置文件和工作空间数据,如需完全清理,请手动删除以下目录:
> > - 用户数据目录:`%APPDATA%\.bmc-Studio`
> - 远程连接服务目录:`~/.bmcstudio-server` > > **注意**:
> 删除配置目录和工作空间数据是不可逆操作,请确保已备份重要数据后再执行删除。 --- # openUBMC Studio使用指导 > URL: https://openubmc.cn/docs/zh/latest/common_tools/bmc_studio/user_guide/bmc_studio_usage_instructions.html > Language: zh BMC Studio 是一款可视化的配置工具,用于辅助 BMC 进行灵活定制。支持配置 CSR、资源协作接口、MDS、接口映射,同时也支持在线调试、板卡定制、原生开发、接口定制以及一键出包等功能。 # 简介 BMC Studio分为“开发任务”和“操作模块”两个板块,您可以在首页单击“切换视图”进行切换。 - 操作模块 ![首页-操作模块](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/home_operation_modules.png) - **CSR配置**:CSR描述了板卡上的具体组成结构,包括链路拓扑和器件描述信息,记录板卡的静态硬件信息。 - **资源协作接口配置**:支持从系统视角对BMC软件管理功能的抽象定义,包含接口和路径的定义,先定义接口,再使用路径实现这个接口。 - **MDS配置**:APP的模型描述文件,定义APP如何管理资源协作接口和具体存在的私有属性。 - **接口映射配置**:支持定义接口请求与资源协作接口的对应关系、接口及属性的校验信息、属性执行映射的前置与后置处理等。 - 开发任务 ![首页-开发任务](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/home_development_tasks.png) - **板卡定制**:支持对新增的板卡器件进行定义以及对已有板卡的器件适配。 - **原生开发**:支持开发新的APP功能。 - **接口定制**:支持定制北向接口和对Redfish、WebREST、CLI、SNMP接口映射配置的新增、修改和删除。 - **编译构建**:上传工具生成的CSR文件,对接编译服务器,实现一键编译出包。 - **仿真验证**:支持管理Qemu设备和BMC设备,并提供了在线调试接口和查询数据库的功能。 # 安装与启用 BMC Studio ## 环境准备 - BMC Studio 需要在 Ubuntu24 环境上运行,使用前须先搭建环境,请用户根据使用的操作系统,参考“环境准备”对应章节进行环境搭建。例如:本地使用 Windows 开发环境,请参考“Windows 开发环境搭建”。 > [!NOTE]说明:
> 如果本地环境已搭建完成,可跳过此操作。
- 操作过程中需要使用 git 和 bingo 工具,请确保本地已安装。 ## 运行环境 操作系统:Ubuntu 24.04。 ## 安装方式 本文提供三种安装 BMC Studio 的方式:“自动升级与安装”、“通过 apt 源手动安装仓颉工具链和 BMC Studio”、“通过应用市场安装”。 ### 自动升级与安装 目前通过 manifest 初始化工作环境时,会自动安装 BMC Studio。 如果本地已存在 BMC Studio 工具,可执行以下命令将工具升级到最新版本。 ```bash bingo upgrade ``` ### 通过 apt 源手动安装仓颉工具链和 BMC Studio 1. 执行以下命令检查本地是否已配置 apt 源: ```bash sudo apt update apt policy openubmc-bingo ``` - 如果出现以下输出,表示 apt 源已配置完成,可直接执行步骤 5。 - 如果未出现以下输出,表示未配置 apt 源,请执行步骤 2-步骤 5。 ```bash openubmc-bingo: Installed: 0.0.1 Candidate: 0.0.1 Version table: 0.0.1 500 500 https://openubmc-apt-repo.obs.cn-north-4.myhuaweicloud.com/Ubuntu noble/main amd64 Packages ``` 2. 下载 GPG 公钥 1. 安装 gnupg。 ```bash sudo apt update && sudo apt install gnupg ``` 2. 安装 GPG 公钥。 - (方式一)直接下载 GPG 文件安装 1. 指定下载公钥的位置。 ```bash sudo mkdir -p /etc/apt/keyrings ``` 2. 下载 GPG 文件。 ```bash wget -O- https://openubmc-apt-repo.obs.cn-north-4.myhuaweicloud.com/Ubuntu/gpg_key.public | sudo gpg --dearmor -o /etc/apt/keyrings/openubmc.gpg ``` - (方式二)通过公钥服务器下载 1. 指定下载公钥的位置。 ```bash sudo mkdir -p /etc/apt/keyrings ``` 2. 下载 GPG 文件。 ```bash gpg --keyserver keyserver.ubuntu.com --recv-keys BF3B2D407FDEDEA0DC91CC9412640FBCB175287A gpg --export BF3B2D407FDEDEA0DC91CC9412640FBCB175287A | sudo tee /etc/apt/keyrings/openubmc.gpg >/dev/null ``` 3. 配置 apt 源。 ```bash echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/openubmc.gpg] https://openubmc-apt-repo.obs.cn-north-4.myhuaweicloud.com/Ubuntu/ noble main" | sudo tee /etc/apt/sources.list.d/openubmc.list ``` 4. 验证APT配置。 ```bash sudo apt update apt policy bmc-studio ``` 5. 安装仓颉依赖包和 BMC-Studio deb 包。 ```bash apt remove bmc-studio apt install cangjie-runtime apt install bmc-studio ``` ### 通过应用市场安装 1. 进入 [openUBMC应用市场](https://openubmc.cn/marketplace),在“开发工具”模块下。选择“BMC Studio”。 2. 在 BMC Studio 下载页面,单击右侧“立即下载”按钮,将 BMC Studio 软件包下载到本地。 3. 根据该页面的安装指引安装 BMC Studio 即可。 ## 启动 BMC Studio - 如果您有 BMC Studio 插件,直接点击插件即可在 VS Code 中启动 BMC Studio。 ![插件启用](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/plugin_enable.png) - 如果您有 bingo,执行以下命令,即可启动 BMC Studio。(此方法需要 bingo 版本大于等于0.5.238) ```bash bingo studio ``` - 如果您使用的是 wsl 系统,可以直接在浏览器中看到 BMC Studio 的前端页面。 - 如果您使用的不是 wsl 系统,需要在浏览器中手动输入后端日志显示的该地址(视您的系统环境而定) ![手动唤起BMC-Studio](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/manually_invoke_bmc_studio.png) - 如果您想使用 BMC Studio 本身的启动方式,请参考以下命令。 ```bash /usr/share/bmc_studio/bmc_studio.sh start /usr/share/bmc_studio/bmc_studio.sh start backend(后台启动) ``` ## 常用命令 - 通过 bingo 执行的常用命令: - 启动 BMC Studio: ```bash bingo studio ``` - 停止 BMC Studio: ```bash bingo studio -stop ``` - 重启 BMC Studio: ```bash bingo studio -restart ``` - 通过 BMC Studio 执行的常用命令: - 启动 BMC Studio: ```bash /usr/share/bmc_studio/bmc_studio.sh start /usr/share/bmc_studio/bmc_studio.sh start backend(后台启动) ``` - 停止 BMC Studio: ```bash /usr/share/bmc_studio/bmc_studio.sh stop ``` - 重启 BMC Studio: ```bash /usr/share/bmc_studio/bmc_studio.sh restart ``` # 安装与使用BMC Studio 插件 ## 使用前准备 - 进入[openUBMC应用市场](https://openubmc.cn/marketplace),在“开发工具”模块中下载 BMC Studio 安装包(`.zip`格式),并将下载的安装包解压,获得`.vsix`文件。 - 确保本地已安装 VS Code(全称:Visual Studio Code,以下简称:VS Code),且已经通过 Remote 插件连接到开发使用的 Ubuntu/docker 环境。 ## 环境要求 BMC Studio 需要在 Ubuntu24 环境上运行,使用前须先搭建环境,请用户根据使用的操作系统,参考“环境准备”对应章节进行环境搭建。例如:本地使用 Windows 开发环境,请参考“Windows开发环境搭建”。 ## 安装插件 - 通过 VS Code 安装插件。 1. 打开 VS Code,参考下图步骤操作。 ![从VSIX安装](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/install.png) 2. 选择`.vsix`文件存放路径,安装插件。 > [!NOTE]说明:
> 选择前,请先确定`.vsix`文件存放的操作系统,Windows 或 wsl。 3. 安装完成后重启 VS Code 生效。 - 在 WLS 开发环境中安装插件。 根据实际情况在 Ubuntu 或 Linux 环境下,执行以下命令进行安装(“xxxxxx”表示`.vsix`文件的存放路径)。 ```bash code --install-extension xxxxxx ``` ## 安装和使用工具 1. 在 VS Code 打开已安装的 BMC Studio 的插件。 2. 插件将会自动对环境进行检测,查询是否安装 BMC Studio 和 Qemu。 - 如果检测到环境中未安装工具,请执行以下步骤3~步骤7安装和启动。 - 如果检测到环境中已安装工具,插件将会自动启动 BMC Studio。 > [!NOTE]说明:
> 如果当前安装的工具非最新版本,您可以单击界面上的“一键更新”升级工具版本,也可以直接使用当前的旧版本。 3. 单击“一键安装工具”,弹出“使用协议”相关弹框。 4. 勾选“同意《BMC软件许可协议》协议”,单击“继续安装”。插件将开始下载并安装您缺失的工具和依赖。安装时间根据网络情况,预计在1~10分钟不等。 5. (可选)如果下载时间过长,您可以在 VS Code 上方导航栏中选择“终端 > 新建终端”,在新建的终端中选择“输出”,右侧下拉框选择“Debug Logs”,打开日志查看是否报错,如果存在报错,请根据日志的实际情况处理。 ![查看日志信息](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/type.png) 6. 安装成功后“一键安装工具”的按钮变为“开始使用”。 7. 单击“开始使用”,即可启动 BMC Studio。 ## 插件实时模型检查 BMC Studio 启动后,在 VS Code 中编辑 CSR 文件或任意 BMC Studio 工作空间内的 MDS、资源协作接口、映射接口文件,保存后会触发插件进行模型检查。检查完成后,在控制台窗口会显示检查结果,查看检查结果操作如下: ![检查结果](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/check_result.png) ## 插件双屏显示 BMC Studio 插件支持双屏查看文件的能力。在打开一个 .sr 或 .json文件后,vscode 右上角会出现这个图标。点击该图标,即可启动 BMC Studio 双屏模式。 ![双屏模式](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/dual_screen_mode.png) 双屏模式中,插件会使用 BMC Studio 打开该 .sr 或 .json 文件,然后展示在插件页面里。 ![双屏模式2](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/dual_screen_mode_2.png) ## 插件在线调试 前置条件: - BMC Studio 版本不低于1.2.0。 - BMC Studio 插件版本不低于0.0.5。 - Qemu 已安装。 开发环境初始化过程会安装 Qemu,无需手动安装。 在线调试: 在线调试的具体流程,请参考Qemu设备管理使用指南。 ## 卸载插件 安装了插件后,可以在 vscode 的扩展页面的“已安装”一栏中看到 BMC Studio 插件。按图中顺序点击。 ![卸载插件1](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/uninstall_plugin_1.png) 点击图中的“卸载”按钮即可完成卸载。 ![卸载插件2](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/uninstall_plugin_2.png) # 仓库部署 以下视频介绍了BMC Studio 仓库部署操作指导,通过该视频您可以详细了解仓库部署的具体步骤,从而有效提升BMC Studio的部署效率。 # 配置工作空间 首次使用BMC Studio,必须配置默认空间,如果未配置则无法进入系统。 ## 默认空间配置 > **说明**:
> 默认工作空间配置完成后,暂不支持删除,支持切换。 1. 首次登录BMC Studio,界面提示配置默认空间。 ![新建默认空间](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/create_default_workspace.png) 2. 根据实际需求配置默认空间。 - 空间名称:填写工作空间的名称,要求如下: - 支持数字、字母、下划线和点号(.),且必须包含数字或字母。 - 工作空间名称设定后不支持修改。 - 工作空间的名称不能重复,建议用产品名称命名。 - 数据导入方式:请根据实际情况,选择数据导入的方式。 - 如果选择“导入Manifest”:则通过Manifest来初始化空间数据。 - 如果选择“指定文件路径”:则导入本地开发环境的数据作为空间数据进行管理。 - 如果选择“自定义”:则需要手动上传一个文件夹或 zip 压缩包作为初始化的工作空间数据。 - Git地址:请输入Manifest的git仓库地址。 - 远端分支名称:请选择待开发产品对应的Manifest分支。 - 指定文件路径:“数据导入方式”选择“指定文件路径”时必填。请输入本地开发环境的数据所在的路径。例如:`/usr/share/bmc_studio/server/users/xxxxx/oem_files`。 - 一键迁移:数据导入方式”选择“指定文件路径”时支持此勾选项。如果勾选,则表示将指定路径下的工作数据无损迁移到BMC Studio工作空间进行管理。 3. 填写完毕后,单击“确认”,完成配置。 ## 新建工作空间 新建的工作空间可用于管理不同系列化产品,空间之间的数据相互独立。最多支持创建10个(包含默认工作空间)。 1. 在BMC Studio首页,单击右上角工作空间按钮。 ![新建工作空间](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/create_workspace.png) 2. 选择“新建工作空间”。 3. 根据实际需求配置空间信息,详细参数可参考“配置默认空间”中的参数说明。 4. 填写完毕后,单击“确认”。 5. 根据弹框提示,选择跳转到新的工作空间。 6. 单击右上角“仓库管理”按钮进入仓库。 ![仓库管理按钮](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/repository_management_button.png) 7. 选择产品名称,为新的工作空间指定产品。 ![工作空间-仓库管理](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/workspace_repository_management.png) 8. 单击“一键仓库部署”拉取对应产品的代码仓库到创建的工作空间内。 ![一键仓库部署](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/one_click_repo_deployment.png) > **说明**:
> 新建的工作空间如果未执行“一键仓库部署”,模型文件将显示不存在。
> 执行一键仓库部署需要有仓库权限。 ## 切换工作空间 支持工作空间相互切换。 > **说明**:
切换工作空间不会删除工作空间内的数据。
工具拉取代码和执行模型检查时,不支持切换工作空间。
切换工作空间成功后,工具的所有操作都是基于新工作空间的数据。
切换工作空间不会删除切换前和切换后工作空间的数据。 1. 在BMC Studio首页,单击右上角工作空间名称。 ![切换工作空间](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/switch_workspace.png) 2. 选择需要切换的工作空间。 3. 单击“切换到此空间”。提示“操作成功”表示空间切换成功。 ## 删除工作空间 最多支持创建10个工作空间,如果达到创建上限,则需要删除已有的工作空间,才可继续创建。 > **说明**:
默认工作空间不支持删除。
工具拉取代码和执行模型检查时,不支持删除工作空间。
删除工作空间会解除工具与工作目录的关系。
如果删除正在使用的工作空间,删除成功后将自动切换到默认工作空间。 1. 在BMC Studio首页,单击右上角工作空间名称。 ![删除工作空间](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/delete_workspace.png) 2. 选择需要删除的工作空间。 3. 单击“删除此空间”,弹出删除确认的提示框,请确认后操作。 ![删除工作空间弹框](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/delete_workspace_dialog.png) - 确认删除操作,请单击“确认”。如果勾选“同步删除工作空间数据”,删除成功后数据无法恢复,请谨慎操作。 - 取消删除操作,请单击“取消”。 4. 确认后,完成删除工作空间操作。 # 操作模块 ## 配置CSR模块 CSR描述了硬件板卡的物理组成结构,包括链路拓扑和器件描述信息。将一个可独立更换的Fru抽象为板卡(组件和部件),为每一个板卡都定义一个CSR描述文件,在运行过程中由BMC系统自动发现和解析。 > **说明**:
> 支持查看文件代码和比对代码修改前后数据,具体操作方法请参考[代码预览](#代码预览)和[查看修改](#查看修改)章节。 ### 修改模型 1. 在BMC Studio选择操作模块的首页,选择CSR。 2. 进入CSR模型界面,工具会自动识别产品空间中的CSR仓库。 3. 在CSR列表中,选择需要操作的模型。 4. 搭建模型。 5. 修改完毕后,单击“保存”。 ### 新增组件仓 1. 在BMC Studio选择操作模块的首页,选择CSR。 ![导入本地文件夹](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/import_local_folder.png) 2. 点击图中所示的加号按钮。 3. 选择需要上传的文件夹,然后点击右下角的“打开”。 ### 新增文件夹 1. 在BMC Studio选择操作模块的首页,选择CSR。 2. 在CSR列表中,选择需要新增文件夹的目标文件夹。 3. 单击目标文件夹后的“操作”。例如:需要在vpd文件夹下新增文件夹,请单击vpd后的“操作”按钮。 ![新建CSR文件夹](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/create_csr_folder.png) 4. 选择“新增文件夹”。 5. 输入文件夹名称,完成新建操作。 > **说明**:
> 名称仅支持数字、字母和下划线。 ### 新增组件 目前提供三种方式新增组件。 #### 手动新增 1. 在BMC Studio选择操作模块的首页,选择CSR。 2. 在CSR列表中,选择需要新增组件的目标文件夹。 3. 单击目标文件夹后的“操作”。例如:需要在src文件夹下新增组件,请单击src后的“操作”按钮。 ![新增CSR组件](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/add_csr_component.png) 4. 选择“新增组件”。 5. 填写组件名称、格式版本和数据版本。数据版本和格式版本要求为A.BC的格式校验,A、B、C均为0-255的数字(不能有前导零)。 6. 填写完毕后,单击“保存”。 #### 上传组件 1. 在BMC Studio选择操作模块的首页,选择CSR。 2. 在CSR列表中,选择需要新增组件的目标文件。 3. 单击目标文件夹后的“操作”。例如:需要在src文件夹下新增组件,请单击src后的“导入本地sr文件”按钮。
![导入本地sr文件](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/import_local_sr_file.png) 4. 选择需要上传的sr文件,并点击“打开” #### 复制CSR 1. 在BMC Studio选择操作模块的首页,选择CSR。 2. 在CSR列表中,选择需要复制的目标文件。 3. 单击目标文件后的“操作”,然后点击复制按钮。 ![复制CSR](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/copy_csr.png) 4. 选择您要将 CSR 复制过去的文件夹,点击文件名后的“操作”,然后点击粘贴按钮。 ![粘贴CSR](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/paste_csr.png) ### 删除组件 支持撤销删除操作,具体操作方法方法请参考“常用操作”章节中的[撤销删除文件和撤销修改](#撤销删除文件和撤销修改)。 1. 在CSR列表中,选择需要删除的文件、模型或组件,单击“操作”。 ![删除CSR组件](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/delete_csr_component.png) 2. 选择“删除”。 3. 工具弹出确认删除的提示框,请根据情况选择。 - 确认删除,请单击“确认”。 - 取消删除,请单击“取消”。 ### CSR页面检查 以下视频介绍了 BMC Studio 的 CSR 页面模型检查操作指导,通过该视频您可以详细了解 CSR 模型检查的具体步骤,模型检查可以检查出模型之间不一致的错误,并给出告警提示。 ### 同步代码 通过Git命令,将CSR配置提交到代码仓。 1. 选择要同步代码的主文件夹,单击“操作”。 ![CSR同步代码](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/csr_sync_code.png) 2. 选择“同步代码”。 3. 如果提示“代码同步成功”,表示同步代码操作成功。 > **说明**:
> 如果弹出“代码同步失败”,提示“检测到待同步数据与工具本地数据存在冲突,请通过其它工具解决冲突。
> 您也可以执行强制覆盖操作,此操作不可逆,存在数据丢失的风险”。建议先通过其他工具解决冲突,再执行代码同步。 ### 适配板卡 适配板卡具体操作流程,请参见[板卡适配指南](#板卡适配指南)。 ### CSR出包 支持单个和批量打包CSR。 > **说明**:
> 批量生成时仅支持下载为HPM包格式。
> 选择的CSR文件中,必须包含UID,且批量出包中的UID不能重复。 #### 单个CSR打包 1. 模型配置完成后,单击页面右上角“CSR出包”。 ![CSR单个出包](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/csr_single_package_build.png) 2. 参考以下内容,填写出包信息。 ![单个CSR出包配置](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/single_csr_package_build_config.png) - **FormatVersion**:填写Format的版本。 - **DataVersion**:填写Data的版本。 - **EEPROM大小限制**:选择16k或32k。 - **OEM定制信息**:选填项,请根据情况选择是否上传 OEM 定制信息。上传要求格式为.bin 和 .ini,大小不超过4KB。 - **下载选项**:勾选下载生成的格式,可同时勾选多个。支持hpm、二进制bin、json文件。 3. 单击“CSR出包”。生成的CSR将自动下载到本地。如果通过SSH连接了BMC 真机,则还可以选择“出包并升级到BMC”将出的包直接生效到真机环境。 #### 批量CSR打包 批量生成时仅支持下载为HPM包格式。 1. 在CSR列表右上方单击“批量CSR出包”。 ![CSR批量出包](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/csr_batch_package_build.png) 2. 勾选需要出包的文件,单击CSR出包。 ![CSR出包](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/csr_package_build.png) 3. 参考以下内容,填写出包信息。 ![批量CSR出包配置](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/batch_csr_package_build_config.png) - **OEM共享文件**:上传的OEM文件可用于全部CSR出包使用。 - **EEPROM大小限制**:选择16k或32k。 - **OEM文件**:为对应的CSR上传OEM文件,上传要求格式为.bin 和 .ini,大小不超过4KB。 - **使用共享文件**:如果勾选,表示携带“OEM共享文件”中上传的文件。如果不勾选,表示不携带“OEM共享文件”中上传的文件直接携带本文件选择的对应“OEM文件”。 - **删除**:删除对应的CSR文件。 4. 单击“批量CSR出包”。 > **说明**:
> “出包并升级到BMC”功能需要您有真实服务器,并且通过BMC Studio连接到这台机器才能使用,可以将出完的包直接生效到环境中。 ### 生效到 QEMU 在连接到 Qemu 后,可以将文件直接生成到 Qemu 环境。
![csr_qemu生效](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/csr_qemu_effect.png) 在点击了按钮后,可以选择生效方式。
![选择生效方式](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/select_effect_mode.png) BMC Studio 会把该文件以对应的方式生效到 Qemu。 ## 配置资源协作接口 资源协作接口即为从系统视角对BMC软件管理功能的抽象定义。资源协作接口包含对象和接口的定义,接口以bmc.kepler开头。 > **说明**:
> 支持查看文件代码和比对代码修改前后数据,具体操作方法请参考[代码预览](#代码预览)和[查看修改](#查看修改)章节。 ### 修改资源协作接口/路径信息 > **说明**:
> 配置资源协作接口的基本信息时,属性、方法和信号要求至少配置一个。 1. 选择需要操作的资源协作接口/路径。 2. 修改资源协作接口的配置。 3. 修改资源协作接口路径的配置。 4. 修改完毕后,单击“保存”,完成修改。 ### 新增文件夹 1. 选择需要新增文件夹类型,路径或接口。 2. 在资源协作接口列表中,选择需要新增文件夹的目标文件。 3. 单击目标文件夹后的“操作”。以新增路径文件举例,例如:需要在Accessor文件夹下新增文件夹,请单击Accessor后的“操作”按钮。 ![资源协作接口新增文件夹](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/resource_collaboration_interface_new_folder.png) 4. 选择“新增文件夹”。 5. 输入文件夹名称,完成新建操作。 > **说明**:
> 名称仅支持数字、字母和下划线,且要求不能以数字开头。 ### 新增资源协作接口/路径 1. 在资源协作接口列表中选择新增的类型:接口/路径。 2. 在资源协作接口的列表中,选择需要新增接口或路径的目标文件。 3. 单击目标文件夹后的“操作”。例如:需要在kepler文件夹下新增资源协作接口,请单击kepler后的“操作”按钮。 ![新增资源协作接口](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/add_resource_collaboration_interface.png) 4. 选择“新增资源协作接口”。 5. 参考“修改资源协作接口/路径信息”中的参数列表。配置资源协作接口/路径。 6. 配置完成后,单击“保存”。 ### 检查 1. 在资源协作接口/路径列表中,选择需要检查的文件,单击“操作”。 ![检查资源协作接口](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/check_resource_collaboration_interface.png) 2. 选择“检查”,工具开始检查所选文件的模型一致性。 3. 检查完成后,单击“检查结果”可查看详情。界面展示“错误提示”、“错误影响”和“修复建议”。 ### 删除资源协作接口/路径 支持撤销删除操作,具体操作方法请参考[撤销删除文件和撤销修改](#撤销删除文件和撤销修改)。 1. 在资源协作接口/路径列表中,选择需要删除的文件,单击“操作”。 ![删除资源协作接口](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/delete_resource_collaboration_interface.png) 2. 选择“删除”。 3. 工具弹出确认删除的提示框,请根据情况选择。 - 确认删除,请单击“确认”。 - 取消删除,请单击“取消”。 ## 配置MDS MDS是APP的模型描述文件,定义了该APP管理的资源协作接口和私有属性。 > **说明**:
> 支持查看文件代码和比对代码修改前后数据,具体操作方法请参考[代码预览](#代码预览)和[查看修改](#查看修改)章节。 ### 修改MDS信息 > **说明**:
> 信息填写完毕后,未保存当前页面信息,切换页面时会清空当前页面编辑的全部内容,请谨慎操作。 1. 选择需要操作的文件。 2. 修改配置信息。 3. 修改完毕后,单击“保存”,完成修改。 ### 检查 1. 在MDS列表中,选择需要检查的文件,单击“操作”。 ![MDS检查](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/mds_check.png) 2. 选择“检查”,工具开始检查所选文件的模型一致性。 3. 检查完成后,单击“检查结果”可查看详情,界面展示“错误提示”、“错误影响”和“修复建议”。 ### 同步代码 通过Git命令,将MDS配置提交到代码仓。 1. 选择要同步代码的主文件夹,单击“操作”。 ![MDS同步代码](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/mds_sync_code.png) 2. 选择“同步代码”。 3. 如果提示“代码同步成功”,表示同步代码操作成功。 > **说明**:
> 如果弹出“代码同步失败”,提示“检测到待同步数据与工具本地数据存在冲突,请通过其它工具解决冲突。
> 您也可以执行强制覆盖操作,此操作不可逆,存在数据丢失的风险”。建议先通过其他工具解决冲突,再执行代码同步。 ### 删除MDS文件 1. 在MDS列表中,选择需要删除的文件,单击“操作”。 ![删除MDS](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/delete_mds.png) 2. 选择“删除”。 3. 工具弹出确认删除的提示框,请根据情况选择。 ## 配置接口映射 使用Redfish/WebREST/SNMP/CLI的设计,引入数据映射器机制,框架解析数据映射配置,将接口请求转发到资源协作接口,拼装返回对应格式的数据。 映射配置定义了如下内容: * 接口请求与资源协作接口的对应关系。 * 接口及属性的校验信息。 * 属性执行映射的前置与后置处理等。 ### 新增文件夹 1. 选择需要新增的接口类型:Redfish、WebREST、CLI或SNMP。 ![新建接口文件夹](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/create_interface_folder.png) 2. 在文件列表中,选择需要新增文件的目标文件夹。 3. 单击目标文件后的“操作”。例如:需要在Accounts文件夹下新增文件夹,请单击Accounts后的“操作”按钮。 4. 输入文件夹名称,完成新建操作。名称仅支持数字、字母、下划线和中划线,且要求不能以数字开头。 ### 新增接口映射 1. 选择需要新增的接口类型:Redfish、WebREST、CLI或SNMP。 2. 在文件列表中,选择需要新增接口映射的目标文件夹。 3. 单击目标文件后的“操作”。例如:需要在Accounts文件夹下新增接口映射,请单击Accounts后的“操作”按钮。 ![新增映射接口](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/add_mapping_interface.png) 4. 选择“新增接口映射”。 5. 输入接口名称。名称仅支持数字、字母、下划线和中划线,且要求不能以数字开头。 6. 单击“新增资源”,输入URI资源。 7. 单击“确认”接口新增成功。 8. 配置接口信息。 ### 检查 1. 在接口文件或文件夹中,选择需要检查的文件,单击“操作”。 ![检查接口映射](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/check_interface_mapping.png) 2. 选择“检查”,工具开始检查所选文件的模型一致性。 3. 检查完成后,单击“检查结果”可查看详情。界面展示“错误提示”、“错误影响”和“修复建议”。 ### 删除接口文件 支持撤销删除操作,具体操作方法请参考撤销删除文件和撤销修改。 1. 在接口文件列表中,选择需要删除的文件,单击“操作”。 ![删除接口映射](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/delete_interface_mapping.png) 2. 选择“删除”。 3. 工具弹出确认删除的提示框,请根据情况选择。 # 开发任务 ## 板卡定制 板卡定制,分为以下两种情况。 - 板卡新增:定制新的板卡时,对新的器件进行定义,对新增板卡定制前,请先执行以下操作。 1. 在原生开发定义资源协作接口和路径,操作方法请参考:操作模块 >资源协作接口配置。 2. MDS里进行管理定义的资源协作接口。 3. 打开对应的CSR开关。 - 板卡适配:基于已有器件库,对硬件组件进行定制,包含对组件上器件类型、数量的编排等操作。 ### 定义新器件操作流程(板卡新增) 1. 在BMC Studio首页,单击“板卡定制”,进入定制板卡操作界面。 2. 请按照如下流程新增器件,操作方法参见[配置CSR模型](#配置csr模块)章节。 ![板卡定制](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/board_customization.png) 1. (可选)新增CSR模型文件夹。 2. 新增CSR组件。 3. 配置模型数据。 4. 保存配置。 3. 单击“保存”完成配置。 ### 定制硬件组件(板卡适配) 板卡适配详细操作可参见BMC Studio板卡适配指南,也就是[板卡适配指南](#板卡适配指南)。 ## 原生开发 使用原生开发功能开发新的APP。 1. 在BMC Studio首页,单击“原生开发”,进入原生开发操作界面。 2. 为板卡定义资源协作接口信息。请按照如下流程配置,具体操作方法参见[配置资源协作接口](#配置资源协作接口)章节。 ![原生开发](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/native_development.png) 1. (可选)新增资源协作接口文件夹。 2. 新增资源协作接口。 3. 新增资源协作接口路径。 4. 保存配置。 3. 在原生开发的导航条上,单击“MDS”。 ![原生开发MDS](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/native_development_mds.png) 4. 为板卡配置MDS信息。具体操作方法参见[配置MDS](#配置mds)。 5. 配置完成后,单击“保存”。 ## 接口定制 可使用BMC Studio定制北向接口,包含对Redfish、WebREST、CLI、SNMP接口映射配置的新增、修改和删除,具体操作方法,请参考[配置接口映射](#配置接口映射)。 ## 编译构建 BMC Studio的工作空间包含多个代码仓,这些代码仓可能被本地管理或被设置为Git工作空间。用户可通过页面配置Git仓地址,将代码同步到工作空间。工具也会自动扫描工作空间,识别出Git仓,并在仓库管理页面展示。 > **说明**:
> 选择Manifest产品后,才可进行仓库初始化操作。仓库完成初始化操作后,才可获取代码。 1. 参考以下内容选择出包信息。 ![仓库管理](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/repository_management.png) - **一键出包**:基于该产品空间的本地代码一键出包。仅root用户支持一键出包。 - **Git仓库地址**:工作空间中的Git代码仓。 - **本地分支名称**:默认取值为导入Manifest时选择的远端分支,可手动切换分支。 - **同步远端最新配置**:本地分支选择后,单击此按钮进行切换。说明:切换本地分支时将同步最新的远端代码。切换分支时,要求本地代码和Manifest的库上最新代码不能存在冲突,如果存在冲突,请手动解决冲突后再切换分支。 - **产品名称**:选择分支对应的产品名称,切换产品后需重新进行仓库部署。如果该产品已执行过一键仓库部署,则无须再重新进行仓库部署。 - **一键仓库部署**:根据Manifest中产品的配置信息,动态获取仓库配置并完成全量仓库代码的获取。 - 如果有代码变动,会弹框提示是否覆盖代码, - 如果代码未变动,不会提示覆盖代码,但会做代码检查。 - **获取全量代码**:一键拉取全量仓库代码到对应的分支。支持编辑个人远端地址和个人远端分支。 2. 单击“一键出包”,选择对应产品。 3. 在组件列表勾选需要出包的组件。 4. 单击“下一步:出包”,出包会显示进度条,出包成功之前请勿执行其他操作。 > **说明**:
> 一键仓库部署和获取全量代码只能拉取有权限的仓库,只要有一个组件仓库拉取成功,则表示操作成功,未能成功拉取的仓库可查看“仓库日志”确认原因。
> 如果出包失败,仓库管理右侧的“构建日志”列会展示出包失败的日志,可下载全量日志到本地进行分析。
> 如果出包成功,仓库管理右侧的“固件信息”列会展示出包信息,单击“下载”将固件包下载到本地。
> 固件包仅保留三天,失效后将无法下载。
> “一键仓库部署”和“获取全量代码”的日志将展示在仓库日志中。 # BMC Studio SSH 连接功能操作 本章节主要介绍如何使用BMC Studio SSH的连接功能。 ## 使用前准备 - 软件:请安装最新版本的BMC Studio工具。 - 硬件:请准备一台可远程访问的服务器,并提前获取服务器的IP地址、端口号、用户名和登录密码。 ## 使用须知 - BMC Studio仅支持保持一个活跃连接,如果新建SSH连接或重新连接另一个设备,之前的会话将会被断开。 - 为确保设备信息安全,离开设备时,请主动断开连接。 ## 创建SSH连接 1. 在BMC Studio首页,单击右上角第一个图标“仿真管理”按钮,进入“接入设备管理”界面。 ![仿真管理按键](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/simulation_management_button.png) 2. 在“BMC设备管理”区域单击“+新建设备”。 ![新建设备](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/create_device.png) 3. 填写设备的IP地址、端口、用户名和密码。 ![新建BMC设备](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/create_bmc_device.png) 4. 单击“确定”,完成设备认证。认证成功后,新建的设备会展示在BMC设备管理区域下。 ![bmc设备管理](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/bmc_device_management.png) ## 连接管理 ### 重新连接会话 1. 在“BMC设备管理”区域下的设备列表中,选择需要重新连接的会话。 2. 确认设备处于未连接状态,操作列将展示“连接”和“删除”。 ![重新连接会话](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/reconnect_session.png) 3. 单击“连接”按钮,输入对应设备的密码。 > **说明**:
> 基于安全考虑,BMC Studio不会自动保存设备密码,涉及密码处均须手动输入确认。 ### 断开当前连接 1. 在“BMC设备管理”区域下的设备列表中,选择需要断开连接的会话。 2. 确认设备处于连接状态,操作列将展示“取消连接”和“删除”。 3. 单击“取消连接”按钮,等待“取消连接”按钮变为“连接”时,断开成功。 ![未连接](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/not_connected.png) ### 删除设备配置 1. 在“BMC设备管理”区域下的设备列表中,选择需要删除的会话。 2. 单击“删除”按钮,删除成功后会清除当前设备的全部缓存信息。 ![删除连接](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/delete_connection.png) ## 连接状态说明 - **绿灯**:表示设备已连接,可执行断开或发送命令操作。 - **灰标**:表示设备未连接,可执行新建连接或重新连接操作。 # 板卡适配指南 本章节主要介绍如何适配板卡。 ## 使用前准备 - 已安装bingo工具。 - BMC Studio工具能正常启动。 - 已创建工作空间并进行一键仓库部署或手动导入业务组件的`MDS`文件、`vpd`、`mdb_interface`和`rackmount`代码仓到工作空间。 ## 拓扑视图化 当前将CSR页面划分为“管理视图”,“业务视图”和“告警事件”三大板块,大大提升了配置页面的易用性。 ## 板卡适配 1. 在BMC Studio首页,选择CSR,进入CSR配置界面。 ![进入CSR](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/CSR.png) 2. 在vpd仓库进入`vendor/Huawei/Server/Kunpeng/openUBMC`路径,选择`root.sr`文件。 ![root.sr文件](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/root_sr_file.png) 3. 将LM75芯片拖拽到I2c_8上。 ![拖拽LM75](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/drag_lm75.png) 4. 拖拽完成后,单击M75芯片上方的扳手图标,配置参数,鼠标停在对应字段的"?"图标上即可查看字段类型和描述。 ![点击扳手图标进行配置](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/click_wrench_icon_for_config.png) ![描述信息显示](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/description_info_display.png) - 配置基本信息:填写“器件别名”,并自定义`properties`中的`Address`、`AddrWidth`、`OffsetWidth`参数。 ![配置LM75](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_lm75.png) - 配置传感器读数:按照属性进行配置,选择`Scanner`,配置“名称”、“偏移”、“长度”、“掩码”、“扫描周期”,配置完成后,单击“操作”列下的“保存”按钮。 ![配置LM75的读取器](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_lm75_reader.png) 5. 选择业务视图,进入软件对象配置页面。 ![功能器件配置](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/functional_device_config.png) 6. 单击左上角“+新增”按钮,弹出“新增功能器件”窗口。 7. 搜索`Entity`,并进行配置。 ![新增Entity](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/add_entity.png) ![配置Entity](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_entity.png) 8. 新增`ThresholdSensor`进行配置。 - 对于需要使用动态应用的场景,在下拉框中选择动态引用,并关联到对应的对象。 - 对于需要使用数据同步的场景,在下拉框中选择数据同步,并关联到对应`Scanner`的`value`值。 ![配置动态引用](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_dynamic_reference.png) ![配置数据同步](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_data_sync.png) 9. 配置完成后,在管理视图中单击“查看代码”,即可查看新增CSR配置的内容。 ![点击查看代码](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/click_to_view_code.png) ![查看代码结果](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/view_code_result.png) ## CSR拓扑配置 以下视频介绍了 BMC Studio 的 CSR 拓扑配置操作指导,通过该视频您可以详细了解 CSR 拓扑配置的具体步骤,从而快速和准确配置CSR文件。 ## CSR可视化配置 1. 在BMC Studio首页,选择CSR,进入CSR配置界面。 ![进入CSR](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/CSR.png) 2. 新增组件,模板选择"RiserCard",具体操作方法可参考“配置CSR模块”章节。[配置CSR模块](#操作模块) 3. 添加“I2c总线”。 ![添加I2c总线](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/add_i2c_bus.png) 4. 将器件和连接器拖拽到总线上或9545芯片的不同`channel`上,创建拓扑并进行配置,配置完成后,拓扑和Riser卡拓扑图一致。 ![拓扑生成结果](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/topology_generation_result.png) > **说明**:
> 如果需要将总线传到`Connector`中,可以拖拽总线连接到`Connector`。
![将总线传入Connector](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/pass_bus_to_connector.png) > 将光标移动到总线上,并单击红色叉号,可以删除这条传入的总线。
![删除传入Connector的总线](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/delete_bus_passed_to_connector.png) > 单击右侧“查看代码”可查看生成的CSR内容。
![拓扑生成代码](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/topology_generation_code.png) 5. 双击框图的空白处配置板卡对象`RiserCard_1`。 ![配置RiserCard](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_riser_card.png) 6. 在页面上方选择“业务视图”配置`Chip_MCU`和`MCU`升级的对象。 ![MCUFirmware添加](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/mcu_firmware_add.png) ![配置MCU升级对象](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_mcu_upgrade_object.png) 7. 配置`Eeprom_IEU`并在业务视图中配置`SRUpgrade_1`对象,由于`SRUpgrade_1`对象的`WriteProtect`需要从`Pca9555`芯片获取,因此需要在`pca9555`芯片上配置读取器`Scanner`类型对象。 ![配置MCUAccessor](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_mcu_accessor.png) ![配置MCUScanner](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_mcu_scanner.png) ## 事件定制 以板卡适配中配置Riser卡电源失效事件为例:
配置事件前,需先配置要关联的组件,当前组件为Riser卡,如果配置Riser卡的电子标签信息和部件信息,需要在业务视图中完成`Fru_IEU`对象和`FruDate_IEU`对象的配置。 > **说明**:
> `Fru_IEU`对象的每个属性的配置描述可以参考板卡适配中“对象配置 > fru类”中的`Fur`。
> `FruData_IEU`对象的每个属性的配置描述可参考板卡适配中的“对象配置 > fru类”中的`FruData`。 ![告警所需对象配置](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/alarm_required_object_config.png) 1. 在CSR配置页面选择“告警事件”,并选择需要配置的告警项。 ![选择告警事件模板](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/select_alarm_event_template.png) 2. 对内容进行配置,Reading字段取值可以从Scanner对象获取。 ![配置告警读值](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_alarm_reading.png) ![配置告警内容](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/config_alarm_content.png) 3. 创建事件需要关联`Component`,在事件配置中选择`Component`配置关联。 ![告警与器件关联](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/alarm_device_association.png) 4. 如果需要配置新的事件告警,可以在页面右上角选择自定义添加,手动配置告警。`EvenKeyld`需要手动配置,告警信息和修复信息分别支持10个参数。 ![自定义告警配置](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/custom_alarm_config.png) ## CSR事件告警配置 以下视频介绍了 BMC Studio 的 CSR 事件告警配置操作指导,通过该视频您可以详细了解 CSR 事件告警配置的具体步骤,从而快速配置一个事件精细化告警。 ## 告警可视化配置 告警事件页面支持查看现有告警定义及告警描述信息,同时也可以直观查看当前板卡中已配置的告警内容。 ![告警事件总览](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/alarm_event_overview.png) > **说明**:
> 特性需要较高版本的社区vpd仓,对于历史版本的工作空间,可以手动下载社区[vpd仓库](https://gitcode.com/openUBMC/vpd)中`vendor`路径下的`event_def.json`文件,放在工作空间中的`vpd/vendor`路径下。
> 支持从预定义模板添加现有事件,添加事件自动关联事件ID和类型。 # Qemu设备管理使用指南 本章节主要介绍如何管理 Qemu 虚拟机。 ## 使用前准备 - 安装 Qemu - 使用 VS Code 插件安装。具体操作方法请参考BMC Studio插件使用说明。 - 准备镜像文件 - 通过 openUBMC 应用市场下载预制镜像:在“Qemu设备管理”配置虚拟机参数时,仿真镜像来源选择“应用市场”。 - 本地下载:单击[Qemu镜像](https://www.openubmc.cn/marketplace/QEMU),下载对应版本的镜像文件到本地(镜像文件通常以`.cpio.gz`为后缀)。 ## 配置 Qemu 虚拟机 1. 在 BMC Studio 首页,单击右上角“仿真管理”按钮,进入“接入设备管理”界面。 ![接入设备管理入口](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/device_management_entry.png) 2. 在“Qemu设备管理”区域单击“配置”。 ![QEMU配置页面](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/qemu_config_page.png) 3. 参考以下内容设置虚拟机参数。 | 参数 | 参数说明 | | ----------------- | ---------------------------------------------------------- | | 机型 | 自定义标识名称,例如:`MyUbuntuVM` | `> | | 模拟环境CPU核心数 | 分配的计算核心(建议 ≤ 物理核心数),例如:`2` | `> | | 模拟环境内存 | 分配的内存(单位:GB),例如:`4` | `> | | 仿真镜像来源 | 选“应用市场/Ubuntu镜像/本地文件”,例如:`ubuntu-22.04.iso` | `> | | 网络端口 | 设置 SSH/HTTPS/IPMI/SNMP 访问端口,例如:`SSH:2222` | `> | > [!NOTE]说明:
> 仿真镜像来源:
> - 应用市场:连接 openUBMC 应用市场自动预装系统的官方镜像。
> - 本地镜像:需要提前上传至 BMC Studio 的镜像目录。
> - Ubuntu镜像:如果您已经通过“应用市场”预装了镜像或通过“本地镜像”方式上传了镜像,可选择此项。 ## 启动和使用虚拟机 启动虚拟机的操作方法如下: 1. 在 BMC Studio 首页,单击右上角第一个图标“仿真管理”按钮,进入“接入设备管理”界面。 ![接入设备管理入口](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/device_management_entry.png) 2. 在“Qemu设备管理”区域选择虚拟机,单击“启动”,启动时间预计需要3~5分钟左右。 ![QEMU启动中](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/qemu_starting.png) 3. 等待状态显示为蓝色时,表示启动成功。启动完成后,相关参数含义请参考以下内容: ![QEMU已启动](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/qemu_started.png) | 参数 | 参数说明 | | -------- | ---------------------------------------------------------------- | | 重新启动 | 重启虚拟机 | `> | | 停止 | 强制关闭虚拟机。长时间不使用虚拟机时,可以使用此功能释放CUP/内存 | `> | | 连接 | 通过 SSH 终端访问(需配置端口) | `> | | BMC登录 | 通过浏览器访问仿真 BMC 设备 Web 图形界面 | `> | > [!NOTE]说明:
> 删除虚拟机的配置不会清除镜像文件。 ## 虚拟机仿真文件配置 本功能在 QEMU 未启动时,只能进行修改操作,无法生效到 QEMU。如果要生效到 QEMU,请在 QEMU 启动时保存修改。 1. 在BMC Studio首页,单击右上角第一个图标“仿真管理”按钮,点击上方“仿真文件”进入界面。在此页面,可以对文件进行任意修改。 ![仿真管理](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/simulation_management.png) 2. 修改好文件后,点击下方“保存”和“取消”分别可以将修改的配置保存并生效到 QEMU 或放弃。 3. 可以通过点击下方“修改对比”按钮检查修改的部分。如果确认无误,可以点击“确定修改”保存并生效到 QEMU。也可以点击“退出对比”继续修改。 ![查看修改](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/view_simulation_file_changes.png) ## 在线调试接口 前置要求: - BMC Studio 版本不低于1.2.0 - BMC Studio 插件版本不低于0.0.5 - Qemu 已安装 ### 通过 BMC Studio 结合 Qemu 进行代码调试 在已经建立 Qemu 连接的情况下,可以配合 BMC Studio 的 Vs Code 插件实现代码调试功能。请确保 BMC Studio 插件已安装,且 BMC Studio 已连接到 Qemu,否则调试按钮不会在 Vs Code 页面出现。 ![BMC Studio插件](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/plugin_store.png) 1. 通过 VsCode 在 openUBMC 的组件代码仓下打开新窗口。 以北向接口定制开发为例: 1. 打开 rackmount 文件夹。 2. 打开任意北向接口定制文件,即可在右上角看到两个图标,分别是文件级调试和组件级调试。 ![调试按钮](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/debug_button.png) 2. 单击“文件调试”按钮,文件会自动生效到 Qemu,并重启对应子系统进程。等待进程重启完成后即可连接 Qemu 查看调试结果。 3. 单击“组件调试:按钮,BMC Studio 会自动进行一次 bingo build 操作,并将 conan 制品中的文件替换到 Qemu 环境中,重启对应子系统,该方式适合代码修改涉及多个文件,或者修改C语言代码的情形。 4. 修改 web_backend 的接口,并启动调试。以 Login 接口的版权信息为例,修改后点击单文件生效。 ![上传单文件](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/upload_single_file.png) 5. 等待 interface 进程重启完毕。 ![重启子系统](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/restart_subsystem.jpeg) 6. 重启后,接口信息会发生更改。 7. 选择组件调试,由于需要编译组件,时间会稍微长。 ![组件调试](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/component_debug.png) ![上传成功](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/upload_success.png) 8. 等待子系统重新拉起,此时耗时可能更长。 ![组件调试](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/component_debug.jpeg) 9. 组件调试完成,页面发生变化。 ### 通过 BMC Studio 进行 Qemu 或者真机环境的资源协作接口和数据库调试 除了代码调试能力外,BMC Studio 的 Web 页面支持对资源协作接口进行可视化查看和调试,以及对数据库信息进行查询,具体如下: #### 连接到任意 Qemu 环境或者真机环境 1. 连接到 BMC 环境后,选择右上角的仿真调试。 ![仿真调试](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/simulation_debug.png) 2. 资源协作接口查看与调试。 由于组件数量较多,资源协作接口会在后台持续按照组件更新,可以点击刷新按钮刷新。 ![资源协作接口可视化](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/resource_collaboration_interface_visualization.png) 3. 以资源`/bmc/kepler/Managers/1/BMC`为例,根据路径找到对应资源,点击后即可展开资源详情,内容按照接口进行折叠。 ![BMC资源内容](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/bmc_resource_content.png) #### 资源协作接口属性实时修改 BMC Studio 基于 mdbctl 命令封装了属性设置功能。 1. 单击属性框即可修改属性,修改完成后点击其他任意处,属性修改会自动生效,例如:将 openUBMC 改为 MyBMC。 ![修改BMC名称](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/modify_bmc_name.png) 2. 修改完成后,即可进入命令行或者页面查看资源协作接口的修改结果。页面变化如下: ![页面变化](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/page_change.jpeg) > [!NOTE]说明:
> 部分不在 mdbctl 命令支持范围内的对象不支持修改属性,修改后不会生效。 #### RPC一键调用 BMC Studio 简化了 RPC 调用过程,开发者只需要关注调用参数即可,无需关心完整命令的拼接,我们会帮您自动完成。调用参数操作方法如下: ![RPC调用](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/rpc_call.png) 1. 展开接口。 2. 单击选择需要调用的 RPC。 3. 在参数框中输入参数信息。 4. 单击右侧调试按钮,将会自动将下方拼接好的命令在 BMC 环境上执行,并返回结果,结果内容与命令行调用一致。 ### 通过 BMC Studio 插件进行仿真调试 ![插件仿真调试](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/plugin_simulation_debug.png) 1. 使用 VS Code 打开一个代码仓,页面右上角会出现“仿真调试”按钮。 2. 单击“仿真调试”的按钮就可以进行和 BMC Studio 相同的仿真调试功能。 ![插件仿真调试页面](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/plugin_simulation_debug_page.png) ### 数据库信息查看 1. 单击仿真调试窗口上方的数据库页签即可查看全部组件的数据库信息。每个组件下的数据库按照不同的持久化类型分类。 2. 单击对应的表即可查看数据表内容。 ![数据库查看](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/database_view.png) # 代码预览 使用代码预览功能,可在工具界面预览各文件的代码,同时支持在预览界面直接修改并保存代码。 1. 选择需要查看代码的文件。 2. 单击页面右侧的“代码预览”按钮。 3. 界面右侧展示对应文件的代码。 > **说明**:
> 如需搜索代码内的关键字,请将鼠标选中代码框内的任意位置,使用Ctrl+F,输入关键字搜索。代码内存在多个相同的关键字时,可使用Ctrl+G跳转。 > DDS文件不支持编辑保存。 # 模型检查 BMC Studio支持模型的可视化配置,模型与模型之间存在配套关系,通过此功能可以检查出模型之间不一致的错误,并给出告警提示。 > **说明**:
> 工具根据默认的检查规则,检查指定的模型。
> 如果错误级别未定义或取值不符合规范要求,无法勾选“CSR扩展规则检查样例”。 1. 在工具首页单击右上角“模型检查”按钮。 ![模型一致性检查按钮](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/model_consistency_check_button.png) 2. 进入“模型检查”界面。 ![模型一致性检查](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/model_consistency_check.png) 3. 选择想要检查的规则。 4. 单击右上角“开始检查”按钮。 ![开始检查](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/start_check.png) 5. 工具将根据已有的检查规则,检查各模型一致性。 ![模型检查结果](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/model_check_result.png) 6. 检查结束后,可在“检查结果”页签查看检查详情。参数说明请参考如下: - **规则ID**:检查规则的ID。 - **所属模型**:可筛选需要展示的报错模块。 - **错误提示**:具体错误原因。 - **错误影响**:错误的影响。 - **修复建议**:具体的修复建议。 - **告警等级**:可筛选展示的高级等级。“严重”,“一般”,“提示”。 - **产生时间**:最后一次检查结果的时间。 7. 单击右上角“导出”可将检查结果导出至本地。 ![导出](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/export.png) # 常用操作 ## 查看修改 使用“查看修改”功能,可将修改前和修改后的数据进行比对,同时支持在预览界面直接修改并保存代码。 > **说明**:
> 仅支持比对最近一次保存前后的数据。 1. 选择操作模块。 2. 单击左上角“查看修改”的按钮。 ![查看修改](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/view_changes.png) 3. 选择目标文件,比对修改前后的数据。 ![比对修改](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/compare_changes.png) - 如需搜索代码内的关键字,请将鼠标选中需要搜索的代码框内任意位置,使用Ctrl+F,输入关键字搜索。代码内存在多个相同的关键字时,可使用Ctrl+G跳转。 - 勾选“统一缩进查看”,可统一缩进格式,便于查看。 - 如需编辑数据,请单击右上角“编辑”按钮,编辑完成后,单击“保存”。 ## 撤销删除文件和撤销修改 CSR配置、资源协作接口、接口映射均支持撤销删除文件和撤销修改,MDS仅支持撤销修改。 > **注意**:
> 撤销不会有弹框再次确认,单击”撤销“后,工具将直接执行撤销操作。
> 撤销修改后,代码将变为初始拉取的状态。 撤销修改和撤销删除的方法一致,以下以CSR中的文件已被删除,需要撤销删除的操作。 1. 进入CSR操作模块。 2. 在CSR列表上方单击蓝色字体“查看修改"。 ![查看修改](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/view_changes.png) 3. 选择需要撤销删除的文件,单击后方的“撤销”按钮。如果需要批量撤销,可勾选需要操作的文件,单击最上方的“撤销”按钮进行操作。 ![撤销修改和删除](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/undo_changes_and_delete.png) ## 侧边栏 BMC Studio 目前有侧边栏,可以实现 openubmc.cn 常用链接的跳转。 五个图标从上到下分别是: ![侧边栏](../../images/bmc_studio/user_guide/bmc_studio_usage_instructions/sidebar.png) - [代码仓](https://gitcode.com/openUBMC) - [文档中心](https://www.openubmc.cn/docs) - [社区论坛](https://discuss.openubmc.cn) - [sig中心](https://www.openubmc.cn/sig) - [应用市场](https://www.openubmc.cn/marketplace) ## 卸载BMC Studio 在 linux 命令行中执行以下命令可卸载BMC Studio。 ```bash dpkg -P bmc-studio ``` --- # openUBMC Studio插件使用指南 > URL: https://openubmc.cn/docs/zh/latest/common_tools/bmc_studio/user_guide/plugin_usage.html > Language: zh 本文档主要介绍如何使用 BMC Studio 插件。 # 一键安装 欢迎使用 BMC Studio 一键安装视频操作指导,本视频将为您介绍自动安装步骤,助您轻松完成 BMC Studio 的安装。 # 使用前准备 - 进入[openUBMC应用市场](https://openubmc.cn/marketplace),在“开发工具”模块中下载 BMC Studio 安装包(`.zip`格式),并将下载的安装包解压,获得`.vsix`文件。 - 确保本地已安装 VS Code(全称:Visual Studio Code,以下简称:VS Code), 且已经通过 Remote 插件连接到开发使用的 Ubuntu/docker 环境。 # 环境要求 BMC Studio 需要在 Ubuntu24 环境上运行,使用前须先搭建环境,具体的搭建方法请参见[环境准备](../../../installation/env_prepare.md),请用户根据使用的操作系统,参考“环境准备”对应章节进行环境搭建。例如:本地使用 Windows 开发环境,请参考“Windows开发环境搭建”。 # 安装插件 - 通过 VS Code 安装插件。 1. 打开 VS Code,参考下图步骤操作。 ![从VSIX安装](../../images/bmc_studio/user_guide/plugin_usage/install.png) 2. 选择`.vsix`文件存放路径,安装插件。 > [!NOTE]说明:
> 选择前,请先确定`.vsix`文件存放的操作系统,Windows 或 wsl。 3. 安装完成后重启 VS Code 生效。 - 在 WLS 开发环境中安装插件。 根据实际情况在 Ubuntu 或 Linux 环境下,执行以下命令进行安装(“xxxxxx”表示`.vsix`文件的存放路径)。 ```bash code --install-extension xxxxxx ``` # 安装和使用工具 1. 在 VS Code 打开已安装的 BMC Studio 的插件。 2. 插件将会自动对环境进行检测,查询是否安装 BMC Studio 和 Qemu。 - 如果检测到环境中未安装工具,请执行以下步骤3~步骤7安装和启动。 - 如果检测到环境中已安装工具,插件将会自动启动 BMC Studio。 > [!NOTE]说明:
> 如果当前安装的工具非最新版本,您可以单击界面上的“一键更新”升级工具版本,也可以直接使用当前的旧版本。 3. 单击“一键安装工具”,弹出“使用协议”相关弹框。 4. 勾选“同意《BMC软件许可协议》协议”,单击“继续安装”。插件将开始下载并安装您缺失的工具和依赖。安装时间根据网络情况,预计在1~10分钟不等。 5. (可选)如果下载时间过长,您可以在 VS Code 上方导航栏中选择“终端 > 新建终端”,在新建的终端中选择“输出”,右侧下拉框选择“Debug Logs”,打开日志查看是否报错,如果存在报错,请根据日志的实际情况处理。 ![查看日志信息](../../images/bmc_studio/user_guide/plugin_usage/type.png) 6. 安装成功后“一键安装工具”的按钮变为“开始使用”。 7. 单击“开始使用”,即可启动 BMC Studio。 # 插件实时模型检查 BMC Studio 启动后,在 VS Code 中编辑 CSR 文件或任意 BMC Studio 工作空间内的 MDS、资源协作接口、映射接口文件,保存后会触发插件进行模型检查。检查完成后,在控制台窗口会显示检查结果,查看检查结果操作如下: ![检查结果](../../images/bmc_studio/user_guide/plugin_usage/check.png) # 插件双屏显示 BMC Studio 插件支持双屏查看文件的能力。在打开一个 .sr 或 .json文件后,vscode 右上角会出现这个图标。点击该图标,即可启动 BMC Studio 双屏模式。 ![双屏模式](../../images/bmc_studio/user_guide/plugin_usage/dual_screen_mode.png) 双屏模式中,插件会使用 BMC Studio 打开该 .sr 或 .json 文件,然后展示在插件页面里。 ![双屏模式2](../../images/bmc_studio/user_guide/plugin_usage/dual_screen_mode_2.png) # 插件在线调试 前置条件: - BMC Studio 版本不低于1.2.0。 BMC Studio 最新版本获取方法请参考[BMC Studio安装指南](../installation_guide/bmc_studio_installation.md)。 - BMC Studio 插件版本不低于0.0.5。 插件安装方法请参考[安装插件](#安装插件)。 - Qemu 已安装。 开发环境初始化过程会安装 Qemu,无需手动安装。 在线调试: 在线调试的具体流程,请参考[Qemu文档](./qemu_device_management.md)。 # 卸载插件 安装了插件后,可以在 vscode 的扩展页面的“已安装”一栏中看到 BMC Studio 插件。按图中顺序点击。 ![卸载插件1](../../images/bmc_studio/user_guide/plugin_usage/uninstall_plugin_1.png) 点击图中的“卸载”按钮即可完成卸载。 ![卸载插件2](../../images/bmc_studio/user_guide/plugin_usage/uninstall_plugin_2.png) --- # openUBMC Studio Qemu设备管理使用指南 > URL: https://openubmc.cn/docs/zh/latest/common_tools/bmc_studio/user_guide/qemu_device_management.html > Language: zh 本文档主要介绍如何管理 Qemu 虚拟机。 # 使用前准备 - 安装 Qemu - 使用 VS Code 插件安装。具体操作方法请参考[BMC Studio插件使用说明](plugin_usage.md)。 - 准备镜像文件 - 通过 openUBMC 应用市场下载预制镜像:在“Qemu设备管理”配置虚拟机参数时,仿真镜像来源选择“应用市场”。 - 本地下载:单击[Qemu镜像](https://www.openubmc.cn/marketplace/QEMU),下载对应版本的镜像文件到本地(镜像文件通常以`.cpio.gz`为后缀)。 # 配置 Qemu 虚拟机 1. 在 BMC Studio 首页,单击右上角“设备管理”按钮,进入“接入设备管理”界面。 ![接入设备管理按钮](../../images/bmc_studio/user_guide/qemu_device_management/device_management_button.png) 2. 在“Qemu设备管理”区域单击“配置”。 ![QEMU配置页面](../../images/bmc_studio/user_guide/qemu_device_management/qemu_config_page.png) 3. 参考以下内容设置虚拟机参数。 | 参数 | 参数说明 | |------|----------------------------------------------------------------| | 机型 | 自定义标识名称,例如:`MyUbuntuVM` | `> | 模拟环境CPU核心数 | 分配的计算核心(建议 ≤ 物理核心数),例如:`2` | `> | 模拟环境内存 | 分配的内存(单位:GB),例如:`4` | `> | 仿真镜像来源 | 选“应用市场/Ubuntu镜像/本地文件”,例如:`ubuntu-22.04.iso` | `> | 网络端口 | 设置 SSH/HTTPS/IPMI/SNMP 访问端口,例如:`SSH:2222` | `> > [!NOTE]说明:
> 仿真镜像来源:
> - 应用市场:连接 openUBMC 应用市场自动预装系统的官方镜像。
> - 本地镜像:需要提前上传至 BMC Studio 的镜像目录。
> - Ubuntu镜像:如果您已经通过“应用市场”预装了镜像或通过“本地镜像”方式上传了镜像,可选择此项。 # 启动和使用虚拟机 启动虚拟机的操作方法如下: 1. 在 BMC Studio 首页,单击右上角第一个图标“设备管理”按钮,进入“接入设备管理”界面。 2. 在“Qemu设备管理”区域选择虚拟机,单击“启动”,启动时间预计需要3~5分钟左右。 ![QEMU启动中](../../images/bmc_studio/user_guide/qemu_device_management/qemu_starting.png) 3. 等待状态显示为蓝色时,表示启动成功。启动完成后,相关参数含义请参考以下内容: ![QEMU已启动](../../images/bmc_studio/user_guide/qemu_device_management/qemu_started.png) | 参数 | 参数说明 | |------|----------------------------------------------------------------| | 重新启动 | 重启虚拟机 | `> | 停止 | 强制关闭虚拟机。长时间不使用虚拟机时,可以使用此功能释放CUP/内存 | `> | 连接 | 通过 SSH 终端访问(需配置端口) | `> | BMC登录 | 通过浏览器访问仿真 BMC 设备 Web 图形界面 | `> > [!NOTE]说明:
> 删除虚拟机的配置不会清除镜像文件。 # 虚拟机仿真文件配置 本功能在 QEMU 未启动时,只能进行修改操作,无法生效到 QEMU。如果要生效到 QEMU,请在 QEMU 启动时保存修改。 1. 在BMC Studio首页,单击右上角第一个图标“设备管理”按钮,点击上方“仿真文件”进入界面。在此页面,可以对文件进行任意修改。 ![仿真管理](../../images/bmc_studio/user_guide/qemu_device_management/simulation_management.png) 2. 修改好文件后,点击下方“保存”和“取消”分别可以将修改的配置保存并生效到 QEMU 或放弃。 3. 可以通过点击下方“修改对比”按钮检查修改的部分。如果确认无误,可以点击“确定修改”保存并生效到 QEMU。也可以点击“退出对比”继续修改。 ![查看修改](../../images/bmc_studio/user_guide/qemu_device_management/view_simulation_file_changes.png) # 在线调试接口 前置要求: - BMC Studio 版本不低于1.2.0 BMC Studio 最新版本获取方法请参考[BMC Studio安装指南](../installation_guide/bmc_studio_installation.md)。 - BMC Studio 插件版本不低于0.0.5 BMC Studio 插件目前需要以文件方式安装,安装过程参考[插件文档](./plugin_usage.md)。 - Qemu 已安装 开发环境初始化过程会安装 Qemu,无需手动安装。 ## 通过 BMC Studio 结合 Qemu 进行代码调试 在已经建立 Qemu 连接的情况下,可以配合 BMC Studio 的 Vs Code 插件实现代码调试功能。请确保 BMC Studio 插件已安装,且 BMC Studio 已连接到 Qemu,否则调试按钮不会在 Vs Code 页面出现。 ![BMC Studio插件](../../images/bmc_studio/user_guide/qemu_device_management/plugin_store.png) 1. 通过 VsCode 在 openUBMC 的组件代码仓下打开新窗口。 以北向接口定制开发为例: 1. 打开 rackmount 文件夹。 2. 打开任意北向接口定制文件,即可在右上角看到两个图标,分别是文件级调试和组件级调试。 ![调试按钮](../../images/bmc_studio/user_guide/qemu_device_management/debug_button.png) 2. 单击“文件调试”按钮,文件会自动生效到 Qemu,并重启对应子系统进程。等待进程重启完成后即可连接 Qemu 查看调试结果。 3. 单击“组件调试:按钮,BMC Studio 会自动进行一次 bingo build 操作,并将 conan 制品中的文件替换到 Qemu 环境中,重启对应子系统,该方式适合代码修改涉及多个文件,或者修改C语言代码的情形。 4. 修改 web_backend 的接口,并启动调试。以 Login 接口的版权信息为例,修改后点击单文件生效。 ![上传单文件](../../images/bmc_studio/user_guide/qemu_device_management/upload_single_file.png) 5. 等待 interface 进程重启完毕。 ![重启子系统](../../images/bmc_studio/user_guide/qemu_device_management/restart_subsystem.jpeg) 6. 重启后,接口信息会发生更改。 7. 选择组件调试,由于需要编译组件,时间会稍微长。 ![组件调试](../../images/bmc_studio/user_guide/qemu_device_management/component_debug.png) ![上传成功](../../images/bmc_studio/user_guide/qemu_device_management/upload_success.png) 8. 等待子系统重新拉起,此时耗时可能更长。 ![组件调试](../../images/bmc_studio/user_guide/qemu_device_management/component_debug.jpeg) 9. 组件调试完成,页面发生变化。 ## 通过 BMC Studio 进行 Qemu 或者真机环境的资源协作接口和数据库调试 除了代码调试能力外,BMC Studio 的 Web 页面支持对资源协作接口进行可视化查看和调试,以及对数据库信息进行查询,具体如下: ### 连接到任意 Qemu 环境或者真机环境 1. 连接到 BMC 环境后,选择右上角的仿真调试。 ![仿真调试](../../images/bmc_studio/user_guide/qemu_device_management/simulation_debug.png) 2. 资源协作接口查看与调试。 由于组件数量较多,资源协作接口会在后台持续按照组件更新,可以点击刷新按钮刷新。 ![资源协作接口可视化](../../images/bmc_studio/user_guide/qemu_device_management/resource_collaboration_interface_visualization.png) 3. 以资源`/bmc/kepler/Managers/1/BMC`为例,根据路径找到对应资源,点击后即可展开资源详情,内容按照接口进行折叠。 ![BMC资源内容](../../images/bmc_studio/user_guide/qemu_device_management/bmc_resource_content.png) ### 资源协作接口属性实时修改 BMC Studio 基于 mdbctl 命令封装了属性设置功能。 1. 单击属性框即可修改属性,修改完成后点击其他任意处,属性修改会自动生效,例如:将 openUBMC 改为 MyBMC。 ![修改BMC名称](../../images/bmc_studio/user_guide/qemu_device_management/modify_bmc_name.png) 2. 修改完成后,即可进入命令行或者页面查看资源协作接口的修改结果。页面变化如下: ![页面变化](../../images/bmc_studio/user_guide/qemu_device_management/page_change.jpeg) > [!NOTE]说明:
> 部分不在 mdbctl 命令支持范围内的对象不支持修改属性,修改后不会生效。 ### RPC一键调用 BMC Studio 简化了 RPC 调用过程,开发者只需要关注调用参数即可,无需关心完整命令的拼接,我们会帮您自动完成。调用参数操作方法如下: ![RPC调用](../../images/bmc_studio/user_guide/qemu_device_management/rpc_call.png) 1. 展开接口。 2. 单击选择需要调用的 RPC。 3. 在参数框中输入参数信息。 4. 单击右侧调试按钮,将会自动将下方拼接好的命令在 BMC 环境上执行,并返回结果,结果内容与命令行调用一致。 ## 通过 BMC Studio 插件进行仿真调试 ![插件仿真调试](../../images/bmc_studio/user_guide/qemu_device_management/plugin_simulation_debug.png) 1. 使用 VS Code 打开一个代码仓,页面右上角会出现“仿真调试”按钮。 2. 单击“仿真调试”的按钮就可以进行和 BMC Studio 相同的仿真调试功能。具体操作和[通过 BMC Studio 进行 Qemu 或者真机环境的资源协作接口和数据库调试](#通过-bmc-studio-进行-qemu-或者真机环境的资源协作接口和数据库调试)。 ![插件仿真调试页面](../../images/bmc_studio/user_guide/qemu_device_management/plugin_simulation_debug_page.png) ## 数据库信息查看 1. 单击仿真调试窗口上方的数据库页签即可查看全部组件的数据库信息。每个组件下的数据库按照不同的持久化类型分类。 2. 单击对应的表即可查看数据表内容。 ![数据库查看](../../images/bmc_studio/user_guide/qemu_device_management/database_view.png) --- # BMC Studio SSH连接功能操作指南 > URL: https://openubmc.cn/docs/zh/latest/common_tools/bmc_studio/user_guide/ssh_connection.html > Language: zh 本文档主要介绍如何使用BMC Studio SSH的连接功能。 # 使用前准备 - 软件:请安装最新版本的BMC Studio工具。 进入[openUBMC应用市场](https://www.openubmc.cn/marketplace/BMC%20Studio),在BMC Studio下载页面,单击右侧“立即下载”按钮,将BMC Studio软件包下载到本地。 - 硬件:请准备一台可远程访问的服务器,并提前获取服务器的IP地址、端口号、用户名和登录密码。 # 使用须知 - BMC Studio仅支持保持一个活跃连接,如果新建SSH连接或重新连接另一个设备,之前的会话将会被断开。 - 为确保设备信息安全,离开设备时,请主动断开连接。 # 创建SSH连接 1. 在BMC Studio首页,单击右上角第一个图标“设备管理”按钮,进入“接入设备管理”界面。 2. 在“BMC设备管理”区域单击“+新建设备”。 3. 填写设备的IP地址、端口、用户名和密码。 4. 单击“连接”,完成设备认证。认证成功后,新建的设备会展示在BMC设备管理区域下。 # 连接管理 ## 重新连接会话 1. 在“BMC设备管理”区域下的设备列表中,选择需要重新连接的会话。 2. 确认设备处于未连接状态,操作列将展示“连接”和“删除”。 3. 单击“连接”按钮,输入对应设备的密码。 > **说明**:
> 基于安全考虑,BMC Studio不会自动保存设备密码,涉及密码处均须手动输入确认。 ## 断开当前连接 1. 在“BMC设备管理”区域下的设备列表中,选择需要断开连接的会话。 2. 确认设备处于连接状态,操作列将展示“取消连接”和“删除”。 3. 单击“取消连接”按钮,等待“取消连接”按钮变为“连接”时,断开成功。 ## 删除设备配置 1. 在“BMC设备管理”区域下的设备列表中,选择需要删除的会话。 2. 单击“删除”按钮,删除成功后会清除当前设备的全部缓存信息。 # 连接状态说明 - **绿灯**:表示设备已连接,可执行断开或发送命令操作。 - **灰标**:表示设备未连接,可执行新建连接或重新连接操作。 --- # QEMU常见问题 > URL: https://openubmc.cn/docs/zh/latest/common_tools/qemu/qemu.html > Language: zh # Qemu启动 ## 【Q】按照官方的最新的manifest以及指导文档运行Qemu后 SSH能访问Ipmi命令能通,但是web不通,端口号也都反复检查了。这时候的固件是跑脚本的时候下载的固件 ![问题1](../images/qemu/qemu/qemu_question_1.png) 1. ssh和ipmi启动时间会比web的启动时间要快,web连接不通可能在于nginx还没拉起,可以稍等几秒再重新拉起,此时可以: - 登录ssh:`ssh Administrator@localhost -p 10022​` - 进入telnet:`/data/home/busybox_x telnet localhost` - 查看nginx服务是否启动:`netstat -ntlpa` 2. 如果还不行,请保持默认config文件内容,删除manifest temp目录和output目录重试拉起qemu,此时能够顺利拉起qemu。 ## 【Q】25.06源码构建的qemu,启动后存在互锁和web网页无法打开的问题:`ERROR:../hw/infc/arm_drcv3_cpuif.c:784:gicv3_cpuif_update:assertion failed: {qemu_mutex_iothread_locked()}` ![问题2-1](../images/qemu/qemu/qemu_question_2_1.png) ![问题2-2](../images/qemu/qemu/qemu_question_2_2.png) ![问题2-3](../images/qemu/qemu/qemu_question_2_3.png) ![问题2-4](../images/qemu/qemu/qemu_question_2_4.png) /hw/infc/arm_drcv3_cpuif.c断言失败导致的问题,可能是您本地缓存的qemu二进制文件和现在不匹配问题,您可以进行如下流程进行恢复: - 删除conan缓存:`rm -rf ~/.conan2/p/*` (conan2);`rm -rf ~/.conan/data/*` (conan1) - 重新出包:`bingo build -sc qemu` - 删除qemu本地缓存的二进制工具:manifest仓的temp目录 - 重新拉起qemu:`python3 build/works/packet/qemu_shells/vemake_1711.py` ![答复2-1](../images/qemu/qemu/qemu_reply_2_1.png) ![答复2-2](../images/qemu/qemu/qemu_reply_2_2.png) ![答复2-3](../images/qemu/qemu/qemu_reply_2_3.png) ![答复2-4](../images/qemu/qemu/qemu_reply_2_4.png) ## 【Q】Qemu启动后存在RTOS版本不一致问题,导致ssh无法连接:x_tables: disagrees about version of symbol module_layout ![问题4](../images/qemu/qemu/qemu_question_4.png) 这个是RTOS版本不一致导致驱动起不来的问题: 先看查看环境的RTOS版本和qemu远程的RTOS版本一致了,查看方法:`ls -l /opt/RTOS`,将会由显示RTOS版本号,然后Qemu的使用的RTOS版本号会在manifest.yml里面存在qemu_rtos_version,将两者进行比较 如果不是的话,请进行以下步骤: 1. 拉最新的[manifest组件仓](https://gitcode.com/openUBMC/manifest.git) ![manifest](../images/qemu/qemu/qemu_reply_3_1.png) 2. 删除conan缓存:`rm -rf ~/.conan2/p/*` 3. 重新初始化环境:执行`python3 init.py xxx` 4. 重新出包:`bingo build -sc qemu` 5. 重新启动qemu:`python3 build/works/packet/qemu_shells/vemake_1711.py` ## 【Q】Qemu仿真环境启动时卡住:Authorized uses only. All activity may be monitored and reported.pe (err -2)localhost login 这种情况有可能是两种因素引起: 1. 修改的内容导致BMC有问题,这种遇到卡顿可以等一下,过了一段时间,可以telnet进去查看日志:`cat /var/log/framework.log`,查看报错,一般都是基础框架没有起来的问题;然后根据日志报错修改自己的代码 2. 由于本地的conan缓存的生命周期失效,可以清除conan缓存 可以尝试这样解决: - 拉最新manifest - 执行`python3 init.py xxx` - 升级bingo:`bingo upgrade` - 清除conan缓存:`rm -rf ~./conan2/p/*` - 出包:`bingo build -sc qemu` - 启动qemu: `python3 build/works/packet/qemu_shells/vemake_1711.py` ## 【Q】执行仿真环境qemu后,有报错但不影响登录openUBMC,请问账号密码是什么? 账号/密码:`Administrator/Admin@90000` ## 【Q】web一直不响应,可以看看nginx服务是否存在 终端登录ssh: `ssh Administrator@localhost -p 10022`​ 进入telnet: `/data/home/busybox_x telnet localhost` 查看nginx服务是否启动:`netstat -ntlpa` 如果nginx服务启动了,web还登录不了,此时可以查看日志:`cat /var/log/app.log`, 或者`killall interface` 如果nginx服务还没启动,需要通过日志来定位问题了:`cat /var/log/app.log`, 来观察是不是本身代码做了其他修改导致的问题 ## 【Q】仿真环境启动后,登进去,缺少ipmcget命令:仿真环境初始化完毕后,用户名Administrator密码Admin@90000,登录到openUBMC里面,没有ipmcget命令,也没有ifconfig命令,如何添加? 在manifest的output/data被异常修改导致的问题: - 停止正在运行的qemu - 删除output/data目录 - 重新运行qemu:`python3 build/works/packet/qemu_shells/vemake_1711.py` 目前openUBMC暂时不支持ifconfig命令 # Qemu构建 ## 【Q】bingo build -sc qemu 报错为啥,用的是普通用户,必须要用root用户嘛? 目前Qemu的二进制工具构建和openUBMC的仿真镜像包仅支持root用户 ## 【Q】25.06源码构建qemu固件包失败,存在组件全量源码构建失败问题:CMake Error: The source directory “/root/.conan/data/bmc_network/1.70.42/openUBMC.release/rc/build/a8cc6717e1ce1e0d9c59af89eaae6d6122f062e6” does not appear to contain CMakeLists.txt ![问题3-1](../images/qemu/qemu/qemu_question_3_1.png) ![问题3-2](../images/qemu/qemu/qemu_question_3_2.png) 1. 因为触发了bmc_network组件的全量源码构建,但bmc_network组件在社区只有conan包导致的,可以直接`conan download bmc_network/1.70.42@openUBMC.release/stable -r openubmc_dev`验证conan有没有问题 2. `conan download bmc_network/1.70.42@openUBMC.release/stable -r openubmc_dev`成功之后,拉最新的manifest,重新`python3 init.py xxx`, 然后清除缓存`rm -rf ~/.conan2/p/*`, 然后重新再来:`bingo build -sc qemu`. ## 【Q】基于修改代码出自己的qemu cpio包,会提示某个组件download失败 首先去查看本地manifest仓的temp/log/task.log,看看有没有说是要输入account和密码,如果有的话: - 杀死正在运行的qemu构建出包进程 ![问题10](../images/qemu/qemu/qemu_question_10.png) - 然后在终端输入命令:`conan search help -r openubmc_dev`,会提示输入账号和密码 - 重新`bingo build -sc qemu`出包即可 --- # QEMU仿真与BMC业务开发指南 > URL: https://openubmc.cn/docs/zh/latest/common_tools/qemu/qemu_tool_guide.html > Language: zh 本文档主要介绍如何启动并在BMC业务中使用QEMU。 ## 1. 🛠️ QEMU 环境搭建 ### 什么是 QEMU? QEMU 是一个开源的硬件仿真器,可以在你的电脑上模拟出一台完整的服务器。对于 BMC(基板管理控制器)开发来说,这是一个非常实用的工具——你不需要准备真实的硬件单板,就可以在虚拟环境中验证大部分功能。 想象一下,传统的开发流程是这样的:修改代码 → 编译 → 烧录到硬件 → 启动服务器 → 测试功能 → 发现问题 → 重复上述过程。每次测试都需要硬件配合,而且烧录固件也需要时间。 有了 QEMU,流程就变成了:修改代码 → 编译 → 重启 QEMU → 测试功能。整个过程在本地就可以完成,大大缩短了开发周期。 ### 为什么使用 openUBMC 的 QEMU? openUBMC 社区针对 BMC 开发的特点,对 QEMU 做了专门的优化和配置。主要优势包括: - **预配置好的硬件拓扑**:模拟了真实服务器的硬件结构,不用自己从头搭建 - **完整的北向接口支持**:CLI、Redfish、Web、IPMI 等接口开箱即用 - **便捷的启动方式**:提供脚本和 deb 包两种启动方式,适应不同使用场景 - **活跃的社区支持**:遇到问题可以在论坛上交流讨论 **关于 manifest 仓库** 你可能会问:为什么总是提到 manifest 仓库?这是因为 manifest 是 openUBMC 社区维护的配置管理中心,里面包含了: - **启动脚本**:用于拉起 QEMU 虚拟机 - **配置文件**:定义了硬件拓扑、端口映射、PCIe 卡等 - **初始化工具**:自动下载和配置 BMC 运行所需的各种文件 后续的环境初始化、QEMU 启动、PCIe 卡配置等操作都需要通过 manifest 仓库来完成。简单来说,它是你使用 openUBMC QEMU 的"控制中心"。 **manifest 仓库地址**:[https://gitcode.com/openUBMC/manifest](https://gitcode.com/openUBMC/manifest) 每次都需要保持本地的 manifest 仓库是最新的,可以执行下面的指令: ```bash # 如果第一次 git clone manifest 仓库 git clone https://gitcode.com/openUBMC/manifest.git cd manifest git pull ``` --- ### 环境初始化 第一次使用前,需要先初始化环境。这一步会下载必要的文件和配置。 ```bash cd manifest python3 init.py -path -user -psw ```

环境初始化

**参数说明**: - `-path`:bmc_sdk.zip 文件的路径,这个 zip 包包含了 BMC 固件运行所需的基础文件(获取路径:[https://www.openubmc.cn/zh/marketplace/bmcsdk](https://www.openubmc.cn/zh/marketplace/bmcsdk)) - `-user`:你的 openUBMC 社区用户名 - `-psw`:你的 openUBMC 社区密码 --- ### 1.1 方式一:通过脚本启动 这是最直接、最常用的启动方式,特别适合日常的开发调试。 #### 为什么推荐这种方式? 脚本启动方式的优点: - **简单直接**:一条命令就能启动,不需要额外配置 - **调试友好**:QEMU 的输出会直接显示在终端,方便查看日志 - **灵活可控**:可以通过修改脚本参数调整 QEMU 的配置 - **更新及时**:脚本总是和 manifest 仓库同步,第一时间获得最新功能 #### 启动 QEMU ```bash cd manifest python3 build/works/packet/qemu_shells/vemake_1711.py ```

脚本启动 QEMU

执行后,你会看到 QEMU 的启动日志滚动显示。等待一段时间后,BMC 固件就会启动完成,你可以通过 SSH 或者 Web 界面连接进去。 ```bash Uncompressing... done, booting... [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x412fd050] [ 0.000000] Linux version 5.10.0 (oe-user@oe-host) (aarch64-euler-linux-gcc (BiSheng Embedded CPU 302.1.0.B016) 7.3.0, GNU ld (BiSheng Embedded CPU 302.1.0.B016) 2.41) #1 SMP PREEMPT Tue Nov 26 22:03:48 CST 2024 ``` #### 如何停止 QEMU? 有时候你需要停止 QEMU,比如要修改配置或者结束今天的工作。 **方法 1:优雅退出(推荐)** 在 QEMU 启动的终端窗口中,直接按 `Ctrl + C`,脚本会自动清理相关进程。 **方法 2:强制结束** 如果 `Ctrl + C` 没有响应,可以用 kill 命令强制结束: ```bash # 先查看 QEMU 进程的 PID ps aux | grep qemu # 然后结束进程, 对应 QEMU 进程的 PID # 一般情况下查找 qemu-system-aarch64 所对应的 PID 号 kill -9 ``` --- ### 1.2 方式二:通过 .deb 软件包启动 如果你习惯了使用 Linux 的包管理工具,或者需要在自动化测试、CI/CD 流程中使用,deb 包方式会更方便。在最开始环境初始化的过程中,就已经将 deb 包安装好了,剩下的事情就只需要一键启动即可。 #### 什么时候选择这种方式? - **CI/CD 环境**:在持续集成流程中,使用 deb 包更容易集成 - **多台机器部署**:安装一次 deb 包,之后可以快速启动 - **命令行偏好**:习惯了 `apt install` 的操作方式 #### deb 包相关命令 ```bash # 查询版本命令 openubmc-qemu version # 查询接口状态命令(当接口 up 时,用户就可以连接) openubmc-qemu status # 关闭 QEMU 命令 openubmc-qemu close ```

查看版本号

#### 启动 QEMU ```bash # 初始化环境(第一次使用时需要) openubmc-qemu init # 启动 QEMU openubmc-qemu run --remote ```

deb包启动

`--remote` 参数表示使用远程模式,这样 QEMU 的服务端口会映射到宿主机上,你可以通过网络访问。 --- ### 1.3 连接到 QEMU 中的 BMC QEMU 启动后,BMC 固件就开始运行了。但是你还没有办法直接操作它,因为 BMC 运行在 QEMU 虚拟出来的"服务器"里,而不是你的物理电脑。 为了解决这个问题,QEMU 使用了**端口映射**技术。简单来说,就是把虚拟机里的端口"转发"到你的物理电脑上。 | BMC 内部端口 | 宿主机映射端口 | 说明 | |:-----------:|:-------------:|:-----| | 22 | 10022 | SSH 服务 | | 23 | 10023 | Telnet 服务 | | 443 | 10443 | HTTPS(Web + Redfish) | | 623 | 10623 | IPMI 服务 | 举个例子,当你连接 `127.0.0.1:10022` 时,实际上连接的是虚拟机里的 `22` 端口(SSH)。 #### SSH 连接 SSH 是最常用的连接方式,可以执行各种管理命令。在登录 SSH 之前需要知晓宿主机的 IP,在 Linux 中执行 `ifconfig` 查看 IP,找到 eth0 的 IP,然后在宿主机中执行: ```bash # 此处默认的 IP 地址是 localhost 也就是 127.0.0.1 ssh -p 10022 Administrator@127.0.0.1 ``` 输入密码 `Admin@90000` 后,你就进入了 BMC 的命令行界面,可以像操作真实服务器一样执行各种命令。 > **默认账号信息**: > > - 用户名:`Administrator` > - 密码:`Admin@90000` > > **安全提示**:在生产环境中,请务必修改默认密码! #### Telnet 连接 Telnet 是一个更简单的协议,主要用于调试。 ```bash telnet 127.0.0.1 10023 ``` ### 1.4 卸载 deb 包 ```bash apt purge -y openubmc-qemu ``` --- ## 2. 🌐 BMC 北向接口在 QEMU 中的应用 ### 什么是北向接口? BMC(基板管理控制器)是服务器上的一个小型独立计算机,负责监控和管理服务器的各种状态。但是 BMC 自己不会主动去"管理"什么——它需要和外部管理系统配合工作。 **北向接口**就是 BMC 对外提供的"沟通渠道"。通过这些接口,外部的管理系统(比如数据中心管理平台、监控软件)可以: - 查询服务器的硬件状态(温度、电压、风扇转速等) - 控制服务器的电源(开机、关机、重启) - 管理固件版本 - 配置各种参数 - 接收告警通知 openUBMC 支持以下北向接口:CLI、Redfish、Web、IPMI。每个接口都有自己的特点和适用场景。

BMC 北向接口架构

### QEMU 如何暴露这些接口? 在真实的服务器上,BMC 的北向接口通过网络对外提供服务。在 QEMU 虚拟环境中,我们使用**端口转发**技术,把虚拟机里的端口映射到宿主机上。 这样,你就可以在宿主机上直接访问 BMC 的各种服务,就像访问一台真实服务器的 BMC 一样。 --- ### ⌨️ a) CLI 接口(命令行接口) CLI(Command Line Interface)是最直接、最原始的管理方式。通过命令行,你可以执行几乎所有的 BMC 管理操作。 #### CLI 的特点 - **响应快速**:没有图形界面的开销,命令执行速度快 - **适合脚本**:可以编写脚本批量执行操作 - **调试利器**:开发者最常用的接口,可以快速定位问题 - **功能完整**:几乎所有功能都可以通过 CLI 访问 #### 步骤 1:查看版本信息 连接上 BMC 后,第一件事通常是查看版本信息,确认 BMC 固件是否正确加载。BMC 提供丰富的 CLI 命令,如下图所示,可以看到 ipmcget 命令支持查询固件版本信息、查询时间等操作。

ipmcget 命令

```bash ipmcget -d v ``` 执行后会输出 BMC 的版本信息,包括: - BMC 固件版本号 - BIOS/UEFI 版本 - CPLD 版本 - 各种子卡固件版本

版本信息

版本信息

#### 步骤 2:使用 D-Bus 接口 D-Bus 是 Linux 系统中用于进程间通信的机制。在 openUBMC 中,各个功能模块之间通过 D-Bus 互相调用,协同工作。 通过 `busctl` 命令,你可以: - 查看 BMC 的组件结构 - 查看每个组件提供的接口 - 调用组件的方法 - 监听组件的事件 **查看组件资源协作接口**: ```bash # 命令可以依赖 bmc.kepler.<组件名> 来拼接 # 以固件管理 firmware_mgmt 为例 busctl --user tree bmc.kepler.firmware_mgmt ```

D-Bus 组件树

这个命令会显示 `bmc.kepler` 服务的对象树结构,像文件系统的目录树一样,展示了各个子组件的层级关系。 **查看接口定义**: ```bash busctl --user introspect bmc.kepler.firmware_mgmt /bmc/kepler/UpdateService/FirmwareInventory/ActiveBMC ```

D-Bus 接口详情

`introspect` 命令会详细列出某个对象的所有接口、方法、属性和信号,包括它们的参数类型和返回值类型。这对于开发者来说是非常有用的调试工具。 --- ### 🦊 b) Redfish 接口 Redfish 是 DMTF(分布式管理任务组)制定的现代数据中心管理标准。相比传统的 IPMI 协议,Redfish 具有以下优势: #### Redfish 的优势 - **基于 HTTP/HTTPS**:使用标准的 Web 协议,易于集成 - **JSON 格式**:数据格式简洁,解析方便 - **RESTful 风格**:API 设计符合 REST 规范,直观易懂 - **安全性更好**:支持 HTTPS 和现代认证机制 - **扩展性强**:可以方便地添加新的资源和功能 #### 认证信息 - **访问地址**:`https://127.0.0.1:10443` - **用户名**:`Administrator` - **密码**:`Admin@90000` #### 步骤 1:使用 Postman 测试 Postman 是一个流行的 API 测试工具,提供图形化界面,支持保存请求历史,非常适合用来调试 Redfish 接口。 **操作步骤**: 1. 打开 Postman,新建一个请求 2. 选择请求方法(GET 用于查询数据,POST 用于创建资源,PATCH 用于修改资源) 3. 输入 URL:`https://127.0.0.1:10443/redfish/v1/` 4. 配置认证: - 切换到 **Authorization** 标签 - Type 选择 **Basic Auth** - Username 输入 `Administrator` - Password 输入 `Admin@90000` 5. 关闭 SSL 验证:Settings → SSL certificate verification → Off(因为 QEMU 使用的是自签名证书) 6. 点击 **Send** 发送请求

Postman 配置

#### 步骤 2:查询系统信息 Redfish 使用树状结构组织资源,`/redfish/v1/` 是根路径,从这里可以访问所有子资源。 查询系统信息: ```bash curl -k -u Administrator:Admin@90000 \ https://127.0.0.1:10443/redfish/v1/Systems/1 ```

系统信息

返回的 JSON 数据包含了服务器的各种信息: - `SerialNumber`:序列号 - `Model`:型号 - `Status`:健康状态 - `PowerState`:电源状态 - `Boot`:启动配置 --- ### 💻 c) Web 接口(Web UI) Web UI 是最直观、最易用的管理方式。你不需要记忆任何命令,也不需要编写代码,通过浏览器就可以完成大部分管理操作。 #### Web UI 的特点 - **图形化界面**:直观易用,不需要培训 - **实时监控**:可以查看传感器的实时读数 - **功能全面**:支持固件管理、用户配置、网络设置等 - **跨平台**:只要有浏览器就可以使用 #### 访问方式 在浏览器中打开:`https://127.0.0.1:10443` 输入用户名和密码登录即可。 #### 步骤 1:访问 Web UI 登录后,你会看到 BMC 的主界面,这里显示了服务器的整体状态概览。

Web UI 主界面

主界面通常包括: - **系统信息**:型号、序列号、健康状态 - **传感器读数**:温度、电压、风扇转速 - **电源状态**:开机/关机状态 - **告警信息**:最近的告警事件 #### 步骤 2:固件管理 固件管理页面可以查看和升级各个组件的固件版本。

固件管理

这里可以管理: - **BMC 固件**:BMC 本身的固件 - **BIOS/UEFI**:主板的 BIOS 固件 - **CPLD/FPGA**:各种可编程逻辑器件的固件 - **子卡固件**:网卡、RAID 卡等扩展卡的固件 #### 步骤 3:服务管理 服务管理页面可以配置 BMC 提供的各种网络服务。

服务管理

可配置的服务包括: - **SSH 服务**:命令行接口 - **Web 服务**:Web UI 和 Redfish - **IPMI 服务**:IPMI over LAN - **虚拟控制台**:KVM/VNC 重定向 你可以启用或禁用某个服务,修改监听端口,配置访问白名单等。 --- ### 🛠️ d) IPMI 接口 IPMI(Intelligent Platform Management Interface,智能平台管理接口)是 BMC 的传统协议。虽然 Redfish 已经成为新的标准,但 IPMI 在许多存量系统中仍然被广泛使用。 #### IPMI 的特点 - **历史悠久**:从上世纪 90 年代就开始使用 - **兼容性好**:几乎所有的服务器都支持 - **工具成熟**:有大量的管理工具可以使用 - **安全性较低**:相比 Redfish,IPMI 的安全性较弱 #### 认证信息 - **端口**:`10623` - **用户名**:`Administrator` - **密码**:`Admin@90000` #### 步骤 1:查询 FRU 信息 FRU(Field Replaceable Unit,现场可替换单元)信息记录了硬件的各种标识数据,包括制造商、型号、序列号等。这些信息对于资产管理和故障追踪非常重要。 ```bash ipmitool -I lanplus -H 127.0.0.1 -p 10623 -U Administrator -P Admin@90000 fru ```

FRU 信息

FRU 信息通常包括: - **Product Info**:产品制造商、型号、序列号 - **Board Info**:主板信息、生产日期 - **Chassis Info**:机箱类型、机箱序列号 #### 步骤 2:读取电子标签 电子标签(E-label)存储在组件的 EEPROM 中,是一种更灵活的存储格式。和 FRU 相比,电子标签可以存储更多信息,并且更容易更新。 ```bash ipmitool -I lanplus -H 127.0.0.1 -p 10623 -U Administrator -P Admin@90000 raw 0x30 0x90 0x05 0x01 0x2 0x03 0x00 0x3 ```

电子标签

这条命令使用 IPMI 的 raw 命令直接发送底层指令。参数的含义: - `0x30 0x90`:读取电子标签的命令码 - `0x05`:FRU ID - `0x01`:区域(Board/Product/Chassis) - `0x2`:字段类型 - `0x03`:偏移量 - `0x00`:读取起始位置 - `0x3`:读取长度 --- ## 3. 🏗️ QEMU 进阶应用 前面的章节介绍了基本的接口使用,这一节我们会进入更高级的主题:模拟复杂的硬件场景。 ### 为什么需要进阶应用? 在真实的运维环境中,服务器会遇到各种突发情况:温度过高、电源故障、设备损坏等。BMC 需要能够及时发现这些异常,并采取相应的措施(发出告警、自动关机、调整风扇转速等)。 如何验证 BMC 的异常处理逻辑是否正确?你不可能真的去破坏硬件来测试。QEMU 提供了一种安全的方式:在虚拟环境中模拟各种异常场景。 本节介绍两个实用场景: 1. **PCIe 卡热插拔**:模拟在线更换 PCIe 设备 2. **事件模拟**:模拟各种硬件告警事件 --- ### ⏰ 3.1 PCIe 卡热插拔 #### 什么是热插拔? 热插拔(Hotplug)是指在系统运行状态下,在线添加或移除硬件设备,而不需要关机。 在数据中心运维中,这是一个非常实用的功能。比如: - 服务器的网卡坏了,需要更换新的网卡 - 需要增加一块 NVMe 硬盘来扩容 - RAID 卡故障,需要紧急更换 传统做法是关机 → 更换硬件 → 开机,这会导致服务中断。有了热插拔,你可以在不影响服务的情况下完成硬件更换。 #### BMC 在热插拔中的作用 当 PCIe 设备插入或拔出时,硬件会触发中断信号。BMC 需要能够: 1. 检测到设备变化 2. 识别新设备的类型和信息 3. 更新资产记录 4. 发送告警通知给管理系统 通过 QEMU,我们可以模拟整个热插拔流程,验证 BMC 的响应是否正确。 #### 默认支持的 PCIe 卡 openUBMC 的 QEMU 环境目前支持以下 PCIe 卡的仿真: | 卡型号 | 类型 | BMC 支持情况 | |:------|:-----|:------------| | **SP680** | 网卡 | 大部分功能已支持,包括端口状态查询、MAC 地址获取、VLAN 配置等 | | **SAS 3152** | RAID 卡 | 基础仿真,支持设备识别和基本信息查询 | --- #### 步骤 1:查看 pcie_card.json 配置 PCIe 卡的配置信息存储在 manifest 仓库的 `pcie_card.json` 文件中。这个文件控制着哪些 PCIe 卡"在位"(present)、每个卡的 CSR 数据是什么。

pcie_card.json 配置

文件中每个 PCIe 卡都有一个 `present` 字段: - `1` 表示该卡在位(BMC 会尝试识别它) - `0` 表示该卡不在位(BMC 会忽略它) #### 步骤 2:修改 CSR 名称并启用 CSR(Command Status Register)是一组记录 PCIe 卡信息的寄存器,包括设备 ID、厂商 ID、子系统 ID 等。 要将一张 PCIe 卡"插入"系统,需要: 1. 将 `present` 字段改为 `1` 2. 配置正确的 CSR 名称(这个名字对应 vpd 仓库中的 CSR 文件)

修改 PCIe 卡配置

CSR 数据可以从 vpd 仓库获取,这里存放了各种 PCIe 卡的标准 CSR 定义:

VPD 仓库

#### 步骤 3:添加仿真数据 光有 CSR 名称还不够,BMC 还需要知道 PCIe 卡的详细属性,比如设备名称、功能类型、链路状态等。这些信息需要在配置文件中完整定义。

添加仿真数据

仿真数据详情

**配置示例(SP670 网卡)**: ```json "PCIeDevice_1": { "DeviceName": "PCIe Card $ (SP670)", "FunctionClass": 2, "DiagnosticFault": 0, "PredictiveFault": 0, "CorrectableError": 0, "UncorrectableError": 0, "FatalError": 0, "DeviceType": 8, "PCIeDeviceType": "MultiFunction", "SlotType": "FullLength", "FunctionProtocol": "PCIe", "FunctionType": "Physical" } ``` **字段说明**: | 字段 | 说明 | |:-----|:-----| | `FunctionClass` | 功能类别(0=未指定,1=存储,2=网络) | | `DiagnosticFault` | 诊断故障标志 | | `PredictiveFault` | 预测性故障标志 | | `CorrectableError` | 可纠正错误计数 | | `UncorrectableError` | 不可纠正错误计数 | | `FatalError` | 致命错误标志 | | `DeviceType` | 设备类型 | | `PCIeDeviceType` | PCIe 设备类型 | | `SlotType` | 插槽类型 | | `FunctionProtocol` | 功能协议 | | `FunctionType` | 功能类型(物理/虚拟) | 这些字段会被 BMC 解析后展示在 Web UI 或通过 Redfish 接口对外提供。 #### 步骤 4:验证结果 配置完成后,可以在 BMC 中查看 PCIe 卡是否被正确识别。 ```bash # 查看 PCIe 卡信息 ipmcget -d v ```

PCIe 卡识别结果

如果一切正常,你应该能看到新添加的 PCIe 卡的信息,包括设备名称、厂商、型号等。 --- ### 🔌 3.2 事件模拟 #### 什么是事件模拟? BMC 的一个重要职责是监控服务器的各种状态,当出现异常时及时发出告警。常见的事件类型包括: - **温度告警**:CPU 或环境温度过高 - **电压异常**:电源电压超出正常范围 - **风扇故障**:风扇转速过低或停止 - **设备故障**:硬盘、网卡等设备出现故障 每个事件都会触发 BMC 的响应流程:记录日志(SEL)、更新传感器状态、发送告警通知(SNMP Trap、Redfish Event)、执行预设动作(调整风扇、自动关机)。 通过 QEMU 模拟这些事件,你可以验证 BMC 的告警机制是否正常工作,不用真的去制造硬件故障。 #### 本节示例 我们以 **BCU1 VCC_12V0_2 电压传感器**为例,演示如何手动触发一个电压告警事件。 --- #### 步骤 1:查看 Web 告警列表 先看看 BMC 的当前告警界面长什么样,了解一下告警信息的展示方式。

Web 告警列表

告警列表通常显示: - 告警级别(Info/Warning/Critical) - 告警时间 - 告警描述 - 告警来源(哪个传感器触发) #### 步骤 2:找到目标传感器的 UID 每个传感器在 BMC 系统中都有一个唯一的 UID(唯一标识符),用于精确定位该传感器。 通过 Web 界面导航到 BCU 板卡的传感器页面,找到 VCC_12V0_2 电压传感器的 UID。

BCU 板卡 UID

这里的 UID 是该板卡的唯一标识符。 #### 步骤 3:查看传感器当前状态 使用 `mdbctl` 命令可以查看传感器的实时读数和配置信息。 ```bash # 查看电压传感器的当前值 mdbctl lsprop Scanner_12v2_010101 # 查看电源状态 mdbctl lsprop Scanner_PowerGood_010101 ```

传感器状态

输出会显示传感器的各种属性,如上图中所示: - `Value`:当前读数 - `ClassName`:名称 #### 步骤 4:修改传感器数值触发告警 现在到了关键步骤:手动修改传感器的数值,看看 BMC 是否会触发告警。 ```bash # 设置一个超出正常范围的值(触发告警) mdbctl setprop set Scanner_12v2_010101 bmc.kepler.Scanner Value 3000 # 恢复正常值(清除告警) mdbctl setprop set Scanner_12v2_010101 bmc.kepler.Scanner Value 2200 ```

修改传感器数值

第一条命令将电压值设为 3000(单位通常是毫伏),这明显超出了 12V 电源的正常范围。BMC 检测到这个异常值后,应该会产生一条告警。 刷新 Web 界面的告警列表,你应该能看到新增的电压告警记录。

告警事件

如果你想清除告警,执行第二条命令,将电压值恢复正常即可。 --- ### 🔧 3.3 板卡适配 #### 什么是板卡适配? 板卡适配是将新的硬件板卡(如网卡、RAID 卡、GPU 卡等)集成到 BMC 管理系统中,使其能够被正确识别、监控和管理。 通过 QEMU,你可以在没有真实硬件的情况下完成大部分适配工作,硬件到位后只需做少量验证。 **核心原理**:通过 `mdbctl` 命令修改板卡的加载方式和 ID,实现板卡的在线替换适配。 --- #### 步骤 1:查看当前板卡信息 首先执行以下命令,查看系统中当前的板卡信息: ```bash ipmcget -d v ```

查看板卡信息

记录下需要替换的板卡 UID,后续步骤会用到。 --- #### 步骤 2:执行板卡替换 本节以 UID 为 `00000001040302044504` 的 IEU 板卡为例,演示如何将其替换为 UID 为 `00000001040302044501` 的板卡。 **执行流程**: ```bash # 1. 查看板卡当前属性信息 mdbctl lsprop Connertor_D7a_010101 # 2. 将板卡设置为不在位状态 mdbctl setprop set Scanner_D7a_010101 bmc.kepler.Scanner Value 0 # 3. 设置连接器识别模式 mdbctl setprop set Connertor_D7a_010101 bmc.kepler.Connector IdentifyMode 2 # 4. 修改板卡 ID(替换为新的 UID) mdbctl setprop set Connertor_D7a_010101 bmc.kepler.Connector Id "00000001040302044501" # 5. 将板卡恢复为在位状态 mdbctl setprop set Scanner_D7a_010101 bmc.kepler.Scanner Value 1 ```

板卡替换命令执行

> **说明**:图中的内容是进入了 mdbctl 模式分开执行的命令,可以通过上述的命令直接执行,而不用进入 mdbctl 模式单独执行命令。 **命令说明**: | 步骤 | 命令作用 | 说明 | |:----:|:---------|:-----| | 1 | `lsprop` | 查看板卡的当前属性配置 | | 2 | `Value = 0` | 将板卡标记为"不在位",相当于拔出板卡 | | 3 | `IdentifyMode = 2` | 设置连接器识别模式 | | 4 | `Id` | 修改板卡的 UID,替换为新板卡的标识 | | 5 | `Value = 1` | 将板卡标记为"在位",相当于插入新板卡 | --- #### 步骤 3:验证替换结果 板卡替换完成后,再次执行以下命令验证结果: ```bash ipmcget -d v ```

验证板卡替换结果

你应该能看到板卡的 UID 已经更新为新的值,板卡信息与目标板卡一致。 ## 📚 附录:快速参考 ### 认证信息汇总 所有接口使用统一的账号密码,方便记忆: | 接口 | 用户名 | 密码 | 端口 | |:----:|:------|:-----|:----:| | **CLI / SSH** | `Administrator` | `Admin@90000` | 10022 | | **Redfish** | `Administrator` | `Admin@90000` | 10443 | | **Web UI** | `Administrator` | `Admin@90000` | 10443 | | **IPMI** | `Administrator` | `Admin@90000` | 10623 | ### 常用命令速查 ```bash # SSH 连接 ssh -p 10022 Administrator@127.0.0.1 # 查看版本信息 ipmcget -d v # 查看传感器 ipmcget -d sensorlist # 查看 FRU 信息 ipmitool -I lanplus -H 127.0.0.1 -p 10623 -U Administrator -P Admin@90000 fru # Redfish 查询系统信息 curl -k -u Administrator:Admin@90000 https://127.0.0.1:10443/redfish/v1/Systems/1 # D-Bus 查看资源协作接口 busctl --user tree bmc.kepler.<组件名> # 修改传感器值 mdbctl setprop set bmc.kepler.Scanner Value <值> ``` --- # 部件驱动接入导读 > URL: https://openubmc.cn/docs/zh/latest/component_driver/comp_driver_overview.html > Language: zh # 简介 openUBMC 的部件驱动接入是基于南向部件接口规范,开发者通过编写设备描述文件和驱动代码,让 BMC 自动发现并纳管新硬件部件,实现即插即用的标准化接入能力。 ![硬件适配范围](./image/comp_driver_overview/component_adaptation_scope.png) 本章主要介绍openUBMC部件类适配(部件驱动适配方案2.0)中各部件的适配方案。 关于openUBMC整机类适配和部件类适配(资源树适配方案1.0)中各部件的适配方案,请参考[硬件适配](../hardware/hw_adapt_overview.md)。 # 学习路径 openUBMC部件驱动接入的学习路径主要包括: - 新手入门:帮助您实现快速上手实操,对部件驱动接入有整体的初步了解。 - 进阶开发:掌握深入原理,熟悉驱动接入操作,快速实现部件驱动接入定制开发。 | 新手入门 | 进阶开发 | | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | | | [概念原理](./concept_principle/component_driver_discovery.md) | | [快速上手](./comp_driver_quick_start.md) | [总体指导](./general_guide/bus_chip_driver_guide.md) | | | [网卡适配](./nic_adapt/nic_driver_spec.md) | | | [硬盘适配](./hdd_adapt/hdd_driver_adapt_guide.md) | | | [xPU适配](./xpu_adapt/gpu_driver_spec.md) | | | [风扇电源适配](./fan_power_adapt/fan_power_driver_adapt.md) | --- # 部件驱动接入快速上手 > URL: https://openubmc.cn/docs/zh/latest/component_driver/comp_driver_quick_start.html > Language: zh # 1 环境搭建 可参考[openUBMC环境搭建](../getting_started/quick_start/env_introduction.html)。首先,您需要准备一个Linux编译服务器。 ## 1.1 拉取源码 ### 1.1.1 配置ssh公钥 ```bash ssh-keygen -t rsa -b 2048 -C 个人邮箱地址 ``` 不要输入,一路回车 ```bash cat ~/.ssh/id_rsa.pub ``` 添加到gitcode上 ### 1.1.2 拉取源码 ```bash git clone https://gitcode.com/openUBMC/devmon.git git clone https://gitcode.com/openUBMC/component_drivers.git git clone https://gitcode.com/openUBMC/libmcpp.git ``` ## 1.2 编译构建 ### 1.2.1 升级bingo工具 ```bash bingo upgrade ``` ### 1.2.2 编译构建 在component_drivers根目录下执行,bingo会自动处理依赖拉取与编译 ```bash bingo build ``` ### 1.3 运行测试 ```bash bingo test ``` 打开另一个终端,登录到容器,设置环境变量 ```bash export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus_test_Y2SmMZ/dbus.socket ``` 查看资源协作路径 ```bash busctl --usr tree bmc.kepler.devmon busctl --user introspect bmc.kepler.devmon /bmc/dev/Systems/1/PCIeNicCard/hisi_1822 ``` # 2 场景一:新增一款同代次的网卡驱动 首先,您需要安装Visual Studio Code ## 2.1 编辑器准备 ### 2.1.1 方式一:下载安装Remote-SSH插件(连接远程容器) ### 2.1.2 Remote-SSH登录容器 ```bash ssh root@192.168.0.144 -p 40906 ``` (1)输入容器的root密码 (2)打开component_drivers工程目录 ### 2.1.3 方式二:使用WSL(连接本机容器) 适用于容器运行在WSL环境的情况,无需SSH: (1)在Windows的WSL终端中启动docker容器并进入 ```bash docker start openubmc_hls docker exec -it openubmc_hls /bin/bash ``` (2)编写并执行代码,直接访问`/root/workspace`下的工程目录 (3)在VSCode中全部重新加载,使用容器内已安装的工具进行开发调试 ## 2.2 新增csr 同代次协议不需要变更,驱动复用现有的so,不需要修改,仅需要增加csr即可 ### 2.2.1 拷贝一份同代次的网卡csr到csr目录 ## 2.3 运行测试 (1)拉起devmon服务 ```bash meson test -C builddir -v --timeout=0 ``` (2)加载csr配置:添加新的csr到devmon服务中 ```bash busctl --user call bmc.kepler.devmon /bmc/dev bmc.dev AddDevice sa{sv} “~/workspace/devmon/tests/tests_data/csr/14140130_19e50222_19e500a2.sr” 3 Position i 2 SystemId i 1 Slot i 2 ``` (3)查看资源协作路径: 打开另一个终端,登录到容器,设置环境变量 ```bash export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus_test_Y2SmMZ/dbus.socket ``` 查看资源协作信息 ```bash busctl --usr tree bmc.kepler.devmon busctl --user introspect bmc.kepler.devmon /bmc/dev/Systems/1/PCIeNicCard/SP670 ``` # 3 场景二:新增一款跨代次的网卡驱动 跨代次协议可能需要变更,需要新增驱动so和csr ## 3.1 新增驱动 ### 3.1.1 拷贝一份上代次的驱动 ### 3.1.2 修改编译脚本 (1)在drivers/pcie_nic_card/hisi/meson.build的subdir()中增加hi185x (2)修改drivers/pcie_nic_card/hisi/hi185x/meson.build与实际源文件一致 ### 3.1.3按需修改差异点 例如,需要单独修改bmc.dev.PCIeCard的Name字段,可以在start函数增加差异处理 ## 3.2 新增csr ### 3.2.1 拷贝一份上代次的网卡csr到csr目录 Compatible需要修改为与drivers/pcie_nic_card/hisi/hi185x/meson.build中的配置一致 ### 3.2.2按需修改差异点 例如,修改bmc.dev.PCIeDevice的DeviceName字段为“SP699” ## 3.3 运行测试 打开另一个终端,登录到容器,设置环境变量 ```bash export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus_test_Y2SmMZ/dbus.socket ``` 查看资源协作路径 ```bash busctl --usr tree bmc.kepler.devmon busctl --user introspect bmc.kepler.devmon /bmc/dev/Systems/1/PCIeNicCard/SP699 ``` --- # 部件驱动项目概览 > URL: https://openubmc.cn/docs/zh/latest/component_driver/concept_principle/component_driver_adapt.html > Language: zh # 部件驱动项目概览 ## 项目简介 Component Drivers 是一个基于 C++17 的硬件组件驱动程序项目,使用 Meson 构建系统管理。项目提供了多种硬件设备的驱动支持和通信协议库,主要面向服务器板卡组件管理场景。该项目与devmon(Device Monitor)设备监控框架深度集成,共同构成openUBMC的硬件管理解决方案。 ## 与Devmon框架的关系 ### 整体架构视图 Component Drivers项目作为devmon框架的驱动实现层,通过标准化的ABI接口和插件机制实现无缝集成: ```mermaid flowchart TB subgraph "应用层" BMC["BMC管理应用"] Monitor["监控服务"] RestAPI["RESTful API"] end subgraph "Devmon框架层" DevmonService["devmon_service
设备管理服务"] CSRParser["CSR解析器
配置驱动"] TopoMgr["拓扑管理器
设备树管理"] DriverLoader["驱动加载器
dlopen动态加载"] DeviceFactory["设备工厂
对象创建"] end subgraph "Component Drivers层" direction LR DriverABI["驱动ABI接口
标准C接口"] DeviceObject["设备对象
MC_OBJECT定义"] DeviceInterface["设备接口
gen/dev命名空间"] Protocol["协议库
NCSI/MCTP/IMU"] HAS["硬件访问服务
总线芯片抽象"] end subgraph "硬件层" Hardware["物理硬件设备"] end BMC --> DevmonService Monitor --> DevmonService RestAPI --> DevmonService DevmonService --> CSRParser DevmonService --> TopoMgr CSRParser --> DriverLoader DriverLoader --> DeviceFactory DeviceFactory --> DriverABI DriverABI --> DeviceObject DeviceObject --> DeviceInterface DeviceInterface --> Protocol Protocol --> HAS HAS --> Hardware TopoMgr -.维护设备树.-> DeviceObject ``` ### 核心集成机制 #### 1. CSR配置驱动机制 **CSR (Component Self-Description)** 是设备配置的核心: ```shell CSR配置文件 ├── DDS (Device Description Schema) - 设备描述文件 │ ├── 设备类型定义 (DeviceType) │ ├── 接口集合声明 (Interfaces) │ └── 属性默认值 (Properties) └── SR (Self-Descripition Record) - 自描述记录文件 ├── 拓扑路径 (ManagementTopology) ├── 驱动匹配 (Compatible) └── 连接器信息 (Connector) ``` **工作流程**: 1. devmon读取CSR配置文件 2. 解析设备描述和拓扑关系 3. 根据Compatible字段匹配驱动SO 4. 动态加载对应的驱动库 #### 2. 驱动ABI标准接口 驱动通过标准的C风格ABI接口与devmon交互: ```cpp // 定义在 include/devmon/driver_abi.h // 状态码 typedef enum status { STATUS_OK = 0, STATUS_ERROR = 1, STATUS_NOT_FOUND = 2, STATUS_INVALID_ARG = 3, STATUS_NOT_IMPLEMENTED = 4, STATUS_TIMEOUT = 5, STATUS_BUSY = 6, STATUS_NO_MEMORY = 7, } status_t; typedef void* driver_handle_t; // 每个设备对象一个驱动实例 typedef void* device_config_t; // CSR 共享内存数据对象 // 驱动生命周期函数类型 typedef driver_handle_t (*driver_ctor)(void* service, const char* object_name); typedef status_t (*driver_init)(driver_handle_t, void* csr_object, void* connector); typedef status_t (*driver_start)(driver_handle_t); typedef status_t (*driver_stop)(driver_handle_t); typedef const char* (*driver_dump)(driver_handle_t device); typedef struct device_driver { const char* device_name; // 设备名称 const driver_ctor ctor; // 创建函数 const driver_init init; // 初始化函数 const driver_start start; // 启动函数 const driver_stop stop; // 停止函数 driver_dump dump = nullptr; } device_driver_t; // 驱动SO导出符号 extern "C" { status_t register_device_driver(device_driver_t** device_driver, uint8_t* count); } ``` **设计优势**: - **跨编译器兼容**: C接口避免C++名称修饰问题 - **动态加载友好**: 通过dlopen/dlsym机制加载 - **版本隔离**: 不同版本驱动可独立演进 - **调试便利**: 清晰的生命周期管理 #### 3. MC_REFLECT反射机制 MC_REFLECT是一个编译期反射系统,实现属性的自动序列化和动态访问: **工作原理**: ```cpp // 1. 定义接口类 class PCIeDevice { public: std::string DeviceName; std::string VendorId; std::string DeviceId; uint8_t Bus; uint8_t Device; uint8_t Function; }; // 2. 注册反射信息 MC_REFLECT(PCIeDevice, (), ((DeviceName, "DeviceName")) ((VendorId, "VendorId")) ((DeviceId, "DeviceId")) ((Bus, "Bus")) ((Device, "Device")) ((Function, "Function")) ) // 3. 运行时动态访问 mc::dict properties; mc::reflect::to_variant(pcie_device, properties); // 对象 -> JSON mc::reflect::from_variant(properties, pcie_device); // JSON -> 对象 ``` **核心特性**: - **编译期元数据生成**: 零运行时开销 - **类型安全**: 编译期类型检查 - **双向映射**: C++对象 ↔ JSON/配置文件 - **属性查询**: 运行时枚举对象属性 - **序列化支持**: 自动生成序列化代码 #### 4. 插件化架构 Component Drivers采用分层插件架构: ```shell drivers/ ├── pcie_nic_card/ # PCIe网卡驱动 │ ├── hisi/ # 海思厂商实现 │ │ ├── hi182x/ # Hi182x系列驱动 │ │ │ ├── hi182x_card.h/cpp # 设备对象 │ │ │ ├── hi182x_port.h/cpp # 端口对象 │ │ │ ├── hi182x_om.h/cpp # 光模块对象 │ │ │ ├── hi182x_abi.cpp # ABI导出 │ │ │ └── meson.build # 构建配置 │ │ ├── hi182x_high/ # Hi182x-High系列驱动(同结构) │ │ ├── hi1822_fc/ # Hi1822 FC系列驱动(同结构) │ │ ├── hi1825_board/ # 1825大板驱动(同结构) │ │ ├── interface/ # 接口实现 │ │ │ ├── board.h/cpp # Board接口 │ │ │ ├── cooling.h/cpp # Cooling接口 │ │ │ ├── fru.h/cpp # Fru接口 │ │ │ ├── network_adapter.h/cpp # 网络适配器接口 │ │ │ ├── network_port.h/cpp # 网络端口接口 │ │ │ ├── optical_module.h/cpp # 光模块接口 │ │ │ ├── pcie_card.h/cpp # PCIe卡接口 │ │ │ ├── pcie_device.h/cpp # PCIe设备接口 │ │ │ └── upgrade.h/cpp # 固件升级接口 │ │ └── meson.build │ ├── wangxun/ # 网迅厂商实现(含 rp1000、ff50xx、sfx00ht 等型号,以及 interface/ 与 interface_pldm/) │ ├── mellanox/ # 迈络思厂商实现 │ ├── boardcom/ # 博通厂商实现 │ ├── grt/ # grt厂商实现 │ └── mucse/ # mucse厂商实现 └── pcie_gpu_card/ # PCIe GPU驱动 ├── innosilicon/ # 芯动科技(awm_m11p) ├── jingjia/ # 景嘉微(jm1100) ├── moorethreads/ # 摩尔线程(mtt_s4000) ├── nvidia/ # NVIDIA(nv_common) └── vastai/ # 瀚博(vg1000) ``` **层次关系**: | 层次 | 目录位置 | 职责 | 代码来源 | |------|---------|------|---------| | 接口定义层 | mds/ | JSON 模型契约定义 | 手工编写 | | 生成接口层 | gen/device_tree/interface/ | C++接口基类(dev::gen 命名空间) | 代码生成 | | 实现接口层 | drivers/.../interface/ | 厂商接口实现(dev 命名空间) | 手工编写 | | 设备对象层 | drivers/.../{model}/ | 设备对象类 | 手工编写 | | ABI导出层 | drivers/.../{model}/{model}_abi.cpp | 驱动导出 | 手工编写 | ## 板卡驱动与管理协议关系 ### 🔗 驱动-协议绑定架构 板卡驱动与管理协议采用**分层协作**模式,实现硬件抽象与远程管理的完美结合: ```shell 📱 应用管理层: BMC管理应用、监控服务 ↓ 标准化API调用 🎯 驱动接口层: PCIe板卡驱动、GPU驱动、传感器驱动 ↓ 协议绑定 📡 协议通信层: NCSI over MCTP、MCTP、IMU协议栈 ↓ 传输封装 🚌 物理传输层: PCIe传输、I2C传输、Socket通信 ↓ 硬件访问 🔧 板卡硬件层: 网卡、GPU、传感器等物理设备 ``` ### 💡 协议与驱动映射关系 | 板卡类型 | 对应驱动 | 管理协议 | 厂商支持 | |----------|----------|----------|----------| | PCIe网卡 | `hi182x_card`, `rp1000_card`, `ff50xx_card` | NCSI over MCTP | hisi, wangxun, mellanox, boardcom, grt, mucse | | PCIe GPU | `awm_m11p_card`, `jm1100_card` | MCTP | 芯动、景嘉微、摩尔线程、NVIDIA | | I2C传感器 | 各 chip 驱动(lm75/ina 等) | SMBus/PMBus | 通用 | | PCIe设备 | `accessor` 访问器 | 标准PCIe | 通用 | ### 🔄 协议栈工作流程 1. **驱动初始化**: 板卡驱动检测硬件BDF信息 2. **协议绑定**: 根据硬件类型绑定对应管理协议 3. **通道建立**: 创建MCTP传输通道和端点 4. **定时任务**: 启动周期性状态监控和数据采集 5. **事件响应**: 处理硬件事件和协议消息 ### 设备对象模型 设备对象是Component Drivers的核心抽象,通过MC_OBJECT宏定义其特征: **基本定义**: ```cpp class hi182x_card : public mc::engine::object { public: // MC_OBJECT(对象类型宏名, 设备类型, 路径模式, 接口集合) MC_OBJECT( hi182x_card, "PCIeNicCard", "/bmc/dev/Systems/1/PCIeNicCard/${object_name}", (PCIeDevice)(PCIeDevice_PCIeFunction)(PCIeDevice_Oem)(PCIeDevice_Status)(PCIeCard)(PCIeCard_Oem)( PCIeCard_Metrics)(NetworkAdapter)(NetworkAdapter_FaultStatus)(Cooling)(NetworkAdapter_Oem)(Board)( PCIeDevice_Bandwidth)(NetworkAdapter_LogCollection)(Fru) ) // 协议对象成员 ncsi_over_mctp_hw_ptr m_ncsi_over_mctp_huawei; imu_ptr m_imu_obj; smbus_obj_ptr m_smbus_obj; mc::shared_ptr m_mctp_object; }; ``` **关键特性**: | 特性 | 说明 | 示例 | |------|------|------| | **路径模式** | 支持参数替换的层次化路径 | `/Systems/1/PCIeNicCard/hi182x` | | **接口组合** | 通过组合多个接口实现功能 | PCIeDevice + NetworkAdapter | | **属性反射** | MC_REFLECT实现动态属性访问 | 运行时枚举和修改属性 | | **对象树** | 形成父子关系的设备层次 | Card -> Port -> OpticalModule | | **D-Bus暴露** | 自动注册到D-Bus总线 | busctl查询设备对象 | **对象层次示例**: ```shell /bmc/dev/ └── Systems/ └── 1/ └── PCIeNicCard/ └── hi182x/ # 网卡对象 ├── NetworkPort/ │ ├── 0/ # 端口0对象 │ │ └── OpticalModule/ # 光模块对象 │ └── 1/ # 端口1对象 │ └── OpticalModule/ └── properties # 设备属性 ``` ### 硬件访问服务(HAS) HAS提供了对底层硬件总线和芯片的统一访问抽象: **架构层次**: ```shell 应用层 (设备驱动) ↓ 芯片驱动层 (Chip抽象) ├── drivers/chip/ # 通用芯片驱动(lm75/ina/pca9545/pca9555 等) └── drivers/internal/chip/ # 内部芯片基类封装 ↓ 总线驱动层 (Bus抽象) ├── drivers/bus/ # I2C、I2C-Mux、Hisport 总线驱动 ├── drivers/bus/i2c/ # I2C总线 └── drivers/internal/bus/ # 内部总线基类封装 ↓ 协议/物理层 ├── libraries/smbus/ # SMBus协议实现 ├── libraries/canbus/ # CAN总线协议 └── 物理硬件 ``` **核心组件**: | 组件 | 路径 | 功能 | |------|------|------| | I2C总线 | drivers/bus/i2c/ | I2C通信实现 | | I2C-Mux总线 | drivers/bus/i2c_mux/ | I2C多路复用 | | 芯片驱动 | drivers/chip/ | lm75/ina/pca9545 等芯片 | | SMBus协议 | libraries/smbus/ | SMBus协议实现(smbus/std_smbus) | | CAN总线协议 | libraries/canbus/ | CAN总线通信 | | 总线/芯片基类 | drivers/internal/ | 内部基类封装 | **使用示例**(以 SMBus 总线为例,协议库位于 libraries/smbus/,类在 dev 命名空间): ```cpp // SMBus对象需要父对象和显式构造函数 mc::shared_ptr smbus_obj = mc::make_shared(parent); // 通过总线对象发起读写事务(使用请求构造/响应解包) mc::mutable_dict req = {{"bus_id", 0x01}, {"slave_addr", 0x50}, {"cmd", "read"}}; auto [ok, rsp] = smbus_obj->send_and_receive(smbus_obj->construct_request_data(req), smbus_obj->get_max_frame_len()); ``` ### 协议库系统 Component Drivers集成了多种通信协议: **协议架构**: ```mermaid flowchart LR subgraph "应用层" Driver["设备驱动"] end subgraph "协议库层" NCSI["NCSI协议
网络控制器侧带接口"] MCTP["MCTP协议
管理组件传输"] NOM["NCSI over MCTP
混合协议"] IMU["IMU协议
惯性测量单元"] end subgraph "传输层" PCIeTransport["PCIe传输"] I2CTransport["I2C传输"] SocketTransport["Socket传输"] end Driver --> NCSI Driver --> MCTP Driver --> NOM Driver --> IMU NCSI --> SocketTransport MCTP --> PCIeTransport MCTP --> I2CTransport NOM --> MCTP IMU --> I2CTransport ``` **协议详情**: | 协议 | 标准 | 主要用途 | 支持厂商 | |------|------|---------|---------| | **NCSI** | DMTF标准 | 网卡带外管理 | Intel, 华为, 网迅 | | **MCTP** | DMTF标准 | 组件间通信传输层 | 通用 | | **NCSI over MCTP** | 华为扩展 | 扩展NCSI功能 | 华为海思 | | **IMU** | 自定义 | IPMI获取设备信息 | 通用 | **NCSI协议特性**: - 标准命令支持:链路状态、MAC地址、VLAN配置 - OEM命令扩展:厂商特定功能 - 华为扩展命令:固件版本、日志收集、温度监控 **MCTP协议特性**: - 多种消息类型:控制消息、PLDM、NCSI、NVME等 - 多种物理媒介:PCIe、SMBus、I2C - 端点管理:路由、绑定、传输 **使用示例**: ```cpp // NCSI over MCTP使用(dev 命名空间) // 1. 根据BDF计算物理地址,创建MCTP对象(需要显式构造参数) mc::shared_ptr mctp_obj = mc::make_shared(this, mctp::init_phy_addr(pcie_function.BusNumber, pcie_function.DeviceNumber, pcie_function.FunctionNumber), MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, ""); // 2. 创建并启动传输通道与端点 mctp_obj->create_transport_and_endpoint("mctp", nullptr); // 3. 创建NCSI over MCTP华为扩展对象 dev::ncsi_over_mctp_huawei nom_hw(mctp_obj); // 4. 调用OEM扩展接口 uint8_t mac[6] = {0}; nom_hw.get_mac_addr(package_id, channel_id, mac, sizeof(mac)); uint16_t chip_temp = 0; nom_hw.get_chip_temp(package_id, channel_id, &chip_temp); ``` ## 板卡驱动核心价值 ### 🎯 1. 硬件抽象统一化 - **价值**: 为不同厂商硬件提供统一编程接口 - **实现**: 继承`PCIeCard`、`NetworkAdapter`等标准基类 - **收益**: 应用层代码与硬件解耦,提高代码复用性 ### 🌐 2. 远程管理能力 - **价值**: 实现**带外管理**(Out-of-Band Management) - **实现**: 集成NCSI/MCTP协议栈,支持远程监控配置 - **收益**: 无人值守数据中心管理,降低运维成本 ### 📊 3. 实时状态监控 - **价值**: 提供硬件实时健康状态信息 - **功能**: 温度监控、链路状态、带宽使用、故障检测 - **收益**: 预防性维护,提高系统可靠性99.9%+ ### 🔧 4. 多厂商兼容性 - **价值**: 避免硬件厂商锁定 - **支持**: 华为海思(hisi)、网迅(wangxun)、迈络思(mellanox)、芯动(innosilicon)、景嘉微(jingjia)、摩尔线程(moorethreads)、NVIDIA等主流厂商 - **收益**: 提高采购灵活性,降低硬件成本 ### 🚨 5. 故障隔离与诊断 - **价值**: 快速故障定位和根因分析 - **实现**: 详细错误码、故障状态码、诊断信息 - **收益**: 故障响应时间缩短80%,减少停机损失 ### ⚡ 6. 性能优化支持 - **价值**: 硬件性能调优和资源管理 - **功能**: 带宽管理、功耗控制、负载均衡 - **收益**: 系统性能提升15-30% ## 目录结构与关键功能 ### 🔧 硬件驱动层 - component_drivers/drivers/ **核心作用**: 提供各类硬件设备的底层驱动程序实现 ```shell component_drivers/drivers/ ├── scanner/ # 设备扫描驱动 │ └── scanner/ # 扫描器核心实现 ├── pcie_nic_card/ # PCIe网络接口卡驱动 │ ├── wx/ # 网迅(WX)网卡驱动实现 │ └── hisi/ # 海思(HiSi)网卡驱动实现 ├── pcie_gpu_card/ # PCIe图形处理卡驱动 │ └── innosilicon/ # 芯动科技GPU驱动实现 ├── bus/ # 系统总线驱动 │ └── i2c/ # I2C总线通信驱动 └── accessor/ # 硬件访问器驱动 └── accessor/ # 统一硬件访问接口 ``` **技术特点**: - 支持多厂商硬件设备 - 统一的驱动接口设计 - PCIe设备专门优化 - 模块化驱动架构 **依赖关系**: 依赖 component_drivers/libraries/ 中的协议库,被 component_drivers/tests/ 测试调用 --- ### 📚 协议通信层 - component_drivers/libraries/ **核心作用**: 实现标准化的硬件通信协议和功能库 ```shell component_drivers/libraries/ ├── ncsi/ # 网络控制器侧带接口协议库 │ ├── ncsi_protocol.h # NCSI协议核心定义 │ ├── ncsi_socket.h # NCSI Socket通信 │ ├── ncsi_huawei.h # 华为NCSI实现 │ ├── ncsi_wangxun.h # 网迅NCSI实现 │ ├── ncsi_mellanox.h # 迈络思NCSI实现 │ ├── ncsi_mucse.h # mucse NCSI实现 │ ├── ncsi_grt.h # grt NCSI实现 │ └── adapter.h # 协议适配器 ├── ncsi_over_mctp/ # NCSI over MCTP混合协议 │ ├── ncsi_over_mctp.h # 基础定义 │ ├── ncsi_over_mctp_standard.h/cpp # 标准实现 │ ├── ncsi_over_mctp_huawei.h/cpp # 华为扩展 │ ├── ncsi_over_mctp_wangxun.h/cpp # 网迅扩展 │ ├── ncsi_over_mctp_mellanox.h/cpp # 迈络思扩展 │ └── ncsi_over_mctp_mucse.h/cpp # mucse扩展 ├── mctp/ # 管理组件传输协议库 │ ├── mctp.cpp/.h # MCTP核心功能实现 │ └── pcie_transport.cpp/.h # PCIe传输层实现 ├── imu/ # IMU通信库 │ ├── imu.cpp/.h # IMU设备通信接口 │ └── 传感器数据处理 ├── smbus/ # SMBus总线协议(smbus/std_smbus/xx) ├── pldm/ # PLDM协议(base/fru/monitor/update + 厂商扩展) ├── nvme/ # NVMe协议(nvme_mi_over_mctp 等) ├── pmbus/ # PMBus电源管理协议(含厂商变种) ├── lldp/ # LLDP链路发现协议 ├── canbus/ # CAN总线协议 ├── ipmb/ # IPMB协议 └── protocol/ # 通用协议抽象 ``` **技术特点**: - 实现业界标准协议(NCSI/MCTP) - 支持多厂商协议变种 - 模块化协议栈设计 - 高性能通信优化 **依赖关系**: 被 drivers/ 调用,依赖 include/ 头文件 --- ### 🎯 接口定义层 - component_drivers/include/ **核心作用**: 提供统一的头文件接口和API定义 ```shell component_drivers/include/ └── devmon/ # 设备监控接口定义 ├── 设备状态监控API ├── 硬件事件回调接口 ├── 错误处理机制定义 └── 设备管理接口 ``` **技术特点**: - 统一的API接口规范 - 设备无关的抽象层 - 标准化的错误处理 - 模块间通信接口 **依赖关系**: 被所有模块引用,定义系统接口规范 --- ### 🧪 测试验证层 - component_drivers/tests/ **核心作用**: 提供完整的测试框架和验证用例 ```shell component_drivers/tests/ ├── main.cpp # 测试主程序入口 (27行) ├── drivers/ # 驱动程序测试用例 │ ├── 单元测试 │ ├── 集成测试 │ └── 性能测试 └── meson.build # 测试构建配置 ``` **技术特点**: - 完整的测试覆盖 - 自动化测试流程 - 性能基准测试 - 持续集成支持 **依赖关系**: 测试 drivers/ 和 libraries/ 模块 --- ### ⚙️ 代码生成层 - component_drivers/gen/ **核心作用**: 自动化代码生成和配置管理 ```shell component_drivers/gen/ └── device_tree/ # 设备树相关代码生成 ├── 硬件配置自动生成 ├── 设备驱动模板生成 └── 配置文件转换 ``` **技术特点**: - 自动化配置生成 - 设备树支持 - 模板化代码生成 - 配置一致性保证 **依赖关系**: 为 drivers/ 生成配置,依赖 mds/ 定义 --- ### 📋 模型服务层 - component_drivers/mds/ **核心作用**: 定义数据模型和服务接口规范 ```shell component_drivers/mds/ ├── model.json # 数据模型定义 (3行精简) └── service.json # 服务接口定义 (31行) ``` **技术特点**: - JSON格式的模型定义 - 标准化服务接口 - 版本化管理 - 接口文档自动生成 **依赖关系**: 为 gen/ 提供生成源,被 libraries/ 引用 --- ### 🏗️ 构建输出层 - component_drivers/builddir/ **核心作用**: Meson构建系统的输出和中间文件 ```shell component_drivers/builddir/ ├── build.ninja # Ninja构建脚本 (942行) ├── compile_commands.json # 编译命令数据库 (867行) ├── .ninja_log # 构建日志 (184条记录) ├── meson-info/ # Meson构建信息 ├── meson-logs/ # 详细构建日志 ├── drivers/ # 编译后的驱动模块 ├── libraries/ # 编译后的库文件 └── tests/ # 编译后的测试程序 ``` **技术特点**: - 增量编译支持 - 并行构建优化 - 依赖关系管理 - 交叉编译支持 --- ### 📦 依赖管理层 - component_drivers/subprojects/ **核心作用**: 管理外部依赖和子项目 ```shell component_drivers/subprojects/ ├── libmcpp/ # C++核心库依赖 └── libmcpp.wrap # 依赖包装配置 (8行) ``` **技术特点**: - Meson Wrap系统 - 版本化依赖管理 - 自动依赖解析 - 源码级依赖支持 --- ### 📖 文档说明层 - component_drivers/docs/ **核心作用**: 项目技术文档和开发指南 ```shell component_drivers/docs/ ├── 1-项目概览.md # 项目概览文档 (本文档) ├── 架构设计文档 ├── API参考文档 └── 开发者指南 ``` ## 架构层次关系 ### 🏗️ 整体分层架构 ```shell 📱 应用管理层 [BMC应用] [监控服务] [管理工具] [测试程序] ↓ RESTful API / D-Bus调用 🎯 服务接口层 [设备监控服务] [模型服务] [配置服务] [事件服务] ↓ 对象模型调用 🔌 硬件驱动层 [网卡驱动] [GPU驱动] [总线驱动] [扫描器驱动] ↓ 协议绑定 📡 协议通信层 [NCSI] [MCTP] [IMU] [NCSI over MCTP] ↓ 传输封装 🚌 传输抽象层 [PCIe传输] [I2C传输] [Socket传输] [串口传输] ↓ 硬件访问 🔧 硬件设备层 [PCIe设备] [I2C设备] [传感器] [其他硬件] ``` ### 🔄 驱动-协议交互流程 ```mermaid sequenceDiagram participant App as 管理应用 participant Driver as 板卡驱动 participant Protocol as 管理协议 participant Hardware as 物理硬件 App->>Driver: 启动板卡驱动 Driver->>Protocol: 绑定管理协议 Protocol->>Hardware: 建立通信通道 Hardware-->>Protocol: 硬件信息响应 Protocol-->>Driver: 状态数据更新 Driver-->>App: 设备状态上报 loop 定时监控 Driver->>Protocol: 轮询硬件状态 Protocol->>Hardware: 发送查询命令 Hardware-->>Protocol: 返回状态数据 Protocol-->>Driver: 解析协议数据 Driver-->>App: 推送状态变化 end ``` ## 构建配置 ### 主要构建选项(meson_options.txt) - `meson_build`: 是否在Meson环境中构建(默认:true) - `tests`: 是否构建测试用例(默认:true) - `install_inc_dir`: 头文件安装目录(默认:include) - `enable_conan_compile`: 是否开启共享内存编译(默认:false) - `enable_coverage`: 是否启用代码覆盖率统计(默认:false) - `fast_debug_info`: 压缩调试信息以降低 g++ 内存占用(默认:true) - `use_mold`: 使用 mold 链接器(默认:true) - `use_icf`: 链接期相同代码折叠(默认:true) - `use_pch`: 为高频模板头启用全局预编译头(默认:false) - `inlines_hidden`: 隐藏内联成员/模板实例导出符号,缩减 .dynsym/.dynstr(默认:true) - `unidev`: 启用 unidev 时编译 csr1/connector 相关驱动(默认:false) - `chipv2_enable`: 启用 chipv2 时编译 hisport2 相关驱动(默认:false) ### 项目配置特性 - **编程语言**: C++17 - **构建系统**: Meson + Ninja - **编译器标准**: GCC/Clang,支持交叉编译 - **依赖管理**: Conan + Meson混合模式 - **支持架构**: x86_64, armv8 ### 编译特性 - 支持PIC(位置无关代码) - 警告级别:level 3 - 特殊编译选项: - `-fpermissive` - 允许一些非标准扩展 - `-Wno-deprecated-copy` - 忽略弃用的拷贝警告 - `-fno-strict-aliasing` - 禁用严格别名优化 ## 快速开始 ```bash # 配置构建环境 meson setup builddir # 编译项目 meson compile -C builddir # 运行测试 meson test -C builddir # 清理重新构建 rm -rf builddir; meson setup builddir; meson compile -C builddir ``` ## 项目特点 ### 🚀 技术特性 1. **模块化设计**: 驱动程序和库文件分离,便于维护和复用 2. **多厂商支持**: 支持华为海思、网迅、迈络思、芯动、景嘉微、摩尔线程等多家硬件厂商 3. **标准协议**: 实现NCSI、MCTP等标准化硬件管理协议 4. **灵活构建**: 支持本地和交叉编译,适配不同平台需求 5. **完整测试**: 提供完整的测试框架和用例 ### 🎯 核心优势 - **统一抽象**: 不同厂商硬件通过统一接口访问 - **远程管理**: 支持带外管理,实现无人值守运维 - **实时监控**: 提供硬件健康状态实时监控 - **故障诊断**: 详细的错误码和诊断信息支持 - **性能优化**: 硬件资源管理和性能调优能力 ## 主要应用场景 ### 🏢 数据中心管理 - **服务器硬件管理**: PCIe板卡的生命周期管理 - **网络设备监控**: 网卡状态、链路质量、带宽使用 - **故障预警**: 温度异常、链路中断、性能下降告警 - **远程运维**: 带外管理通道的远程诊断和配置 ### 🔧 嵌入式系统 - **嵌入式设备驱动**: ARM、x86平台的板卡驱动开发 - **传感器数据采集**: IMU、温度、电压等传感器管理 - **工业控制**: 工控板卡的实时监控和控制 ### 🌐 网络通信 - **PCIe设备通信**: 高速PCIe通道的数据传输 - **网络设备侧带管理**: NCSI协议的网卡管理 - **协议栈集成**: MCTP、NCSI等标准协议的实现 ### 📊 系统监控 - **硬件健康监控**: 实时温度、电压、功耗监控 - **性能分析**: 带宽使用、延迟统计、吞吐量分析 - **日志收集**: 硬件事件和错误日志的集中管理 --- **Component Drivers** - 为openUBMC提供强大的硬件管理能力 🚀 --- # 部件驱动自发现机制设计 > URL: https://openubmc.cn/docs/zh/latest/component_driver/concept_principle/component_driver_discovery.html > Language: zh 部件驱动自发现是南向硬件管理中,根据槽位在位状态自动识别部件、选择 CSR 并加载对应驱动 SO 的机制。本文面向驱动适配者和南向框架维护者,说明发现触发、SR 选择、热插拔卸载与排障方法。 # 认识部件驱动自发现 运行时入口在 Connector,驱动匹配与 `dlopen` 在 devmon。代码以 component_drivers 仓的 Connector、Scanner、EEPROM 以及 `include/devmon/driver_abi.h` 为准。运行时不按 PCIe VID 或 DID 搜索 DDS 文件来加载驱动。 适配步骤见后续各部件驱动适配指南;总线与芯片接线见《[总线芯片驱动开发指南](../general_guide/bus_chip_driver_guide.md)》。 > [!NOTE]说明 > > 本文只写发现触发、SR 选择与加载路径。DDS 代码生成与出包步骤见各品类适配指南。 ## 目录 1. [范围与术语](#范围与术语) 2. [端到端时序](#端到端时序) 3. [触发条件](#触发条件) 4. [SR 选择](#sr-选择) 5. [EEPROM 与 LoadStatus](#eeprom-与-loadstatus) 6. [框架侧加载](#框架侧加载) 7. [适配检查清单](#适配检查清单) 8. [故障排查](#故障排查) 9. [附录(对照源码)](#附录对照源码) --- ## 范围与术语 底板或上级板的 CSR 先实例化槽位 Connector。Connector 在部件在位后交出一份 SR JSON,devmon 再按 SR 里的 `Unit.Compatible` 加载对应 SO,并执行 `ctor`、`init`、`start`。 ### 仓边界 ```mermaid flowchart LR subgraph 驱动仓["component_drivers"] Conn["libConnector.so
在位开关 / 选 SR"] Scan["libScanner.so
周期读在位脚"] Acc["libAccessor.so
按需读寄存器"] Eep["libEeprom.so
GetSRData"] Card["业务驱动 SO"] end subgraph 框架["devmon"] Disc["full_discovery
platform.sr / root.sr"] Add["AddDeviceWithData
RemoveDevice"] Match["Compatible 到 dlopen"] Topo["ManagementTopology
内部 Bus 与 Chip"] end Disc --> Conn Scan -->|"Presence 引用"| Conn Eep -->|"BoardId 与 SR JSON"| Conn Acc -->|"可选:Id 或 Presence"| Conn Conn -->|"SR 与 Connector 字典"| Add Add --> Match Match --> Card Add --> Topo ``` | 层 | 组件 | 职责 | | ---- | ---- | ---- | | 发现入口 | component_drivers 的 `libConnector.so` | 监听在位、选择 SR、调用 Devmon。 | | 在位采集 | Scanner、Accessor | 把硬件在位或 BoardId 同步到属性。 | | 身份与 SR 原文 | EEPROM | 提供 `GetSRData`、头解析与验签。 | | 解析与加载 | devmon | 选择 CSR、执行 `dlopen`、建对象树、卸载对象。 | | 业务驱动 | 各品类 SO | 被加载后实现网卡、GPU、电源等接口。 | ### 术语 | 术语 | 含义 | | ---- | ---- | | CSR | 部件自描述的总称。运行时加载的是 SR JSON(来自文件或 EEPROM)。 | | SR | Service Record。扩展名为 `.sr`,或位于 EEPROM 内的 JSON,含 `Unit`、`Objects`,常含 `ManagementTopology`。 | | DDS | Device Description Schema(`.dds`)。定义对象路径与接口,用于代码生成,不作为运行时驱动匹配键。 | | Connector | 槽位对象。`Presence` 为 1 时加载下级 SR,为 0 时卸载。 | | Presence | Connector 在位。取值为常量 1,或 `#/Scanner_xxx.Value` 等引用。 | | IdentifyMode | 下级身份识别方式。代码里只有 3 走 EEPROM;1 与 2 走本地 `.sr`。 | | Compatible | SR 的 `Unit.Compatible[]`。按序尝试 `lib${name}.so`,逗号会先换成下划线。 | | CSR1 与 CSR2 | SR 顶层 `FormatVersion` 小于 5.0 走 CSR1 的 `device_loader`;大于或等于 5.0 走 CSR2 的 `device_manager`。 | | LoadStatus | Connector 加载结果。0 表示成功,255 表示默认或已卸载,其余为错误码。 | DDS 文件名规则(如 `14140130_[VID][DID]_[SVID][SSID].dds`)见各品类适配指南与《[部件驱动接口模型设计](../general_guide/interface_model_spec.md)》,本文不把它当成发现算法。 --- ## 端到端时序 ### 启动到首次加载 ```mermaid sequenceDiagram participant HW as hwdiscovery participant Root as root.sr participant Eep as Eeprom participant Scan as Scanner participant Conn as Connector participant Dev as Devmon HW->>Root: full_discovery:先 platform.sr(00)再 root.sr(01) Root->>Eep: ctor / init / start Note over Eep: CSR2 的 start 会解析 EEPROM 头并预热 SR 缓存
CSR1 的 start 不访问硬件 Root->>Scan: ctor / init / start Root->>Conn: ctor / init(订阅 Presence.changed) Conn->>Conn: start:预热 SR 缓存 alt Presence 已是 1(常量或已被同步) Conn->>Dev: 异步 try_load_device,再 AddDeviceWithData else Presence 仍为 0(常见:CSR1 Scanner 尚未扫到) Conn-->>Conn: 等待 Presence.changed end Scan->>Conn: Value 变为 1 后同步到 Presence Conn->>Conn: resolve_sr_data Conn->>Dev: AddDeviceWithData(sr,connector 字典) Dev->>Dev: Compatible 到 dlopen,再 ctor、init、start ``` `discovery_service` 在 hwproxy 就绪后调用 `discovery::full_discovery`:先加载 `platform.sr`(position 为 `"00"`),再加载 `root.sr`(`"01"`,带 `SystemId=1`)。CSR 文件在镜像、`/data/opt/bmc/sr/gold`、`/data/opt/bmc/sr/temp` 之间按 `DataVersion` 择优。 root SR 描述底板拓扑,包括 I2C、MUX、EEPROM、Scanner、Accessor 与槽位 Connector。每个对象同样经 `Compatible` 加载对应 SO。Connector 的 `start()` 只做两件事:预热 SR 缓存、检查初始 Presence。 ### 热插拔 ```mermaid stateDiagram-v2 [*] --> 未在位: Presence 为 0 未在位 --> 加载中: Presence 变为 1 加载中 --> 已加载: AddDeviceWithData 成功
LoadStatus 为 0 加载中 --> 失败: LoadStatus 为 1 到 7 失败 --> 加载中: Reload 或再次 Presence 为 1 已加载 --> 未在位: Presence 变为 0
RemoveDevice,LoadStatus 为 255 已加载 --> 加载中: Reload ``` - **插入**:`Presence.changed` 变为 1 后调用 `try_load_device()`。同一 `GroupPosition` 已存在时,devmon 跳过重复创建。 - **拔出**:变为 0 后调用 `RemoveDevice`,并置 `m_require_eeprom_refresh_on_next_load` 为 true。下次插入跳过 Connector 缓存,重新读 Chip。 - 拔出时不会 `dlclose` 业务 SO。工厂缓存驱动句柄;卸载的是设备对象,不是 `.so` 文件。 下级 SR 里可以再定义 Connector,形成主板到背板、再到硬盘或电源的递归发现。 --- ## 触发条件 实现位于 component_drivers 仓的 `drivers/connector/connector/connector.cpp`(生命周期)与 `interface/i_connector.cpp`(信号与加载)。 ### Connector 生命周期 | 阶段 | 做什么 | 不做什么 | | ---- | ---- | ---- | | `init` | 用 `from_variant` 灌入 CSR,并订阅 `Presence.property_changed()`。 | 不读 EEPROM,不调用 AddDevice。 | | `start` | 调用 `preload_sr_cache()`;若 `Presence` 为 1,则 `mc::runtime::post(try_load_device)`。 | preload 失败不改 `LoadStatus`。 | | `stop` | 清 SR 缓存;下次必须重读 EEPROM。 | 无。 | 对象表中必须有名为 Devmon 的对象,否则 `try_load_device` 与 `RemoveDevice` 会打错误日志后返回。调用的方法是 `AddDeviceWithData(sr_data, connector_dict)` 与 `RemoveDevice(connector_dict)`。 Connector 对象层还有未出现在 `bmc.kepler.Connector` 接口上的属性:`Chip`(EEPROM 引用)、`Container`、`Position`、`IdChipAddr`、`CSRVersion`。IdentifyMode 为 3 时靠 `Chip` 调用 `GetSRData`。 ### Presence 来源 CSR 示例: ```json "Presence": "#/Scanner_BoardPresence.Value" ``` | 来源 | 行为 | 适用 | | ---- | ---- | ---- | | 常量 1 | `start()` 时就会异步加载。 | 永远在位的部件。 | | `#/Scanner_xxx.Value` | Scanner 周期读 Chip 的 BitIO 或 BlockIO,防抖后执行 `Value.set_value`。 | 热插拔(推荐)。 | | Accessor 的 `Value` | 读属性才访问硬件,无定时器。 | 更适合绑定 `Id`,不适合作为热插拔 Presence。 | CSR2 Scanner(`drivers/scanner/`)按 `Period` 毫秒扫描。CSR1 Scanner(`drivers/csr1/scanner/`)额外有: - 默认约 30s 启动延迟(环境变量 `SCANNER_PERIOD_DELAY_TIME`); - `SuccessDebounceCount` 与 `FailureDebounceCount`(默认 10)满足后才改 `Value`; - 同芯片偏移可合并,只让一个 master 读硬件。 > [!NOTE]说明 > > 把 Presence 绑到 CSR1 Scanner 时,Connector 的 `start()` 那一刻 Presence 常常仍为 0。真正加载发生在 Scanner 第一次把 `Value` 写成 1 之后。 ### Reload 接口 接口为 `bmc.kepler.Connector.Reload(Bom, Id, AuxId, IdentifyMode)`。 1. 若当前 `LoadStatus` 为 SUCCESS,先 `RemoveDevice`; 2. 写入非空的 Bom、Id、AuxId 和新的 IdentifyMode; 3. 清 Connector 缓存与本地 `csr_version.json` 缓存,并置 refresh; 4. 最多两次 `try_load_device`。 用于改识别方式或强制换一份 SR,而不依赖拔插。 --- ## SR 选择 实现为 `IConnector::resolve_sr_data`。单测见 `tests/drivers/connector/test_connector.cpp`。 ### 本地文件名 目录默认 `/opt/bmc/sr`,可用环境变量 `CONNECTOR_SR_DIR` 覆盖。 ```text {dir}/{Bom}_{Id}_{AuxId}.sr ``` 缺 Bom 或缺 AuxId 则少对应段。版本表 `{dir}/csr_version.json` 用去掉扩展名的文件名作 key,读取 `DataVersion`。 ### IdentifyMode | 值 | 规格含义 | 代码行为 | | ---- | ---- | ---- | | 1 | BoardId 可读 | 不读 EEPROM。用 CSR 里的 Bom、Id、AuxId 拼本地 `.sr`。Id 常由 `#/Accessor_xxx.Value` 注入。 | | 2 | BoardId 不可读(由配置上报) | 同上,走本地文件。 | | 3 | EEPROM 自描述 | 读 Chip 的 BoardId 与 SR,再和本地比版本。 | 常量为 `identify_mode::EEPROM = 3`。其它值全部走本地文件。 ### IdentifyMode 为 3 时的决策 ```mermaid flowchart TD Start[IdentifyMode 为 3] --> Fast{CSR2 SelfDescriptionRecord.BoardId 非空} Fast -->|是| Id1[用该 BoardId 与 DataVersion 作身份
尚不调用 GetSRData] Fast -->|否| E2P[get_e2p_csr_data] E2P --> CSR1{bmc.kepler.EepromData.GetSRData 成功且 UID 非空} CSR1 -->|是| Id2[身份为 UID] CSR1 -->|否| CSR2[bmc.dev.Chip.SelfDescriptionRecord.GetSRData] CSR2 --> Id3[身份为 BoardId] E2P --> Fail{芯片返回非 SUCCESS} Fail -->|是| Err[LoadStatus 等于芯片完成码
禁止降级本地] Fail -->|SUCCESS 但身份空| LocalId[用 CSR 配置的 Id 拼本地路径] Id1 --> Cmp[比较 DataVersion] Id2 --> Cmp Id3 --> Cmp Cmp --> Pick{EEPROM 版本非空 且 本地空或 EEPROM 不低于本地} Pick -->|是| UseEep[源为 EEPROM] Pick -->|否| UseLoc[源为本地] UseLoc --> Stamp{仍有 EEPROM 版本} Stamp -->|是| StampY[把 payload.DataVersion 改写成 EEPROM 版本] Stamp -->|否| File[读本地 sr] UseEep --> Soft{FormatVersion 在 3.0 到 5.0 之间} Soft -->|是| Merge[与同名_soft.sr 合并 Objects 与 Topology] Soft -->|否| Done[得到 SR] Merge --> Done StampY --> File File --> Done LocalId --> File ``` - **快路径**:CSR2 的 `eeprom_object::start()` 已解析 128 Byte头并填好 `BoardId` 与 `DataVersion` 时,Connector 先用属性做身份和版本比较,需要 payload 时再 `GetSRData`(通常打中芯片缓存)。 - **慢路径**:CSR1 EEPROM 的 `start()` 不读硬件,BoardId 为空,必然走到 `GetSRData`。先走 CSR1 接口,失败再走 CSR2。 - `version_compare(a, b)` 表示 a 大于或等于 b(`major.minor`)。相等也选 EEPROM。本地严格更新则用本地内容,但对外 `DataVersion` 写成 EEPROM 的版本。 - soft 合并仅针对 EEPROM 源,且 `FormatVersion` 在 3.0(含)到 5.0(不含)之间。同名子字典以 soft 为底、EEPROM 覆盖。合并失败仍返回未合并的 EEPROM 数据。大于或等于 5.0 视为设备树 CSR,不再拆 soft。 > [!WARNING]注意 > > 芯片返回硬件访问失败、验签失败或格式错误时,禁止降级到可能属于另一块板的本地文件。仅当完成码为成功但身份为空时,才使用 CSR 里配置的 Id。 ### 三层缓存 | 层 | 位置 | 命中条件 | 失效 | | ---- | ---- | ---- | ---- | | 芯片内存 | `chip_eeprom::m_sr_cache` | 签名区一致,且 BoardId 与版本一致。 | 头解析失败,或调用 `invalidate_sdr_cache`。 | | 芯片磁盘 | `/data/opt/bmc/sr/backup/{uid}.bin` | 文件尾部签名与当前签名区一致。 | 签名变化。 | | Connector | `IConnector::m_sr_cache` | 来源、board_id、两个版本与文件路径一致。 | Presence 为 0、Reload,或 refresh 标志。 | `m_require_eeprom_refresh_on_next_load` 初始为 true;preload 成功置 false;拔出或 Reload 再置 true。为 true 时跳过 Connector 缓存。缓存命中且 IdentifyMode 为 3 时,正式 load 可以零次访问 Chip。 --- ## EEPROM 与 LoadStatus 设备树入口: - CSR2:`bmc.dev.Chip.SelfDescriptionRecord.GetSRData` 返回 `(uint8_t status, string json)`,同时刷新 `FormatVersion`、`DataVersion`、`BoardId`。 - CSR1:`bmc.kepler.EepromData.GetSRData` 返回 `(status, json, uid)`。 内部均落到 `chip_eeprom::get_sdr_data`(`drivers/internal/chip/chip_eeprom/eeprom.cpp`)。访问前锁 host_bus。 ### 头与流水线 EEPROM 偏移以 8 Byte步长计。开头 128 Byte含 UID、`sign_offset`、`csr_offset`、CRC32。由此得到: - `BoardId` 与 CSR1 的 uid 等于头内 24 Byte UID 字符串; - `FormatVersion` 等于 `{ver}.00`; - `DataVersion` 等于 `{sr_version_high}.{sr_version_low:02}`。 `get_sdr_data` 顺序:解析头,读签名区,查内存或磁盘缓存,读被签名区。签名区非全 0 则做 ECDSA-SHA256 验签(先内置 P-256 公钥,失败再读 `/opt/bmc/trust/partner/device_desc_pubkey.bin`),再从 `csr_offset` 解 gzip JSON。签名全 0 视为老硬件无签名。部分遗留 UID 在白名单内,签名参数非法或验签失败也可放行(不备份)。 解压失败返回完成码 4(获取 SR 失败),此时 Connector 才允许转本地 CSR。页读写与 CRC 实现细节见 EEPROM 源码,本文不展开。 ### LoadStatus 与 EEPROM 完成码对齐,由 Connector 在正式 load 时写入(preload 失败不改): | 值 | 名称 | 典型原因 | | ---- | ---- | ---- | | 0 | SUCCESS | `AddDeviceWithData` 成功。 | | 1 | HARDWARE_ACCESS_FAIL | I2C、总线或前级 MUX 失败。 | | 2 | SIGNATURE_VERIFY_ERROR | 验签失败且不在白名单。 | | 3 | DATA_FORMAT_ERROR | 头 CRC 失败、非 JSON 或 gzip,或本地 JSON 损坏。 | | 4 | LOCAL_FILE_ERROR | `.sr` 不存在或读失败。 | | 5 | OBJECT_PARSE_ERROR | 预留。 | | 6 | INTEGRITY_VERIFY_ERROR | 预留。 | | 7 | FORMAT_VERSION_ERROR | 预留。 | | 255 | DEFAULT | 初始、已 Remove,或 Reload 清状态。 | `try_load_device` 在拿到 SR 后调用 AddDevice;invoke 抛异常时打错误日志,不一定改写 `LoadStatus`(成功路径才置 0)。拿不到 SR 时把上述错误码写到 `LoadStatus`。 --- ## 框架侧加载 Connector 交出 SR 之后的工作在 devmon。`FormatVersion` 小于 5.0 走 CSR1 的 `device_loader`;否则走 CSR2 的 `device_manager::add_device`。 ### 从 Compatible 到 SO ```mermaid flowchart LR SR["SR 的 Unit.Compatible"] --> Loop["按列表依次尝试"] Loop --> Name["逗号换成下划线"] Name --> File["lib 加 name 加 .so"] File --> Flash["image、gold、temp 按版本择优"] Flash --> ABI["dlsym register_device_driver"] ABI --> Type["device_name 等于 Unit.Type"] ``` - `Compatible: ["hisi_182x"]` 对应 `libhisi_182x.so`。 - `Compatible: ["Mellanox,CX5"]` 对应 `libMellanox_CX5.so`。 - CSR1 还会尝试 `libCsr1${name}.so`。 - 列表从前到后,第一个加载成功的即停;全部失败则解析失败,设备不会 start。 - SO 候选来自驱动安装目录与 `/data/opt/bmc/drivers/gold`、`temp`(`flash_driver_store`)。实现细节以 devmon 为准。 `Unit.Type` 必须等于该 SO 注册的某个 `device_name`(如 `PCIeNicCard`)。对象实例名来自 `Unit.Name`,并可按 Connector 的 position 重命名以保证全局唯一。 ### ManagementTopology SR 的 `ManagementTopology` 把模板总线名映射到 Connector 字典里的 `Buses`(字符串数组,元素是底板已有总线对象名)。devmon 抽出可达的 Bus 与 Chip,在 `device_manager`(component_drivers 的 `libInternal.so`)里创建内部对象并接线 `left_bus`、`host_bus`、`left_chip`。设备树 SO 的 `init()` 不创建内部芯片,只按 `object_name` 执行 `find_object`。EEPROM 能 `GetSRData` 的前提是这条拓扑已经接好。详见《[总线芯片驱动开发指南](../general_guide/bus_chip_driver_guide.md)》。 ### ABI 以 component_drivers 仓的 `include/devmon/driver_abi.h` 为准。每个 SO 必须用 `extern "C"` 导出 `register_device_driver`。 ```cpp typedef enum status { STATUS_OK = 0, STATUS_ERROR = 1, STATUS_NOT_FOUND = 2, STATUS_INVALID_ARG = 3, STATUS_NOT_IMPLEMENTED = 4, STATUS_TIMEOUT = 5, STATUS_BUSY = 6, STATUS_NO_MEMORY = 7, } status_t; struct device_driver { const char* device_name; const driver_ctor ctor; // (service, object_name) -> handle const driver_init init; // (handle, csr_object, connector) const driver_start start; const driver_stop stop; driver_dump dump; // 可为 nullptr }; ``` 一个 SO 可注册多种 `device_name`。以 `drivers/pcie_nic_card/hisi/hi182x/hi182x_abi.cpp` 为例,同一库导出 `PCIeNicCard`、`NicPort`、`OpticalTransceiver`。空指针参数返回 `STATUS_ERROR`,不要使用已不存在的 `STATUS_INVALID_PARAM`。 `ctor` 只创建对象并设置 service 与 object_name。`init` 灌入 CSR、建子对象关系,不开定时器和协议。`start` 才启动业务。`stop` 停业务并清理。Connector 自身就是这个模型:`init` 订阅信号,`start` 才检查 Presence。 热插拔 `RemoveDevice` 对主对象调 `stop`,并尝试 stop 同 position 下的子类型对象,不会因此卸载 `.so`。若调用 `device_driver::unload()`,必须先清空 `m_devices` 再 `dlclose`,因为函数指针在库内。 ### 属性注入 CSR 的 `Objects` 按接口名组织,经 `MC_REFLECT` 与 `from_variant` 映射到对象属性。占位符(`${Slot}`、`#/Scanner.Value` 等)由 devmon 的 CSR 解析与引擎引用机制处理,不是 Connector 里的独立函数。Connector 传给框架的字典字段包括:`ObjectName`、`Bom`、`Slot`、`GroupId`、`GroupPosition`、`Presence`、`Id`、`AuxId`、`Buses`、`SystemId`、`ManagerId`、`SilkText`、`Type`、`IdentifyMode`、`ChassisId`、`LoadStatus`、`Container`、`Chip`。缺省时用默认值,避免类型转换失败。 --- ## 适配检查清单 驱动写完却加载不上时按此核对,不必先怀疑 VID 或 DID 扫描。 底板或上级 CSR: - [ ] 有对应槽位的 Connector 对象,且 `Compatible` 能加载到 `libConnector.so`。 - [ ] `Presence` 有来源:常量 1,或指向已创建的 Scanner 的 `Value`。 - [ ] `IdentifyMode` 与板类型一致:EEPROM 自描述用 3;否则保证本地 `.sr` 的 Bom、Id、AuxId 能拼出文件。 - [ ] IdentifyMode 为 3 时,`Chip` 指向已接线的 EEPROM 对象(`host_bus` 与 `left_bus` 非空)。 - [ ] `Buses` 列出下级 SR 拓扑要用到的底板总线名。 - [ ] `GroupPosition` 在同一 CSR 内不重复。 下级 SR 与驱动 SO: - [ ] 文件在 `/opt/bmc/sr/`(或 gold、temp、EEPROM);IdentifyMode 不是 3 时,`csr_version.json` 有对应条目。 - [ ] `Unit.Type` 等于 SO 里某个 `device_name`。 - [ ] `Unit.Compatible` 能落到已安装的 `libxxx.so`(注意逗号转下划线)。 - [ ] `Objects` 接口名与 `MC_REFLECT`、DDS 生成的 `gen::` 接口一致。 - [ ] 需要热插拔时,不要把 Presence 只绑在无定时器的 Accessor 上。 品类目录、DDS 命名与出包步骤仍以《[网卡驱动适配指南](../nic_adapt/south_nic_driver_adapt.md)》至《[风扇电源驱动适配指南](../fan_power_adapt/fan_power_driver_adapt.md)》为准。 --- ## 故障排查 ### 按 LoadStatus | LoadStatus | 先查 | | ---- | ---- | | 255 且部件已在位 | Presence 是否从未变成 1(Scanner 延迟或防抖);对象表有无 Devmon。 | | 1 | I2C、MUX、EEPROM 总线;Chip 引用是否为空。 | | 2 | 验签公钥、是否老 UID 白名单、签名区是否损坏。 | | 3 | EEPROM 头 CRC、gzip 或 JSON;或本地 `.sr` 不是合法 JSON。 | | 4 | `/opt/bmc/sr/{Bom}_{Id}_{AuxId}.sr` 是否存在;Id 是否已从 EEPROM 改写导致文件名变化。 | | 0 但业务对象没有 | AddDevice 后 Compatible 与 `Unit.Type` 是否匹配;查看 devmon 侧加载日志。 | ### 日志关键字 - `[self-discovery]` 与 `[self-release]`:Presence 边沿。 - `SR source=EEPROM` 与 `SR source=LOCAL`:最终选用哪份数据。 - `merge soft data`:soft 合并是否成功。 - `Devmon.AddDeviceWithData failed`:框架解析或建对象失败(此时 SR 已选出)。 ### Connector dump `LoadStatus` 为 SUCCESS 时,`Connector::dump()` 在标准属性(`.` 前缀)之外输出 `-` 前缀字段,包括 `SourcePath`、`SoftSourcePath`、`DataSource`(`EEPROM`、`LOCAL` 或 `NA`),以及有效、EEPROM、本地的 FormatVersion 与 DataVersion。hwdiscovery 的 discovery dump 会汇总各 Connector,并补 flash 副本完整性字段。 > [!WARNING]注意 > > 不要用主机上的 `lspci` 或 `i2cdetect` 作为 BMC 南向自发现的诊断手段。 --- ## 附录(对照源码) 路径相对于对应 Git 仓根目录。component_drivers 见 [GitCode 仓库](https://gitcode.com/openUBMC/component_drivers);devmon 见 [GitCode 仓库](https://gitcode.com/openUBMC/devmon)。 | 主题 | 路径 | | ---- | ---- | | Connector 状态机、SR 选择 | `drivers/connector/connector/interface/i_connector.cpp` | | Connector ABI 与 dump | `drivers/connector/connector/connector.cpp`、`connector_abi.cpp` | | CSR2 EEPROM 的 GetSRData | `drivers/chip/interface/i_self_description_record.cpp` | | 头解析、验签、backup | `drivers/internal/chip/chip_eeprom/eeprom.cpp` | | CSR1 GetSRData(start 不读硬件) | `drivers/csr1/chip/common/interface/i_eeprom_data.cpp`、`drivers/csr1/chip/eeprom/eeprom.cpp` | | CSR2 与 CSR1 Scanner | `drivers/scanner/scanner/`、`drivers/csr1/scanner/scanner/` | | Accessor | `drivers/accessor/accessor/` | | ABI 头文件 | `include/devmon/driver_abi.h` | | 启动发现 | `libs/hwdiscovery/src/discovery/discovery.cpp`(devmon) | | Add 与 Remove | `libs/hwdiscovery/src/discovery/hwdiscovery_root_interface.cpp`(devmon) | | Compatible 与拓扑 | `libs/common/src/device/csr.cpp`、`manager.cpp`(devmon) | | SO 加载与 flash 择优 | `libs/common/src/device_driver.cpp`、`flash_driver_store.cpp`(devmon) | | Connector 行为单测 | `tests/drivers/connector/test_connector.cpp` | --- # 南向风扇电源驱动适配指南 > URL: https://openubmc.cn/docs/zh/latest/component_driver/fan_power_adapt/fan_power_driver_adapt.html > Language: zh # 南向风扇电源驱动适配指南 > 南向驱动是基于硬件组件驱动程序框架,采用分层架构设计,支持多种设备类型和通信协议。本文档面向风扇和电源适配的设备驱动开发者,提供从设计到实现的完整开发流程,并基于现有代码实例分析,提供一篇快速适配的开发指南。 > > 章节总览与分册选型见《[部件驱动适配指南](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/4-部件驱动适配指南.md)》。电源接口契约见 `dmc/intf/bmc/dev/PowerSupply*`(含 `Control/Metrics/Status/Oem/LogCollection/...` 子接口);电源对象路径与接口组合见 `dmc/path/bmc/dev/PowerSupply/PowerSupply.json`;风扇部件对象见 `dmc/path/bmc/dev/Fan/{Fan,Fans,FanType}.json`(Fan 对象可选 `bmc.dev.Fru` / `bmc.dev.PCB` / `bmc.dev.Temperature`,CESA 表 58);总览:《[Device Management Contract](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md)》。 ## 1. 概述 ### 1.1 什么是南向风扇电源驱动适配 南向风扇电源驱动适配是指在 BMC 系统中,为不同厂商的电源(PSU)设备提供统一的驱动程序接入方案,使 BMC 能够管理和监控电源设备。电源设备通常包含内置风扇,因此本文档同时涵盖电源和风扇的管理。 **风扇与电源的关系:** - **内置风扇**:电源设备通常内置 1-4个风扇,用于散热 - **统一管理**:风扇作为电源的一部分,通过电源驱动统一管理 - **PMBus 协议**:通过 PMBus 协议的风扇相关命令监控和控制风扇 ### 1.2 适配后可以实现什么功能 **电源功能:** - 获取电源基本信息(厂商、型号、序列号、固件版本等) - 监控电源状态(输入/输出电压、电流、功率、温度等) - 管理电源模式(主用/备用、正常/休眠模式) - 故障诊断和健康状态监控 - 电源复位操作 **风扇功能:** - 监控风扇转速(RPM - 每分钟转数) - 监控风扇状态(运行状态、故障状态) - 控制风扇转速(设置目标转速或 PWM 占空比) - 风扇告警和故障诊断 - 支持多风扇管理(1-4个风扇) ### 1.3 需要了解的关键概念 #### 契约与代码分层 在开始之前先厘清四个易混淆的概念:`dmc/`、`gen/`、`dev` 命名空间、以及厂商驱动目录。它们之间的关系见 [1.4](#14-驱动分层架构)。 | 概念 | 位置 | 说明 | |------|------|------| | **接口契约(dmc)** | `dmc/intf/bmc/dev/*.json` | 定义 `bmc.dev.*` 接口的属性、方法、类型与描述(如 `PowerSupply.json`、`PowerSupply/Metrics.json`、`Fan/Control.json`),是南向接口契约的单一事实源 | | **对象路径(dmc)** | `dmc/path/bmc/dev/**` | 定义设备树对象挂载路径与接口组合,如 `PowerSupply/PowerSupply.json`、`Fan/{Fan,Fans,FanType}.json` | | **接口基类(gen)** | `gen/include/device_tree/interface/` | 与契约对应的 C++ 接口基类,位于 `dev::gen` 命名空间,如 `gen::PowerSupply`、`gen::PowerSupply_Control`、`gen::Fan`;当前仓库没有自动重新生成的工具链,改动接口时需要人工同步维护 | | **驱动实现(dev)** | `drivers/` 下各驱动目录 | 厂商/协议实现,位于 `dev` 命名空间,如 `dev::OnePowerPmbus`、`dev::IPowerSupply` | | **设备描述(CSR)** | 驱动目录内 `csr/*.dds` / `*.sr` | `.dds` 声明设备对象到 D-Bus 路径的映射与接口列表,`.sr` 是型号级实例配置(总线拓扑、静态属性、`Compatible` 等) | #### 设备对象 | 对象类型 | 说明 | 代码示例 | |---------|------|------| | **电源主对象** | 代表整个电源设备,承载 `OnePowerBase` 公共逻辑并组合各接口 | `dev::OnePowerPmbus`(`drivers/psu/pmbus/`) | | **电源公共基类** | 协议无关的电源对象基类:协议管理、属性采集、更新回调、升级、BMC 主从带外管理等 | `dev::OnePowerBase`(`drivers/psu/common/`) | | **风扇框/风扇对象** | 风扇部件对象(非 PSU 内置风扇) | `dev::Fans` / `dev::Fan` / `dev::FanType`(`drivers/fan/huawei/`) | #### 接口 - **gen 命名空间(`dev::gen`)**:与 dmc 契约对应的接口基类,只声明属性与虚方法,用 `MC_INTERFACE("bmc.dev.Xxx")` 声明接口名;改动契约时需要人工同步修改 - **dev 命名空间**:驱动实现类。接口实现类通过 `mc::engine::interface` 双模板参数继承对应 gen 基类 - **接口组合**:一个设备可实现多个接口(`PowerSupply`、`PowerSupply.Control`、`PowerSupply.Metrics`、`PowerSupply.Status`、`PowerSupply.Oem` 等),组合关系在 `.dds/.sr` 与 `MC_OBJECT` 中声明 #### 协议库 - **`libraries/protocol`**:`power_supply_protocol_base` 电源协议抽象基类(`ps_protocol_t`) - **`libraries/pmbus`**:PMBus 电源管理总线协议(业界标准),含厂商变种实现(如 `pmbus_FP1420`、`pmbus_qb900` 等) - **`libraries/smbus`、`libraries/canbus` 等**:底层通信协议封装;不同协议族(PMBus/CANbus/SMC)使用不同的驱动目录 - 电源驱动按“通信协议”组织而非按厂商,公共部分下沉到 `drivers/psu/common` --- ### 1.4 驱动分层架构 1. **分层架构**:从契约定义到硬件交互的完整体系:契约层(`dmc`)→ 基类层(`gen`,`dev::gen` 接口基类,需随 dmc 人工同步)→ 实现层(`dev`,厂商/协议实现)→ 部署层(`.so` + `csr` 配置由 devmon 加载并实例化到 D-Bus 设备树); 2. **设计理念**:接口与实现分离。“改契约先改 `dmc`”(`dmc/intf` 定义接口、`dmc/path` 定义对象路径与接口组合),与契约对应的 C++ 接口基类维护在 `gen/`(当前仓库无自动生成工具,需人工同步),具体部件驱动在 `drivers/` 下实现;驱动只对 `devmon` 导出统一的 ABI(`register_device_driver`),设备实例由型号级 CSR(`.dds`/`.sr`)描述并按需加载。 ```mermaid flowchart TD subgraph dmc["契约层(dmc)"] direction TB INTF["dmc/intf JSON 契约
PowerSupply.json / PowerSupply.Control.json /
PowerSupply.Metrics.json / Fan.json ..."] PATH["dmc/path 对象路径+接口组合
PowerSupply/PowerSupply.json
Fan/Fan.json / Fans.json / FanType.json"] end subgraph gen["基类层(gen)"] GEN_IF["gen/include/device_tree/interface/
dev::gen::PowerSupply / gen::PowerSupply_Metrics / gen::Fan ..."] end subgraph dev["实现层(drivers)"] direction TB subgraph psu_common["drivers/psu/common"] BASE["OnePowerBase(协议管理/采集/回调/升级/主从带外管理)"] DIF["IPowerSupply / IPowerSupply_Control /
IPowerSupply_Metrics / IPowerSupply_Status ..."] end subgraph psu_proto["drivers/psu/pmbus 等协议目录"] OBJ["OnePowerPmbus : mc::app::object + OnePowerBase"] ABI["psu_abi.cpp(register_device_driver)"] end subgraph fan_dev["drivers/fan/huawei"] FOBJ["Fans / Fan / FanType 对象"] FABI["fan_abi.cpp"] end BASE --> DIF end subgraph csr["型号配置(CSR)"] SR["14191046_PSU_pmbus.dds / .sr
(Unit/Compatible/Objects/接口静态属性)"] end subgraph runtime["运行时(devmon)"] TREE["D-Bus 设备树
/bmc/dev/Chassis/:SystemId/PowerSubsystem/PowerSupplies/:Id"] end INTF -->|契约对应/同步维护| GEN_IF PATH -->|对象定义参考| SR GEN_IF -->|继承实现 mc::engine::interface<Impl, gen::Base>| DIF DIF -->|组合为设备对象| OBJ OBJ -->|ABI 导出| ABI ABI -->|devmon 按 CSR 加载 .so| TREE SR -->|声明对象实例| TREE DIF -->|同一套接口实现也可被风扇侧复用思路| FOBJ FOBJ -->|ABI 导出| FABI ``` ## 2. 前置准备 ### 2.1 明确电源信息 #### 必需信息 | 信息项 | 说明 | 示例 | |-------|------|------| | **I2C 地址** | 电源的 I2C 从设备地址 | `0x58` | | **协议类型** | 支持的协议 | `pmbus` | | **槽位信息** | 电源槽位编号 | `1`, `2` | #### 协议信息 - 支持的 PMBus 命令集(标准命令、厂商扩展命令) - 数据格式(LINEAR11、LINEAR16 等格式) - 特殊功能(休眠模式、N+R 支持等) #### 硬件信息 - 额定功率 - 输入电压范围(AC/DC) - 输出电压/电流规格 - 风扇数量和控制方式 ### 2.2 驱动代码结构熟悉 Component Driver 采用分层架构设计,代码组织清晰,各个目录职责明确。理解这些目录的结构和作用是快速适配驱动的基础。 --- #### 2.2.1 整体目录结构 ```shell component_drivers/ ├── dmc/ # Device Management Contract(接口契约与对象路径,单一事实源) │ ├── intf/bmc/dev/ # 接口契约 JSON(bmc.dev.* 的属性/方法) │ │ ├── PowerSupply.json + PowerSupply/ # 电源接口契约及子接口 │ │ ├── Fan.json + Fan/、Fans.json、FanType.json # 风扇接口契约 │ │ ├── Cooling.json / Upgrade.json / SharedManagement.json / Fru.json ... │ │ └── ... │ └── path/bmc/dev/ # 对象路径与接口组合 JSON │ ├── PowerSupply/PowerSupply.json │ ├── Fan/{Fan,Fans,FanType}.json │ └── ... ├── drivers/ # 设备驱动实现目录(按部件类型组织) ├── gen/ # 与 dmc 契约对应的接口/对象 C++ 基类(dev::gen 命名空间,需随 dmc 人工同步) ├── libraries/ # 协议库目录(通信协议封装) ├── include/devmon/ # 公共头文件(含 driver_abi.h,定义统一驱动 ABI) ├── tests/ # 测试代码目录 ├── docs/ # 文档目录(分册规范与适配指南) ├── mds/ # 模型/服务描述文件 └── meson.build # 构建配置文件 ``` > [!NOTE]说明 > `dmc/` 是接口契约与对象路径的**单一事实源**:`dmc/intf` 定义“能提供什么属性/方法”,`dmc/path` 定义“对象挂在设备树哪个路径、组合哪些接口”。电源/风扇驱动需要实现的接口都以这两个目录中的 JSON 为准,细节见《[Device Management Contract](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md)》。 --- #### 2.2.2 drivers 目录 - 设备驱动实现 `drivers/` 目录包含所有硬件设备的具体驱动实现,第一层按部件类型组织(如 `psu`、`fan`、`bus`、`chip`、`pcie_nic_card` 等),第二层电源按“通信协议”组织(公共实现统一放在 `common/`),风扇部件按厂商组织。 ##### 目录结构 ```shell drivers/ ├── psu/ # 电源驱动(本指南重点) │ ├── common/ # 电源公共实现(协议无关,多协议复用) │ │ ├── one_power_base.h/.cpp # OnePowerBase 电源公共基类 │ │ ├── interface/ # 电源接口实现(继承 dev::gen 基类) │ │ │ ├── i_power_supply.h/cpp # PowerSupply 接口实现 │ │ │ ├── power_supply/ # 电源子接口实现 │ │ │ │ ├── i_control.h/cpp # Control │ │ │ │ ├── i_metrics.h/cpp # Metrics │ │ │ │ ├── i_status.h/cpp # Status │ │ │ │ ├── i_log_collection.h/cpp / i_oem.h/cpp / i_upgrade.h/cpp │ │ │ │ ├── i_capacitor.h/cpp (+ Capacitor/i_capacitor_metric.h/cpp) │ │ │ │ ├── i_dual_inputs.h/cpp / i_dual_channel.h/cpp │ │ │ ├── shared_management.h/cpp # SharedManagement 接口实现 │ │ │ └── meson.build │ │ └── meson.build │ ├── csr/ # 电源设备描述配置(各协议型号的 .dds/.sr) │ │ ├── 14191046_PSU_pmbus.dds/.sr │ │ ├── 14191046_PSU_pmbus_qb900.dds/.sr │ │ ├── 14191046_PSU_canbus.dds/.sr │ │ ├── 14191046_PSU_canbus_tpsu.dds/.sr │ │ └── 14191046_PSU_smc.dds/.sr │ ├── pmbus/ # PMBus 协议电源驱动 │ │ ├── one_power.h/.cpp # OnePowerPmbus 电源主对象 │ │ ├── psu_abi.cpp # ABI 导出接口(register_device_driver) │ │ └── meson.build │ ├── pmbus_qb900/ # PMBus QB900 变种(OnePowerPmbusQb900) │ ├── canbus/ # CANbus 协议电源(OnePowerCanbus) │ ├── canbus_tpsu/ # CANbus-TPSU 协议电源 │ ├── smc/ # SMC 协议电源 │ └── meson.build │ ├── fan/ # 风扇部件驱动 │ └── huawei/ # 华为风扇框驱动(Fans/Fan/FanType 对象) │ ├── smc/ # fan_object / fans_object / fantype_object + fan_abi.cpp │ ├── interface/ # i_fan / i_fans / i_fantype / i_shared_management 及子接口 │ └── csr/ # 14100363_*.dds/.sr │ ├── bus/ # 总线驱动(i2c、i2c_mux、i2c_over_hisport、localbus ...) ├── chip/ # 芯片驱动(eeprom、lm75、pca9555、cpld_register ...) ├── pcie_nic_card/ # 网卡驱动(hisi、wangxun、mellanox ...) ├── pcie_gpu_card/ # GPU 卡驱动(nvidia、innosilicon、moorethreads ...) ├── internal/ # 内部实现(驱动框架基础类) └── meson.build ``` ##### 关键目录说明 | 目录 | 说明 | 用途 | |------|------|------| | **psu/common/** | 电源公共实现 | `OnePowerBase` 提供协议无关的公共能力;`interface/` 下是所有协议电源共享的接口实现(`IPowerSupply_*`) | | **psu/csr/** | 电源设备描述配置 | 集中存放各协议的 `.dds`/`.sr` 型号配置,定义设备接口、路径与实例化参数 | | **psu/pmbus/ 等协议目录** | 各协议电源驱动 | 每个协议目录一个电源主对象(如 `OnePowerPmbus`)+ `psu_abi.cpp`,通过协议工厂表把 `协议名` 映射到 `libraries/pmbus` 中的具体实现类 | | **fan/huawei/** | 风扇部件驱动 | 提供 `Fans`/`Fan`/`FanType` 三类对象(风扇框/风扇/风扇类型)及其接口实现、CSR 配置 | | **internal/** | 内部基础框架 | 提供驱动框架的基础类 | --- #### 2.2.3 gen 目录 - 接口/对象 C++ 基类 `gen/` 目录存放与 `dmc/` 契约对应的接口/对象 C++ 基类(`dev::gen` 命名空间),驱动代码继承这些基类实现功能。代码随仓库提交,meson 只负责编译。 > [!WARNING]注意 > 当前仓库内没有随构建执行的代码生成/重新生成工具链,`gen/` 下的代码需要**人工维护**:新增/修改接口属性时,除同步修改 `dmc/` 契约 JSON 外,还需人工同步修改 `gen/include/device_tree/interface/` 下的头文件(及其 `gen/src/` 实现),否则接口实现类将无法通过编译或属性缺失。仓库中 dmc/CSR 与 gen/驱动实现存在的不一致(如 `.dds`/`.sr` 仍引用 `bmc.dev.Cooling`、接口实现类与 `MC_OBJECT` 声明不齐等)多数与未做到同步有关。 ##### 目录结构 ```shell gen/ ├── include/ # 头文件目录 │ ├── device_tree/ │ │ ├── base.h # 基础类定义 │ │ ├── runtime_registrar.h # 运行时注册 │ │ ├── interface/ # 接口基类定义(namespace dev::gen) │ │ │ ├── PowerSupply.h # 电源接口基类 gen::PowerSupply │ │ │ ├── PowerSupply/ # 电源子接口基类 │ │ │ │ ├── Control.h # gen::PowerSupply_Control │ │ │ │ ├── Metrics.h # gen::PowerSupply_Metrics │ │ │ │ ├── Status.h # gen::PowerSupply_Status │ │ │ │ ├── Oem.h / LogCollection.h / Capacitor.h / DualInputs.h / DualChannel.h ... │ │ │ ├── Cooling.h / Upgrade.h / SharedManagement.h │ │ │ ├── Fan.h + Fan/ # gen::Fan 及子接口(Control/Status/Metrics/PWMChannel/Oem/LogCollection) │ │ │ ├── Fans.h + Fans/、FanType.h │ │ │ └── ... │ │ └── object/ # 对象组合定义(部分部件类型) │ └── resource_tree/ # 资源树(总线/芯片/扫描器等)接口基类 ├── src/ # 源文件目录(与 include 结构对应) └── meson.build # 编成 libdevice_tree.so / libresource_tree.so ``` ##### 关键概念 | 概念 | 说明 | 示例 | |------|------|------| | **接口基类** | 定义接口的属性与虚方法,用 `MC_INTERFACE("bmc.dev.Xxx")` 声明接口名 | `gen::PowerSupply`(即 `dev::gen::PowerSupply`)定义了 `Model`、`Manufacturer`、`SerialNumber` 等属性 | | **接口实现类** | 用双模板参数继承接口基类,实现具体逻辑 | `class IPowerSupply : public mc::engine::interface` | | **命名空间** | 接口基类位于 `dev::gen`,驱动实现位于 `dev` | 驱动代码中写 `gen::PowerSupply` 即 `dev::gen::PowerSupply` | | **同步维护** | 以 `dmc/` 契约为准,`gen/` 基类需人工同步 | 在 `dmc/intf/bmc/dev/PowerSupply.json` 新增属性后,同步在 `gen/include/device_tree/interface/PowerSupply.h` 增加对应 `property<>`(当前仓库无自动生成工具) | | **对象基类** | 部分部件类型提供对象基类(`mc::app::object` 派生) | `gen/include/device_tree/object/...` | ##### 使用方式 接口基类的风格如下(以电源接口为例,摘自仓库实际代码): ```cpp // gen/include/device_tree/interface/PowerSupply.h(namespace dev::gen) class MC_API PowerSupply : public mc::engine::interface { public: MC_INTERFACE("bmc.dev.PowerSupply") property FirmwareVersion; // 电源固件版本 property Manufacturer; // 厂商 property Model; // 电源型号 property SerialNumber; // 序列号 property SlotNumber; // 槽位号 // ... }; ``` 驱动中实现接口时,不要直接继承 gen 基类,而是用**双模板参数**形式,并在 `.cpp` 中通过单参数 `MC_REFLECT` 完成反射注册: ```cpp // 厂商接口实现类(dev 命名空间) class IPowerSupply : public mc::engine::interface { public: void init(OnePowerBase* base_ptr); void start(); // 内部注册更新回调 void stop(); bool update_power_supply(std::string_view property, const mc::variant& info); private: OnePowerBase* m_base; }; // .cpp 文件末尾:反射注册(单参数,无需列出 gen 基类) MC_REFLECT(dev::IPowerSupply) ``` --- #### 2.2.4 libraries 目录 - 通信协议库 `libraries/` 目录包含各种通信协议的封装实现,为驱动提供标准化的协议接口。除电源/风扇相关的 `protocol`/`pmbus`/`smbus` 外,还包含网卡/硬盘等部件使用的 `mctp`、`pldm`、`ncsi`、`nvme` 等协议库。 ##### 目录结构 ```shell libraries/ ├── protocol/ # 电源协议抽象基类 │ ├── power_supply_protocol.h/.cpp # power_supply_protocol_base(ps_protocol_t) │ ├── protocol.h/.cpp # 协议公共定义 │ └── meson.build │ ├── pmbus/ # PMBus 协议库(含厂商/型号变种) │ ├── pmbus.h/.cpp # PMBus 协议实现(继承 power_supply_protocol_base) │ ├── pmbus_FP1420.h/.cpp / pmbus_qb900.h/.cpp / pmbus_eb1000_1.h/.cpp ... │ ├── powerconverter_pmbus.h/.cpp │ └── meson.build │ ├── smbus/ # SMBus/I2C 协议库 │ ├── smbus.h/.cpp、std_smbus.h/.cpp、smbus_postbox.h/.cpp │ └── meson.build │ ├── canbus/ # CANbus 协议(电源/机框等使用) ├── mctp/ ncsi/ ncsi_over_mctp/ pldm/ pldm_over_mctp/ nvme/ # 带外管理/板卡协议 ├── ipmb/ lldp/ imu/ ssu_oob/ # 其他协议 └── meson.build ``` ##### 协议库说明 | 协议库 | 说明 | 传输方式 | 应用场景 | |--------|------|---------|---------| | **protocol** | 电源协议抽象基类 `power_supply_protocol_base` | - | 定义电源协议的通用接口(读取/控制/状态/升级),所有电源协议类的基类 | | **pmbus** | PMBus 电源管理总线协议 | I2C/SMBus | 电源管理的主要协议;厂商变种(`pmbus_FP1420`、`pmbus_qb900`、`pmbus_eb1000_1` 等)以子类形式扩展 | | **smbus** | 系统管理总线协议 | I2C | 底层总线通信,PMBus 的物理承载 | | **canbus** | CANbus 协议(含 TPSU 变种) | CAN | 采用 CANbus 的电源/机框场景 | ##### 协议分层关系(以 PMBus 电源为例) ```shell 应用层: 电源驱动代码(OnePowerBase → OnePowerPmbus) ↓ 协议层: libraries/protocol(power_supply_protocol_base) ↓ libraries/pmbus(pmbus 及厂商变种) ↓ 传输层: libraries/smbus(smbus) ↓ 物理层: I2C 硬件 ``` ##### 使用示例 协议库与驱动之间通过“协议工厂表”解耦:`drivers/psu/pmbus/one_power.cpp` 中把协议名字符串映射到具体的协议实现类,运行时由 `OnePowerBase::init_protocol()` 按名创建: ```cpp // drivers/psu/pmbus/one_power.cpp:PMBus 协议工厂表(节选) #define DEFINE_PS_PROTOCOL(name, ClassType) \ {name, [](mc::dict& data) -> std::unique_ptr { \ return std::make_unique(data); \ }} static const ps_protocol_map_t pmbus_protocol_map = { DEFINE_PS_PROTOCOL("pmbus", pmbus), DEFINE_PS_PROTOCOL("pmbus_qb900", pmbus_qb900), DEFINE_PS_PROTOCOL("pmbus_FP1420", pmbus_FP1420), DEFINE_PS_PROTOCOL("psu_pmbus", pmbus_FP1420), // ... }; // 读取属性(接口方法大多返回 std::optional,便于判空/重试) auto voltage = m_ps_protocol->get_input_voltage(); // 输入电压(V) auto current = m_ps_protocol->get_output_current_amps(); // 输出电流(A) auto power = m_ps_protocol->get_input_power_watts(); // 输入功率(W) auto temp = m_ps_protocol->get_env_temperature_celsius(); // 环境温度(℃) auto rpm = m_ps_protocol->get_psu_fan_speed_rpm(); // 风扇转速(RPM) // 控制(如设置风扇 PWM 占空比,0-100) m_ps_protocol->set_fan_speed_percent(30); ``` --- #### 2.2.5 目录之间的关系 ```mermaid flowchart TB subgraph "契约层" DMC["dmc/intf + dmc/path
接口契约与对象路径 JSON"] end subgraph "应用/驱动层" Driver["drivers/psu/pmbus + drivers/psu/common
OnePowerPmbus / OnePowerBase"] Interface["drivers/psu/common/interface
IPowerSupply / IPowerSupply_* 接口实现"] end subgraph "基类层" GenInterface["gen/include/device_tree/interface
dev::gen 接口基类"] end subgraph "协议层" ProtoBase["libraries/protocol
power_supply_protocol_base"] PMBus["libraries/pmbus
pmbus 及厂商变种"] SMBus["libraries/smbus
SMBus 协议实现"] end DMC -->|契约对应/人工同步| GenInterface GenInterface -->|mc::engine::interface<Impl, gen::Base>| Interface Interface -->|组合进对象| Driver Driver -->|调用| PMBus PMBus -->|继承| ProtoBase PMBus -->|使用| SMBus style Driver fill:#e1f5ff style GenInterface fill:#fff4e1 style PMBus fill:#ffe1f5 ``` ##### 工作流程 1. **契约定义**:在 `dmc/` 中维护接口(`intf`)与对象路径/接口组合(`path`) 2. **基类维护**:`gen/` 下与契约对应的 C++ 接口/对象基类(`dev::gen`)需人工同步维护(当前仓库无自动生成工具链) 3. **接口实现**:在 `drivers/*/common/interface` 等位置用 `mc::engine::interface` 实现接口 4. **驱动组装**:在协议驱动目录(如 `drivers/psu/pmbus`)组合接口、继承公共基类(`OnePowerBase`),创建完整驱动对象并导出 ABI 5. **协议调用**:驱动通过 `libraries/` 中的协议库与硬件通信 6. **部署加载**:配套 `csr` 下的 `.dds/.sr`,由 devmon 在设备树中实例化设备对象 ### 2.3 驱动协议架构 以 PMBus 电源为例,驱动、协议库与物理总线的分层关系如下(其他协议族如 CANbus、SMC 结构相同,只是中间协议库不同): ```mermaid flowchart LR subgraph "设备驱动层" Driver["设备驱动
OnePowerBase + OnePowerPmbus"] end subgraph "协议库层" Proto["libraries/protocol
power_supply_protocol_base"] PMBus["libraries/pmbus
pmbus + 厂商变种"] SMBus["libraries/smbus
SMBus协议"] end subgraph "传输层" I2C["I2C/SMBus"] end Driver -->|电源管理| PMBus PMBus -->|继承协议接口| Proto PMBus --> SMBus SMBus --> I2C ``` ### 2.4 底层协议确定 仓库中电源驱动按协议族组织:`drivers/psu/` 下有 `pmbus`、`pmbus_qb900`、`canbus`、`canbus_tpsu`、`smc` 五个协议目录,公共能力(`OnePowerBase` 与 `IPowerSupply_*` 接口实现)统一在 `common/`。 #### 协议类型 | 协议 | 驱动目录 | 说明 | 适用场景 | |------|---------|------|---------| | **PMBus** | `drivers/psu/pmbus` | 业界标准电源管理协议(SMBus/I2C),同一驱动内通过协议工厂表支持 `pmbus`、`pmbus_qb900`、`pmbus_FP1420`、`pmbus_eb1000_1` 等具体实现 | 标准 PMBus 电源 | | **CANbus / CANbus-TPSU** | `drivers/psu/canbus`、`drivers/psu/canbus_tpsu` | CANbus 通信的电源 | 使用 CANbus 的电源 | | **SMC** | `drivers/psu/smc` | 通过 SMC 通道访问电源 | 带 SMC 通道的整机电源 | #### 协议实现关系 | 协议库(libraries) | 关系 | 说明 | |------|------|------| | `protocol/power_supply_protocol.h` | 抽象基类 | 定义 `power_supply_protocol_base`,统一读取/控制/状态/升级等虚方法 | | `pmbus/pmbus.h` | 具体实现 | `pmbus` 实现标准 PMBus 命令 | | `pmbus/pmbus_*.h` | 厂商/型号变种 | 在标准 `pmbus` 之上扩展厂商私有命令(如 `pmbus_FP1420`、`pmbus_qb900`、`pmbus_PDC3KD5412_LC` 等),由 `drivers/psu/pmbus/one_power.cpp` 的协议工厂表注册 | --- ### 2.5 电源与风扇支持的能力 本节以 `drivers/psu/pmbus` 的 `OnePowerPmbus`(PMBus 电源主对象)为例,说明当前驱动已具备的能力,帮助开发者明确适配时需要实现/复用哪些接口。 > [!NOTE]说明 > 电源主对象的能力由两部分决定:接口实现类(`drivers/psu/common/interface`,各协议共享)和对象上实际组合的接口列表(`MC_OBJECT` 宏 + 型号 `.sr/.dds` 声明)。可按型号裁剪,也可随 `dmc` 契约演进补充新接口。 #### 电源级能力 `OnePowerPmbus` 通过 `MC_OBJECT` 组合了以下 8 个接口(接口实现均在 `drivers/psu/common/interface`,各协议电源复用): | 能力类别 | 接口名称 | 说明 | 可获取/可设置的信息 | |---------|---------|------|-------------| | **电源基本信息** | `PowerSupply` | 电源设备基础信息 | 厂商、型号、序列号、部件号、固件版本、硬件版本、生产日期、槽位、协议类型、供电类型、是否参与整机功率计算等 | | **指标接口** | `PowerSupply.Metrics` | 电源电气与温度指标 | 输入/输出电压、电流、功率、输入频率、额定功率/额定电流、环境/入口/内部/原边芯片/副边芯片温度、风扇转速 `FanSpeedRPM`、累计运行时长等 | | **控制接口** | `PowerSupply.Control` | 电源控制功能 | `SetFanMinPWM`(风扇最小 PWM)、`SetWorkMode`(工作模式)、`SetSleepMode`(休眠)、`Reset`(复位)、`SetAlarmLatch`/`SetPowerLatch`(锁存)、`SetOutputPowerLimitWatts`(输出功率限值) | | **状态接口** | `PowerSupply.Status` | 电源状态信息 | 在位 `Presence`、`Vout/Iout/Temperature/Input/CML/Mfr_Specific/Other` 告警状态、风扇状态 `Fans_1_2`/`Fans_3_4`、通信状态 `CommunicationStatus`、设备模式、输入/输出状态 | | **日志接口** | `PowerSupply.LogCollection` | 电源故障日志 | 黑匣子信息导出 | | **OEM 接口** | `PowerSupply.Oem` | 厂商私有能力 | 私有寄存器读写(`get_register_value`)等 | | **升级接口** | `Upgrade`(`bmc.dev.Upgrade`) | 固件升级/激活 | 升级触发、进度/状态上报、激活(PMBus 升级接口 `pmbus_upgrade`) | | **共享管理** | `SharedManagement`(`bmc.dev.SharedManagement`) | 多 BMC/共享电源场景 | 电源控制权(`ControlOwner`)、BMC 主从(Active/Standby)下带外管理启停 | **可选增强接口**(按电源型号能力在 `.sr/.dds` 与对象上按需启用):`PowerSupply.Capacitor`/`PowerSupply.Capacitor.Metrics`(超级电容)、`PowerSupply.DualInputs`(双路输入)、`PowerSupply.DualChannel`(双通道/轮询)。对应实现同样位于 `drivers/psu/common/interface/power_supply/`。 --- #### 风扇管理能力 电源内置的风扇通过以下方式进行管理: ##### 风扇状态监控 通过`PowerSupply.Status`接口获取风扇状态: | 状态属性 | 说明 | 可能的值 | |---------|------|---------| | **Fans_1_2** | 风扇 1 和风扇 2 的状态字节 | PMBus `STATUS_FANS_1_2`(0x81)寄存器值 | | **Fans_3_4** | 风扇 3 和风扇 4 的状态字节 | PMBus `STATUS_FANS_3_4`(0x82)寄存器值 | > [!NOTE]注意 > 状态字节为寄存器原始值。驱动解析 `health_event` 时主要关注高位置位(如 bit7 风扇故障 `fan_fault`、bit6 风扇转速超控等),其余位的具体含义需以电源厂商的 PMBus 规格书为准,不同型号存在差异。 ##### 风扇转速监控 电源内置风扇转速通过协议库读取(对应 Metrics 接口的 `FanSpeedRPM` 属性): | 监控项 | 协议接口(libraries/pmbus) | 说明 | 单位 | |-------|---------------------------|------|-----| | **风扇转速** | `get_psu_fan_speed_rpm()` | 读取电源当前风扇转速(返回 `std::optional`) | RPM | | **风扇占空比** | `get_fan_speed_percent()` | 读取风扇 PWM 占空比(0-100) | % | ##### 风扇转速控制 通过 `PowerSupply.Control` 接口及协议库控制风扇: | 控制项 | 接口/方法 | 说明 | |-------|----------|------| | **风扇最小 PWM** | `IPowerSupply_Control::SetFanMinPWM()`(属性 `Control.FanMinPWM`) | 设置风扇最小 PWM 占空比;取值范围/含义以 `dmc` 契约与厂商规格书为准 | | **直接调速** | 协议库 `set_fan_speed_percent()` | 直接按占空比控制风扇 | | **自动调速** | 电源固件自动控制 | 固件根据温度自动调节风扇转速 | > [!NOTE]说明 > > 1. 电源内置风扇通常由电源固件按温度自动调速,BMC 侧一般只设置**下限(最小 PWM)**; > 2. 风扇部件(风扇框/风扇模块)的调速不在电源驱动内,而是由 `drivers/fan/huawei` 的 `Fans`/`Fan` 对象提供(PWM 通道、`Fan.Control` 等接口),见 [2.2.2](#222-drivers-目录---设备驱动实现)。 **控制示例:** ```cpp // 通过 Control 接口设置风扇最小 PWM(示例:40%) m_power_supply_control.SetFanMinPWM(40); // 通过协议直接控制风扇占空比 m_ps_protocol->set_fan_speed_percent(40); ``` ##### 风扇管理流程 ```mermaid flowchart LR subgraph "应用层" App["Redfish/应用"] end subgraph "驱动层" Control["PowerSupply.Control接口"] Status["PowerSupply.Status接口"] OnePower["OnePowerPmbus(含 OnePowerBase)"] end subgraph "协议层" PMBus["PMBus协议"] end subgraph "硬件层" PSU["电源硬件"] Fan1["风扇1"] Fan2["风扇2"] Fan3["风扇3"] Fan4["风扇4"] end App -->|"设置风扇最小PWM"| Control App -->|"查询风扇状态"| Status Control -->|"SetFanMinPWM"| OnePower Status -->|"读取 Fans_1_2/Fans_3_4"| OnePower OnePower -->|"PMBus写(set_fan_speed_percent)"| PMBus OnePower -->|"PMBus读(get_psu_fan_speed_rpm)"| PMBus PMBus -->|"I2C通信"| PSU PSU -->|"控制"| Fan1 PSU -->|"控制"| Fan2 PSU -->|"控制"| Fan3 PSU -->|"控制"| Fan4 ``` --- #### 能力获取方式 以 `OnePowerPmbus`(PMBus)为例,数据获取分为“上电读取”与“周期采集”两个阶段: | 阶段 | 获取方式 | 内容 | 说明 | |-----|---------|------|------| | **上电/带外启动** | 启动时带重试读取 | 厂商、型号、序列号、部件号、生产日期、固件版本、电源类型、输入电压类型、硬件版本、额定功率,以及输入/输出电压初始值 | 保证设备树尽早出现非零的关键值 | | **周期采集(快)** | 500ms 定时器 | 输入功率、健康事件(`health_event`:`vout/iout/temperature/input/fans_1_2/cml/mfr_specific/other` 故障位)、通信状态 | `read_frequency_property()` | | **周期采集(慢)** | 每约 3 秒 | 输出/输入电流、电压、功率、环境/原边芯片/副边芯片温度、风扇转速 | 在快采中分帧读取 | | **周期采集(慢)** | 每约 5 秒 | 控制数据(休眠/工作模式、N+R 支持)、设备模式、额定功率、电源类型 | `read_slow_property()` | > [!NOTE]说明 > > - 实际周期与分帧策略见 `OnePowerPmbus::read_frequency_property()` / `read_slow_property()`(`drivers/psu/pmbus/one_power.cpp`);CANbus/SMC 协议驱动的采集策略可能不同; > - 产品信息(型号、序列号等)来自电源 FRU/寄存器数据,通常只在启动与低速周期读取,避免占用总线; > - 监测任务统一由 `OnePowerBase` 的 `start_monitor()/restart_monitor()` 管理,500ms 是其基类默认值,子类可覆写。 --- ## 3. 适配流程详解 > 场景假设:仓库需要支持一款新电源“XYZ”(PMBus 协议族),或使用全新通信协议的新电源。下面先判断适配形态,再按步骤落地。文中示例以 `drivers/psu/pmbus` 的 `OnePowerPmbus` 为蓝本。 ### 3.1 确定适配形态与目录结构 与早期“按厂商在 `drivers/psu/huawei` 下新建驱动”不同,当前电源驱动已按协议组织,且公共能力全部抽到 `drivers/psu/common`。因此多数适配**不需要新建驱动目录**: | 适配形态 | 场景 | 需要做的事 | |--------|------|-----------| | **新增电源型号(已有协议)** | 新电源使用 PMBus/CANbus/SMC 等仓库已覆盖的协议 | 在 `drivers/psu/csr/` 增加该型号的 `.dds/.sr`;若命令集差异较大,在 `libraries/pmbus` 增加厂商变种协议子类并注册到 `drivers/psu/pmbus/one_power.cpp` 的协议工厂表 | | **新增协议/全新通道** | 电源使用仓库未覆盖的通信协议 | 参考 `drivers/psu/pmbus` 新建协议驱动目录 + 配套协议库与 CSR | 仅在“新增协议驱动”时才需要创建如下目录(目录名/类名与 `pmbus` 对齐,以 `xyz` 为例): ```shell psu/ ├── common/ # 公共实现:直接复用,无需复制修改 │ ├── one_power_base.h/.cpp # OnePowerBase │ └── interface/ # IPowerSupply_* 接口实现(所有协议电源共享) ├── csr/ # 型号配置:增加 14191046_PSU_xyz.dds / .sr ├── xyz/ # 新协议驱动目录(对齐 pmbus 结构) │ ├── one_power.h # OnePowerXyz 电源主对象头文件 │ ├── one_power.cpp # 主对象实现(协议工厂表、start/stop、数据采集) │ ├── psu_abi.cpp # ABI 导出(register_device_driver) │ └── meson.build └── meson.build # 增加 subdir('xyz') ``` ### 3.2 配置型号描述(CSR:.dds + .sr) 型号级 CSR 成对存放在 `drivers/psu/csr/`: - **`.dds`**(Device Description Standard,`Schema: "dds-v1"`):声明设备对象到 D-Bus 路径的映射、以及该对象挂载的接口列表; - **`.sr`**(Self-Description Record):型号级实例配置,描述总线/芯片拓扑(`ManagementTopology`)、`Unit`(`Type`/`Compatible`)与各接口的静态属性,供 devmon 建树和驱动加载时使用。 #### 文件命名规则 ```shell 格式:[分类代码]_PSU_<协议>.dds 与 [分类代码]_PSU_<协议>.sr 示例:14191046_PSU_pmbus.dds / 14191046_PSU_pmbus.sr 说明:14191046 是电源的分类代码;<协议> 与驱动/协议库对应(pmbus、pmbus_qb900、canbus、canbus_tpsu、smc) ``` #### DDS 文件内容(摘自 `drivers/psu/csr/14191046_PSU_pmbus.dds`) ```json { "Schema": "dds-v1", "Type": "Component", "DeviceCategory": "OnePower", "ID": "N/A", "Objects": { "OnePower": { "Path": "/bmc/dev/Chassis/:SystemId/PowerSubsystem/PowerSupplies/:Id", "Interfaces": [ "bmc.dev.PowerSupply", "bmc.dev.Cooling", "bmc.dev.PowerSupply.Control", "bmc.dev.PowerSupply.Metrics", "bmc.dev.PowerSupply.Status", "bmc.dev.PowerSupply.LogCollection", "bmc.dev.PowerSupply.Oem" ] } } } ``` #### 关键字段说明 | 字段 | 说明 | 注意事项 | |------|------|---------| | `DeviceCategory` | 设备类别 | 电源为 `"OnePower"`(风扇部件为 `"Fan"` 等,见 2.2.2) | | `Objects` | 对象定义 | 键名(如 `OnePower`)与主对象 `MC_OBJECT` 的第 2 个参数(对象类型名)对应 | | `Path` | 对象 D-Bus 路径模板 | `:SystemId`、`:Id` 等为动态参数;对象路径契约以 `dmc/path/bmc/dev/PowerSupply/PowerSupply.json` 为准 | | `Interfaces` | 接口列表 | 应与代码 `MC_OBJECT` 声明、型号 `.sr` 中实际配置的接口保持一致 | #### .sr 文件要点(摘自 `14191046_PSU_pmbus.sr`) ```json { "FormatVersion": "5.00", "DataVersion": "5.00", "Unit": { "Type": "PSU", "Name": "OnePower_0", "Compatible": ["psu_pmbus"] }, "ManagementTopology": { "Anchor": { "Buses": ["I2c_2", "I2c_3"] }, "I2c_2": { "Chips": ["Smc_ExpBoardSMC"] }, "I2c_3": { "Chips": ["Eeprom_PsuChip"] } }, "Objects": { "OnePower_0": { "PhysicalInterface": "pmbus", "RefChip": "#/Eeprom_PsuChip", "bmc.dev.PowerSupply": { "SlotNumber": "${Slot}", "Protocol": "pmbus", "...": "..." }, "bmc.dev.PowerSupply.Metrics": { "...": "..." }, "bmc.dev.PowerSupply.Status": { "...": "..." } } } } ``` **配置要点:** 1. **`Unit` 匹配关系要对齐**:`.sr` 的 `Unit.Type`(电源为 `PSU`)与驱动 ABI 的 `device_name` 对应;`Compatible` 与驱动加载/协议工厂表使用的名称(如 `psu_pmbus`)对应,保证 devmon 能匹配到正确的 `.so`; 2. **`RefChip` 与拓扑要完整**:`ManagementTopology` 声明电源所在总线与关联芯片(如 EEPROM),`Objects.<对象>.RefChip` 引用该芯片,主对象 `init()` 据此解析出硬件访问通道; 3. **接口静态属性写在对应接口段**:`SlotNumber`、`Protocol` 等由 `.sr` 静态下发(经 `from_variant` 加载),运行期通过接口属性读取; 4. **风扇调速需求段(可选)**:需要“风扇随温度调速”的场景可在 `.sr` 中追加冷却/风扇需求(如 `CoolingRequirement_*`),由上层协同使用。 --- ### 3.3 创建电源主对象(协议驱动) > 电源主对象是每个协议驱动的核心:它组合各接口实现类,并承载协议相关的初始化和数据采集逻辑。公共逻辑(协议创建、属性读取分发、升级、BMC 主从带外管理、监控定时器管理等)已在 `OnePowerBase` 中实现,协议驱动只需完成少量协议相关的工作,参考对象:`drivers/psu/pmbus/one_power.h`(`OnePowerPmbus`)。 #### 代码示例:`one_power.h`(XYZ 协议电源主对象) ```cpp #ifndef ONE_POWER_XYZ_H #define ONE_POWER_XYZ_H #include #include #include #include #include "../common/interface/i_power_supply.h" #include "../common/interface/power_supply/i_control.h" #include "../common/interface/power_supply/i_log_collection.h" #include "../common/interface/power_supply/i_metrics.h" #include "../common/interface/power_supply/i_oem.h" #include "../common/interface/power_supply/i_status.h" #include "../common/interface/power_supply/i_upgrade.h" #include "../common/interface/shared_management.h" #include "../common/one_power_base.h" namespace dev { class OnePowerXyz : public mc::app::object, public OnePowerBase { public: // MC_OBJECT 参数:类名 / 对象类型名 / 路径模板 / 接口列表 MC_OBJECT( OnePowerXyz, "OnePower", "/bmc/dev/Chassis/1/PowerSubsystem/PowerSupplies/${SlotNumber}", (IPowerSupply)(IPowerSupply_Control)(IPowerSupply_Metrics)(IPowerSupply_Status) (IPowerSupply_LogCollection)(IPowerSupply_Oem)(IPowerSupply_Upgrade)(IPowerSupply_SharedManagement)) OnePowerXyz() = default; ~OnePowerXyz() = default; bool init(mc::mutable_dict& csr_object, const mc::dict& connector); bool start(); bool stop(); void from_variant(const mc::dict& d, dev::OnePowerXyz& obj); // 实现 OnePowerBase 纯虚接口 const ps_protocol_map_t& get_protocol_map() const override; // 协议工厂表(协议名 -> 协议对象) IPowerSupply& get_power_supply() override; // 返回 m_power_supply const IPowerSupply& get_power_supply() const override; IPowerSupply_SharedManagement& get_shared_mgmt() override; const IPowerSupply_SharedManagement& get_shared_mgmt() const override; // 接口成员变量(与 MC_OBJECT / MC_REFLECT 一一对应) IPowerSupply m_power_supply; IPowerSupply_Control m_power_supply_control; IPowerSupply_Metrics m_power_supply_metrics; IPowerSupply_Status m_power_supply_status; IPowerSupply_LogCollection m_power_supply_log_collection; IPowerSupply_Oem m_power_supply_oem; IPowerSupply_Upgrade m_power_supply_upgrade; IPowerSupply_SharedManagement m_shared_mgmt; private: // 协议名/物理通道(来自 .sr 静态属性) mc::engine::property RefChip{"RefChip"}; mc::engine::property PhysicalInterface{"PhysicalInterface"}; std::string get_active_interface() const; // 返回 PhysicalInterface // 协议相关的数据采集(按需覆写 start_monitor 等) void read_frequency_property(); void read_slow_property(); bool start_oob_management() override; // 启动带外数据采集 }; } // namespace dev #endif // ONE_POWER_XYZ_H ``` 对应的 `MC_REFLECT` 注册(`one_power.cpp` 末尾),把接口成员映射到 `bmc.dev.*` 接口名: ```cpp MC_REFLECT(dev::OnePowerXyz, ((RefChip, "RefChip"))((PhysicalInterface, "PhysicalInterface")) ((m_power_supply, "bmc.dev.PowerSupply")) ((m_power_supply_control, "bmc.dev.PowerSupply.Control")) ((m_power_supply_metrics, "bmc.dev.PowerSupply.Metrics")) ((m_power_supply_status, "bmc.dev.PowerSupply.Status")) ((m_power_supply_log_collection, "bmc.dev.PowerSupply.LogCollection")) ((m_power_supply_oem, "bmc.dev.PowerSupply.Oem")) ((m_power_supply_upgrade, "bmc.dev.Upgrade")) ((m_shared_mgmt, "bmc.dev.SharedManagement"))) ``` > [!NOTE]说明 > > - 若协议型号只支持部分接口,可在 `MC_OBJECT`/`MC_REFLECT`/`.dds`/`.sr` 中同步裁剪; > - 如需温度数值、告警状态等属性,无需新增 `Cooling` 等“额外接口”:温度数值在 `PowerSupply.Metrics`(`EnvTemperatureCelsius` 等),告警/风扇状态位在 `PowerSupply.Status`,见 [2.5](#25-电源与风扇支持的能力)。 #### 关键说明 **1. MC_OBJECT 宏的参数:** - **第 1 个**:类名(如 `OnePowerXyz`) - **第 2 个**:对象类型名(电源为 `"OnePower"`,与 `.dds` 的 `Objects` 键名/`DeviceCategory` 对应) - **第 3 个**:对象路径模板(`${SlotNumber}` 为属性占位,实际槽位号由 `.sr` 下发) - **第 4 个**:对象组合的接口列表(按型号能力增删) **2. 接口选择原则:** | 接口 | 必需性 | 说明 | |------|--------|------| | `PowerSupply` | 必需 | 电源基础信息 | | `PowerSupply.Control` | 常见 | 工作/休眠模式、复位、风扇最小 PWM 等控制 | | `PowerSupply.Metrics` | 常见 | 电压/电流/功率/温度/风扇转速等指标 | | `PowerSupply.Status` | 常见 | 在位与各类告警/风扇状态 | | `PowerSupply.LogCollection`/`Oem`/`Upgrade`/`SharedManagement` | 可选 | 日志、私有能力、升级、共享管理 | | `PowerSupply.Capacitor`/`DualInputs`/`DualChannel` | 按型号 | 超级电容、双路输入、双通道电源 | --- ### 3.4 实现电源主对象(one_power.cpp) 电源主对象的实现重点有三处:**协议工厂表**(`get_protocol_map`)、**生命周期**(`init/start/stop`)、**数据采集**(`start_oob_management` 与周期读取)。其余公共逻辑(属性更新分发、监控定时器管理、升级、BMC 主从等)复用 `OnePowerBase`,参考实现:`drivers/psu/pmbus/one_power.cpp`。 #### 协议工厂表与生命周期 ```cpp // one_power.cpp(节选,示意) #include "one_power.h" #include #include #include #include #include // 新协议实现(libraries/xyz,若有) namespace dev { // 协议工厂表:协议名字符串 -> 具体协议对象(构造参数为 mc::dict&,包含芯片/总线信息) #define DEFINE_PS_PROTOCOL(name, ClassType) \ {name, [](mc::dict& data) -> std::unique_ptr { \ return std::make_unique(data); \ }} static const ps_protocol_map_t xyz_protocol_map = { DEFINE_PS_PROTOCOL("pmbus_xyz", pmbus_xyz), // ...支持多个协议/厂商变种时在此追加 }; const ps_protocol_map_t& OnePowerXyz::get_protocol_map() const { return xyz_protocol_map; } // init:from_variant 装载 .sr 静态属性,并解析 RefChip 引用(协议访问硬件的通道) bool OnePowerXyz::init(mc::mutable_dict& csr_object, const mc::dict& connector) { m_self = this; try { OnePowerXyz::from_variant(csr_object, *this); // 装载 SlotNumber/Protocol/静态属性 m_ref_obj = RefChip.get_value().as(); if (m_ref_obj == nullptr) { elog("OnePowerXyz init FAILED: RefChip ref_object is NULL"); return false; } } catch (const std::exception& e) { elog("OnePowerXyz init FAILED: ${exception}", ("exception", e.what())); return false; } return true; } void OnePowerXyz::from_variant(const mc::dict& d, dev::OnePowerXyz& obj) { mc::from_variant(d, obj); } // start:创建协议 -> 初始化/启动接口 -> 评估并启动带外采集 bool OnePowerXyz::start() { // 1. 按 .sr 的 PhysicalInterface(协议名)创建协议对象,失败不阻断上线 init_protocol(get_active_interface(), m_power_supply.SlotNumber.get_value().as()); // 2. 接口对象 init(base)/start():start 时向 base 注册“属性名->属性值”更新回调 m_power_supply.init(this); m_power_supply_control.init(this); m_power_supply_metrics.init(this); m_power_supply_status.init(this); m_power_supply_log_collection.init(this); m_power_supply_oem.init(this); m_power_supply_upgrade.init(this); // ...各接口 start() 统一在协议就绪后调用(参考 pmbus 实现) // 3. 主从/共享电源场景:按 ControlOwner 建立 BMC 主从监听,再评估是否启动采集 setup_oob_management(); evaluate_oob_management(); return true; } bool OnePowerXyz::stop() { teardown_oob_management(); // 断开主从监听、停止带外采集 m_power_supply.stop(); m_power_supply_control.stop(); m_power_supply_metrics.stop(); m_power_supply_status.stop(); m_power_supply_oem.stop(); m_power_supply_upgrade.stop(); return true; } std::string OnePowerXyz::get_active_interface() const { return PhysicalInterface.get_value().as(); // 例:"pmbus_xyz" } } // namespace dev ``` > [!NOTE]说明 > > - `init_protocol()` 由 `OnePowerBase` 实现:按协议名查 `get_protocol_map()` 创建协议对象,并用 `RefChip` 关联的芯片完成总线访问准备;`reinit_protocol()` 可在运行期按“厂商+型号”切换具体协议实现; > - `setup_oob_management()/evaluate_oob_management()` 由 `OnePowerBase` 提供:无主从(`ControlOwner=0`)时协议就绪即开始采集;有主从(`ControlOwner=1`)时仅主 BMC 的 Active 态采集; > - 协议就绪后的首次采集入口是虚函数 `start_oob_management()`(协议驱动实现),见下。 #### 数据采集(start_oob_management 与周期读取) 协议就绪后的带外数据采集入口为 `start_oob_management()`(协议驱动实现),示意如下: ```cpp // 启动带外数据采集:首次带重试读取产品信息 + 启动周期采集(示意,参考 OnePowerPmbus) bool OnePowerXyz::start_oob_management() { if (!is_protocol_ready()) { ilog("OnePowerXyz protocol not ready, skip data collection"); return false; } // 1. 启动时带重试读取产品信息,保证设备树尽早出现非零关键值 get_dynamic_data("firmware_version", 3); get_dynamic_data("manufacturer", 3); get_dynamic_data("model", 3); get_dynamic_data("serial_number", 3); get_dynamic_data("rated_power_watts", 3); // ... get_dynamic_data("input_voltage", 5); get_dynamic_data("output_voltage", 5); // 2. 启动周期采集(500ms 定时器,由 OnePowerBase::start_monitor 管理) start_monitor(mc::make_shared(this)); reinit_protocol(); return true; } // 周期回调(示意):500ms 高频 + 分帧读取,参考 OnePowerPmbus::read_frequency_property() void OnePowerXyz::read_frequency_property() { get_dynamic_data("input_power_watts", 1); // 健康事件:告警状态位直接分发给 Status 接口 auto [ev, health_failed] = m_ps_protocol->get_health_event(); if (!health_failed) { update_property("vout", ev.output_voltage_fault); update_property("iout", ev.output_current_fault); update_property("temperature", ev.temper_fault); update_property("input", ev.input_voltage_fault); update_property("fans_1_2", ev.fan_fault); update_property("cml", ev.cml_fault); update_property("mfr_specific", ev.mfr_specific_status); update_property("other", ev.other_fault); } // 每 6 次(约 3s)读取一组动态指标:电压/电流/温度/风扇转速等 static uint8_t cnt = 0; if (++cnt >= 6) { get_dynamic_data("output_power_watts", 1); get_dynamic_data("input_current_amps", 1); get_dynamic_data("output_current_amps", 1); get_dynamic_data("env_temperature_celsius", 1); get_dynamic_data("primary_chip_temperature_celsius", 1); get_dynamic_data("psu_fan_speed_rpm", 1); cnt = 0; } } // 慢速属性:每约 5s 读取控制数据/设备模式等(示意) void OnePowerXyz::read_slow_property() { auto control = m_ps_protocol->get_ps_control_data(); if (control.has_value()) { m_power_supply_control.SleepMode = control->sleep_mode; m_power_supply_control.WorkMode = control->work_mode; update_property("normal_and_redundancy_supported", mc::variant(control->normal_and_redundancy_supported ? 1 : 0)); } get_dynamic_data("equipment_mode", 1); get_dynamic_data("rated_power_watts", 1); } ``` > [!NOTE]说明 > > - `get_dynamic_data(属性名, 重试次数)` 由 `OnePowerBase` 实现:按“属性名”调用协议库对应方法,成功后经 `update_property()` 分发给在 `start()` 中注册的各接口实现(接口侧再把 `snake_case` 属性名映射到自身属性,见 [3.5](#35-复用与补充接口实现))。大多数属性无需协议驱动自己写 if-else 分发; > - 控制类方法(`set_power_work_mode`/`reset`/`set_sleep_mode`/风扇最小 PWM 等)已在 `OnePowerBase` 中统一转发给协议库,主对象内无需重复实现,除非新协议需要特殊处理; > - 轮询节奏建议与 PMBus 驱动保持一致(500ms 高频、约 3s/5s 分帧慢速),新协议可覆写 `start_monitor()/stop_monitor()` 调整。 #### 生命周期小结 | 阶段 | 关键动作 | 实现位置 | |------|---------|---------| | `init()` | `from_variant` 装载 `.sr` 静态属性并解析 `RefChip` | 协议驱动主对象 | | `start()` | `init_protocol()` 创建协议对象 → 接口 `init/start`(注册更新回调)→ `setup_oob_management()`/`evaluate_oob_management()` | 协议驱动主对象 + `OnePowerBase` | | 采集 | `start_oob_management()`:首次读取 + `start_monitor()` 周期采集 | 协议驱动覆写 + `OnePowerBase` | | `stop()` | `teardown_oob_management()` → 接口 `stop()`(注销回调) | 协议驱动主对象 | **启动流程:** 1. `from_variant()` 装载 `.sr` 静态属性(槽位、协议、接口静态配置),解析 `RefChip` 引用 2. `init_protocol()`:按 `.sr` 的 `PhysicalInterface` 从协议工厂表创建协议对象并绑定芯片 3. 各接口对象 `init(base)`、`start()`:向 `OnePowerBase` 注册“属性名→属性”更新回调 4. `setup_oob_management()`:无主从直接放行;有主从则监听 BMC Active/Standby 状态 5. `evaluate_oob_management()` → 协议就绪时调用 `start_oob_management()` 开始采集 --- ### 3.5 复用与补充接口实现 #### 核心要点 电源各接口实现类位于 `drivers/psu/common/interface/`(`IPowerSupply`、`IPowerSupply_Control/Metrics/Status/LogCollection/Oem/Upgrade`、`IPowerSupply_SharedManagement` 等),**所有协议电源共享**,通常无需为新协议重写。每个接口实现类的职责是:继承对应的 `dev::gen` 基类,向 `OnePowerBase` 注册更新回调,把“协议返回的 `snake_case` 属性名”映射为接口自身的属性。 以 `IPowerSupply_Metrics` 为例(摘自仓库实际代码): ```cpp // interface/power_supply/i_metrics.h class IPowerSupply_Metrics : public mc::engine::interface { public: void init(OnePowerBase* base_ptr); // 保存 base 指针 void start(); // 注册指标更新回调 void stop(); // 注销回调 bool update_metrics(std::string_view property, const mc::variant& info); private: OnePowerBase* m_base; }; // interface/power_supply/i_metrics.cpp namespace dev { void IPowerSupply_Metrics::start() { register_metrics_handler(); } void IPowerSupply_Metrics::init(OnePowerBase* base_ptr) { m_base = base_ptr; } void IPowerSupply_Metrics::register_metrics_handler() { if (!m_base) { elog("register_metrics_handler failed, OnePowerBase is null"); return; } // 向公共基类注册更新回调:属性名 -> 更新本接口属性 m_base->register_update_interface(this, [this](std::string_view property, const mc::variant& info) -> bool { return update_metrics(property, info); }); } bool IPowerSupply_Metrics::update_metrics(std::string_view property, const mc::variant& info) { if (property == "input_power_watts") { InputPowerWatts = info.as(); return true; } if (property == "input_voltage") { InputVoltage = info.as(); return true; } // output_power_watts / output_voltage / env_temperature_celsius / psu_fan_speed_rpm ... return false; } } // namespace dev MC_REFLECT(dev::IPowerSupply_Metrics) // 单参数反射注册,无需列出 gen 基类 ``` **关键要点:** - 接口实现类用**双模板参数**继承:`mc::engine::interface`,不要直接 `class Impl : public gen::Base`; - `MC_REFLECT(dev::Xxx)` 写在实现 `.cpp` 末尾(单参数形式); - 属性名采用 `snake_case` 字符串(如 `input_power_watts`),与协议/基类 `get_dynamic_data()` 使用的名字一致;更新属性后框架自动对外发信号,无需手动通知上层; - 如果某协议对接口方法有特殊处理(如控制方法差异大),在协议库实现类中覆写对应虚方法即可,接口层不变。 #### 补充新属性/新能力 适配中若需要暴露新属性,正确路径是: 1. **先在 `dmc/` 契约中定义**:在 `dmc/intf/bmc/dev/PowerSupply*.json` 增加属性/方法(改契约先改 dmc); 2. **同步 `gen/`**:人工在 `gen/include/device_tree/interface/` 增加/修改对应基类属性(并同步 `gen/src/`),与 `dmc` 契约保持一致——当前仓库没有自动生成工具,不会自动重新生成; 3. **在对应接口实现中映射**:`update_xxx()` 增加属性名分支(或控制方法覆写); 4. **配置下发**:静态值写进型号 `.sr` 对应接口段,动态值在协议库/驱动采集逻辑中读取。 > [!NOTE]说明 > 厂商私有/未标准化属性优先放到 `PowerSupply.Oem` 相关能力中,避免污染通用接口;风扇部件(非 PSU 内置风扇)的接口实现见 `drivers/fan/huawei/interface/`(`IFan`、`IFans`、`IFan_Control`、`IFan_PWMChannel` 等),实现方式与本节的电源接口一致。 --- ### 3.6 实现 ABI 导出 ABI(Application Binary Interface)是驱动 `.so` 与 devmon 交互的标准接口:每个驱动 `.so` 导出一个 `register_device_driver()` 符号,返回 `device_driver_t` 数组。结构体与函数类型定义见 `include/devmon/driver_abi.h`。 #### 代码示例:`psu_abi.cpp`(XYZ 协议电源) ```cpp #include #include #include "one_power.h" #ifndef DEVICE_DRIVER_NAME #define DEVICE_DRIVER_NAME "psu_xyz" // 与 .sr 的 Compatible、协议名对应 #endif using namespace dev; extern "C" { driver_handle_t create_one_power(void* service, const char* name) { try { if (service == nullptr || name == nullptr) { return nullptr; } auto* device = new OnePowerXyz(); device->set_service(static_cast(service)); device->set_object_name(name); return device; } catch (const std::exception& e) { elog("create_one_power failed: ${error}", ("error", e.what())); return nullptr; } } status_t init_one_power(driver_handle_t device, void* csr_object, void* connector) { if (device == nullptr || csr_object == nullptr || connector == nullptr) { return STATUS_ERROR; } auto* device_object = static_cast(device); mc::mutable_dict* csr_object_ptr = static_cast(csr_object); mc::dict* connector_ptr = static_cast(connector); return device_object->init(*csr_object_ptr, *connector_ptr) ? STATUS_OK : STATUS_ERROR; } status_t start_one_power(driver_handle_t device) { if (device == nullptr) { return STATUS_ERROR; } return static_cast(device)->start() ? STATUS_OK : STATUS_ERROR; } status_t stop_one_power(driver_handle_t device) { if (device == nullptr) { return STATUS_ERROR; } static_cast(device)->stop(); return STATUS_OK; } // device_name 与 .sr 的 Unit.Type(电源为 "PSU")对应 device_driver_t one_power_device_driver = {.device_name = "PSU", .ctor = create_one_power, .init = init_one_power, .start = start_one_power, .stop = stop_one_power}; device_driver_t psu_device_driver[] = {one_power_device_driver}; status_t register_device_driver(device_driver_t** device_driver, uint8_t* count) { *device_driver = psu_device_driver; *count = sizeof(psu_device_driver) / sizeof(psu_device_driver[0]); return STATUS_OK; } } ``` #### 关键说明 - 所有 ABI 函数必须用 `extern "C"` 包装,确保符号可被 devmon 按 C 方式加载; - 每个设备类型需要 4 个函数:`create`、`init`、`start`、`stop`(`device_driver_t` 还支持可选的 `dump`); - `device_name` 与 `.sr` 的 `Unit.Type` 对应(电源为 `"PSU"`,风扇部件为 `"Fans"`/`"Fan"`/`"FanType"`),`DEVICE_DRIVER_NAME` 与 `.sr` 的 `Compatible`、协议工厂表名称对应; - 一个 `.so` 可注册多个设备类型:风扇驱动 `fan_abi.cpp` 一次注册 `Fans`/`Fan`/`FanType` 3 个条目,`register_device_driver` 返回 `count = 3`; - `register_device_driver` 是框架调用的唯一入口符号。 --- ### 3.7 配置构建编译 电源驱动的构建沿用仓库 meson 体系(`drivers/psu/meson.build` 先编 `common` 公共库,再编各协议驱动)。以 `pmbus` 为例(`drivers/psu/pmbus/meson.build`): ```meson # 公共库(drivers/psu/common/meson.build):one_power_base + 全部接口实现编入 libPsu_common libpsu_common = static_library('Psu_common', psu_common_sources, ...) # 协议驱动:先静态库,再 link_whole 公共库打成动态库 libpsu_pmbus_static = static_library( 'psu_pmbus', files('one_power.cpp', 'psu_abi.cpp'), include_directories: include_dirs, dependencies: [dev_deps, libpsu_common_dep, libpmbus_dep], install: false, ) libpsu_pmbus = shared_library( 'psu_pmbus', include_directories: include_dirs, name_prefix: 'lib', name_suffix: 'so', install: true, install_dir: drivers_install_dir, # 驱动安装目录(框架定义) link_whole: [libpsu_common, libpsu_pmbus_static], dependencies: [dev_deps, libpsu_common_dep, libpmbus_dep], ) ``` 若新增协议驱动目录 `drivers/psu/xyz`,还需在 `drivers/psu/meson.build` 增加 `subdir('xyz')`;若配套新增协议库 `libraries/xyz`,需在 `libraries/meson.build` 注册并让驱动依赖它。 #### 关键说明 - 库名即驱动 SO 文件名(`libpsu_pmbus.so`),与 `.sr` 的 `Compatible`/`DEVICE_DRIVER_NAME` 对齐; - `install_dir` 使用 `drivers_install_dir` 变量(框架定义);`build_tests` 开启时仓库会把驱动拷贝到该目录(`custom_target` 的 `cp` 逻辑),便于本地联调; - 公共库 `libPsu_common` 通过 `link_whole` 全量打入协议驱动,保证各接口实现符号随 `.so` 一起导出; - 依赖关系要明确列出(`dev_deps`、`libpsu_common_dep`、协议库依赖等),避免链接错误。 --- ## 4. 最佳实践建议 ### 4.1 代码规范 #### 命名规范 | 类型 | 规范 | 示例 | |------|------|------| | 对象类名 | 对象类型/协议相关 | `OnePowerPmbus`、`OnePowerXyz`(主对象);`IPowerSupply_Metrics`(接口实现) | | 文件名 | 与对象对应 | `one_power.h/.cpp`、`psu_abi.cpp`、`one_power_base.h/.cpp` | | 成员变量 | `m_` 前缀 | `m_ps_protocol`、`m_property_query_timer` | | 协议库类名 | 协议/型号相关 | `pmbus`、`pmbus_FP1420`、`pmbus_qb900` | | 常量 | 大写+下划线 | `PSU_CONTROL_OWNER_YES`、`BMC_ROLE_ACTIVE` | #### 日志规范 - **启动/停止**:使用 `ilog` - **错误**:使用 `elog` - **调试信息**:使用 `dlog` - **日志要包含上下文信息** ```cpp ilog("OnePowerXyz ${slot} started, protocol=${protocol}", ("slot", m_power_supply.SlotNumber)("protocol", get_active_interface())); ``` #### 错误处理 - 所有可能失败的操作都要检查返回值 - 使用`try-catch`捕获异常 - 记录详细的错误信息 ```cpp try { auto value = m_ps_protocol->get_input_voltage(); if (!value.has_value()) { elog("Failed to get input voltage"); return false; } } catch (const std::exception& e) { elog("Exception caught: ${error}", ("error", e.what())); return false; } ``` --- ### 4.2 性能优化 #### 定时任务间隔 - 根据数据变化频率设置不同的更新间隔,避免不必要的通信开销 - **快速变化数据**:0.5秒(500ms) - 电压、电流、功率、温度、状态 - **慢速变化数据**:5秒(5000ms) - 产品信息、配置信息 **实际应用示例(`OnePowerBase::start_monitor` 定时回调示意):** ```cpp // 500ms 定时器,回调内区分快慢属性(参考 OnePowerPmbus 实现) m_property_query_timer->timeout.connect([this]() { read_frequency_property(); // 每次 500ms:功率、健康事件等 static uint8_t slow_cnt = 0; // 慢属性:约每 10 次(5s)读取 if (++slow_cnt >= 10) { read_slow_property(); slow_cnt = 0; } }); m_property_query_timer->set_single_shot(false); m_property_query_timer->start(mc::milliseconds(500)); ``` #### 内存管理 - 优先使用智能指针(`unique_ptr`、`shared_ptr`) - 及时清理定时器等资源 **定时器资源管理:** ```cpp // 清理定时器 if (m_property_query_timer) { m_property_query_timer->stop(); m_property_query_timer.reset(); } ``` #### 协议优化 - 批量请求减少通信次数 - 缓存不变的数据(如产品信息) - 失败时使用重试机制(带指数退避) ### 4.3 测试建议 #### 单元测试 - 测试每个接口的功能 - 测试异常情况处理 - 使用 mock 对象模拟协议 ```cpp // 1) 接口映射单测:验证“snake_case 属性名 -> 接口属性”的分发逻辑(无需硬件) TEST(i_power_supply_metrics, update_metrics_mapping) { dev::IPowerSupply_Metrics metrics; EXPECT_TRUE(metrics.update_metrics("input_power_watts", mc::variant(100.0))); EXPECT_TRUE(metrics.update_metrics("input_voltage", mc::variant(220.0))); // 校验 InputPowerWatts / InputVoltage 属性已更新... } // 2) 协议层单测:mock 底层总线(参考 tests/libraries/smbus/chip_mock.*), // 直接验证协议类(如厂商 PMBus 变种)的属性读取/命令解析 TEST(pmbus_variant, read_input_voltage) { MockChip chip; // 打桩 I2C/SMBus 读写 mc::dict data{{"chip", ...}}; pmbus_xyz proto(data); // 厂商变种协议对象 auto v = proto.get_input_voltage(); EXPECT_TRUE(v.has_value()); } ``` > [!NOTE]说明 > > - 电源主对象 `init()` 依赖 `.sr` 下发并解析 `RefChip` 引用,完整生命周期(create→init→start→stop)联调建议用 `AddDevice` 加载型号 `.sr` 验证(见《快速上手》); > - 风扇/电源控制类方法最终落到协议库,单测时在协议层打桩即可,不必构造真实对象。 #### 集成测试 - 测试完整的生命周期:`create` → `init` → `start` → `stop` - 测试与实际硬件的通信 - 测试长时间运行的稳定性 **风扇相关测试重点:** - 测试风扇转速监控的准确性 - 测试风扇转速控制的响应时间 - 测试风扇故障检测和告警 - 测试多风扇同时控制 - 测试风扇转速与温度的联动 #### 回归测试 - 每次修改后重新测试基本功能 - 检查是否影响其他电源驱动 - 验证 Redfish 接口数据正确 ### 4.4 风扇管理最佳实践 > 风扇管理分两类场景,实现位置不同: > > 1. **PSU 内置风扇**:BMC 侧通常只设置**最小 PWM 下限**(`SetFanMinPWM`),实时调速由电源固件按温度完成;转速/状态经 `Metrics.FanSpeedRPM`、`Status.Fans_1_2`/`Fans_3_4` 上报; > 2. **风扇部件(风扇框/模块)**:对象路径与接口见 [2.2.2](#222-drivers-目录---设备驱动实现),由 `drivers/fan/huawei` 的 `Fans`/`Fan` 对象配合上层散热策略实现 PWM 通道与转速闭环,接口实现方式与电源接口一致。 #### PSU 内置风扇控制要点 - 通过 `PowerSupply.Control` 设置风扇最小 PWM(占空比),**取值范围与含义以 `dmc` 契约和厂商规格书为准**,不要在驱动里猜测单位或做 rpm 换算; - 若确需直接调速(测试/调试),使用协议库 `set_fan_speed_percent()`;生产场景建议仅用“最小 PWM”+固件自动调速; - 读取风扇状态时以**健康事件 + Status 接口**为准,不要在驱动对象里自行拼读寄存器位(厂商私有解析放协议库子类)。 #### 温度联动调速 - PSU 内置风扇的温度联动由**电源固件**完成;驱动侧保证温度指标(`EnvTemperatureCelsius` 等)与 `FanSpeedRPM` 采集及时、`.sr` 静态配置正确即可; - 风扇框/风扇模块的温度联动属于上层散热策略,通过 `Fans` 对象(如 `SetPWM`)下发目标占空比,不在单驱动内做闭环。 #### 风扇故障处理 周期回调中健康事件已把风扇故障位分发给 `Status` 接口(例如 `update_property("fans_1_2", ev.fan_fault)` → `Status.Fans_1_2`),驱动只需保证: ```cpp // 周期回调(示意):健康事件 -> Status 接口,含风扇故障位 auto [ev, health_failed] = m_ps_protocol->get_health_event(); if (!health_failed) { update_property("fans_1_2", ev.fan_fault); // 驱动把故障位交给 Status 接口 update_property("vout", ev.output_voltage_fault); // ... } ``` - 告警判定与防抖(连续 N 次才置位)由 `IPowerSupply_Status` 内部使用 `mc::debounce` 完成,无需驱动重复实现; - 风扇故障后的“告警/日志”由上层(日志与告警接口)消费,驱动不直接处理自愈策略。 #### 风扇监控频率建议 | 监控项 | 建议频率 | 说明 | |-------|---------|------| | **健康事件(含风扇故障位)** | 500ms | 随快采周期,风扇故障能及时反映到 `Status.Fans_1_2` | | **风扇转速 FanSpeedRPM** | 约 3s | 随指标分帧读取(`read_frequency_property` 内分帧) | | **产品信息/慢速属性** | 约 5s 或启动时读取 | 避免频繁占用总线 | > [!NOTE]说明 > 监控频率只是建议值。实际以各协议驱动的采集实现为准,且要避免在慢速 I2C 总线上对多路电源同时高频采集造成拥塞(必要时错峰)。 #### PMBus 命令注意事项 **1. 命令兼容性与厂商变种** 不同厂商/型号的 PMBus 实现存在差异,**不要在主对象里直接读写寄存器**;差异点收敛到 `libraries/pmbus` 的协议子类中,通过覆写虚方法表达,再注册进协议工厂表: ```cpp // libraries/pmbus/pmbus_xyz.h(示意):厂商变种协议子类 class pmbus_xyz : public pmbus { public: explicit pmbus_xyz(mc::dict& data) : pmbus(data) {} // 厂商差异点:覆写风扇转速/私有属性读取等 std::optional get_psu_fan_speed_rpm() override; std::optional get_firmware_version() override; }; // drivers/psu/pmbus/one_power.cpp:注册进协议工厂表 // DEFINE_PS_PROTOCOL("psu_xyz", pmbus_xyz), ... ``` **2. 数据格式处理** PMBus 的 LINEAR11/LINEAR16 等格式解析已封装在 `libraries/pmbus`(如 `get_linear_11()`/`get_linear_16()`),驱动层直接拿到物理量,**无需重复实现**;个别厂商编码不同时在协议子类内处理。 **3. 错误重试机制** 属性读取带重试能力由 `OnePowerBase::get_dynamic_data(属性名, 重试次数)` 提供: ```cpp // 读取失败自动重试(例如启动阶段读产品信息,失败率高的场景给 3-5 次) bool ok = get_dynamic_data("psu_fan_speed_rpm", 3); ``` 总线级读写失败、超时等由 `chip/smbus` 层处理并上报日志;驱动无需自行 `sleep` 重试。若某个属性需要更精细的失败处理,可在协议子类中覆写对应方法并返回 `std::nullopt`,由调用侧按空值处理。 ## 结语 南向风扇电源驱动适配是一项系统性工作,需要对硬件特性、PMBus 协议、软件架构都有深入理解。本文档提供了一套完整的适配流程和代码示例,涵盖了电源管理和内置风扇控制的方方面面。 **关键要点回顾:** **电源管理:** - 契约先行:接口/对象路径以 `dmc/`(`intf`+`path`)为准;`gen/` 下的 `dev::gen` 基类当前需人工随 dmc 同步修改(仓库内无自动生成工具链) - 驱动按协议族组织(PMBus/CANbus/SMC…),公共能力(`OnePowerBase`、`IPowerSupply_*`)下沉 `drivers/psu/common` 供各协议复用 - 支持电压、电流、功率、温度、风扇转速等指标的周期采集,以及工作/休眠模式、复位、风扇最小 PWM、固件升级等控制 - 状态/告警经 `PowerSupply.Status` 上报(含防抖),共享电源场景支持 BMC 主从(Active/Standby)下的带外管理启停 **风扇管理:** - PSU 内置风扇:`Metrics.FanSpeedRPM` + `Status.Fans_1_2`/`Fans_3_4` + `Control.SetFanMinPWM`,调速策略由固件完成 - 风扇部件(风扇框/模块):由 `drivers/fan/huawei` 的 `Fans`/`Fan`/`FanType` 对象提供(PWM 通道/转速/状态等接口) - 厂商差异(命令/数据格式)收敛到 `libraries/pmbus` 等协议库子类,避免散落在驱动对象中 **开发建议:** - 适配新电源型号先判断适配形态:已有协议通常只需新增 `.sr/.dds` 与协议变种,无需新建驱动目录 - 仔细阅读厂商提供的 PMBus 命令规格书,注意不同型号扩展命令差异 - 依托 `get_dynamic_data()` 重试与接口更新回调,实现完善的错误处理 - 采用合理的监控频率(快慢分帧),避免 I2C 总线拥塞 - 定期进行长时间稳定性测试与回归测试 实际适配中还会遇到各种具体问题,欢迎大家积极在社区沟通交流和贡献。 --- # 总线芯片驱动开发指南 > URL: https://openubmc.cn/docs/zh/latest/component_driver/general_guide/bus_chip_driver_guide.html > Language: zh # 总线芯片驱动开发指南 ## 概述 总线芯片驱动是南向硬件访问的底座,把 CSR 拓扑里的每个 Bus / Chip 节点变成可访问对象。本文面向需要在 `component_drivers` 中新增或修改总线、芯片驱动的开发人员。 > [!NOTE]说明 > > 相对旧稿删除了已不存在的 `libhas/`、`Hi182x` / `SMBusHuawei` 示例和未落地的 SPI 教程。现行实现以 `device_topo`、`device_manager` 与 ABI 为准,并以 I2C、PCA9545 作为可对照源码的模板。 ## 环境要求 硬件要求:交叉编译需要目标板与 `libsoc_adapter`。原生测试可用打桩驱动,不强制真实总线硬件。 软件要求:`component_drivers` 源码(以 `drivers/internal/`、`drivers/bus/`、`drivers/chip/` 为准)、meson 构建、能运行 `tests/drivers/` 单测。 权限要求:具备源码编译与单测执行权限。 ## 目录 - [概述](#概述) - [环境要求](#环境要求) 1. [范围与术语](#1-范围与术语) 2. [架构与调用链](#2-架构与调用链) 3. [目录与关键文件](#3-目录与关键文件) 4. [基类与 ACCESS_DATA_S](#4-基类与-access_data_s) 5. [CSR 配置与对象命名](#5-csr-配置与对象命名) 6. [新增 Bus 驱动](#6-新增-bus-驱动) 7. [新增 Chip 驱动](#7-新增-chip-驱动) 8. [对外接口、级联与错误处理](#8-对外接口级联与错误处理) 9. [构建与注册](#9-构建与注册) 10. [检查清单与常见问题](#10-检查清单与常见问题) --- ## 1. 范围与术语 总线芯片驱动不描述一块完整板卡。上层网卡、GPU、电源、Connector、Accessor 通过统一接口读写 I2C、Hisport、MUX、EEPROM 等器件。 | 术语 | 含义 | |------|------| | CSR | 部件自描述(`.sr` / `.dds` / 测试用 json)。含 `ManagementTopology` 与 `Objects`。 | | 设备树对象 | `drivers/bus/`、`drivers/chip/` 中继承 `mc::engine::object` 的类,对 devmon 暴露 ABI 与属性。 | | 内部器件对象 | `drivers/internal/` 中继承 `bus_base` / `chip_base` 的类,执行真正的硬件 I/O。 | | HAS | 历史称呼。现行实现就是内部器件层 + `ACCESS_DATA_S`,没有独立 `libhas/` 目录。 | | ABI | `include/devmon/driver_abi.h` 的 C 接口。每个设备树 SO 导出 `register_device_driver`。 | | `device_manager` | 内部对象单例工厂,按 class_name 创建、按 object_name 索引。 | | `device_topo` | devmon 侧拓扑引擎:解析 CSR、创建内部对象、dlopen SO、接线 `left_bus` / `host_bus` / `left_chip`。 | | host_bus | 根物理总线。`Interface_Chip` 加锁必须锁它。 | | left_bus | 芯片直连的那条总线,可能是 I2cMux 虚总线。 | | left_chip | 前级 MUX / SMC 等,访问前会 `open_channel`。 | 协议栈(NCSI、MCTP、PMBUS)在 `libraries/`,不属于本指南。CSR1 专用类型(GPIO、JTAG、CPLD 等)由 `COMPONENT_DRIVERS_ENABLE_UNIDEV` 控制,不写入默认检查清单。 --- ## 2. 架构与调用链 ### 2.1 双层对象 每个总线 / 芯片都有两套对象,职责不能混: ```text 设备树对象(libI2c.so / libPca9545.so) I2c_object / pca9545_object └── Interface_*(属性 + 对外方法) └── 裸指针 ──► 内部对象 内部对象(libInternal.so,device_manager 持有 shared_ptr) bus_i2c / chip_pca9545 └── DRIVER_I2C::I2c 等底层驱动(生产环境来自 libsoc_adapter) ``` 设备树 `init()` **不会 new 内部对象**,只按 `object_name` 从 `device_manager::find_object` 取已有实例。内部对象由 `device_topo` 在解析 CSR 时先 `create_bus` / `create_chip`。 ### 2.2 加载顺序 ```mermaid sequenceDiagram participant CSR as CSR participant Topo as device_topo participant Mgr as device_manager participant SO as libXxx.so ABI participant App as Interface_Chip CSR->>Topo: ManagementTopology + Objects Topo->>Mgr: create_bus / create_chip Mgr->>Mgr: 工厂 lambda + 内部对象 init(csr) Topo->>SO: ctor(service, name) Topo->>SO: init(csr) → find_object + from_variant Topo->>Topo: set_left_bus / set_host_bus / set_left_chip Topo->>SO: start() App->>App: BusLock(host_bus) App->>Mgr: block_read / bit_write ... ``` 类型名不是 CSR 里的单独字段,而是 **对象名第一个 `_` 之前的子串**: | 对象名 | 抽出的类型 | 内部类 | 设备树 SO | |--------|------------|--------|-----------| | `I2c_3` | `I2c` | `bus_i2c` | `libI2c.so` | | `Hisport_0` | `Hisport` | `bus_hisport` | `libHisport.so` | | `I2cMux_Pca9545_PCA9545_4` | `I2cMux` | `bus_i2c_mux` | `libI2cMux.so` | | `Pca9545_PCA9545` | `Pca9545` | `chip_pca9545` | `libPca9545.so` | | `Chip_MCU1` | `Chip` | `chip_base` 或 `chip_mcu_switch` | `libChip.so` | | `Eeprom_IEU` | `Eeprom` | `chip_eeprom` | `libEeprom.so` | `device_name`、工厂 key、对象名前缀三者必须一致(区分大小写)。写成 `PCA9545_0` 会去找工厂 `"PCA9545"`,创建失败。 ### 2.3 BlockIO 调用路径 ```text Interface_Chip::BlockIORead → BusLock(*host_bus) // 锁根物理总线,不是 I2cMux → chip_base::block_read → data_access → pack ACCESS_DATA_S → input() ├─ 同 topo_path 的 follower 转给 master(ChipMerge) ├─ 有 left_chip: │ 类名 "smc" → forward_by_front_chip │ 否则 open_channel(left_bus) → left_chip->output() → close_channel └─ 只有 left_bus:bus->read / write → 物理驱动(如 DRIVER_I2C::I2c) ``` > [!WARNING]注意 > > `open_channel` 失败必须返回,不能继续访问,否则可能写到错误通道。 ### 2.4 默认支持的类型(CSR2) **总线**:`I2c`、`Hisport`、`I2cMux`;打开 `chipv2` 时还有 `I2cOverHisport`。 **芯片**:`Chip`(`drivers/chip/complex/` 通用对象)、`Pca9545`、`Pca9555`、`Lm75`、`Eeprom`、`Ads78`、`Ina`、`Smc`。 `I2cMux` 是虚总线:只保存 `ChannelId`,`read` / `write` / `bus_lock` / `bus_unlock` 全部抛错。它的 `get_id()` 返回通道号,供 PCA9545 等 MUX 的 `open_channel` 使用。 --- ## 3. 目录与关键文件 ```text component_drivers_blue/ ├── drivers/ │ ├── bus/ # 总线设备树对象(每个类型一个 SO) │ │ ├── i2c/ i2c_mux/ hisport/ i2c_over_hisport/ │ ├── chip/ # 芯片设备树对象 │ │ ├── interface/ # Interface_Chip、BlockIO、SelfDescriptionRecord │ │ ├── pca9545/ pca9555/ lm75/ eeprom/ ads78/ powermeter/ smc/ complex/ │ ├── internal/ # 内部器件 + device_manager → libInternal.so │ │ ├── hasdef.h # ACCESS_DATA_S │ │ ├── manager.h/.cpp │ │ ├── bus/bus_base/ bus_i2c/ bus_i2c_mux/ bus_hisport/ ... │ │ └── chip/chip_base/ chip_pca9545/ chip_eeprom/ ... │ ├── accessor/ scanner/ connector/ │ └── csr1/ # CSR1 设备树对象(unidev) ├── gen/include/device_tree/interface/ │ ├── Bus/I2c.h Hisport.h I2cMux.h │ ├── Chip.h # bmc.dev.Chip 基础属性与 IO 方法 │ └── Chip/Pca9545.h Ina.h BlockIO.h SelfDescriptionRecord.h ├── include/devmon/driver_abi.h └── tests/drivers/bus/ chip/ internal/ ``` 对照源码时优先看: - 物理总线模板:`drivers/internal/bus/bus_i2c/` + `drivers/bus/i2c/`。 - 虚总线模板:`drivers/internal/bus/bus_i2c_mux/` + `drivers/bus/i2c_mux/`。 - MUX 芯片模板:`drivers/internal/chip/chip_pca9545/` + `drivers/chip/pca9545/`。 - 通用芯片:`drivers/chip/complex/`(工厂 key `"Chip"`)。 - CSR 样例:`tests/drivers/chip/eeprom/00000001040302044498.json`。 --- ## 4. 基类与 ACCESS_DATA_S ### 4.1 ACCESS_DATA_S 定义在 `drivers/internal/hasdef.h`,是总线 `read` / `write` 的唯一入参。芯片层由 `chip_base::pack_access_data` 填充。 | 字段 | 含义 | |------|------| | `addr` | 器件地址。I2C 路径只取低 8 位,CSR 里通常是 **8-bit 写地址**(7-bit `<< 1`)。 | | `offset` / `offset_width` | 寄存器或 EEPROM 偏移,及偏移Byte数(0~4)。`offset == 0xffffffff` 走 I2C / Hisport **扩展读**(无寄存器寻址,`in_buffer` 作写前缀)。 | | `length` | 读写长度。 | | `in_buffer` / `out_buffer` | 写数据 / 读回数据。 | | `mask` | 位操作掩码。I2C 写路径不用它;`bit_read` 在读回后按掩码提取。 | | `read_time_out` / `write_time_out` | 超时。 | | `drv_write_delay` | 写后延时(ms),对应 CSR `DrvWriteDelay`。 | | `optype` | `0` 读 / `1` 写。 | | `protocol_flag` | `I2cOverHisport` 上 `== 2` 走 MCTP;I2C 上 `== 0x02` 走 SMBus。 | | `cs` | SPI over Hisport 片选。 | 返回值:`HAS_OK`(0)成功,`HAS_ERR`(-1)或底层驱动错误码表示失败。 ### 4.2 bus_base 路径:`drivers/internal/bus/bus_base/bus.h`。 物理总线必须覆盖: ```cpp virtual uint32_t read(ACCESS_DATA_S& input) = 0; virtual uint32_t write(ACCESS_DATA_S& input) = 0; virtual void bus_lock() = 0; virtual void bus_unlock() = 0; virtual uint8_t get_id(); // 默认 0;I2C 返回 Id,I2cMux 返回 ChannelId ``` 工厂创建成功后应调用 `set_class_name("I2c")` 等,供 `build_topo_path()` 生成 `BusType:BusId`。还有 `set_left_chip`、业务锁 `BusLockInfo`、单次最大传输长度。 I2C 组帧(`bus_i2c::format_tx_buf`): ```text [addr 1B] [offset 大端,OffsetWidth Byte] [payload length Byte] ``` `OffsetWidth = 0` 时没有偏移段(PCA9545 切通道)。普通读 `re_read_cnt = 1`;扩展读重试 3 次。 ### 4.3 chip_base 路径:`drivers/internal/chip/chip_base/chip.h`。基类已实现默认 I/O,子类只覆盖差异。 可覆盖: | 类别 | 函数 | 何时覆盖 | |------|------|----------| | 配置 / 自检 | `chip_init` / `chip_test` / `chip_reset` | 写阈值、复位脚等。`chip_init` 在拓扑接好后的 `start()` 调用,不是 `init(csr)`。 | | 通道 | `open_channel` / `close_channel` | MUX 必须成对覆盖。 | | 访问 | `bit_*` / `block_*` / `block_write_read` / `combo_block_write_read` | 分页、换算、RMW。 | | 透传 | `forward_by_front_chip` / `get_class_name` | SMC 等前级。`get_class_name` 需返回稳定短名(如 `"lm75"`、`"smc"`)。 | | 插件 | `plugin_request` | 默认:unidev 走 Lua,否则写 `0x1f` 再读 129 Byte。 | | 诊断 | `dump` | 默认输出读写计数与错误历史 CSV。 | `init(csr)` 解析 `Address`、`OffsetWidth`、`AddrWidth`、超时、块大小、间隔、重试、`DrvWriteDelay`。遇到 `$sync:` / `$ref:` / `<=` 等绑定表达式时跳过,留默认值,由设备树 property 系统再绑。 > [!NOTE]说明 > > `WriteRetryTimes` / `ReadRetryTimes` 会写入成员,但 `data_access` 与 `bus_i2c` **当前不按它们重试**。真正用到写间隔的是 EEPROM 分页写的 `WriteInterval`。 CSR2 的 `Interface_Chip` 运行时只把 `DrvWriteDelay` 的变更写回内部对象。改 Address 等 property 不会自动同步到 `chip_base`(CSR1 对象才普遍绑了 `update_*`)。 --- ## 5. CSR 配置与对象命名 没有合法 CSR,`device_topo` 不会 `create_*`,设备树 `init` 里 `find_object` 必然失败。 ### 5.1 最小结构 ```json { "ManagementTopology": { "Anchor": { "Buses": ["I2c_3"] }, "I2c_3": { "Chips": ["Pca9545_Mux0"] }, "Pca9545_Mux0": { "Buses": ["I2cMux_Pca9545_Mux0_0"] }, "I2cMux_Pca9545_Mux0_0": { "Chips": ["Eeprom_Board"] } }, "Objects": { "I2c_3": { "Id": 3, "Speed": 0, "Mode": 0, "SlaveAddr": 0, "UseSmbus": false }, "Pca9545_Mux0": { "Address": 226, "OffsetWidth": 0, "AddrWidth": 1, "WriteTmout": 100, "ReadTmout": 100, "ChannelNum": 4 }, "I2cMux_Pca9545_Mux0_0": { "ChannelId": 0 }, "Eeprom_Board": { "Address": 174, "OffsetWidth": 2, "AddrWidth": 1, "WriteTmout": 100, "ReadTmout": 100, "RwBlockSize": 32, "WriteInterval": 20 } } } ``` 完整板卡样例见 `tests/drivers/chip/eeprom/00000001040302044498.json`(Hisport → PCA9545 → 多路 I2cMux → EEPROM / PCA9555 / Connector)。 ### 5.2 接线规则(device_topo) - 芯片 `left_bus` = 父总线。 - 有父芯片时:`left_chip` = 父芯片,`host_bus` = 父芯片的 host_bus(根物理总线)。 - 无父芯片:`host_bus` = 父总线。 - 子总线 `left_chip` = 当前芯片。 访问 `Eeprom_Board` 时:`left_bus` 是 I2cMux(不能 lock),`left_chip` 是 PCA9545(先 `open_channel`),`host_bus` 是 `I2c_3`(加锁并真正发事务)。 ### 5.3 属性约定 **I2c**(`bmc.dev.Bus.I2c`):`Id`、`Speed`(0→100k、1→400k、2→3400k,其它值当 kHz)、`Mode`、`SlaveAddr`、`UseSmbus`。 **I2cMux**(`bmc.dev.Bus.I2cMux`):只有 `ChannelId`,**没有 `Id`**。不是所有总线都必须声明 `Id` 属性。 **Hisport**(`bmc.dev.Bus.Hisport`):`Id`、`BusNum`、`RegNum`、收发 / 标志寄存器、最大长度等,见 `gen/include/device_tree/interface/Bus/Hisport.h`。 **Chip 基础**(`bmc.dev.Chip`):`Address`、`OffsetWidth`、`AddrWidth`、`WriteTmout`、`ReadTmout`、`RwBlockSize`、`WriteInterval`、`ReadInterval`、`WriteRetryTimes`、`ReadRetryTimes`、`DrvWriteDelay`。 PCA9545 另有 `ChannelNum`。`Chip` + `"SwitchSupported": true` 时内部对象为 `chip_mcu_switch`。 --- ## 6. 新增 Bus 驱动 以下以物理总线为模板。虚总线(通道选择)为可选路径,请对照 `I2cMux`:只解析 `ChannelId`,`read` / `write` / `lock` / `unlock` 抛 `invalid_op_exception`。 ### 6.1 准备文件清单 新增如下路径: ```text gen/include/device_tree/interface/Bus/{Name}.h drivers/internal/bus/bus_{name}/{name}.h {name}.cpp meson.build drivers/bus/{name}/ {name}.h {name}.cpp {name}_abi.cpp meson.build interface/i_{name}.h i_{name}.cpp ``` 另外还要改:`drivers/internal/manager.h` 的 include、`manager.cpp` 注册工厂;`drivers/internal/bus/meson.build` 与 `drivers/bus/meson.build` 增加 `subdir`。 ### 6.2 新增设备树接口 `MC_INTERFACE` 路径:`"bmc.dev.Bus.{Name}"`。物理总线一般有 `Id`;虚总线按硬件语义定义(如 `ChannelId`)。 ```cpp namespace dev::gen { class MC_API I2c : public mc::engine::interface { public: MC_INTERFACE("bmc.dev.Bus.I2c") // 须与 CSR 抽出的类型名一致 property Id; property Speed; property Mode; property SlaveAddr; property UseSmbus; }; } ``` ### 6.3 实现内部对象 继承 `bus_base`,`init` 从 CSR 取属性并创建底层驱动。`read` / `write` 只处理 `ACCESS_DATA_S`。 ```cpp class bus_i2c : public bus_base { public: bool init(mc::mutable_dict& csr_object); // 解析 CSR 并创建底层驱动 uint32_t read(ACCESS_DATA_S& input) override; uint32_t write(ACCESS_DATA_S& input) override; uint8_t get_id() override; void bus_lock() override; void bus_unlock() override; private: uint8_t m_id{}; uint32_t m_speed = 100; std::unique_ptr m_i2c_drv; }; ``` 测试 / 原生构建链入 `tests/drivers/bus/i2c/drivers/i2c.cpp` 打桩;交叉编译链 `libsoc_adapter`。不要在驱动里直接 `new` 一套与工厂无关的总线对象。 ### 6.4 实现设备树对象 ```cpp class I2c_object : public mc::engine::object { public: MC_OBJECT(I2c_object, "I2c_object", "${object_name}", (Interface_I2c)) bool init(mc::mutable_dict& csr_object, const mc::dict& connector); Interface_I2c m_interface_i2c; }; ``` `MC_OBJECT` 第二参数在仓内不完全统一(`I2c_object` 为 `"I2c_object"`,`Hisport_object` 为 `"Hisport"`)。**运行时匹配靠 ABI `device_name` 与对象名前缀**,新增时建议与工厂 key 一致(如 `"Hisport"`)。 `init` 只绑定内部对象: ```cpp auto& manager = dev::device_manager::get_instance(); // 内部对象已由 device_topo 创建,这里只按 object_name 查找 auto bus_variant = manager.find_object(csr_object["object_name"].as(), dev::object_type::bus); auto bus_ptr = std::get>(bus_variant); m_interface_i2c.m_bus_i2c = static_cast(bus_ptr.get()); m_interface_i2c.from_variant(csr_object); ``` `from_variant` 用 `contains()` 再 `as()`,缺省走接口类构造函数里的默认值。`.cpp` 末尾: ```cpp MC_REFLECT(dev::I2c_object, ((m_interface_i2c, "bmc.dev.Bus.I2c"))) MC_REFLECT(dev::Interface_I2c) ``` 接口类持有内部对象的 **裸指针**;生命周期由 `device_manager` 的 `shared_ptr` 管理。 ### 6.5 实现 ABI `extern "C"` 中实现 `create_*` / `init_*` / `start_*` / `stop_*`,可选 `dump_*`。 > [!WARNING]注意 > > 禁止把 C++ 异常漏到 C 边界,否则 ABI 调用方进程可能崩溃。 ```cpp device_driver_t i2c_device_driver = { .device_name = "I2c", // 须与对象名前缀、工厂 key 一致 .ctor = create_i2c, .init = init_i2c, .start = start_i2c, .stop = stop_i2c }; status_t register_device_driver(device_driver_t** device_driver, uint8_t* count) { *device_driver = i2c_device_driver_list; *count = sizeof(i2c_device_driver_list) / sizeof(i2c_device_driver_list[0]); return STATUS_OK; // create / init / start / stop 内须捕获异常后再返回 } ``` `ctor` 原型是 `(void* service, const char* object_name)`,不是旧文档里的 `create(config_json)` / `get_device_driver()`。 ### 6.6 注册工厂 ```cpp m_bus_factories["I2c"] = [](mc::mutable_dict& csr_data) -> std::shared_ptr { auto ptr = std::make_shared(); if (ptr && ptr->init(csr_data)) { ptr->set_class_name("I2c"); // 供 topo_path 使用,须与工厂 key 一致 return ptr; } return nullptr; // init 失败则不注册 }; ``` 同名对象已存在时 `create_bus` 直接返回表中实例(跨 position 共享总线)。meson 与单测注册见[构建与注册](#9-构建与注册)。 ### 6.7 验证新增结果 完成本章与第 9 章后,确认: 1. 内部单测 `tests/drivers/bus/{name}/` 的 `read` / `write` 通过。 2. ABI `init` 后 `find_object` 能取到内部对象。 3. 产物 `lib{Name}.so` 已拷贝到 `drivers_install_dir`。 --- ## 7. 新增 Chip 驱动 通用寄存器类芯片可只复用 `Chip`(`complex_object` + `chip_base`),不必新 SO。需要 MUX、分页、换算或专有属性时再新增类型。 ### 7.1 确认是否复用 Chip 先确认不能复用 `"Chip"` / `complex`,再新增类型。所有 Chip 设备树对象都必须包含 `Interface_Chip`(`drivers/chip/interface/`)。专有属性再加 `Interface_{Name}`。`meson.build` 通过 `chip_interface_sources` 链入公共 `i_chip.cpp`。 ### 7.2 准备文件清单 新增如下路径: ```text gen/include/device_tree/interface/Chip/{Name}.h # 仅专有属性时需要 drivers/internal/chip/chip_{name}/{name}.h {name}.cpp meson.build drivers/chip/{name}/ {name}.h {name}.cpp {name}_abi.cpp meson.build interface/i_{name}.h i_{name}.cpp # 有专有接口时 ``` ### 7.3 新增设备树接口 基础属性在 `bmc.dev.Chip`,不要重复定义。PCA9545 只额外声明通道数: ```cpp namespace dev::gen { class MC_API Pca9545 : public mc::engine::interface { public: MC_INTERFACE("bmc.dev.Chip.Pca9545") // 专有接口名,基础属性仍走 bmc.dev.Chip property ChannelNum; }; } ``` EEPROM **没有** `Chip/Eeprom.h`。分页用基础属性 `RwBlockSize` / `WriteInterval`,自描述用 `bmc.dev.Chip.SelfDescriptionRecord`。 ### 7.4 实现内部对象 ```cpp class chip_pca9545 : public chip_base { public: bool init(mc::mutable_dict& csr_object); int32_t open_channel(std::shared_ptr bus) override; int32_t close_channel(std::shared_ptr bus) override; int32_t chip_reset() override; }; ``` `init` 必须先调基类: ```cpp bool chip_pca9545::init(mc::mutable_dict& csr_object) { // 先解析 Address、超时等基础字段 if (!chip_base::init(csr_object)) { return false; } if (csr_object.contains("ChannelNum")) { m_channel_num = csr_object["ChannelNum"].as(); } return true; } ``` 通道切换按下游虚总线的 `get_id()` 写控制寄存器: ```cpp uint8_t write_reg = static_cast(1 << bus->get_id()); block_write(0, {write_reg}, empty, error); // OffsetWidth=0,无寄存器寻址 ``` 关闭通道写 `0x00`。`open_channel` 失败用 `MC_THROW` 或返回 `HAS_ERR`,不要继续 I/O。 按需覆盖的其它模式: - **PCA9555**:`bit_write` 先把 config 寄存器对应位配成输出,再 RMW 输出寄存器。 - **EEPROM**:`block_read` / `block_write` 按页拆分,写完 `sleep(WriteInterval)`。 - **LM75**:`start()` 里调 `chip_init()` 写温度阈值;覆盖 `bit_read` 做换算。 ### 7.5 实现设备树对象 ```cpp class pca9545_object : public mc::engine::object { public: MC_OBJECT(pca9545_object, "Pca9545", "${object_name}", (Interface_Pca9545)(Interface_Chip)) bool init(mc::mutable_dict& csr_object, const mc::dict& connector); std::string dump(); Interface_Pca9545 m_interface_pca9545; Interface_Chip m_interface_chip; }; ``` `init` 中把同一个 `chip_pca9545*` 赋给各接口的裸指针,再分别 `from_variant`。反射: ```cpp MC_REFLECT(dev::pca9545_object, ((m_interface_chip, "bmc.dev.Chip")) ((m_interface_pca9545, "bmc.dev.Chip.Pca9545"))) ``` 需要硬件侧初始化时实现 `start()`(如 `eeprom_object::start` 解析 header,`lm75_object` 调 `chip_init()`)。总线类 `start` / `stop` 多为空操作。 ### 7.6 实现 ABI 与工厂 `device_name` 用 `"Pca9545"`。芯片 SO 建议实现 `dump`(调用 `chip_base::dump`)。工厂: ```cpp m_chip_factories["Pca9545"] = [](mc::mutable_dict& csr_data) -> std::shared_ptr { auto ptr = std::make_shared(); if (ptr && ptr->init(csr_data)) { return ptr; } return nullptr; // init 失败则不注册 }; ``` 通用 `"Chip"` 工厂在 `SwitchSupported == true` 时创建 `chip_mcu_switch`,否则 `chip_base`。meson 与单测注册见[构建与注册](#9-构建与注册)。 ### 7.7 验证新增结果 完成本章与第 9 章后,确认: 1. 内部 `init` 先调用了 `chip_base::init`。MUX 的 `open_channel` / `close_channel` 成对生效。 2. ABI `device_name`、工厂 key、对象名前缀三者一致。 3. 单测 `tests/drivers/chip/{name}/` 通过,且 ABI `init` 能 `find_object`。 --- ## 8. 对外接口、级联与错误处理 ### 8.1 Interface_Chip(上层真正调用的 API) 声明在 `gen/include/device_tree/interface/Chip.h`,实现 `drivers/chip/interface/i_chip.cpp`。 | 方法 | 内部实现 | 说明 | |------|----------|------| | `BitIORead(offset, length, mask)` | `bit_read` | 读后按 mask 提取,length 仅 1 / 2 / 4。 | | `BitIOWrite(...)` | `bit_write` | 按 mask 做读改写。 | | `BlockIORead(offset, length)` | `block_read` | 连续块读。 | | `BlockIOWrite(offset, buffer)` | `block_write` | 连续块写。 | | `BlockIOWriteRead(indata, read_length)` | `block_write_read`,offset=`0xffffffff` | 扩展写读。 | | `BlockIOComboWriteRead(...)` | 先 `block_write` 再 `block_read` | 两次独立事务。 | 每个方法都是: ```cpp BusLock lock(*m_chip->get_host_bus()); // 锁根物理总线,不要锁 I2cMux auto result = m_chip->block_read(...); if (result != HAS_OK) { MC_THROW(mc::method_call_exception, "BlockIORead failed, ..."); } ``` `BusLock`(`drivers/chip/bus_lock.h`)构造时 `bus_lock()`,析构时 `bus_unlock()` 且不抛异常。 `bmc.kepler.Chip.BlockIO` 的 `PluginRequest` 走 `plugin_request`。Lua 插件设计见《Chip 器件插件机制详细设计说明书》。 Accessor 通过 CSR 的 `Chip` + `Offset` + `Mask` + `Size` 调 BitIO,不在芯片 SO 内实现轮询。 ### 8.2 级联与 ChipMerge `chip_base::input` / `output` 沿 `left_chip` 递归。首次 I/O 按 `topo_path` 注册到 `ChipMergeRegistry`:相同路径的后续实例成为 follower,I/O 转到 master。路径形如: ```text Hisport:0@Pca9545:e2w1_0-I2cMux:4@Eeprom:aew1_2 ``` 多份 CSR 描述同一颗物理芯片时会合并。调试时 `dump()` 统计记在 master 上。 ### 8.3 错误处理 - 内部 I/O:返回 `HAS_OK` / 非 0;失败写入 `m_last_access_error` 与最多 10 条 `m_error_history`。 - 设备树 / 接口:`MC_THROW` + `elog`;ABI 捕获后返回 `STATUS_ERROR`。 - `open_channel` 失败:记录并返回,不继续 `output`。 - 参数:空 CSR、空 `in_buffer`、非法 `offset_width` 在对应层抛 `invalid_arg_exception` / `invalid_op_exception`。 - 日志:`tlog` / `dlog` / `ilog` / `wlog` / `elog`,格式 `"${key}"` + `("key", value)`。 --- ## 9. 构建与注册 内部实现链接进 **一个** `libInternal.so`。每种设备树类型一个 SO:`libI2c.so`、`libPca9545.so`。测试通过 `dlopen` 加载 SO,因此必须把产物拷到 `drivers_install_dir`。 必须采用 core 静态库 + `link_whole` 共享库,禁止在测试侧重复编译驱动源文件。 ```meson # 源码只编译进 core,避免测试再编一份 xxx_core_lib = static_library( 'XxxCore', xxx_sources, include_directories: xxx_include_dirs, dependencies: [internal_dep, libmcpp_deps], cpp_args: ['-Os', '-ffunction-sections', '-fdata-sections'], pic: true, install: false, ) # 空 sources + link_whole,生成运行时 SO xxx_lib = shared_library( 'Xxx', [], dependencies: [internal_dep, libmcpp_deps], link_whole: [xxx_core_lib], link_args: common_link_args, name_prefix: 'lib', name_suffix: 'so', install: true, install_dir: drivers_install_dir, ) # 单测链接 core,不要再列驱动 .cpp xxx_test_dep = declare_dependency( link_whole: xxx_core_lib, dependencies: [internal_dep, libmcpp_deps], ) ``` 测试拷贝使用 stamp 文件。`cp` 建议 `--remove-destination`。现行部分 meson 仍写 `cp -f`,新增请按本节模板。 还需要按顺序完成: 1. 在 `drivers/internal/bus/meson.build` 或 `chip/meson.build` 增加 `subdir('bus_xxx')`,并加入 `bus_sources` / `chip_sources`。 2. 在 `drivers/bus/meson.build` 或 `drivers/chip/meson.build` 增加 `subdir('xxx')`。 3. 在 `manager.h` include 头文件,在 `init_factory_maps()` 注册,总线调用 `set_class_name`。 单测放 `tests/drivers/bus/{name}/`、`tests/drivers/chip/{name}/`、`tests/drivers/internal/`。ABI 测试 `dlopen` 对应 `libXxx.so`,`test()` 声明 `depends: all_copy_targets` 并设置 `LD_LIBRARY_PATH`。 ### 9.1 验证构建结果 构建完成后确认:`ninja` 能生成 `libInternal.so` 与 `libXxx.so`;测试目录能加载到拷贝后的 SO;`LD_LIBRARY_PATH` 指向 `drivers_install_dir`。 --- ## 10. 检查清单与常见问题 ### 10.1 新增 Bus - [ ] 已新增 `gen/include/device_tree/interface/Bus/{Name}.h`,并声明 `MC_INTERFACE("bmc.dev.Bus.{Name}")`。 - [ ] 已在 `drivers/internal/bus/bus_{name}/` 实现纯虚函数(虚总线除 `get_id` 外应抛错)。 - [ ] 已在 `drivers/bus/{name}/` 实现设备树对象、`from_variant`、ABI、`MC_REFLECT`。 - [ ] meson 已在 internal 与 drivers 两处增加 `subdir`,并采用 core + `link_whole` 与 copy stamp。 - [ ] 已在 `manager.h` / `manager.cpp` 注册工厂,调用 `set_class_name`,且 key 与 `device_name`、对象名前缀一致。 - [ ] CSR 的 `Objects` 与拓扑同名,物理总线属性与接口一致。 - [ ] 内部 `read` / `write` 单测通过,ABI `init` 能 `find_object`。 ### 10.2 新增 Chip - [ ] 已确认不能复用 `"Chip"` / `complex`。 - [ ] 仅在有专有属性时新增 `Chip/{Name}.h`,并且挂了 `Interface_Chip`。 - [ ] 内部 `init` 先调 `chip_base::init`。MUX 已覆盖 `open_channel` / `close_channel`。 - [ ] 设备树 `init` 只 `find_object`。需要硬件配置时在 `start()` 调 `chip_init`。 - [ ] ABI `device_name`、工厂 key、对象名前缀一致,并建议实现 `dump`。 - [ ] meson 与 manager 注册与第 9 章一致。 - [ ] CSR 的 `Address` 为 8-bit 写地址,`OffsetWidth` 与手册一致(PCA9545 常为 0,EEPROM 常为 2)。 ### 10.3 常见问题 | 现象 | 原因 | 处理 | |------|------|------| | `Unsupported chip/bus type` 或 create 返回 nullptr | 未注册工厂,或对象名前缀与 key 不一致。 | 检查 `extract_device_type` 与 `m_*_factories`。 | | `bus/chip not found` | 拓扑未 `create_*`,或设备树 `init` 早于内部对象。 | 检查 CSR 拓扑与 object_name。 | | 段错误 / 空 host_bus | 未接线或锁了 I2cMux。 | 确认 `set_host_bus`;锁 `get_host_bus()`。 | | 读写到错误通道 | `open_channel` 失败仍继续,或 `ChannelId` 错。 | 失败即返回;核对 I2cMux 的 `ChannelId`。 | | 配置不生效 | `from_variant` 字段名与 CSR 不一致;或改了 property 但 CSR2 未回写内部对象。 | 对齐字段;Address 等以内部 `init(csr)` 为准。 | | 链接 / 测试找不到 SO | meson 未 copy,或测试未依赖 `all_copy_targets`。 | 按第 9 章补 copy 与 `LD_LIBRARY_PATH`。 | | ABI 进程崩溃 | 异常穿过 `extern "C"`。 | 全部 catch 并返回状态码。 | 调试一次失败的 BlockIO,按顺序查:对象名能否抽出正确类型 → `device_manager` 是否已有内部对象 → `host_bus` / `left_bus` / `left_chip` 是否接上 → `open_channel` 是否成功 → `addr` / `offset_width` 是否与手册一致。 --- # 设备驱动开发指南 > URL: https://openubmc.cn/docs/zh/latest/component_driver/general_guide/device_driver_develop_guide.html > Language: zh # 设备驱动开发指南 ## 1. 概述 本指南面向Component Drivers项目的设备驱动开发者,提供从设计到实现的完整开发流程。Component Drivers是一个基于C++17的硬件组件驱动程序框架,采用分层架构设计,支持多种设备类型和通信协议。 ### 1.1 项目特点 - **分层架构**:设备树对象层 + 内部器件对象层 + 协议通信层 - **多设备支持**:PCIe网卡、GPU、传感器、总线设备、访问器等 - **协议集成**:NCSI over MCTP、IMU、MCTP、多厂商协议支持 - **配置驱动**:基于设备树的配置管理和反射机制 - **标准化ABI**:统一的驱动注册和生命周期管理 - **统一管理**:采用device_manager单例模式管理所有设备对象 - **智能指针**:使用shared_ptr自动管理设备生命周期 ### 1.2 支持的设备类型 | 设备类型 | 实现示例 | 协议支持 | 厂商支持 | |----------|----------|----------|----------| | PCIe网卡 | `rp1000_card`, `hi182x_card`, `hi1822_fc_card` | NCSI over MCTP, IMU | 网迅、华为海思等 | | PCIe GPU | `awm_m11p_card` | MCTP | 全志元芯等 | | 通用访问器 | `accessor` | 标准PCIe | 通用 | | 总线设备 | `bus_i2c`, `bus_hisport`, `bus_i2c_mux` | I2C, Hisport | 通用 | | 芯片设备 | `chip_pca9545`, `chip_lm75`, `chip_eeprom` | I2C协议 | 通用芯片 | | 扫描器 | `scanner` | 设备扫描 | 通用 | | 复合器件 | `complex` | 多协议组合 | 通用 | ### 1.3 设备对象系统 Component Drivers采用基于MC_OBJECT宏的设备对象模型,实现设备的层次化管理: #### 1.3.1 设备对象定义 设备对象通过MC_OBJECT宏定义其核心特征: ```cpp // 以华为海思 hi182x 网卡为例(完整定义见 drivers/pcie_nic_card/hisi/hi182x/hi182x_card.h) namespace dev { // 协议智能指针类型别名(与库中定义一致) using ncsi_over_mctp_hw_ptr = std::shared_ptr; using smbus_obj_ptr = mc::shared_ptr; using imu_ptr = std::shared_ptr; class hi182x_card : public mc::engine::object { public: MC_OBJECT( hi182x_card, "PCIeNicCard", "/bmc/dev/Systems/1/PCIeNicCard/${object_name}", (PCIeDevice)(PCIeDevice_PCIeFunction)(PCIeDevice_Oem)(PCIeDevice_Status)(PCIeCard)(PCIeCard_Oem) (PCIeCard_Metrics)(NetworkAdapter)(NetworkAdapter_FaultStatus)(Cooling)(NetworkAdapter_Oem)(Board) (PCIeDevice_Bandwidth)(NetworkAdapter_LogCollection)(Fru)) // 接口实例 - 组合多个接口实现复杂功能(类型即接口名,与 MC_OBJECT 中声明一致) PCIeDevice m_pcie_device; PCIeDevice_PCIeFunction m_pcie_device_pcie_function; NetworkAdapter m_network_adapter; PCIeCard m_pcie_card; Board m_board; Cooling m_cooling; NetworkAdapter_FaultStatus m_network_adapter_fault_status; PCIeDevice_Bandwidth m_pcie_device_bandwidth; NetworkAdapter_LogCollection m_network_adapter_log_collection; // 子设备集合(原始指针由框架通过 get_children() 管理,驱动只做类型转换) std::vector m_network_ports; // 协议实例(MCTP 使用 mc::shared_ptr,其余使用 std::shared_ptr) ncsi_over_mctp_hw_ptr m_ncsi_over_mctp_huawei; imu_ptr m_imu_obj; smbus_obj_ptr m_smbus_obj; mc::shared_ptr m_mctp_object; // 生命周期方法(实际签名) bool init(mc::mutable_dict& csr_object, const mc::dict& connector); bool start(); bool stop(); }; } // namespace dev ``` #### 1.3.2 设备对象层次结构 设备对象形成树状层次结构: ```shell /bmc/dev/ # 根节点 └── Systems/ # 系统节点 └── 1/ # 系统ID └── PCIeNicCard/ # 设备类型 └── {object_name}/ # 设备实例(由 ${object_name} 替换) ├── [PCIeDevice] # 接口:PCIe设备信息 ├── [NetworkAdapter] # 接口:网络适配器 ├── [PCIeCard] # 接口:PCIe卡信息 ├── [Board] # 接口:板卡信息 └── NicPort/ # 子设备 ├── 0/ # 端口0 │ ├── [NetworkPort] # 接口:网络端口 │ └── OpticalTransceiver/ # 光模块 │ └── [OpticalModule] └── 1/ # 端口1 ├── [NetworkPort] └── OpticalTransceiver/ └── [OpticalModule] ``` #### 1.3.3 接口系统 接口采用"自动生成 + 手动实现"的模式: | 命名空间 | 来源 | 职责 | 示例 | |---------|------|------|------| | **gen::** | 代码生成 | 接口基类定义 | `gen::PCIeDevice` | | **dev::** | 手工编写 | 厂商接口实现 | `dev::PCIeDevice` | | **子接口** | 手工编写 | 功能细分接口 | `NetworkPort_LinkInfo` | **接口组合示例**: ```cpp // PCIe网卡组合了多个接口 class hi182x_card { PCIeDevice m_pcie_device; // PCIe设备接口 PCIeDevice_PCIeFunction m_pcie_device_pcie_function; // PCIe功能接口(BDF/VID/DID) NetworkAdapter m_network_adapter; // 网络适配器接口 PCIeCard m_pcie_card; // PCIe卡接口 Board m_board; // 板卡信息接口 Cooling m_cooling; // 散热子接口(bmc.dev.Cooling) NetworkAdapter_FaultStatus m_network_adapter_fault_status; // 故障状态子接口 NetworkAdapter_LogCollection m_network_adapter_log_collection; // 日志收集子接口 PCIeDevice_Bandwidth m_pcie_device_bandwidth; // 带宽监控子接口 }; ``` #### 1.3.4 MC_REFLECT反射机制 MC_REFLECT实现属性的编译期反射和运行时动态访问: ```cpp // 1. 接口类继承 mc::engine::interface 并关联的 gen:: 基类 class PCIeDevice : public mc::engine::interface { public: std::string DeviceName; std::string VendorId; std::string DeviceId; uint8_t Bus, Device, Function; }; // 2. 设备对象注册反射信息:将成员与 D-Bus 接口名关联(与 hi182x_card.cpp 一致) MC_REFLECT(dev::hi182x_card, ((m_system_id, "SystemId"))((m_pcie_device, "bmc.dev.PCIeDevice")) ((m_pcie_device_pcie_function, "bmc.dev.PCIeDevice.PCIeFunction")) ((m_pcie_device_oem, "bmc.dev.PCIeDevice.Oem")) ((m_pcie_device_status, "bmc.dev.PCIeDevice.Status")) ((m_pcie_card, "bmc.dev.PCIeCard"))((m_pcie_card_oem, "bmc.dev.PCIeCard.Oem")) ((m_pcie_card_metrics, "bmc.dev.PCIeCard.Metrics")) ((m_network_adapter, "bmc.dev.NetworkAdapter")) ((m_network_adapter_fault_status, "bmc.dev.NetworkAdapter.FaultStatus")) ((m_cooling, "bmc.dev.Cooling"))((m_network_adapter_oem, "bmc.dev.NetworkAdapter.Oem")) ((m_board, "bmc.dev.Board"))((m_pcie_device_bandwidth, "bmc.dev.PCIeDevice.Bandwidth")) ((m_fru, "bmc.dev.Fru")) ((m_network_adapter_log_collection, "bmc.dev.NetworkAdapter.LogCollection"))) // 3. 运行时使用 mc::dict properties; mc::reflect::to_variant(card->m_pcie_device, properties); // 对象 -> JSON card->m_pcie_device.DeviceName = "NewCard"; // 直接访问属性 ``` ### 1.4 协议库系统 Component Drivers集成了多种通信协议,为设备驱动提供底层通信能力: #### 1.4.1 协议架构 ```mermaid flowchart LR subgraph "设备驱动层" Driver["设备驱动
hi182x_card"] end subgraph "协议库层" NCSI["NCSI
标准协议"] MCTP["MCTP
传输协议"] NOM["NCSI over MCTP
华为扩展"] IMU["IMU协议
IPMI接口"] end subgraph "传输层" PCIe["PCIe传输"] I2C["I2C/SMBus"] Socket["Socket通信"] end Driver -->|网卡管理| NOM Driver -->|设备信息| IMU NOM --> MCTP NOM --> NCSI MCTP --> PCIe MCTP --> I2C IMU --> I2C NCSI --> Socket ``` #### 1.4.2 NCSI协议 **NCSI (Network Controller Sideband Interface)** 是DMTF标准的网卡带外管理协议: **核心命令**: | 命令 | 代码 | 功能 | 用途 | |------|------|------|------| | GET_LINK_STATUS | 0x0A | 获取链路状态 | 监控链路UP/DOWN | | SET_MAC_ADDRESS | 0x0E | 设置MAC地址 | 配置网卡MAC | | ENABLE_VLAN | 0x0C | 启用VLAN | 配置VLAN过滤 | | GET_CAPABILITIES | 0x16 | 获取能力 | 查询控制器功能 | | OEM_COMMAND | 0x50 | 厂商命令 | 厂商扩展功能 | **使用示例**: ```cpp // NCSI 标准命令通过 ncsi_over_mctp_standard 提供,需基于 MCTP 对象构造 mc::shared_ptr mctp_obj = mc::make_shared(this, mctp::init_phy_addr(0x01, 0x00, 0x00), MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, ""); ncsi_over_mctp_standard ncsi(mctp_obj); // 获取链路状态 ncsi_link_status_info_t link_status; if (ncsi.get_link_status(DEFAULT_PACKAGE_ID, DEFAULT_CHANNEL_ID, &link_status)) { ilog("Link: ${status}, Speed: ${speed} Mbps", ("status", link_status.link_status ? "UP" : "DOWN")("speed", link_status.speed_mbps)); } // 获取能力信息 ncsi_capabilities_info_t capability; ncsi.get_capabilities(DEFAULT_PACKAGE_ID, DEFAULT_CHANNEL_ID, &capability); ``` #### 1.4.3 MCTP协议 **MCTP (Management Component Transport Protocol)** 是DMTF标准的管理组件传输协议: **消息类型**: - `MCTP_MESSAGE_TYPE_MCTP_CTRL` (0x00) - MCTP控制消息 - `MCTP_MESSAGE_TYPE_PLDM` (0x01) - PLDM消息 - `MCTP_MESSAGE_TYPE_NCSI` (0x02) - NCSI消息 - `MCTP_MESSAGE_TYPE_NVME` (0x04) - NVMe管理消息 - `MCTP_MESSAGE_TYPE_VDPCI` (0x7E) - PCIe厂商定义消息 **物理媒介**: - `PHY_MEDIUM_PCI` (0x0F) - PCIe绑定 - `PHY_MEDIUM_SMBUS` (0x02) - SMBus绑定 - `PHY_MEDIUM_SMBUS_OEM` (0x80) - SMBus OEM绑定 **使用示例**: ```cpp // MCTP 对象无默认构造函数,需传入父对象、物理地址、消息类型和位置 uint16_t phy_addr = mctp::init_phy_addr(bus, device, function); // 静态方法计算物理地址 mc::shared_ptr mctp_obj = mc::make_shared(this, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, ""); // 创建传输对象和端点对象,端点和传输就绪后回调初始化业务任务 mctp_obj->create_transport_and_endpoint(std::string(get_object_name()), [this]() { // 端点就绪后,启动 NCSI 等上层协议任务 }); // 发送请求(request 返回 bool,响应保存在 rsp 字符串中) mc::dict ctx = {{"timeout", 1000}}; std::vector request_data = {...}; // 填充请求数据 std::string rsp; if (mctp_obj->request(ctx, request_data, 1000, rsp)) { // 处理响应... } ``` #### 1.4.4 NCSI over MCTP协议 **NCSI over MCTP** 是华为扩展的混合协议,通过MCTP传输层发送NCSI命令: **架构优势**: | 特性 | NCSI | MCTP | NCSI over MCTP | |------|------|------|----------------| | 传输方式 | Socket | PCIe/I2C | MCTP传输NCSI | | OEM扩展 | 有限 | 丰富 | 丰富OEM命令 | | 性能 | 中等 | 高 | 高性能 | | 适用场景 | 标准网卡 | 通用管理 | 华为网卡 | **协议栈实现**: ```shell ncsi_over_mctp_huawei (华为OEM命令实现) ↓ ncsi_over_mctp_standard (标准NCSI命令实现) ↓ ncsi_over_mctp (基础封装) ↓ mctp (MCTP传输层) ``` **华为OEM命令**: | 命令 | 功能 | 用途 | |------|------|------| | `get_bdf` | 获取 BDF 信息 | 获取网卡所在总线/设备/功能号 | | `get_mac_addr` / `get_default_mac_addr` | 获取 MAC 地址 | MAC 地址管理 | | `get_chip_temp` / `get_om_temp` | 获取芯片/光模块温度 | 温度监控 | | `get_link_ability` / `get_link_info` | 获取链路能力/信息 | 链路状态查询 | | `get_dcbx_status` | 获取 DCBX 状态 | 数据中心桥接配置 | | `get_fault_state_code` | 获取故障状态码 | 故障诊断 | | `get_optical_module_info` | 获取光模块信息 | 光模块管理 | | `collect_logs_by_ncsi` / `collect_logs_by_new_cmd` | 收集日志 | 故障诊断 | | LLDP 系列(`enable/disable/get_lldp_*`) | 管理 LLDP 能力与发送 | 链路发现 | **使用示例**: ```cpp // 1. 创建 MCTP 对象(NCSI over MCTP 基于 MCTP 传输层) uint16_t phy_addr = mctp::init_phy_addr(m_pcie_device_pcie_function.BusNumber, m_pcie_device_pcie_function.DeviceNumber, m_pcie_device_pcie_function.FunctionNumber); mc::shared_ptr mctp_obj = mc::make_shared(this, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, ""); // 2. 通过 MCTP 对象构造华为扩展协议实例 ncsi_over_mctp_hw_ptr nom_hw = std::make_shared(mctp_obj); // 3. 获取链路信息(package_id/channel_id 为入参,信息写入出参指针) ncsi_link_info_t link_info; if (nom_hw->get_link_info(DEFAULT_PACKAGE_ID, DEFAULT_CHANNEL_ID, &link_info)) { ilog("Link width: ${width}, speed: ${speed}", ("width", link_info.link_width)("speed", link_info.link_speed)); } // 4. 获取芯片温度 uint16_t chip_temp = 0; if (nom_hw->get_chip_temp(DEFAULT_PACKAGE_ID, DEFAULT_CHANNEL_ID, &chip_temp)) { ilog("Chip temperature: ${temp}", ("temp", chip_temp)); } // 5. 在设备对象中,通常通过 mctp->create_transport_and_endpoint 回调中创建并绑定任务: mctp_obj->create_transport_and_endpoint(std::string(get_object_name()), [this, mctp_obj]() { m_ncsi_over_mctp_huawei = std::make_shared(mctp_obj); m_network_adapter.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, m_interval); }); ``` #### 1.4.5 IMU协议 **IMU (Inertial Measurement Unit)** 协议用于通过IPMI获取PCIe设备信息: **使用示例**: ```cpp // 创建IMU对象(无默认构造函数,需传入服务指针) imu_ptr m_imu_obj = std::make_shared(get_service()); // 准备请求 imu_pcie_device_req_t req = { .system_id = m_system_id, .socket_id = m_pcie_device.SocketId, .bus = m_pcie_device_pcie_function.BusNumber, .device = m_pcie_device_pcie_function.DeviceNumber, .function = m_pcie_device_pcie_function.FunctionNumber, .pci_info_address = VID_DID_ADDRESS, // VendorID + DeviceID .rlen = 4, }; // 获取设备信息(返回 std::optional>,小端序 VID/DID) auto info = m_imu_obj->get_info_from_imu(true, req); if (info && info->size() >= 4) { uint16_t device_id = (static_cast((*info)[3]) << 8) | (*info)[2]; uint16_t vendor_id = (static_cast((*info)[1]) << 8) | (*info)[0]; ilog("VID=0x${vid:04x}, DID=0x${did:04x}", ("vid", vendor_id)("did", device_id)); } ``` ### 1.5 驱动ABI接口 驱动通过标准的C风格ABI接口与devmon框架交互。ABI定义在`include/devmon/driver_abi.h`中: ```cpp // 设备驱动描述结构 struct device_driver { const char* device_name; // 设备名称(如 "PCIeNicCard") const driver_ctor ctor; // 创建函数 const driver_init init; // 初始化函数 const driver_start start; // 启动函数 const driver_stop stop; // 停止函数 driver_dump dump = nullptr; // 可选:设备状态转储 }; typedef struct device_driver device_driver_t; // 驱动SO导出的注册函数:返回驱动数组及其数量 status_t register_device_driver(device_driver_t** device_driver, uint8_t* count); ``` 驱动SO导出的是`register_device_driver`符号(而非`get_device_driver`),实现方式见 4.6 节示例。 ## 2. 架构设计 ### 2.1 分层架构概览 ```mermaid graph TB A[应用管理层
BMC管理应用、devmon服务] B[设备树对象层
配置管理、ABI接口、生命周期管理] C[设备管理层
device_manager单例管理] D[内部器件对象层
硬件操作、业务逻辑、资源管理] E[协议通信层
NCSI over MCTP、MCTP、IMU、SMBUS协议栈] F[物理传输层
PCIe传输、I2C传输、Socket通信] A -->|标准化ABI调用| B B -->|设备管理| C C -->|创建和管理| D D -->|协议绑定| E E -->|传输封装| F style A fill:#e1f5fe style B fill:#f3e5f5 style C fill:#fff9c4 style D fill:#e8f5e8 style E fill:#fff3e0 style F fill:#fce4ec ``` ### 2.2 设备树对象与内部器件对象关系 ```mermaid graph LR subgraph "设备树对象层" A[hi182x_card
PCIe网卡对象] B[PCIeDevice
接口对象] C[NetworkAdapter
接口对象] D[Board
接口对象] E[network_ports
子设备集合] end subgraph "设备管理层" F[device_manager
单例管理器] end subgraph "协议通信层" G[ncsi_over_mctp_huawei
协议实例] H[imu协议实例] end subgraph "内部器件对象层" I[Hi182xCardInternal
内部实现] J[硬件操作接口] K[业务逻辑处理] end A --> B A --> C A --> D A --> E A -.管理.-> F B --> G C --> G A --> H A --> I I --> J I --> K style A fill:#ffeb3b style F fill:#fff9c4 style G fill:#4caf50 style H fill:#ff9800 style J fill:#2196f3 ``` #### 2.2.1 职责分工 **设备树对象**: - 负责设备树配置管理和对外ABI接口 - 继承自`mc::engine::object`,支持设备树配置 - 包含接口类成员,用于属性管理和配置加载 - 实现`init()`, `start()`, `stop()`等生命周期方法 **内部器件对象**: - 负责具体的硬件操作和业务逻辑实现 - 继承自`bus_base`或`chip_base`基类 - 实现具体的读写、初始化、硬件自检等功能 - 管理底层驱动实例和硬件资源 ## 3. 开发流程 ### 3.1 开发准备 #### 3.1.1 环境要求 - **操作系统**:Linux (推荐Ubuntu 18.04+) - **编译器**:支持C++17的GCC 7.0+或Clang 5.0+ - **构建系统**:Meson 0.50+ - **依赖库**:libmcpp (自动管理) #### 3.1.2 源码结构 ```shell component_drivers/ ├── drivers/ # 驱动实现 │ ├── [device_type]/ # 设备类型目录 │ │ ├── [vendor]/ # 厂商实现目录 │ │ └── interface/ # 接口实现 │ └── internal/ # 内部器件对象 ├── gen/device_tree/interface/ # 生成的设备树接口 ├── libraries/ # 协议通信库 ├── include/devmon/ # 公共头文件 └── tests/ # 测试代码 ``` ### 3.2 新驱动开发步骤 ```mermaid flowchart TD A[步骤1: 需求分析和设计] --> B[步骤2: 设备树接口定义] B --> C[步骤3: 内部器件对象实现] C --> D[步骤4: 接口类实现] D --> E[步骤5: 设备对象实现] E --> F[步骤6: ABI接口实现] F --> G[步骤7: 构建配置] G --> H[编译测试] H --> I[集成测试] I --> J[部署运行] A1[确定设备类型
选择基类
协议选择
接口设计] -.-> A B1[定义属性
虚函数接口
反射配置] -.-> B C1[硬件操作逻辑
资源管理
状态控制] -.-> C D1[连接设备树接口
配置加载
内部对象管理] -.-> D E1[生命周期管理
子设备管理
协议集成] -.-> E F1[驱动注册
生命周期函数
错误处理] -.-> F G1[Meson配置
依赖管理
安装目录] -.-> G style A fill:#ffeb3b style B fill:#4caf50 style C fill:#2196f3 style D fill:#ff9800 style E fill:#9c27b0 style F fill:#f44336 style G fill:#607d8b ``` #### 步骤1: 需求分析和设计 1. **确定设备类型**:PCIe设备、I2C设备、传感器等 2. **选择基类**:继承相应的基类(`PCIeCard`, `bus_base`, `chip_base`等) 3. **协议选择**:确定需要的通信协议(NCSI, MCTP, IMU等) 4. **接口设计**:定义需要暴露的属性和方法 #### 步骤2: 设备树接口定义 在`gen/include/device_tree/interface/`中定义设备接口: ```cpp // gen/include/device_tree/interface/MyDevice.h #ifndef GEN_MY_DEVICE_INTERFACE_H #define GEN_MY_DEVICE_INTERFACE_H #include namespace dev::gen { class MC_API MyDevice : public mc::engine::interface { public: MC_INTERFACE("bmc.dev.MyDevice") // 设备属性定义 property DeviceName; property DeviceId; property Version; property IsEnabled; // 虚函数接口(如需要) virtual bool Initialize(); virtual bool GetStatus(); virtual void SetEnabled(bool enabled); }; } // namespace dev::gen #endif // GEN_MY_DEVICE_INTERFACE_H ``` **注意**: - 现在使用`dev::gen`命名空间 - 无需手动编写反射宏,框架自动处理 - 属性使用`property`模板定义 - 虚函数可以有默认实现 #### 步骤3: 内部器件对象实现 实现具体的硬件操作逻辑: ```cpp // drivers/internal/my_device/my_device_internal.h #ifndef MY_DEVICE_INTERNAL_H #define MY_DEVICE_INTERNAL_H #include #include #include class MyDeviceInternal { public: MyDeviceInternal() = default; ~MyDeviceInternal() = default; bool init(const mc::dict& config); bool start(); bool stop(); // 硬件操作接口 bool read_register(uint32_t offset, uint32_t& value); bool write_register(uint32_t offset, uint32_t value); bool get_device_status(); private: std::string m_device_name; uint8_t m_device_id; bool m_initialized = false; // 硬件资源管理 void* m_hardware_handle = nullptr; }; #endif // MY_DEVICE_INTERNAL_H ``` ```cpp // drivers/internal/my_device/my_device_internal.cpp #include "my_device_internal.h" #include bool MyDeviceInternal::init(const mc::dict& config) { try { m_device_name = config["DeviceName"].as(); m_device_id = config["DeviceId"].as(); // 硬件初始化逻辑 // m_hardware_handle = open_hardware_device(m_device_id); m_initialized = true; ilog("MyDevice initialized: ${name} (ID: ${id})", ("name", m_device_name)("id", m_device_id)); return true; } catch (const std::exception& e) { elog("Failed to initialize MyDevice: ${error}", ("error", e.what())); return false; } } bool MyDeviceInternal::read_register(uint32_t offset, uint32_t& value) { if (!m_initialized) { elog("Device not initialized"); return false; } // 实现具体的寄存器读取逻辑 // value = hardware_read(m_hardware_handle, offset); return true; } ``` #### 步骤4: 接口类实现 创建接口类,连接设备树接口和内部实现: ```cpp // drivers/my_device/interface/i_my_device.h #ifndef I_MY_DEVICE_H #define I_MY_DEVICE_H #include #include "../internal/my_device_internal.h" namespace dev { // MyDevice 默认值常量 constexpr uint8_t MY_DEVICE_DEFAULT_ID = 0; constexpr bool MY_DEVICE_DEFAULT_ENABLED = false; constexpr const char* MY_DEVICE_DEFAULT_VERSION = "1.0"; class IMyDevice : public mc::engine::interface { public: IMyDevice() { // 使用默认值初始化成员变量 DeviceId = MY_DEVICE_DEFAULT_ID; IsEnabled = MY_DEVICE_DEFAULT_ENABLED; Version = MY_DEVICE_DEFAULT_VERSION; } ~IMyDevice() = default; // 实现设备树接口的虚函数 bool Initialize() override; bool GetStatus() override; void SetEnabled(bool enabled) override; // 从variant中加载配置到基类属性 void from_variant(mc::mutable_dict& csr_object); private: std::unique_ptr m_internal; }; } // namespace dev #endif // I_MY_DEVICE_H ``` #### 步骤5: 设备对象实现 实现主设备对象,管理整个设备的生命周期: ```cpp // drivers/my_device/my_device.h #ifndef MY_DEVICE_H #define MY_DEVICE_H #include #include "interface/i_my_device.h" namespace dev { class MyDevice : public mc::engine::object { public: MC_OBJECT(MyDevice, "MyDevice", "/bmc/dev/MyDevice/${DeviceName}", (IMyDevice)) MyDevice() = default; ~MyDevice() = default; // 生命周期管理 bool init(mc::mutable_dict& csr_object, const mc::dict& connector); bool start(); bool stop(); // 设备接口实例 IMyDevice i_my_device; private: bool m_started = false; }; } // namespace dev MC_REFLECT(dev::MyDevice, ((i_my_device, "bmc.dev.MyDevice"))) #endif // MY_DEVICE_H ``` #### 步骤6: ABI接口实现 实现驱动注册和生命周期管理的ABI接口: ```cpp // drivers/my_device/my_device_abi.cpp #include #include #include "my_device.h" using namespace dev; extern "C" { driver_handle_t create_my_device(void* service, const char* name) { try { if (service == nullptr || name == nullptr) { elog("Error creating MyDevice: invalid parameters"); return nullptr; } MyDevice* device = new MyDevice(); device->set_service(static_cast(service)); device->set_object_name(name); return (void*)device; } catch (const std::exception& e) { elog("Error creating MyDevice: ${error}", ("error", e.what())); return nullptr; } } status_t init_my_device(driver_handle_t device, void* csr_object, void* connector) { if (device == nullptr || csr_object == nullptr || connector == nullptr) { elog("Error initializing MyDevice: invalid parameters"); return STATUS_ERROR; } MyDevice* device_object = static_cast(device); mc::mutable_dict* csr_object_ptr = static_cast(csr_object); mc::dict* connector_ptr = static_cast(connector); bool ret = device_object->init(*csr_object_ptr, *connector_ptr); return ret ? STATUS_OK : STATUS_ERROR; } status_t start_my_device(driver_handle_t device) { if (device == nullptr) { elog("Error starting MyDevice: device is null"); return STATUS_ERROR; } MyDevice* device_object = static_cast(device); bool ret = device_object->start(); return ret ? STATUS_OK : STATUS_ERROR; } status_t stop_my_device(driver_handle_t device) { if (device == nullptr) { elog("Error stopping MyDevice: device is null"); return STATUS_ERROR; } MyDevice* device_object = static_cast(device); bool ret = device_object->stop(); return ret ? STATUS_OK : STATUS_ERROR; } // 设备驱动信息 device_driver_t my_device_driver = { .device_name = "MyDevice", .ctor = create_my_device, .init = init_my_device, .start = start_my_device, .stop = stop_my_device }; } // extern "C" ``` #### 步骤7: 构建配置 创建Meson构建配置: ```meson # drivers/my_device/meson.build my_device_sources = [ 'my_device.cpp', 'my_device_abi.cpp', 'interface/i_my_device.cpp', 'internal/my_device_internal.cpp', ] my_device_lib = shared_library( 'MyDevice', my_device_sources, include_directories: [ include_directories('.'), include_directories('interface'), gen_inc, internal_inc ], dependencies: [mcpp_dep, internal_dep], install: true, install_dir: drivers_install_dir, ) my_device_dep = declare_dependency( link_with: my_device_lib, include_directories: include_directories('.') ) ``` ## 4. PCIe板卡驱动开发规范 ### 4.1 板卡驱动架构设计 PCIe板卡驱动采用分层架构,支持多厂商、多型号的复杂板卡设备: ```mermaid graph TB subgraph "PCIe板卡驱动总体架构" A[板卡主对象
Card Object] subgraph "多接口组合层" B[PCIeDevice
PCIe设备接口] C[PCIeCard
PCIe卡片接口] D[NetworkAdapter/Gpu
功能专用接口] E[Board
板卡信息接口] F[扩展接口
Cooling/Status/Power等] end subgraph "协议通信层" G[NCSI over MCTP
网络控制协议] H[IMU
设备管理协议] I[SMBUS
系统管理总线] J[定时任务管理
Timer Management] end subgraph "子设备管理层" K[NicPort 1..N
网络端口] L[OpticalModule
光模块] M[Gpu Memory
GPU内存] N[Processor
处理器] end subgraph "厂商差异化层" O[华为海思
Hi182x/Hi183x] P[网迅
WX] Q[英诺硅
AWM-M11P] end end A --> B A --> C A --> D A --> E A --> F A --> G A --> H A --> I G --> J H --> J I --> J A --> K A --> L A --> M A --> N O --> A P --> A Q --> A style A fill:#ffeb3b style G fill:#4caf50 style H fill:#ff9800 style I fill:#9c27b0 style K fill:#2196f3 style L fill:#2196f3 ``` ### 4.2 板卡驱动文件组织规范 #### 4.2.1 目录结构标准 ```shell drivers/pcie_{card_type}_card/ # 板卡类型根目录 ├── {vendor}/ # 厂商实现目录 │ ├── {model}/ # 型号具体实现 │ │ ├── {model}_card.h # 主板卡对象定义 │ │ ├── {model}_card.cpp # 主板卡对象实现 │ │ ├── {model}_abi.cpp # ABI导出实现 │ │ ├── {model}_{sub_device}.h # 子设备对象定义 │ │ ├── {model}_{sub_device}.cpp # 子设备对象实现 │ │ └── meson.build # 构建配置 │ ├── csr/ # 设备树配置 │ │ ├── *.dds # 设备描述文件 │ │ └── *.sr # 自描述记录文件 │ └── interface/ # 厂商专用接口 │ ├── {interface}.h # 接口定义 │ ├── {interface}.cpp # 接口实现 │ └── {interface}/ # 子接口目录 └── meson.build # 根构建配置 ``` **实际目录示例**: - `pcie_nic_card/hisi/hi182x/` - 华为海思Hi182x网卡 - `pcie_nic_card/wangxun/rp1000/` - 网迅RP1000网卡 - `pcie_gpu_card/innosilicon/awm_m11p/` - 英诺硅AWM-M11P GPU #### 4.2.2 命名规范 **主对象命名**: - 类名:`{vendor}_{model}_card`(如`hi182x_card`, `wx_card`) - 文件名:`{vendor}_{model}_card.{h|cpp}` - ABI函数:`create_{vendor}_{model}_card` **子设备命名**: - 类名:`{vendor}_{model}_{sub_type}`(如`hi182x_port`, `awm_m11p_gpu`) - 设备类型:`NicPort`, `OpticalTransceiver`, `Gpu`, `Memory` ### 4.3 板卡主对象设计模式 #### 4.3.1 多接口组合模式 板卡驱动的核心特征是组合多个标准接口,形成完整的设备功能。以华为海思Hi182x网卡为例: ##### 接口组合架构 | 接口类别 | 接口名称 | 成员变量 | 功能说明 | 是否必需 | |---------|---------|---------|---------|---------| | **基础接口** | PCIeDevice | m_pcie_device | PCIe设备基本信息(VID/DID) | ✅ 必需 | | **基础接口** | PCIeDevice_PCIeFunction | m_pcie_device_pcie_function | PCIe功能信息(BDF、链路能力) | ✅ 必需 | | **基础接口** | PCIeCard | m_pcie_card | PCIe卡片信息(插槽、链路状态) | ✅ 必需 | | **基础接口** | Board | m_board | 板卡信息(序列号、制造商) | ⭕ 可选 | | **功能接口** | NetworkAdapter | m_network_adapter | 网络适配器功能(MAC地址、速率) | ✅ 网卡必需 | | **扩展接口** | NetworkAdapter_FaultStatus | m_network_adapter_fault_status | 故障状态监控 | ⭕ 可选 | | **扩展接口** | Cooling | m_cooling | 冷却和温度管理(bmc.dev.Cooling) | ⭕ 可选 | | **扩展接口** | PCIeDevice_Bandwidth | m_pcie_device_bandwidth | PCIe带宽监控 | ⭕ 可选 | | **扩展接口** | NetworkAdapter_LogCollection | m_network_adapter_log_collection | 日志收集功能 | ⭕ 可选 | | **扩展接口** | NetworkAdapter_Oem | m_network_adapter_oem | 厂商扩展功能 | ⭕ 可选 | ##### 协议栈集成 | 协议类型 | 成员变量 | 协议作用 | 应用场景 | |---------|---------|---------|---------| | **NCSI over MCTP** | m_ncsi_over_mctp_huawei | 华为扩展的NCSI协议 | 网卡状态查询、配置管理、OEM命令 | | **IMU** | m_imu_obj | 设备管理单元协议 | 通过IPMI获取设备信息、固件版本 | | **SMBUS** | m_smbus_obj | 系统管理总线协议 | 温度监控、电源管理、芯片通信 | ##### 子设备管理 | 子设备类型 | 容器类型 | 说明 | 生命周期管理 | |-----------|---------|------|------------| | **网络端口** | `std::vector` | 管理多个物理网络端口 | 父设备启动时初始化,停止时清理 | | **光模块** | 由端口对象管理 | 每个端口可包含光模块 | 随端口生命周期管理 | ##### 生命周期方法 | 方法类型 | 方法名称 | 调用时机 | 主要职责 | |---------|---------|---------|---------| | **公有方法** | `init()` | 设备创建后 | 加载CSR配置、初始化成员变量 | | **公有方法** | `start()` | 初始化完成后 | 启动协议、初始化子设备、注册回调 | | **公有方法** | `stop()` | 设备停止时 | 停止协议、清理子设备、释放资源 | | **私有方法** | `init_network_ports()` | start()阶段 | 发现和初始化网络端口 | | **私有方法** | `start_ncsi_protocol()` | start()阶段 | 启动NCSI协议并绑定接口 | | **私有方法** | `start_smbus_protocol()` | start()阶段 | 启动SMBUS协议通信 | | **私有方法** | `init_imu_protocol()` | start()阶段 | 初始化IMU设备管理 | ##### 类定义示例 ```cpp // 华为海思Hi182x网卡示例 class hi182x_card : public mc::engine::object { public: MC_OBJECT( hi182x_card, "PCIeNicCard", "/bmc/dev/Systems/1/PCIeNicCard/${object_name}", (PCIeDevice)(PCIeDevice_PCIeFunction)(PCIeDevice_Oem)(PCIeDevice_Status)(PCIeCard)(PCIeCard_Oem) (PCIeCard_Metrics)(NetworkAdapter)(NetworkAdapter_FaultStatus)(Cooling)(NetworkAdapter_Oem)(Board) (PCIeDevice_Bandwidth)(NetworkAdapter_LogCollection)(Fru)) // === 接口对象组合 === NetworkAdapter_Oem m_network_adapter_oem; // 网络适配器OEM扩展 PCIeDevice m_pcie_device; // PCIe设备信息 PCIeDevice_PCIeFunction m_pcie_device_pcie_function; // PCIe功能信息 PCIeDevice_Oem m_pcie_device_oem; // PCIe设备OEM扩展 PCIeDevice_Status m_pcie_device_status; // PCIe设备状态 PCIeCard m_pcie_card; // PCIe卡片信息 PCIeCard_Oem m_pcie_card_oem; // PCIe卡片OEM扩展 PCIeCard_Metrics m_pcie_card_metrics; // 卡片运行态指标 Cooling m_cooling; // 冷却管理 NetworkAdapter m_network_adapter; // 网络适配器 NetworkAdapter_FaultStatus m_network_adapter_fault_status; // 故障状态 Board m_board; // 板卡信息 PCIeDevice_Bandwidth m_pcie_device_bandwidth; // 带宽监控 NetworkAdapter_LogCollection m_network_adapter_log_collection; // 日志收集 Fru m_fru; // FRU信息 uint8_t m_system_id; // 系统ID // === 生命周期管理 === bool start(); bool stop(); bool init(mc::mutable_dict& csr_object, const mc::dict& connector); private: // === 子设备管理 === std::vector m_network_ports; // 网络端口集合 // === 协议支持 === ref_chip_ptr m_ref_chip; // 参考芯片对象 smbus_obj_ptr m_smbus_obj; // SMBUS通信 imu_ptr m_imu_obj; // IMU设备管理 ncsi_over_mctp_hw_ptr m_ncsi_over_mctp_huawei; // 华为NCSI over MCTP协议 mc::milliseconds m_interval = mc::milliseconds(5000); // NCSI更新间隔5s mc::milliseconds m_smbus_interval = mc::milliseconds(5000); // SMBUS更新间隔5s mc::shared_ptr m_mctp_object; // MCTP底层协议 // === 协议生命周期管理 === void init_network_ports(); // 初始化网络端口 bool start_ncsi_protocol(); // 启动NCSI协议 bool start_smbus_protocol(); // 启动SMBUS协议 bool init_imu_protocol(); // 初始化IMU协议 bool start_protocol(); // 启动NCSI over MCTP协议 }; ``` ##### 接口组合设计原则 | 原则 | 说明 | 示例 | |------|------|------| | **必需接口优先** | 基础接口(PCIeDevice/PCIeCard/Board)必须实现 | 所有PCIe设备都需要 | | **功能接口明确** | 根据设备类型选择功能接口 | 网卡选NetworkAdapter,GPU选Gpu | | **扩展接口可选** | 根据硬件能力添加扩展接口 | 支持温度监控则添加Cooling | | **接口命名规范** | 使用下划线连接主接口和子接口 | NetworkAdapter_FaultStatus | | **接口分组排列** | MC_OBJECT宏中按功能分组 | 基础接口→功能接口→扩展接口 | #### 4.3.2 GPU板卡设计模式 ```cpp // 英诺硅AWM-M11P GPU卡示例 class awm_m11p_card : public mc::engine::object { public: MC_OBJECT(awm_m11p_card, "PCIeGpuCard", "/bmc/dev/Systems/1/PCIeGpuCard/${object_name}", (PCIeDevice)(PCIeDevice_Oem)(PCIeDevice_Status)(PCIeDevice_PCIeFunction)(PCIeCard)(PCIeCard_Oem)) PCIeDevice m_pcie_device; // PCIe设备信息 PCIeDevice_Oem m_pcie_device_oem; // PCIe设备OEM信息 PCIeDevice_Status m_pcie_device_status; // PCIe设备状态 PCIeDevice_PCIeFunction m_pcie_device_pcie_function; // PCIe功能信息 PCIeCard m_pcie_card; // PCIe卡片信息 PCIeCard_Oem m_pcie_card_oem; // PCIe卡片OEM信息 uint8_t SystemId; // 系统ID bool start(); bool stop(); bool init(mc::mutable_dict& csr_object, const mc::dict& connector); }; ``` ### 4.4 协议集成管理 #### 4.4.1 多协议并行管理 PCIe板卡通常需要集成多种通信协议,每种协议有独立的生命周期: ```cpp class hi182x_card : public mc::engine::object { private: // === 协议对象管理 === ncsi_over_mctp_hw_ptr m_ncsi_over_mctp_huawei; // 华为NCSI over MCTP imu_ptr m_imu_obj; // IMU设备管理协议 smbus_obj_ptr m_smbus_obj; // SMBUS系统管理总线 mc::shared_ptr m_mctp_object; // MCTP底层协议对象 // === 定时任务管理 === mc::milliseconds m_interval = mc::milliseconds(5000); // NCSI更新间隔 mc::milliseconds m_smbus_interval = mc::milliseconds(5000); // SMBUS更新间隔 // === 协议启动和管理 === // 各协议独立启动,start() 中按序调用: // start_protocol(); // 启动 NCSI over MCTP // start_smbus_protocol(); // 启动 SMBUS // init_imu_protocol(); // 初始化 IMU bool start_protocol() { return start_ncsi_protocol(); } bool start_ncsi_protocol() { // 校验BDF已初始化 if (m_pcie_device_pcie_function.BusNumber == 0 && m_pcie_device_pcie_function.DeviceNumber == 0 && m_pcie_device_pcie_function.FunctionNumber == 0) { elog("PCIe device BDF not initialized"); return false; } // 1. 计算物理地址并创建 MCTP 对象 uint16_t phy_addr = mctp::init_phy_addr(m_pcie_device_pcie_function.BusNumber, m_pcie_device_pcie_function.DeviceNumber, m_pcie_device_pcie_function.FunctionNumber); m_mctp_object = mc::make_shared(this, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, ""); // 2. 在端点就绪回调中创建 NCSI over MCTP 实例并绑定各接口任务 auto ncsi_update_task = [this]() { m_ncsi_over_mctp_huawei = std::make_shared(m_mctp_object); for (auto& port : m_network_ports) { port->start_ncsi_update_task(m_ncsi_over_mctp_huawei, m_interval); port->enable_lldp_over_mctp(); // 开启 lldp_over_mctp 透传 } m_network_adapter.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, mc::milliseconds(120000)); m_network_adapter_fault_status.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, m_interval); m_pcie_device_bandwidth.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, mc::milliseconds(180000)); m_pcie_device_pcie_function.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, mc::milliseconds(120000)); m_cooling.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, m_interval); m_network_adapter_log_collection.init_ncsi_endpoint(m_ncsi_over_mctp_huawei); }; m_mctp_object->create_transport_and_endpoint(std::string(get_object_name()), ncsi_update_task); return true; } }; ``` **协议集成规范**: 1. **协议隔离**:每种协议使用独立的智能指针管理 2. **统一初始化**:在`start_protocol()`中统一管理协议启动 3. **接口绑定**:将协议实例绑定到相关接口对象 4. **错误处理**:协议初始化失败时进行适当的错误处理和资源清理 5. **定时任务**:使用统一的定时间隔管理协议更新 #### 4.4.2 协议差异化处理 不同厂商的板卡支持不同的协议组合: ```cpp // 华为海思 - 支持NCSI+IMU+SMBUS class hi182x_card { ncsi_over_mctp_hw_ptr m_ncsi_over_mctp_huawei; // 华为专用NCSI imu_ptr m_imu_obj; // IMU协议 smbus_obj_ptr m_smbus_obj; // SMBUS协议 }; // 网迅 - 支持NCSI+IMU,附加四元组更新 class rp1000_card { ncsi_over_mctp_wx_ptr m_ncsi_over_mctp_wx; // 网迅专用NCSI over MCTP imu_ptr m_imu_obj; // IMU协议 mc::shared_ptr m_mctp_object = nullptr; // MCTP底层协议 mc::milliseconds m_interval = mc::milliseconds(5000); // NCSI更新间隔5s mc::milliseconds m_quadruple_interval = mc::milliseconds(10000); // 四元组更新间隔10s mc::shared_ptr m_quadruple_timer; // 四元组更新定时器 bool m_first_quadruple_update; // 是否首次四元组更新 }; // 英诺硅GPU - 简化协议支持 class awm_m11p_card { // GPU卡通常协议需求较简单,主要依赖PCIe标准接口 }; ``` ### 4.5 子设备管理模式 #### 4.5.1 动态子设备发现 板卡驱动通过框架提供的`get_children()`方法动态发现和管理子设备: ```cpp void hi182x_card::init_network_ports() { auto objects = get_children(); // 获取所有子对象 if (objects.empty()) { elog("Error: No network ports found"); return; } for (auto& object : objects) { auto object_name = object->get_name(); // 通过对象名前缀识别设备类型 if (object_name.substr(0, object_name.find_first_of("_")) == "NicPort") { // 使用 dynamic_cast 并校验空指针,避免向下转换失败 auto* port = dynamic_cast(object.get()); if (port == nullptr) { elog("hi182x_card child ${name} is not hi182x_port, skip", ("name", object_name)); continue; } ilog("hi182x_card init network port ${name}", ("name", object_name)); m_network_ports.push_back(port); } // 可以添加其他子设备类型的识别 else if (object_name.find("OpticalTransceiver") != std::string::npos) { // 光模块设备处理 } } } ``` **子设备管理规范**: 1. **类型识别**:通过对象名前缀或特征字符串识别子设备类型 2. **类型转换**:使用`dynamic_cast`将基类指针转换为具体子设备类型,并必须校验空指针(禁止使用`static_cast`向下转换) 3. **集合管理**:使用`std::vector`管理同类型子设备集合 4. **生命周期同步**:主设备的启动/停止时同步管理所有子设备 #### 4.5.2 子设备生命周期管理 ```cpp bool hi182x_card::start() { // 1. 初始化子设备 init_network_ports(); // 2. 启动所有子设备 for (auto& port : m_network_ports) { port->start(); if (port->m_optical_module) { port->m_optical_module->m_optical_module_status.set_network_adapter_oem(&m_network_adapter_oem); port->m_optical_module->m_optical_module_temperature_celsius.set_network_adapter_oem( &m_network_adapter_oem); } } // 3. 建立主接口间的交叉引用 m_cooling.set_network_adapter_oem(&m_network_adapter_oem); m_network_adapter_fault_status.set_network_adapter_oem(&m_network_adapter_oem); m_network_adapter_oem.set_network_adapter(&m_network_adapter); m_network_adapter.set_network_adapter_oem(&m_network_adapter_oem); // 4. 各协议独立启动 start_protocol(); // 启动 NCSI over MCTP start_smbus_protocol(); // 启动 SMBUS setup_vdpci_lldp_listener(); init_imu_protocol(); // 初始化 IMU // 5. 注册事件回调 m_network_adapter_oem.register_os_reset_callback([this]() { this->handle_os_reset(); }); m_network_adapter_oem.register_os_off_callback([this]() { this->handle_os_off(); }); return true; } bool hi182x_card::stop() { // 1. 停止各协议更新任务 stop_ncsi_update_task(); m_network_adapter_log_collection.clean_ncsi_endpoint(); for (auto& port : m_network_ports) { if (port != nullptr) { port->stop_ncsi_update_task(); } } if (m_smbus_obj) { stop_smbus_update_task(); m_network_adapter_log_collection.clean_smbus_obj(); m_network_adapter_oem.clean_smbus_obj(); for (auto& port : m_network_ports) { if (port != nullptr) { port->stop_smbus_update_task(); } } } for (auto& port : m_network_ports) { if (port != nullptr) { port->stop_lldp_clear_timer(); } } // 2. 注销回调并断开交叉引用 m_network_adapter_oem.unregister_os_reset_callback(); m_network_adapter_oem.unregister_os_off_callback(); m_network_adapter_oem.unregister_eeprom_wp_callback(); m_network_adapter_oem.set_network_adapter(nullptr); m_network_adapter.set_network_adapter_oem(nullptr); m_cooling.set_network_adapter_oem(nullptr); m_network_adapter_fault_status.set_network_adapter_oem(nullptr); return true; } ``` ### 4.6 ABI实现规范 #### 4.6.1 多设备ABI导出 PCIe板卡驱动通常需要导出主设备和多个子设备的ABI接口: ```cpp // PCIe网卡ABI实现示例 extern "C" { // === 主板卡设备ABI === driver_handle_t create_hi182x_card(void* service, const char* name) { try { if (service == nullptr || name == nullptr) { return nullptr; } hi182x_card* device = new hi182x_card(); device->set_service(static_cast(service)); device->set_object_name(name); return (void*)device; } catch (const std::exception& e) { elog("Error creating hi182x PCIeNicCard: ${error}", ("error", e.what())); return nullptr; } } status_t init_hi182x_card(driver_handle_t device, void* csr_object, void* connector) { if (device == nullptr || csr_object == nullptr || connector == nullptr) { elog("Error initializing hi182x PCIeNicCard: device is null"); return STATUS_ERROR; } hi182x_card* device_object = static_cast(device); mc::mutable_dict* csr_object_ptr = static_cast(csr_object); mc::dict* connector_ptr = static_cast(connector); bool ret = device_object->init(*csr_object_ptr, *connector_ptr); return ret ? STATUS_OK : STATUS_ERROR; } status_t start_hi182x_card(driver_handle_t device) { if (device == nullptr) { elog("Error starting hi182x PCIeNicCard: device is null"); return STATUS_ERROR; } hi182x_card* device_object = static_cast(device); device_object->start(); return STATUS_OK; } status_t stop_hi182x_card(driver_handle_t device) { if (device == nullptr) { elog("Error stopping hi182x PCIeNicCard: device is null"); return STATUS_ERROR; } hi182x_card* device_object = static_cast(device); device_object->stop(); return STATUS_OK; } // === 网络端口子设备ABI === driver_handle_t create_hi182x_port(void* service, const char* name) { try { if (service == nullptr || name == nullptr) { return nullptr; } hi182x_port* device = new hi182x_port(); device->set_service(static_cast(service)); device->set_object_name(name); return (void*)device; } catch (const std::exception& e) { elog("Error creating hi182x NicPort: ${error}", ("error", e.what())); return nullptr; } } // === 光模块子设备ABI === driver_handle_t create_hi182x_optical_module(void* service, const char* name) { try { if (service == nullptr || name == nullptr) { return nullptr; } hi182x_optical_module* device = new hi182x_optical_module(); device->set_object_name(name); device->set_service(static_cast(service)); return (void*)device; } catch (const std::exception& e) { elog("Error creating hi182x OpticalTransceiver: ${error}", ("error", e.what())); return nullptr; } } // === 设备驱动注册表 === device_driver_t hi182x_card_device_driver = { .device_name = "PCIeNicCard", .ctor = create_hi182x_card, .init = init_hi182x_card, .start = start_hi182x_card, .stop = stop_hi182x_card }; device_driver_t hi182x_port_device_driver = { .device_name = "NicPort", .ctor = create_hi182x_port, .init = init_hi182x_port, .start = start_hi182x_port, .stop = stop_hi182x_port }; device_driver_t hi182x_optical_module_device_driver = { .device_name = "OpticalTransceiver", .ctor = create_hi182x_optical_module, .init = init_hi182x_optical_module, .start = start_hi182x_optical_module, .stop = stop_hi182x_optical_module }; // === 驱动导出 === device_driver_t hi182x_device_driver[] = { hi182x_card_device_driver, hi182x_port_device_driver, hi182x_optical_module_device_driver }; status_t register_device_driver(device_driver_t** device_driver, uint8_t* count) { *device_driver = hi182x_device_driver; *count = sizeof(hi182x_device_driver) / sizeof(hi182x_device_driver[0]); return STATUS_OK; } } // extern "C" ``` **ABI实现规范**: 1. **设备分离**:主设备和子设备分别实现独立的ABI函数 2. **统一命名**:函数名格式`{action}_{vendor}_{model}_{device_type}` 3. **设备表管理**:使用数组管理多个设备驱动结构 4. **错误处理**:每个ABI函数都要进行参数验证和异常处理 ### 4.7 构建系统集成 #### 4.7.1 分层构建配置 ```meson # 主目录 drivers/pcie_nic_card/hisi/hi182x/meson.build hisi_182x_sources = files( 'hi182x_abi.cpp', # ABI导出实现 'hi182x_card.cpp', # 主板卡对象 'hi182x_om.cpp', # 光模块子设备 'hi182x_port.cpp', # 网络端口子设备 ) include_dirs += include_directories('../../../chip') # 芯片驱动路径 include_dirs += include_directories('../../../internal') # 内部实现路径 # 静态库构建(用于测试) libhisi_182x_static = static_library( 'hisi_182x', hisi_182x_sources, include_directories: include_dirs + hisi_interface_inc, # 接口实现编译为独立共享库 libhisi_interface,此处仅声明依赖 dependencies: [ dev_deps, # 基础开发依赖 libhisi_interface_dep, # 厂商接口共享库 libncsi_over_mctp_dep, # NCSI over MCTP协议库 libpldm_over_mctp_dep, # PLDM over MCTP协议库 libmctp_dep, # MCTP协议库 libimu_dep, # IMU协议库 libsmbus_dep, # SMBUS协议库 liblldp_dep, # LLDP协议库 ], cpp_args: ['-Os', '-ffunction-sections', '-fdata-sections'], install: false, ) # 动态库构建(用于部署) libhisi_182x = shared_library( 'hisi_182x', include_directories: include_dirs + hisi_interface_inc, name_prefix: 'lib', name_suffix: 'so', install: true, install_dir: drivers_install_dir, cpp_args: ['-Os', '-ffunction-sections', '-fdata-sections'], link_args: ['-Wl,--gc-sections', '-Wl,--strip-all', '-Wl,--as-needed'], link_whole: [libhisi_182x_static], # 链接静态库 ) # 测试依赖声明 if build_tests hisi_182x_dep = declare_dependency( include_directories: include_dirs + hisi_interface_inc, link_with: libhisi_182x_static, dependencies: [ libmcpp_deps, libncsi_over_mctp_dep, libmctp_dep, libimu_dep, libsmbus_dep, liblldp_dep, ], ) endif ``` **构建配置规范**: 1. **协议依赖**:明确声明所有使用的协议库依赖 2. **路径管理**:正确配置include路径,包括芯片和内部实现路径 3. **双库构建**:同时提供静态库(测试用)和动态库(部署用) 4. **条件编译**:支持测试模式和部署模式的条件编译 ### 4.8 设备树配置规范 #### 4.8.1 DDS设备描述文件 ```json { "Schema": "dds-v1", "Type": "Component", "DeviceCategory": "PCIeNicCard", "ID": "N/A", "Objects": { "PCIeNicCard": { "Path": "/bmc/dev/Systems/:SystemId/PCIeNicCard/:Id", "Interfaces": [ "bmc.dev.PCIeDevice", // PCIe设备基础接口 "bmc.dev.PCIeDevice.PCIeFunction", // PCIe功能信息接口 "bmc.dev.PCIeDevice.Status", // PCIe设备状态接口 "bmc.dev.PCIeDevice.Oem", // PCIe设备OEM扩展接口 "bmc.dev.PCIeCard", // PCIe卡片信息接口 "bmc.dev.PCIeCard.Oem", // PCIe卡片OEM扩展接口 "bmc.dev.PCIeCard.Metrics", // PCIe卡片指标接口 "bmc.dev.Board", // 板卡信息接口 "bmc.dev.NetworkAdapter", // 网络适配器接口 "bmc.dev.PCIeDevice.Bandwidth", // 带宽扩展接口 "bmc.dev.Cooling", // 冷却扩展接口 "bmc.dev.NetworkAdapter.FaultStatus", // 故障状态扩展接口 "bmc.dev.NetworkAdapter.LogCollection", // 日志收集扩展接口 "bmc.dev.NetworkAdapter.Oem" // 网络适配器OEM扩展接口 ] }, "NicPort": { "Path": ":Parent/NicPort/:Id", "Interfaces": [ "bmc.dev.NetworkPort", // 网络端口基础接口 "bmc.dev.NetworkPort.LinkInfo", // 链路信息扩展接口 "bmc.dev.NetworkPort.DataCenterBridging", // 数据中心桥接 "bmc.dev.NetworkPort.LLDPReceive", // LLDP接收扩展接口 "bmc.dev.NetworkPort.Metrics" // 监控指标扩展接口 ] }, "OpticalTransceiver": { "Path": ":Parent/OpticalTransceiver", "Interfaces": [ "bmc.dev.OpticalModule", // 光模块基础接口 "bmc.dev.OpticalModule.Status", // 状态扩展接口 "bmc.dev.OpticalModule.TemperatureCelsius", // 温度扩展接口 "bmc.dev.OpticalModule.Voltage", // 电压扩展接口 "bmc.dev.OpticalModule.Power", // 功耗扩展接口 "bmc.dev.OpticalModule.Current", // 电流扩展接口 "bmc.dev.OpticalModule.Diagnose" // 诊断扩展接口 ] } } } ``` **设备树配置规范**: 1. **层次结构**:主设备作为根,子设备通过`:Parent`引用父设备 2. **接口组合**:每个设备明确列出支持的所有接口 3. **路径约定**:遵循BMC设备路径标准,支持动态参数替换 4. **扩展接口**:使用点号分隔的命名空间表示扩展接口 ## 5. 板卡驱动开发最佳实践 ### 5.1 开发流程规范 ```mermaid flowchart TD A[需求分析] --> B[设备树接口设计] B --> C[接口类实现] C --> D[主设备对象实现] D --> E[子设备对象实现] E --> F[协议集成] F --> G[ABI导出实现] G --> H[构建配置] H --> I[设备树配置] I --> J[测试验证] J --> K[部署集成] A1[确定板卡类型
分析厂商差异
定义功能需求] -.-> A B1[设计接口组合
定义扩展接口
规划子设备结构] -.-> B C1[实现基础接口
添加协议绑定
配置参数加载] -.-> C D1[组合多接口
管理协议实例
实现生命周期] -.-> D E1[继承框架基类
实现设备功能
绑定父设备] -.-> E F1[初始化协议
配置定时任务
处理协议差异] -.-> F G1[导出多设备ABI
实现驱动注册
错误处理] -.-> G H1[配置依赖库
设置构建选项
支持条件编译] -.-> H I1[定义设备路径
配置接口列表
设置参数映射] -.-> I J1[单元测试
集成测试
协议验证] -.-> J K1[驱动安装
配置部署
运行验证] -.-> K style A fill:#ffeb3b style D fill:#4caf50 style F fill:#ff9800 style J fill:#2196f3 ``` ### 5.2 代码质量规范 #### 5.2.1 架构设计原则 **单一职责原则**: - 主设备对象:负责接口组合和协议管理 - 子设备对象:负责具体功能实现 - 接口类:负责配置加载和协议绑定 **开闭原则**: - 通过继承扩展新厂商支持 - 通过接口组合扩展新功能 - 避免修改现有稳定代码 **依赖倒置原则**: - 依赖抽象接口而非具体实现 - 使用智能指针管理协议依赖 - 通过依赖注入管理对象关系 #### 5.2.2 内存管理规范 ```cpp class hi182x_card : public mc::engine::object { private: // === 智能指针管理协议对象 === mc::shared_ptr m_mctp_object; // 框架智能指针管理MCTP std::shared_ptr m_ncsi_over_mctp_huawei; // 自动管理生命周期 std::shared_ptr m_imu_obj; // 支持多对象共享 mc::shared_ptr m_smbus_obj; // 框架智能指针 mc::shared_ptr m_quadruple_timer; // 定时器使用框架智能指针 public: ~hi182x_card() { // === 取消回调注册,避免悬空指针 === m_network_adapter_oem.unregister_os_reset_callback(); m_network_adapter_oem.unregister_os_off_callback(); } }; ``` **内存管理规范**: 1. **智能指针为主**:协议对象、定时器等动态资源统一使用`mc::shared_ptr`或`std::shared_ptr`管理,禁止手动`delete`原始指针 2. **明确所有权**:MCTP底层对象使用`mc::shared_ptr`(框架对象),协议上层使用`std::shared_ptr` 3. **回调注销**:析构/停止时先注销回调,避免悬空指针 #### 5.2.3 异常安全保证 ```cpp bool hi182x_card::start_ncsi_protocol() { // === 资源获取即初始化(RAII) === // MCTP对象由框架智能指针管理,端点就绪后创建 NCSI over MCTP 实例 if (m_mctp_object == nullptr) { elog("mctp object is null"); return false; } auto ncsi_update_task = [this]() { try { // 创建 NCSI over MCTP 实例(构造参数为 MCTP 智能指针) m_ncsi_over_mctp_huawei = std::make_shared(m_mctp_object); // === 批量操作的事务性处理 === for (auto& port : m_network_ports) { port->start_ncsi_update_task(m_ncsi_over_mctp_huawei, m_interval); } // === 各接口绑定独立的更新任务 === m_network_adapter.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, mc::milliseconds(120000)); m_network_adapter_fault_status.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, m_interval); m_pcie_device_bandwidth.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, mc::milliseconds(180000)); m_pcie_device_pcie_function.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, mc::milliseconds(120000)); m_cooling.start_ncsi_update_task_huawei(m_ncsi_over_mctp_huawei, m_interval); m_network_adapter_log_collection.init_ncsi_endpoint(m_ncsi_over_mctp_huawei); } catch (const std::exception& e) { elog("Exception in start_ncsi_protocol: ${error}", ("error", e.what())); // 异常时清理已启动的任务 stop_ncsi_update_task(); } catch (...) { elog("Unknown exception in start_ncsi_protocol"); stop_ncsi_update_task(); } }; // 创建传输层和端点,就绪后回调 ncsi_update_task m_mctp_object->create_transport_and_endpoint(std::string(get_object_name()), ncsi_update_task); return true; } ``` ### 5.3 多厂商差异化处理 #### 5.3.1 厂商特性对比表 | 板卡类型 | 厂商 | 型号 | 协议支持 | 特有功能 | 子设备 | |---------|------|------|----------|----------|---------| | PCIe网卡 | 华为海思 | Hi182x | NCSI+IMU+SMBUS | 温度监控、故障诊断、日志收集 | NicPort, OpticalModule | | PCIe网卡 | 华为海思 | Hi1822_Fc | NCSI+IMU+SMBUS | FC网络功能支持 | NicPort, OpticalModule | | PCIe网卡 | 网迅 | RP1000 | NCSI+IMU | 四元组更新、电源状态检测 | NicPort | | PCIe GPU | 英诺硅 | AWM-M11P | 基础PCIe | GPU监控、内存管理 | Gpu, Memory | #### 5.3.2 差异化实现策略 ```cpp // === 基础接口统一,实现差异化 === // 1. 协议差异 - 继承统一基类,实现厂商专用协议 class ncsi_over_mctp_huawei : public ncsi_over_mctp_base { /* 华为实现 */ }; class ncsi_over_mctp_wx : public ncsi_over_mctp_base { /* 网迅实现 */ }; // 2. 功能差异 - 通过接口组合支持不同功能集 class hi182x_card { NetworkAdapter_FaultStatus m_fault_status; // 华为特有 NetworkAdapter_LogCollection m_log_collection; // 华为特有 }; class wx_card { // 网迅不支持故障状态和日志收集接口 mc::shared_ptr m_quadruple_timer; // 网迅特有四元组更新定时器 }; // 3. 定时任务差异 - 不同厂商使用不同更新间隔 class hi182x_card { mc::milliseconds m_interval = mc::milliseconds(5000); // 5秒NCSI更新 mc::milliseconds m_smbus_interval = mc::milliseconds(5000); // 5秒SMBUS更新 }; class wx_card { mc::milliseconds m_interval = mc::milliseconds(5000); // 5秒NCSI更新 mc::milliseconds m_quadruple_interval = mc::milliseconds(10000); // 10秒四元组更新 }; ``` ### 5.4 调试和故障排除 #### 5.4.1 日志记录规范 ```cpp class hi182x_card { bool start() { ilog("Starting hi182x_card: ${name}", ("name", get_object_name())); // === 关键步骤日志 === ilog("Initializing network ports..."); init_network_ports(); ilog("Found ${count} network ports", ("count", m_network_ports.size())); // === 协议启动日志 === ilog("Starting NCSI protocol..."); if (!start_ncsi_protocol()) { elog("Failed to start NCSI protocol"); return false; } ilog("NCSI protocol started successfully"); // === 性能监控日志 === dlog("hi182x_card started in ${time}ms", ("time", start_time)); return true; } void update_device_status() { try { // === 调试级详细日志 === dlog("Updating device status via NCSI..."); // NCSI over MCTP 实例未创建时记录警告 if (m_ncsi_over_mctp_huawei == nullptr) { wlog("NCSI over MCTP instance is null, skip update"); return; } dlog("Device status updated: ${name}, BDF=${bus}:${dev}:${func}", ("name", m_pcie_device.DeviceName.get_value().as()), ("bus", m_pcie_device_pcie_function.BusNumber), ("dev", m_pcie_device_pcie_function.DeviceNumber), ("func", m_pcie_device_pcie_function.FunctionNumber)); } catch (const std::exception& e) { elog("Exception in update_device_status: ${error}", ("error", e.what())); } } }; ``` **日志级别使用规范**: - `elog()`: 错误和异常情况 - `wlog()`: 警告和非致命问题 - `ilog()`: 重要信息和状态变化 - `dlog()`: 调试信息和详细过程 - `tlog()`: 临时调试和开发期日志 #### 5.4.2 常见问题诊断 **协议初始化失败**: ```cpp bool start_ncsi_protocol() { // 1. 验证PCIe设备BDF已初始化 if (m_pcie_device_pcie_function.BusNumber == 0 && m_pcie_device_pcie_function.DeviceNumber == 0 && m_pcie_device_pcie_function.FunctionNumber == 0) { elog("PCIe device ${name} BDF not initialized", ("name", m_pcie_device.DeviceName.get_value().as())); return false; } // 2. 检查网络端口子设备是否发现 if (m_network_ports.empty()) { elog("No network ports found, NCSI protocol cannot start"); return false; } // 3. 计算物理地址并创建MCTP对象 uint16_t phy_addr = mctp::init_phy_addr(m_pcie_device_pcie_function.BusNumber, m_pcie_device_pcie_function.DeviceNumber, m_pcie_device_pcie_function.FunctionNumber); m_mctp_object = mc::make_shared(this, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, ""); // 4. 创建传输层和端点,就绪后回调绑定接口任务 m_mctp_object->create_transport_and_endpoint(std::string(get_object_name()), ncsi_update_task); return true; } ``` **子设备管理失败**: ```cpp void init_network_ports() { auto objects = get_children(); // 1. 检查子设备数量 if (objects.empty()) { wlog("No child objects found, expected network ports"); return; } // 2. 验证子设备类型 for (auto& object : objects) { if (!dynamic_cast(object.get())) { wlog("Invalid child object type: ${name}", ("name", object->get_name())); continue; } // 添加到管理列表 } // 3. 验证最终结果 if (m_network_ports.empty()) { elog("No valid network ports found"); } } ``` ## 5. 测试开发 ### 5.1 测试策略 ```mermaid graph TD A[测试策略] A --> B[单元测试] A --> C[集成测试] A --> D[性能测试] A --> E[压力测试] B --> F[设备初始化测试] B --> G[接口功能测试] B --> H[错误处理测试] C --> I[ABI接口测试] C --> J[协议通信测试] C --> K[多设备协同测试] D --> L[吞吐量测试] D --> M[延迟测试] D --> N[资源使用测试] E --> O[长时间运行测试] E --> P[并发访问测试] E --> Q[异常恢复测试] style A fill:#ffeb3b style B fill:#4caf50 style C fill:#2196f3 style D fill:#ff9800 style E fill:#f44336 ``` ### 5.1 单元测试 ```cpp // tests/my_device_test.cpp #include #include "../drivers/my_device/my_device.h" class MyDeviceTest : public ::testing::Test { protected: void SetUp() override { m_device = std::make_unique(); } void TearDown() override { if (m_device) { m_device->stop(); } } std::unique_ptr m_device; }; TEST_F(MyDeviceTest, InitializationTest) { mc::mutable_dict config; config["DeviceName"] = std::string("TestDevice"); config["DeviceId"] = uint8_t(1); mc::dict connector; EXPECT_TRUE(m_device->init(config, connector)); } ``` ### 5.2 集成测试 ```cpp // tests/integration/my_device_integration_test.cpp class MyDeviceIntegrationTest : public ::testing::Test { protected: void SetUp() override { m_service = std::make_unique(); } std::unique_ptr m_service; }; TEST_F(MyDeviceIntegrationTest, ABI_Test) { driver_handle_t handle = create_my_device(m_service.get(), "TestDevice"); EXPECT_NE(handle, nullptr); mc::mutable_dict config; config["DeviceName"] = std::string("TestDevice"); mc::dict connector; EXPECT_EQ(init_my_device(handle, &config, &connector), STATUS_OK); EXPECT_EQ(start_my_device(handle), STATUS_OK); EXPECT_EQ(stop_my_device(handle), STATUS_OK); } ``` ## 6. 性能优化 ### 6.1 性能优化策略 ```mermaid mindmap root((性能优化)) 内存管理 对象池 预分配缓冲区 智能指针 RAII原则 并发优化 异步操作 线程池 锁优化 无锁数据结构 IO优化 批量操作 缓冲机制 DMA传输 零拷贝 算法优化 时间复杂度优化 空间复杂度优化 缓存友好 分支预测 ``` ### 6.1 内存管理 ```cpp class PerformantDevice { private: // 使用对象池减少内存分配 std::vector> m_buffer_pool; std::mutex m_pool_mutex; static constexpr size_t BUFFER_POOL_SIZE = 64; static constexpr size_t BUFFER_SIZE = 4096; public: void init_buffer_pool() { m_buffer_pool.reserve(BUFFER_POOL_SIZE); for (size_t i = 0; i < BUFFER_POOL_SIZE; ++i) { m_buffer_pool.push_back( std::make_unique(BUFFER_SIZE)); } } std::unique_ptr get_buffer() { std::lock_guard lock(m_pool_mutex); if (!m_buffer_pool.empty()) { auto buffer = std::move(m_buffer_pool.back()); m_buffer_pool.pop_back(); return buffer; } return std::make_unique(BUFFER_SIZE); } }; ``` ### 6.2 异步操作 ```cpp class AsyncDevice { private: // 使用 mc::runtime 线程池执行异步任务 std::shared_ptr m_thread_pool; mc::runtime::thread_pool::executor_type m_executor; public: AsyncDevice() : m_thread_pool(std::make_shared(4, "device_pool")), m_executor(m_thread_pool->get_executor()) {} // 提交异步任务(post 不等待返回) void submit_async_task(std::function task) { m_executor.post(std::move(task)); } // 分发任务(dispatch 可在调用线程直接执行) void dispatch_async_task(std::function task) { m_executor.dispatch(std::move(task)); } // 延迟执行(defer 延迟到当前任务结束后执行) void defer_async_task(std::function task) { m_executor.defer(std::move(task)); } }; ``` ## 7. 错误处理和调试 ### 7.1 错误处理流程 ```mermaid flowchart TD A[错误发生] --> B{错误类型} B -->|初始化失败| C[重试初始化] B -->|硬件错误| D[硬件重置] B -->|协议错误| E[重启协议] B -->|超时错误| F[调整超时参数] B -->|配置错误| G[验证配置] C --> H{重试成功?} D --> I{重置成功?} E --> J{重启成功?} F --> K[继续操作] G --> L[修正配置] H -->|是| M[记录恢复日志] H -->|否| N[报告严重错误] I -->|是| M I -->|否| N J -->|是| M J -->|否| N M --> O[正常运行] N --> P[停止设备] L --> A style A fill:#f44336 style N fill:#f44336 style O fill:#4caf50 style M fill:#4caf50 ``` ### 7.1 错误处理策略 ```cpp enum class DeviceError { SUCCESS = 0, INIT_FAILED, HARDWARE_ERROR, PROTOCOL_ERROR, TIMEOUT_ERROR, INVALID_CONFIG }; class ErrorHandler { public: static bool handle_error(DeviceError error, const std::string& context) { switch (error) { case DeviceError::INIT_FAILED: elog("Device initialization failed in ${context}", ("context", context)); return retry_initialization(); case DeviceError::HARDWARE_ERROR: elog("Hardware error detected in ${context}", ("context", context)); return perform_hardware_reset(); default: elog("Unknown error in ${context}", ("context", context)); return false; } } }; ``` ### 7.2 调试工具 ```cpp class DebugHelper { public: // 设备状态转储 static void dump_device_state(const MyDevice& device) { ilog("=== Device State Dump ==="); ilog("Name: ${name}", ("name", device.i_my_device.DeviceName.value())); ilog("ID: ${id}", ("id", device.i_my_device.DeviceId.value())); ilog("========================"); } // 性能监控 class PerformanceMonitor { private: std::chrono::high_resolution_clock::time_point m_start; std::string m_operation; public: PerformanceMonitor(const std::string& operation) : m_operation(operation), m_start(std::chrono::high_resolution_clock::now()) {} ~PerformanceMonitor() { auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - m_start); dlog("${operation} took ${duration} microseconds", ("operation", m_operation)("duration", duration.count())); } }; }; ``` ## 8. 最佳实践 ### 8.1 开发最佳实践 ```mermaid mindmap root((最佳实践)) 代码规范 命名规范 PascalCase类名 snake_case函数名 m_前缀成员变量 文件组织 模块化设计 清晰的目录结构 接口与实现分离 资源管理 RAII原则 智能指针使用 异常安全 内存泄漏防护 线程安全 读写锁 原子操作 无锁编程 避免死锁 性能优化 减少拷贝 缓存优化 异步处理 批量操作 ``` ### 8.1 代码规范 #### 8.1.1 命名规范 - **类名**:使用PascalCase,如`MyDevice`, `NetworkAdapter` - **函数名**:使用snake_case,如`init_device()`, `start_protocol()` - **变量名**:使用snake_case,成员变量添加`m_`前缀 - **常量**:使用UPPER_CASE,如`MAX_BUFFER_SIZE` #### 8.1.2 文件组织 ```shell drivers/my_device/ ├── my_device.h # 主设备对象头文件 ├── my_device.cpp # 主设备对象实现 ├── my_device_abi.cpp # ABI接口实现 ├── interface/ # 接口层 │ ├── i_my_device.h │ └── i_my_device.cpp ├── internal/ # 内部实现 │ ├── my_device_internal.h │ └── my_device_internal.cpp └── meson.build # 构建配置 ``` ### 8.2 资源管理 #### 8.2.1 RAII原则 ```cpp class ResourceManager { private: struct Resource { void* handle; std::function deleter; ~Resource() { if (handle && deleter) { deleter(handle); } } }; std::vector> m_resources; }; ``` ### 8.3 线程安全 ```cpp class ThreadSafeDevice { private: mutable std::shared_mutex m_device_mutex; DeviceState m_state; public: // 读操作使用共享锁 DeviceState get_state() const { std::shared_lock lock(m_device_mutex); return m_state; } // 写操作使用独占锁 void set_state(const DeviceState& state) { std::unique_lock lock(m_device_mutex); m_state = state; } }; ``` ## 9. 常见问题和解决方案 ### 9.1 问题诊断流程 ```mermaid flowchart TD A[问题报告] --> B{问题类型} B -->|编译错误| C[编译问题诊断] B -->|运行时错误| D[运行时问题诊断] B -->|性能问题| E[性能问题诊断] C --> F[检查头文件路径] C --> G[验证链接配置] C --> H[检查语法错误] D --> I[查看日志输出] D --> J[验证配置参数] D --> K[检查硬件连接] E --> L[性能监控分析] E --> M[资源使用分析] E --> N[瓶颈定位] F --> O[修复路径配置] G --> P[修复链接问题] H --> Q[修正语法] I --> R[分析错误信息] J --> S[修正配置] K --> T[检查硬件状态] L --> U[优化算法] M --> V[优化资源使用] N --> W[消除瓶颈] style A fill:#ffeb3b style B fill:#2196f3 style C fill:#f44336 style D fill:#ff9800 style E fill:#9c27b0 ``` ### 9.1 编译问题 #### 问题:找不到头文件 ```bash fatal error: 'device_tree/interface/MyDevice.h' file not found ``` **解决方案**: 1. 确保在`gen/device_tree/interface/`中定义了接口 2. 检查include路径配置 3. 运行代码生成:`meson compile -C builddir` #### 问题:链接错误 ```bash undefined reference to 'register_device_driver' ``` **解决方案**: 1. 确保ABI函数正确导出 2. 检查`extern "C"`包装 3. 验证meson.build配置 ### 9.2 运行时问题 #### 问题:设备初始化失败 **诊断步骤**: 1. 检查日志输出 2. 验证配置参数 3. 确认硬件连接 4. 检查权限设置 #### 问题:协议通信失败 **诊断步骤**: 1. 验证协议配置 2. 检查网络连接 3. 分析协议日志 4. 使用协议调试工具 ### 9.3 性能问题 #### 问题:设备响应慢 **优化策略**: 1. 使用异步操作 2. 实现缓冲和批处理 3. 优化锁粒度 4. 使用内存池 ## 10. 参考资料 ### 10.1 相关文档 - [项目概览](../concept_principle/component_driver_adapt.md) - [总线芯片驱动开发指南](./bus_chip_driver_guide.md) - Component Drivers API文档 - Meson构建系统文档 ### 10.2 示例代码 - `drivers/pcie_nic_card/wx/` - 网迅网卡驱动示例 - `drivers/pcie_nic_card/hisi/` - 华为海思网卡驱动示例 - `drivers/accessor/` - 通用访问器驱动示例 - `drivers/bus/i2c/` - I2C总线驱动示例 ### 10.3 工具和库 - **libmcpp**: 核心框架库 - **MCTP库**: 管理组件传输协议 - **NCSI库**: 网络控制器侧带接口协议 - **IMU库**: IMU设备通信库 --- ## 总结 本指南提供了Component Drivers项目中设备驱动开发的完整流程,从架构设计到具体实现,再到测试和优化。遵循本指南中的最佳实践,可以开发出高质量、可维护的设备驱动程序。 在开发过程中,建议: 1. **先理解再实现**:深入理解项目架构和设计理念 2. **参考现有实现**:学习已有驱动的实现模式 3. **逐步迭代**:从简单功能开始,逐步完善 4. **充分测试**:确保驱动的稳定性和可靠性 5. **文档同步**:及时更新相关文档 如有疑问,请参考现有代码实现或联系项目维护者。 --- # 部件驱动接口模型设计 > URL: https://openubmc.cn/docs/zh/latest/component_driver/general_guide/interface_model_spec.html > Language: zh # 部件驱动接口模型设计 ## 1. 概述 部件驱动接口模型是Component Drivers项目的核心架构设计,采用"配置驱动+代码生成"的设计理念,通过DDS(Device Description Standard)配置文件自动生成接口层代码和DBus设备树接口,实现了接口定义与实现的彻底分离,极大提升了开发效率和系统可扩展性。 ### 1.1 核心特性 - **DDS配置驱动**: 通过标准化的JSON配置文件定义设备接口和对象模型 - **自动代码生成**: 从DDS配置自动生成C++接口头文件和反射代码 - **接口与实现分离**: 生成的接口代码与厂商实现完全解耦 - **多层抽象**: 支持接口层、设备对象层、驱动实现层的清晰分层 - **反射机制**: 通过MC_REFLECT实现运行时属性访问和序列化 ### 1.2 技术优势 | 优势 | 说明 | 价值 | |------|------|------| | **开发效率提升** | 接口代码自动生成,无需手写 | 减少70%以上的接口代码编写工作 | | **标准化接口** | 统一的接口定义规范 | 确保多厂商设备接口一致性 | | **易于扩展** | 新增接口只需修改DDS配置 | 快速支持新设备类型 | | **跨进程访问** | 自动生成DBus接口 | 支持进程间设备管理 | | **类型安全** | 编译期类型检查 | 减少运行时错误 | | **维护性强** | 接口定义集中管理 | 接口变更影响可控 | ## 2. 设计目标 - 提供统一的设备接口定义和管理机制 - 实现接口定义与实现的完全分离 - 支持从配置文件自动生成接口代码 - 支持多厂商、多型号设备的统一管理 - 提供基于反射的动态属性访问能力 - 实现设备对象的层次化组织和管理 ## 3. 整体架构 ### 3.1 三层架构模型 ```mermaid flowchart TD subgraph 配置层["配置层 (DDS Configuration)"] DDS["DDS配置文件
(JSON格式)
- 接口定义
- 对象模型
- 路径规则"] end subgraph 代码生成["代码生成层 (Code Generation)"] Parser["DDS解析器"] CPPGen["C++接口生成器"] ReflectGen["反射代码生成器"] end subgraph 接口层["接口层 (Interface Layer)"] GenInterface["生成的接口类
gen::PCIeDevice
gen::NetworkAdapter
..."] end subgraph 实现层["实现层 (Implementation Layer)"] DevInterface["厂商接口实现
dev::PCIeDevice
dev::NetworkAdapter
..."] DevObject["设备对象
hi182x_card
cx5_card
..."] Driver["驱动实现
硬件交互
协议通信"] end DDS -->|解析| Parser Parser --> CPPGen Parser --> ReflectGen CPPGen --> GenInterface ReflectGen --> GenInterface GenInterface -->|继承实现| DevInterface DevInterface -->|组合使用| DevObject DevObject -->|调用| Driver style DDS fill:#e1f5fe style GenInterface fill:#f3e5f5 style DevInterface fill:#e8f5e8 ``` ### 3.2 数据流向 ```mermaid flowchart LR subgraph 开发阶段 A["1. 编写DDS配置"] B["2. 运行代码生成器"] C["3. 生成接口代码"] D["4. 实现厂商逻辑"] end subgraph 编译阶段 E["5. 编译驱动库"] F["6. 链接依赖"] end subgraph 运行阶段 G["7. 加载驱动"] H["8. 创建设备对象"] end A --> B --> C --> D --> E --> F --> G --> H style A fill:#ffeb3b style C fill:#4caf50 style D fill:#ff9800 ``` ## 4. DDS配置机制 ### 4.1 DDS配置文件结构 DDS (Device Description Standard) 配置文件采用JSON格式,定义了设备的完整接口模型: ```json { "Schema": "dds-v1", "Type": "Component", "DeviceCategory": "PCIeNicCard", "ID": "N/A", "Objects": { "PCIeNicCard": { "Path": "/bmc/dev/Systems/:SystemId/PCIeNicCard/:Id", "Interfaces": [ "bmc.dev.PCIeDevice", "bmc.dev.PCIeDevice.PCIeFunction", "bmc.dev.PCIeDevice.Status", "bmc.dev.PCIeDevice.Oem", "bmc.dev.PCIeCard", "bmc.dev.PCIeCard.Oem", "bmc.dev.PCIeCard.Metrics", "bmc.dev.Board", "bmc.dev.NetworkAdapter", "bmc.dev.PCIeDevice.Bandwidth", "bmc.dev.Cooling", "bmc.dev.NetworkAdapter.FaultStatus", "bmc.dev.NetworkAdapter.LogCollection", "bmc.dev.NetworkAdapter.Oem" ] }, "NicPort": { "Path": ":Parent/NicPort/:Id", "Interfaces": [ "bmc.dev.NetworkPort", "bmc.dev.NetworkPort.LinkInfo", "bmc.dev.NetworkPort.DataCenterBridging", "bmc.dev.NetworkPort.LLDPReceive", "bmc.dev.NetworkPort.Metrics" ] }, "OpticalTransceiver": { "Path": ":Parent/OpticalTransceiver", "Interfaces": [ "bmc.dev.OpticalModule", "bmc.dev.OpticalModule.Status", "bmc.dev.OpticalModule.TemperatureCelsius", "bmc.dev.OpticalModule.Voltage", "bmc.dev.OpticalModule.Power", "bmc.dev.OpticalModule.Current", "bmc.dev.OpticalModule.Diagnose" ] } } } ``` ### 4.2 DDS配置元素说明 | 字段 | 说明 | 示例 | 作用 | |------|------|------|------| | **Schema** | DDS版本标识 | "dds-v1" | 定义配置文件格式版本 | | **Type** | 设备类型 | "Component" | 标识设备大类 | | **DeviceCategory** | 设备类别 | "PCIeNicCard" | 具体设备类别名称 | | **Objects** | 设备对象集合 | {...} | 定义所有设备对象及其接口 | | **Path** | 对象路径模式 | "/bmc/dev/..." | 设备在系统中的路径规则 | | **Interfaces** | 接口列表 | [...] | 对象支持的所有接口 | ### 4.3 接口定义配置 每个接口通过独立的JSON文件定义其属性和方法: ```json { "name": "PCIeDevice", "namespace": "bmc.dev", "description": "PCIe设备基础接口", "properties": [ { "name": "DeviceName", "type": "string", "description": "设备资源名称", "writable": true }, { "name": "Location", "type": "string", "description": "当前PCIe的物理位置", "writable": true }, { "name": "Slot", "type": "uint8_t", "description": "PCIe设备的物理槽位号", "writable": true }, { "name": "SocketId", "type": "uint8_t", "description": "PCIe设备所属CPU ID", "writable": true }, { "name": "Bus", "type": "uint8_t", "description": "PCIe Root Port的总线号", "writable": true }, { "name": "Device", "type": "uint8_t", "description": "PCIe Root Port的设备号", "writable": true }, { "name": "Function", "type": "uint8_t", "description": "PCIe Root Port的功能号", "writable": true } ], "methods": [ { "name": "SetRootBDF", "description": "设置根设备BDF", "returnType": "bool", "parameters": [ {"name": "bus", "type": "uint8_t"}, {"name": "device", "type": "uint8_t"}, {"name": "function", "type": "uint8_t"} ] } ] } ``` ### 4.4 路径模式规则 路径模式支持以下特殊语法: | 语法 | 说明 | 示例 | |------|------|------| | `:参数名` | 路径参数占位符 | `/Systems/:SystemId/PCIeNicCard/:Id` | | `${参数名}` | 属性引用 | `${DeviceName}` | | `:Parent` | 父对象路径引用 | `:Parent/NicPort/:Id` | ## 5. 接口代码自动生成 ### 5.1 代码生成流程 ```mermaid flowchart TD A[读取DDS配置文件] --> B[解析JSON结构] B --> C[构建内部模型] C --> D{生成类型?} D -->|接口类| E[生成C++接口头文件] D -->|反射代码| F[生成MC_REFLECT宏] E --> H[dev::gen命名空间接口] F --> I[反射元数据] H --> K[输出到gen/include/device_tree/目录] I --> K style A fill:#ffeb3b style E fill:#4caf50 style F fill:#2196f3 ``` ### 5.2 生成的C++接口类 自动生成的C++接口类位于`dev::gen`命名空间: ```cpp // 自动生成文件: gen/include/device_tree/interface/PCIeDevice.h #ifndef GEN_PCIe_DEVICE_INTERFACE_H #define GEN_PCIe_DEVICE_INTERFACE_H #include namespace dev::gen { /** * @brief PCIe设备基础接口 * * 此接口由DDS配置自动生成,定义了PCIe设备的标准属性和方法。 * 厂商实现应继承此接口并实现具体逻辑。 */ class MC_API PCIeDevice : public mc::engine::interface { public: MC_INTERFACE("bmc.dev.PCIeDevice") property DeviceName; ///< 设备资源名称 property Location; ///< 当前PCIe的物理位置 property Slot; ///< PCIe设备的物理槽位号 property SocketId; ///< PCIe设备所属CPU ID property SystemId; ///< PCIe设备所属系统ID property Bus; ///< PCIe Root Port的总线号 property Device; ///< PCIe Root Port的设备号 property Function; ///< PCIe Root Port的功能号 property SlotType; ///< PCIe设备所在槽位的类型 property DeviceType; ///< PCIe设备类型 property Model; ///< PCIe标卡产品型号 property Manufacturer; ///< 厂商 property PartNumber; ///< 部件编码 property SerialNumber; ///< 序列号 property FirmwareVersion; ///< PCIe标卡的固件版本号 property MaxPCIeType; ///< 最大支持的PCIe接口规格 property PCIeType; ///< 实际的PCIe接口规格 property MaxLanes; ///< 支持的最大通道数 property LaneInUse; ///< 实际使用的通道数 virtual bool SetRootBDF(uint8_t bus, uint8_t device, uint8_t function) = 0; }; } // namespace dev::gen #endif // GEN_PCIe_DEVICE_INTERFACE_H ``` > 说明:以上内容与 `gen/include/device_tree/interface/PCIeDevice.h` 完全一致。接口基类为 `mc::engine::interface`(单模板参数),命名空间为 `dev::gen`,头文件包含 `device_tree/base.h`。 ### 5.3 接口反射注册 运行时属性访问通过反射机制实现。与生成的接口头文件不同,反射注册是在厂商接口实现(`.cpp`)中通过 `MC_REFLECT(dev::Xxx)` 宏完成,并不单独生成 `_reflect.h` 文件。示例(与库中 `drivers/pcie_nic_card/hisi/interface/pcie_device.cpp` 一致): ```cpp // 厂商接口实现文件: drivers/pcie_nic_card/hisi/interface/pcie_device.cpp (节选) namespace dev { // 反射注册:将实现类的属性与 D-Bus 接口关联 MC_REFLECT(dev::PCIeDevice) } // namespace dev ``` 反射注册在接口实现源文件中定义,其他厂商接口(`PCIeCard`、`NetworkAdapter`、`Cooling`、`Board`、`Fru` 等)均在各自的 `.cpp` 中以相同方式调用 `MC_REFLECT(dev::Xxx)` 完成注册。 ### 5.4 生成文件组织结构 ```shell gen/ └── include/ └── device_tree/ └── interface/ # 生成的接口类(全部为 dev::gen 命名空间) ├── PCIeDevice.h # PCIe设备接口 ├── NetworkAdapter.h # 网络适配器接口 ├── NetworkPort.h # 网络端口接口 └── ... # 其他接口 ``` ## 6. 接口实现机制 ### 6.1 厂商接口实现 厂商通过继承生成的接口基类实现具体逻辑: ```cpp // 厂商实现文件: drivers/pcie_nic_card/hisi/interface/pcie_device.h #ifndef PCIE_DEVICE_INTERFACE_H #define PCIE_DEVICE_INTERFACE_H #include #include #include #include #include namespace dev { using smbus_obj_ptr = mc::shared_ptr; /** * @brief PCIe设备接口的海思厂商实现 * * 继承 auto-generated 的 dev::gen::PCIeDevice 基类。 * 厂商实现类需以 mc::engine::interface<实现类, 基类> 双模板参数形式继承, * 使接口同时具备厂商实现与生成基类的双重类型信息。 */ class MC_API PCIeDevice : public mc::engine::interface { public: PCIeDevice() = default; ~PCIeDevice() = default; public: // 实现基类虚方法 bool SetRootBDF(uint8_t bus, uint8_t device, uint8_t function) override; public: void set_smbus_obj(smbus_obj_ptr smbus_obj); bool set_slot_by_smbus(uint8_t slot); private: smbus_obj_ptr m_smbus_obj; public: void replace_dynamic_property(mc::mutable_dict& object, const mc::dict& connector); }; } // namespace dev #endif // PCIE_DEVICE_INTERFACE_H ``` 实现文件(节选): ```cpp // 厂商实现文件: drivers/pcie_nic_card/hisi/interface/pcie_device.cpp (节选) namespace dev { bool PCIeDevice::SetRootBDF(uint8_t bus, uint8_t device, uint8_t function) { if (bus == 0 && device == 0 && function == 0) { std::cerr << "Error: Invalid BDF values" << std::endl; return false; } Bus = bus; Device = device; Function = function; return true; } void PCIeDevice::set_smbus_obj(smbus_obj_ptr smbus_obj) { m_smbus_obj = smbus_obj; } // 反射注册:单参数形式,在 .cpp 中完成 MC_REFLECT(dev::PCIeDevice) } // namespace dev ``` > 说明: > > 1. 厂商实现类用 **双模板参数** `mc::engine::interface` 继承,而非直接 `: public gen::PCIeDevice`。 > 2. 反射注册为 **单参数** `MC_REFLECT(dev::PCIeDevice)`,在 `.cpp` 中完成,无 3 参数形式。 > 3. 当前 `dev::PCIeDevice` 不包含 NCSI 定时任务成员,也不声明 `pcie_device_bdf_changed` 信号;该信号声明于 `dev::PCIeDevice_PCIeFunction`(见 `interface/pcie_device/pcie_function.h`)。NCSI 更新任务由具体网卡设备对象(如 `hi182x_card`)及各业务接口发起。 ### 6.2 设备对象组合接口 设备对象通过组合多个接口实现复杂功能: ```cpp // 设备对象文件: drivers/pcie_nic_card/hisi/hi182x/hi182x_card.h #ifndef HI182X_CARD_H #define HI182X_CARD_H #include #include #include #include #include #include #include "hi182x_port.h" #include "interface/board.h" #include "interface/cooling.h" #include "interface/fru.h" #include "interface/network_adapter.h" // ... 其余接口头文件 namespace dev { using ncsi_over_mctp_hw_ptr = std::shared_ptr; using smbus_obj_ptr = mc::shared_ptr; using imu_ptr = std::shared_ptr; class hi182x_card : public mc::engine::object { public: // MC_OBJECT宏定义:类名 / 设备类型名 / 路径模式 / 支持的接口列表 MC_OBJECT( hi182x_card, "PCIeNicCard", "/bmc/dev/Systems/1/PCIeNicCard/${object_name}", (PCIeDevice)(PCIeDevice_PCIeFunction)(PCIeDevice_Oem)(PCIeDevice_Status)(PCIeCard)(PCIeCard_Oem)(PCIeCard_Metrics)(NetworkAdapter)(NetworkAdapter_FaultStatus)(Cooling)(NetworkAdapter_Oem)(Board)(PCIeDevice_Bandwidth)(NetworkAdapter_LogCollection)(Fru)) hi182x_card(); ~hi182x_card(); // 生命周期方法(非虚,不带 override) bool start(); bool stop(); bool init(mc::mutable_dict& csr_object, const mc::dict& connector); void init_network_ports(); void replace_dynamic_property(mc::mutable_dict& object, const mc::dict& connector); // === 接口实例(组合模式) === NetworkAdapter_Oem m_network_adapter_oem; PCIeDevice m_pcie_device; PCIeDevice_PCIeFunction m_pcie_device_pcie_function; PCIeDevice_Oem m_pcie_device_oem; PCIeDevice_Status m_pcie_device_status; PCIeCard m_pcie_card; PCIeCard_Oem m_pcie_card_oem; PCIeCard_Metrics m_pcie_card_metrics; Cooling m_cooling; NetworkAdapter m_network_adapter; NetworkAdapter_FaultStatus m_network_adapter_fault_status; Board m_board; PCIeDevice_Bandwidth m_pcie_device_bandwidth; NetworkAdapter_LogCollection m_network_adapter_log_collection; Fru m_fru; uint8_t m_system_id; private: std::vector m_network_ports; // === 协议管理 === bool start_ncsi_protocol(); void stop_ncsi_update_task(); bool start_smbus_protocol(); bool init_smbus_protocol(); bool init_imu_protocol(); bool start_protocol(); ref_chip_ptr m_ref_chip; smbus_obj_ptr m_smbus_obj; imu_ptr m_imu_obj; ncsi_over_mctp_hw_ptr m_ncsi_over_mctp_huawei; mc::milliseconds m_interval = mc::milliseconds(5000); mc::milliseconds m_smbus_interval = mc::milliseconds(5000); mc::shared_ptr m_mctp_object; }; } // namespace dev // MC_REFLECT定义:建立接口成员与 D-Bus 接口名的映射 MC_REFLECT(dev::hi182x_card, ((m_system_id, "SystemId"))((m_pcie_device, "bmc.dev.PCIeDevice")) ((m_pcie_device_pcie_function, "bmc.dev.PCIeDevice.PCIeFunction")) ((m_pcie_device_oem, "bmc.dev.PCIeDevice.Oem")) ((m_pcie_device_status, "bmc.dev.PCIeDevice.Status")) ((m_pcie_card, "bmc.dev.PCIeCard"))((m_pcie_card_oem, "bmc.dev.PCIeCard.Oem")) ((m_pcie_card_metrics, "bmc.dev.PCIeCard.Metrics")) ((m_network_adapter, "bmc.dev.NetworkAdapter")) ((m_network_adapter_fault_status, "bmc.dev.NetworkAdapter.FaultStatus")) ((m_cooling, "bmc.dev.Cooling"))((m_network_adapter_oem, "bmc.dev.NetworkAdapter.Oem")) ((m_board, "bmc.dev.Board"))((m_pcie_device_bandwidth, "bmc.dev.PCIeDevice.Bandwidth")) ((m_fru, "bmc.dev.Fru")) ((m_network_adapter_log_collection, "bmc.dev.NetworkAdapter.LogCollection"))) #endif // HI182X_CARD_H ``` **子设备识别(节选自 `init_network_ports()`,与库中一致)**: ```cpp // 通过对象名前缀识别设备类型,使用 dynamic_cast 并校验空指针 for (auto& object : objects) { std::string sub_name = object->get_name(); if (sub_name.substr(0, sub_name.find_first_of("_")) == "NicPort") { auto* port = dynamic_cast(object.get()); if (port == nullptr) { elog("hi182x_card child ${name} is not hi182x_port, skip", ("name", sub_name)); continue; } ilog("hi182x_card init network port ${name}", ("name", sub_name)); m_network_ports.push_back(port); } } ``` ### 6.3 接口层次关系 ```mermaid classDiagram class gen_PCIeDevice { <> +DeviceName: property~string~ +VendorId: property~string~ +Bus: property~uint8_t~ +Device: property~uint8_t~ +Function: property~uint8_t~ +SetRootBDF()* +SetDeviceBDF()* } class dev_PCIeDevice { +SetRootBDF() +set_smbus_obj() +set_slot_by_smbus() +replace_dynamic_property() -m_smbus_obj } class dev_PCIeDevice_PCIeFunction { +pcie_device_bdf_changed: signal } class hi182x_card { +init() +start() +stop() +m_pcie_device: dev_PCIeDevice +m_network_adapter: dev_NetworkAdapter +m_pcie_card: dev_PCIeCard +m_board: dev_Board -m_network_ports -start_protocol() } dev__gen_PCIeDevice <|-- dev_PCIeDevice : 继承(interface双模板) hi182x_card *-- dev_PCIeDevice : 组合 note for dev__gen_PCIeDevice "自动生成的接口基类\n位于dev::gen命名空间" note for dev_PCIeDevice "厂商实现类\nmc::engine::interface" note for hi182x_card "设备对象类\n组合多个接口" ``` ## 7. 完整开发流程示例 ### 7.1 步骤1: 编写DDS配置文件 ```json // dds/PCIeGpuCard.dds.json { "Schema": "dds-v1", "Type": "Component", "DeviceCategory": "PCIeGpuCard", "ID": "N/A", "Objects": { "PCIeGpuCard": { "Path": "/bmc/dev/Systems/:SystemId/PCIeGpuCard/:Id", "Interfaces": [ "bmc.dev.PCIeDevice", "bmc.dev.PCIeCard", "bmc.dev.Gpu", "bmc.dev.Board" ] }, "GpuMemory": { "Path": ":Parent/Memory/:Id", "Interfaces": [ "bmc.dev.Memory", "bmc.dev.Memory.Metrics" ] } } } ``` ### 7.2 步骤2: 运行代码生成器 ```bash # 生成接口代码 ./tools/dds_codegen.py \ --input dds/PCIeGpuCard.dds.json \ --output-cpp gen/include/device_tree/ # 生成输出(仅接口头文件,无 _reflect.h;反射在接口 .cpp 中注册): # gen/include/device_tree/interface/Gpu.h # gen/include/device_tree/interface/Memory.h ``` ### 7.3 步骤3: 实现厂商接口 ```cpp // drivers/pcie_gpu_card/nvidia/interface/gpu.h #ifndef NVIDIA_INTERFACE_GPU_H #define NVIDIA_INTERFACE_GPU_H #include namespace dev { /** * @brief GPU接口的NVIDIA厂商实现 */ class Gpu : public mc::engine::interface { public: // 实现基类虚方法 bool Initialize() override { // NVIDIA特定的初始化逻辑 return init_nvidia_gpu(); } bool GetStatus() override { // 通过NVIDIA驱动获取GPU状态 return query_nvidia_status(); } private: bool init_nvidia_gpu(); bool query_nvidia_status(); }; } // namespace dev #endif // NVIDIA_INTERFACE_GPU_H ``` ### 7.4 步骤4: 实现设备对象 ```cpp // drivers/pcie_gpu_card/nvidia/tesla_t4/tesla_t4_card.h #ifndef NVIDIA_TESLA_T4_CARD_H #define NVIDIA_TESLA_T4_CARD_H #include #include "drivers/pcie_gpu_card/nvidia/interface/gpu.h" #include "drivers/pcie_gpu_card/nvidia/interface/pcie_device.h" namespace dev { class tesla_t4_card : public mc::engine::object { public: MC_OBJECT( tesla_t4_card, "PCIeGpuCard", "/bmc/dev/Systems/1/PCIeGpuCard/${object_name}", (PCIeDevice)(PCIeCard)(Board)) bool init(mc::mutable_dict& csr_object, const mc::dict& connector); bool start(); bool stop(); // 接口实例 dev::PCIeDevice m_pcie_device; dev::PCIeCard m_pcie_card; dev::Gpu m_gpu; dev::Board m_board; }; } // namespace dev MC_REFLECT(dev::tesla_t4_card, ((m_pcie_device, "bmc.dev.PCIeDevice")) ((m_pcie_card, "bmc.dev.PCIeCard")) ((m_gpu, "bmc.dev.Gpu")) ((m_board, "bmc.dev.Board")) ) #endif // NVIDIA_TESLA_T4_CARD_H ``` ### 7.5 步骤5: 实现ABI导出 ```cpp // drivers/pcie_gpu_card/nvidia/tesla_t4/tesla_t4_abi.cpp #include #include "tesla_t4_card.h" extern "C" { driver_handle_t create_tesla_t4_card(void* service, const char* name) { try { if (service == nullptr || name == nullptr) { return nullptr; } auto* device = new dev::tesla_t4_card(); device->set_service(static_cast(service)); device->set_object_name(name); return (void*)device; } catch (const std::exception& e) { elog("Error creating tesla_t4_card: ${error}", ("error", e.what())); return nullptr; } } status_t init_tesla_t4_card(driver_handle_t device, void* csr_object, void* connector) { if (device == nullptr || csr_object == nullptr || connector == nullptr) { return STATUS_ERROR; } auto* device_object = static_cast(device); auto* csr_object_ptr = static_cast(csr_object); auto* connector_ptr = static_cast(connector); bool ret = device_object->init(*csr_object_ptr, *connector_ptr); return ret ? STATUS_OK : STATUS_ERROR; } status_t start_tesla_t4_card(driver_handle_t device) { if (device == nullptr) { return STATUS_ERROR; } auto* device_object = static_cast(device); bool ret = device_object->start(); return ret ? STATUS_OK : STATUS_ERROR; } status_t stop_tesla_t4_card(driver_handle_t device) { if (device == nullptr) { return STATUS_ERROR; } auto* device_object = static_cast(device); bool ret = device_object->stop(); return ret ? STATUS_OK : STATUS_ERROR; } device_driver_t tesla_t4_card_driver = { .device_name = "PCIeGpuCard", .ctor = create_tesla_t4_card, .init = init_tesla_t4_card, .start = start_tesla_t4_card, .stop = stop_tesla_t4_card }; status_t register_device_driver(device_driver_t** device_driver, uint8_t* count) { *device_driver = &tesla_t4_card_driver; *count = 1; return STATUS_OK; } } // extern "C" ``` ### 7.6 步骤6: 编译和测试 ```bash # 配置构建 meson setup builddir # 编译驱动库 meson compile -C builddir # 运行测试 meson test -C builddir # 安装驱动 meson install -C builddir ``` ## 8. 最佳实践 ### 8.1 DDS配置设计原则 | 原则 | 说明 | 示例 | |------|------|------| | **单一职责** | 每个接口专注单一功能域 | NetworkPort.LinkInfo只负责链路信息 | | **接口组合** | 通过组合而非继承扩展功能 | PCIeNicCard组合PCIeDevice+NetworkAdapter | | **路径规范** | 使用层次化路径表示设备关系 | /Systems/:SystemId/PCIeNicCard/:Id | | **属性命名** | 使用大驼峰命名法保持一致 | DeviceName, VendorId, NetworkPortCount | | **只读/可写** | 明确标识属性的访问权限 | VendorId只读, DeviceName可写 | ### 8.2 接口实现规范 ```cpp // ✅ 推荐:清晰的接口实现 class PCIeDevice : public mc::engine::interface { public: // 1. 实现所有虚方法 bool SetRootBDF(uint8_t bus, uint8_t device, uint8_t function) override { // 参数验证 if (!validate_bdf(bus, device, function)) { return false; } // 更新生成基类中的属性 Bus = bus; Device = device; Function = function; return true; } private: // 2. 使用私有方法封装复杂逻辑 bool validate_bdf(uint8_t bus, uint8_t device, uint8_t function) { return !(bus == 0 && device == 0 && function == 0); } }; // ❌ 不推荐:不完整的实现 class PCIeDevice : public mc::engine::interface { public: // 缺少虚方法实现,导致编译错误 // 缺少日志记录 // 缺少错误处理 }; ``` ### 8.3 设备对象设计模式 ```cpp // ✅ 推荐:标准的设备对象模式 class hi182x_card : public mc::engine::object { public: // 1. 使用MC_OBJECT定义对象元数据 MC_OBJECT(hi182x_card, "PCIeNicCard", "/bmc/dev/Systems/1/PCIeNicCard/${object_name}", (PCIeDevice)(NetworkAdapter)(Board)) // 2. 实现标准生命周期方法 bool init(mc::mutable_dict& csr_object, const mc::dict& connector) { // 初始化逻辑 return true; } bool start() { // 启动逻辑 return true; } bool stop() { // 停止逻辑 return true; } // 3. 声明接口实例 dev::PCIeDevice m_pcie_device; dev::NetworkAdapter m_network_adapter; dev::Board m_board; private: // 4. 私有成员和辅助方法 void init_ports(); bool start_protocol(); }; // 5. 定义反射映射 MC_REFLECT(dev::hi182x_card, ((m_pcie_device, "bmc.dev.PCIeDevice")) ((m_network_adapter, "bmc.dev.NetworkAdapter")) ((m_board, "bmc.dev.Board")) ) ``` ### 8.4 性能优化建议 ```cpp // 1. 优先使用属性提供的批量/只读访问接口 // 属性值通过 .get_value() 一次读取,避免重复反序列化 std::string model = m_pcie_device.Model.get_value().as(); // 2. 缓存频繁访问的属性(按实际存在的属性为准,此处以 DeviceType 为例) class PCIeDevice { private: std::string m_cached_device_type; bool m_device_type_cached = false; public: const std::string& get_device_type() { if (!m_device_type_cached) { m_cached_device_type = DeviceType.get_value().as(); m_device_type_cached = true; } return m_cached_device_type; } }; ``` ## 9. 总结 部件驱动接口模型通过DDS配置驱动的设计理念,实现了设备驱动开发的标准化和自动化: ### 9.1 核心优势 1. **配置驱动开发**: DDS配置文件定义设备接口和对象模型 2. **自动代码生成**: 从配置自动生成C++接口和反射代码 3. **接口实现分离**: 生成的接口代码与厂商实现完全解耦 4. **类型安全**: 编译期类型检查,减少运行时错误 5. **易于扩展**: 新增接口只需修改DDS配置 ### 9.2 开发流程 ```shell DDS配置 → 代码生成 → 接口实现 → 设备对象 → ABI导出 → 编译测试 ``` ### 9.3 适用场景 - 需要统一管理多种设备类型的系统 - 需要支持多厂商设备的平台 - 需要快速开发新设备驱动的项目 - 需要接口标准化的设备管理系统 通过遵循本文档的设计原则和最佳实践,开发者可以高效地开发出高质量、可维护的设备驱动程序,构建强大的设备管理系统。 --- # 南向硬盘驱动适配指南 > URL: https://openubmc.cn/docs/zh/latest/component_driver/hdd_adapt/hdd_driver_adapt_guide.html > Language: zh > 南向驱动是基于硬件组件驱动程序框架,采用分层架构设计,支持多种设备类型和通信协议。本文档面向硬盘适配的设备驱动开发者,提供从设计到实现的完整开发流程,并基于现有代码实例分析,提供一篇快速适配的开发指南。 **前置阅读**: - 《部件驱动 2.0 适配方案概述》:[部件驱动开发简介](../concept_principle/component_driver_adapt.md) - 《部件驱动 2.0-设备驱动开发指南》:[设备驱动开发指南](../general_guide/device_driver_develop_guide.md) **相关文档**: - 驱动需实现的接口契约见 [3.3 硬盘驱动规范](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3.3-硬盘驱动规范.md),机器可读定义在 [`dmc/`](https://gitcode.com/openUBMC/component_drivers/tree/main/dmc)(总览:[Device Management Contract](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md)) - 硬盘背板(CSR 方式)适配见官网[《硬盘背板开发指南》](../../hardware/system_adapt/HDDkBackplane_adapt/HDDkBackplane_Development_Guide.md) - SSD 存储基础见官网[《SSD 存储介绍》](../../hardware/component_adapt/hdd_adapt/storage_ssd_introduction.md) - MCTP 协议背景见官网[《MCTP 介绍》](../../hardware/principle_intro/mctp.md) ## 1. 概述 ### 1.1 什么是南向硬盘驱动适配? 南向硬盘驱动适配是指在BMC系统中,为不同厂商的PCIe NVMe硬盘提供统一的驱动程序接入方案,使BMC能够管理和监控硬盘设备。 ### 1.2 适配后可以实现什么功能? - 获取硬盘基本信息(厂商、型号、序列号、固件版本等) - 监控硬盘状态(温度、健康状态、寿命等) - 读取SMART信息(读写次数、错误率等) - 获取硬盘容量和使用情况 - 故障诊断和日志收集 ### 1.3 需要了解的关键概念 #### 设备对象 | 对象类型 | 说明 | 示例 | |---------|------|------| | **NVMe硬盘主对象** | 代表整个PCIe NVMe硬盘 | `hw_nvme_pcie4` | #### 接口 - **gen命名空间**:自动生成的接口基类,定义属性(位于 `dev::gen` 命名空间) - **dev命名空间**:厂商具体实现类,实现功能 - **接口组合**:一个设备可以实现多个接口,如`PCIeDevice`、`NVMe`、`NVMe.Smart`等 #### 协议库 - **NVMe-MI over MCTP**:NVMe管理接口协议,通过PCIe或SMBus与硬盘通信 - **NVMe-MI over VPD**:通过VPD(Vital Product Data)访问硬盘信息 - 不同厂商可能使用不同的协议扩展 ### 1.4 驱动分层架构 1. **分层架构**:构建了一个从接口定义到硬件交互的完整体系,接口定义层(DMC)→设备接口层→设备对象层→设备驱动层,每层职责明确,协同工作; 2. **设计理念**:接口与实现分离,先是 `dmc/`(Device Management Contract)建立接口契约,再在"设备接口层"生成/落地 C++ 接口,由各厂商提供"设备驱动层"的具体部件驱动实现; ```mermaid flowchart TD subgraph dmc["接口定义层(dmc)"] direction TB JSON_DEF["dmc/intf JSON 契约"] JSON_PCIe["PCIeDevice.json"] JSON_NVMe["NVMe.json"] JSON_Smart["NVMe.Smart.json"] JSON_DEF --> JSON_PCIe JSON_DEF --> JSON_NVMe JSON_DEF --> JSON_Smart end subgraph CODE_GEN["代码生成工具链"] Parser["JSON解析器"] Generator["C++接口代码生成器"] end subgraph devmon["设备监控系统(devmon)"] direction TB subgraph plugins["设备插件(/plugins)"] direction TB subgraph interface_layer["设备接口层"] PCIeDevice["PCIeDevice接口"] NVMe["NVMe接口"] NVMe_Management["NVMe.Management接口"] NVMe_Smart["NVMe.Smart接口"] NVMe_ProductInfo["NVMe.ProductInfo接口"] Cooling["Cooling接口"] end subgraph object_layer["设备对象层"] NVMeDisk["hw_nvme_pcie4对象"] end subgraph driver_layer["设备驱动层"] huawei["华为实现"] other["其他厂商实现"] end interface_layer --> object_layer object_layer --> driver_layer end end app_layer["应用层

利用插件接口
实现系统功能"] app_layer -->|"调用"| interface_layer dmc --> CODE_GEN CODE_GEN --> interface_layer JSON_PCIe -->|"定义接口"| PCIeDevice JSON_NVMe -->|"定义接口"| NVMe JSON_Smart -->|"定义接口"| NVMe_Smart PCIeDevice -->|"组合"| NVMeDisk NVMe -->|"组合"| NVMeDisk NVMe_Management -->|"组合"| NVMeDisk NVMe_Smart -->|"组合"| NVMeDisk NVMe_ProductInfo -->|"组合"| NVMeDisk Cooling -->|"组合"| NVMeDisk NVMeDisk -->|"厂商实现"| huawei NVMeDisk -->|"厂商实现"| other ``` ## 2. 前置准备 ### 2.1 准备编译环境 可参考社区的[Docker开发环境搭建](../../installation/env_build/docker_env.md)。在完成环境搭建后,推荐通过scripts目录下的smart_build.sh完成首次编译,如果希望通过手动构建的方式,可参考本项目的[README.md文档](https://gitcode.com/openUBMC/component_drivers/blob/main/README.md) ### 2.2 明确硬盘信息 #### 必需信息 | 信息项 | 说明 | 示例 | |-------|------|------| | **VID** | Vendor ID(厂商ID) | `0x19e5` | | **DID** | Device ID(设备ID) | `0x0222` | | **SVID** | Subsystem Vendor ID | `0x19e5` | | **SSID** | Subsystem Device ID | `0x0052` | #### 协议信息 - 支持的通信协议(NVMe-MI标准协议、厂商OEM扩展等) - 协议命令集(获取温度、SMART信息等命令的定义) - 数据格式(响应数据的字节序、字段定义等) #### 硬件信息 - 硬盘容量 - 是否支持NVMe-MI over PCIe - 是否支持NVMe-MI over SMBus - 特殊功能(如厂商特定SMART信息等) ### 2.3 了解驱动规范 驱动规范定义了驱动需要实现的接口。硬盘的驱动规范可参考本项目归档的[硬盘驱动规范](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3.3-硬盘驱动规范.md),机器可读定义在[`dmc/`](https://gitcode.com/openUBMC/component_drivers/tree/main/dmc)(总览:[Device Management Contract](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md)) ### 2.4 了解工程目录 Component Drivers项目采用分层架构设计,硬盘驱动适配需要了解以下关键目录结构: #### 2.4.1 项目整体结构 ```shell component_drivers/ ├── drivers/ # 设备驱动实现目录(各类硬件设备驱动) ├── gen/ # 自动生成的代码目录(接口基类) ├── libraries/ # 协议库目录(通信协议封装) ├── tests/ # 测试代码目录 ├── docs/ # 文档目录 ├── include/ # 公共头文件目录 └── meson.build # 构建配置文件 ``` #### 2.4.2 硬盘驱动目录结构(drivers目录) `drivers/`目录包含所有硬件设备的具体驱动实现,按设备类型组织。以下为PCIe NVMe硬盘驱动的核心目录结构(节选,完整内容见[代码仓](https://gitcode.com/openUBMC/component_drivers/)): ```shell drivers/ ├── pcie_nvme/ # PCIe NVMe硬盘驱动(本指南重点) │ └── huawei/ # 华为硬盘驱动 │ ├── csr/ # 设备配置文件 │ │ ├── 14140224_PROTOCOL_19e5.dds # 设备描述(DDS) │ │ └── 14140224_PROTOCOL_19e5.sr # 资源描述(SR) │ ├── hw_nvme_pcie4/ # 华为NVMe PCIe4硬盘实现 │ │ ├── hw_nvme_pcie4.h # 硬盘主对象头文件 │ │ ├── hw_nvme_pcie4.cpp # 硬盘主对象实现 │ │ ├── hw_nvme_pcie4_abi.cpp # ABI导出接口 │ │ └── meson.build # 构建配置 │ ├── interface/ # 接口实现目录(继承gen基类) │ │ ├── pcie_device/ # PCIe设备接口子目录 │ │ │ ├── oem/ # OEM扩展 │ │ │ ├── pcie_function/ # PCIe功能接口 │ │ │ └── status/ # 状态接口 │ │ ├── pcie_device.h/cpp # PCIe设备接口实现 │ │ ├── nvme/ # NVMe子接口 │ │ │ ├── management.h/cpp # 管理接口 │ │ │ ├── product_info.h/cpp # 产品信息接口 │ │ │ ├── status.h/cpp # 状态接口 │ │ │ ├── smart.h/cpp # SMART接口 │ │ │ ├── basic_management.h/cpp # 基础管理接口 │ │ │ ├── nvme_mi.h/cpp # NVMe-MI接口 │ │ │ ├── log_collection.h/cpp # 日志收集接口 │ │ │ ├── vendor_specific_smart.h/cpp # 厂商特定SMART接口 │ │ │ ├── multi_record.h/cpp # 多记录接口 │ │ │ └── oem.h/cpp # OEM扩展接口 │ │ ├── upgrade.h/cpp # 升级接口 │ │ ├── cooling.h/cpp # 温度监控接口 │ │ └── meson.build │ └── meson.build │ ├── bus/ # 总线驱动 ├── chip/ # 芯片驱动 ├── internal/ # 内部实现(驱动框架基础类) └── meson.build ``` ##### 关键目录说明 | 目录 | 说明 | 用途 | |------|------|------| | **pcie_nvme/** | PCIe NVMe硬盘驱动根目录 | 按厂商组织硬盘驱动 | | **huawei/csr/** | 设备配置文件目录 | 存放DDS/SR配置文件,定义设备接口 | | **huawei/hw_nvme_pcie4/** | 华为NVMe硬盘实现 | 包含硬盘对象的实现代码 | | **huawei/interface/** | 接口实现目录 | 继承gen基类,实现具体协议逻辑和数据更新 | | **internal/** | 内部基础框架 | 提供驱动框架的基础类 | #### 2.4.3 硬盘设备对象层次 硬盘驱动中涉及的主要设备对象: | 对象类型 | 说明 | 示例类 | |---------|------|--------| | **NVMe硬盘主对象** | 代表整个PCIe NVMe硬盘,组合各接口实现 | `hw_nvme_pcie4` | | **接口实现对象** | 硬盘主对象的成员,每个对应一个管理接口 | `NVMe_Smart`、`Cooling` | 与GPU驱动不同,硬盘驱动只有一个主对象,各功能(SMART、温度、状态等)以接口成员的方式组合在主对象中,通过继承不同的gen接口实现相应功能,如`bmc.dev.NVMe.Smart`、`bmc.dev.Cooling`等接口 #### 2.4.4 gen目录 - 自动生成的接口基类 `gen/`目录包含自动生成的接口基类定义,驱动代码继承这些基类实现功能。**注意:此目录的代码由工具自动生成,不要手动修改。** ##### 目录结构 ```shell gen/ ├── include/ # 头文件目录 │ └── device_tree/ │ ├── base.h # 基础类定义 │ ├── interface/ # 接口基类定义 │ │ ├── NVMe.h # NVMe接口基类 │ │ ├── NVMe/ # NVMe子接口 │ │ │ ├── Management.h # 管理接口基类 │ │ │ ├── ProductInfo.h # 产品信息接口基类 │ │ │ ├── Status.h # 状态接口基类 │ │ │ ├── Smart.h # SMART接口基类 │ │ │ ├── BasicManagement.h # 基础管理接口基类 │ │ │ ├── NVMeMI.h # NVMe-MI接口基类 │ │ │ ├── LogCollection.h # 日志收集接口基类 │ │ │ ├── MultiRecord.h # 多记录接口基类 │ │ │ ├── VendorSpecificSmart.h # 厂商特定SMART接口基类 │ │ │ └── Oem.h # OEM扩展接口基类 │ │ ├── PCIeDevice.h # PCIe设备接口基类 │ │ └── Cooling.h # 温度监控接口基类 │ │ │ └── object/ # 对象组合定义 │ └── NVMe/ │ └── nvme.h # NVMe对象组合基类 │ ├── src/ # 源文件目录(与include结构对应) └── meson.build ``` ##### 关键概念 | 概念 | 说明 | 示例 | |------|------|------| | **接口基类** | 定义接口的属性和方法签名 | `gen::NVMe`定义了`MediaType`、`Protocol`等属性 | | **对象组合** | 将多个接口组合成完整对象 | NVMe对象组合了`PCIeDevice`、`NVMe`、`Smart`等接口 | | **命名空间** | 生成的代码位于`dev::gen`命名空间 | 驱动代码继承`dev::gen::NVMe`实现`dev::NVMe` | | **自动生成** | 基于模型文件自动生成,不手动修改 | 通过修改模型文件(JSON)重新生成 | ##### 使用方式 驱动开发时,需要继承对应的gen基类并实现功能: ```cpp // 继承gen命名空间的基类(双参模板:自身类型 + gen基类) class NVMe_Smart : public mc::engine::interface { public: // 实现具体功能 void update_smart_info(); void start_mctp_update_task(...); }; // 注册(在实现文件末尾) MC_REFLECT(dev::NVMe_Smart, (gen::NVMe_Smart), ()) ``` #### 2.4.5 libraries目录 - 通信协议库 `libraries/`目录包含各种通信协议的封装实现,为驱动提供标准化的协议接口。 ##### 目录结构 ```shell libraries/ ├── mctp/ # MCTP协议库(管理组件传输协议) │ ├── mctp.h # MCTP协议接口定义 │ ├── mctp.cpp # MCTP协议实现 │ ├── pcie_transport.h # PCIe传输层实现 │ ├── pcie_transport.cpp │ └── meson.build │ ├── nvme/ # NVMe协议库 │ ├── nvme_mi_over_mctp.h/cpp # NVMe-MI标准协议 │ ├── nvme_mi_over_mctp_huawei.h/cpp # 华为NVMe-MI协议扩展 │ ├── nvme_mi_vpd.h/cpp # NVMe-MI VPD接口 │ ├── sff_vpd.h/cpp # SFF VPD协议 │ ├── vpd_protocol.h # VPD协议公共定义 │ ├── vpd_str_utils.h # VPD字符串工具 │ └── meson.build │ └── meson.build ``` ##### 协议库说明 | 协议库 | 说明 | 传输方式 | 应用场景 | |--------|------|---------|---------| | **mctp** | 管理组件传输协议(DMTF标准) | PCIe、SMBus | 作为底层传输协议,封装上层协议消息 | | **nvme** | NVMe管理接口协议 | MCTP over PCIe/SMBus | 硬盘管理的主要协议,获取硬盘状态、SMART信息 | | **nvme_mi_vpd** | NVMe-MI VPD协议 | VPD | 获取硬盘VPD信息、温度等数据 | ##### 协议分层关系 ```shell 应用层: 硬盘驱动代码 ↓ 协议层: NVMe-MI over MCTP (nvme_mi_over_mctp_huawei) ↓ 传输层: MCTP (mctp + pcie_transport) ↓ 物理层: PCIe硬件 / SMBus硬件 ``` ##### 使用示例 ```cpp // 1. 创建MCTP对象 mctp* mctp_object = new mctp(this, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NVME_MI, ""); // 2. 创建NVMe-MI协议对象 auto nvme_mi_huawei = std::make_shared(*mctp_object); // 3. 发送NVMe-MI请求 auto response = nvme_mi_huawei->get_smart_info(); // 4. 创建VPD对象 auto nvme_mi_vpd_obj = std::make_shared(this); nvme_mi_vpd_obj->init(); // 5. 读取VPD数据 double temperature = nvme_mi_vpd_obj->get_temperature(); ``` #### 2.4.6 目录之间的关系 ```mermaid flowchart TB subgraph "应用层" Driver["drivers/pcie_nvme/huawei/hw_nvme_pcie4/
厂商驱动实现"] end subgraph "接口层" Interface["drivers/pcie_nvme/huawei/interface/
接口实现类"] GenInterface["gen/include/device_tree/interface/
接口基类定义"] end subgraph "协议层" NVMeMI["libraries/nvme/
NVMe-MI协议实现"] MCTP["libraries/mctp/
MCTP传输协议"] end subgraph "框架层" Internal["drivers/internal/
驱动框架基类"] end Driver -->|继承| Interface Interface -->|继承| GenInterface Driver -->|调用| NVMeMI NVMeMI -->|使用| MCTP Driver -->|使用| Internal style Driver fill:#e1f5ff style GenInterface fill:#fff4e1 style NVMeMI fill:#ffe1f5 ``` ##### 工作流程 1. **代码生成**:根据模型文件生成`gen/`目录下的接口基类 2. **接口实现**:在`drivers/*/interface/`下继承gen基类,实现具体功能 3. **驱动组装**:在`drivers/*/具体型号/`下组合接口,创建完整驱动对象 4. **协议调用**:驱动通过`libraries/`中的协议库与硬件通信 5. **框架支持**:`drivers/internal/`提供基础设施支持 ### 2.5 驱动协议架构 ```mermaid flowchart LR subgraph "设备驱动层" Driver["设备驱动
hw_nvme_pcie4"] end subgraph "协议库层" MCTP["MCTP
传输协议"] NVMeMI["NVMe-MI over MCTP
华为扩展"] VPD["NVMe-MI VPD
VPD访问"] end subgraph "传输层" PCIe["PCIe传输"] SMBus["SMBus"] end Driver -->|硬盘管理| NVMeMI Driver -->|硬盘信息| VPD NVMeMI --> MCTP MCTP --> PCIe VPD --> SMBus ``` ### 2.6 底层协议确定(了解硬盘支持的协议类型) 在适配硬盘驱动前,首先要确定硬盘支持的底层通信协议。不同厂商的硬盘可能支持不同的协议组合。华为实现会在启动时读取VPD Common Header自动探测协议类型(NVMe-MI或SFF),并支持MCTP over PCIe失败后回退SMBus。 #### 协议类型 | 协议 | 说明 | 适用场景 | |------|------|---------| | **NVMe-MI over MCTP over PCIe** | 通过PCIe总线进行MCTP通信 | 硬盘直接连接到PCIe总线 | | **NVMe-MI over MCTP over SMBus** | 通过SMBus/I2C进行MCTP通信 | 硬盘通过SMBus桥接芯片管理(华为实现回退时使用地址29) | | **NVMe-MI VPD** | 通过VPD访问硬盘信息 | 获取温度、基本状态等信息 | #### 厂商协议支持对比 | 厂商 | NVMe-MI over MCTP over PCIe | NVMe-MI over MCTP over SMBus | NVMe-MI VPD | 说明 | |------|---------------------------|----------------------------|-------------|------| | 华为 | ✓ | ✓ | ✓ | 主要通过PCIe,VPD用于带外信息获取 | ### 2.7 NVMe硬盘支持的能力 本节以华为NVMe PCIe4硬盘为例,详细列举硬盘驱动可以支持的各种能力,帮助开发者了解可以实现哪些功能接口。 #### 硬盘级能力 华为NVMe硬盘主对象实现了以下接口: | 能力类别 | 接口名称 | 说明 | 可获取的信息 | |---------|---------|------|-------------| | **PCIe设备信息** | `PCIeDevice` | PCIe设备基础信息 | VID/DID、BDF地址、设备名称、设备类型 | | **NVMe基本信息** | `NVMe` | NVMe设备功能信息 | 槽位、媒体类型、协议、速率、寿命百分比 | | **管理信息** | `NVMe.Management` | NVMe管理信息 | 协议类型、是否支持MCTP over PCIe、VPD芯片、SSD芯片 | | **产品信息** | `NVMe.ProductInfo` | 产品制造信息 | 型号、序列号、部件号、厂商、固件版本 | | **多记录信息** | `NVMe.MultiRecord` | 扩展信息记录 | 容量、接口类型等 | | **状态信息** | `NVMe.Status` | 设备状态信息 | 健康状态、功能状态、链路状态、就绪状态 | | **温度监控** | `Cooling` | 温度信息 | 当前温度、温度状态、目标温度、最高温度 | | **基础管理** | `NVMe.BasicManagement` | 基础管理信息 | PCIe链路状态、重置需求、功能状态、SMART警告 | | **NVMe-MI接口** | `NVMe.NVMeMI` | NVMe-MI命令接口 | 发送NVMe-MI命令、获取SMART信息、获取识别数据 | | **日志收集** | `NVMe.LogCollection` | 日志导出功能 | 硬盘日志文件、故障诊断信息、事件记录 | | **SMART信息** | `NVMe.Smart` | SMART健康信息 | 温度、可用容量、介质错误、错误日志条数 | | **厂商特定SMART** | `NVMe.VendorSpecificSmart` | 厂商特定SMART | 厂商自定义的SMART属性 | | **OEM扩展** | `NVMe.Oem` | 厂商扩展功能 | 厂商自定义扩展属性 | #### 能力获取方式 华为NVMe硬盘通过两种协议获取不同的信息: | 协议类型 | 获取的信息 | 更新频率 | 数据来源 | |---------|----------|----------|---------| | **NVMe-MI over MCTP over PCIe** | 产品信息、SMART信息、日志、识别数据 | 120秒 | 硬盘固件 | | **NVMe-MI VPD** | 温度、基本状态、管理信息 | 3秒~10秒 | 硬盘VPD | **更新频率策略:** - **快速变化数据**(3秒):温度 - **中速变化数据**(10秒):状态、基础管理信息 - **慢速变化数据**(120秒):产品信息、SMART信息、厂商特定SMART ## 3. 适配流程详解 > 假设我们要适配一个新厂商"XYZ"的NVMe硬盘"xyz_nvme" ### 3.1 创建目录结构 在 `drivers/pcie_nvme/` 下创建: ```shell pcie_nvme/ └── xyz/ # 厂商目录 ├── xyz_nvme/ # 型号目录 │ ├── xyz_nvme.h # 主对象头文件 │ ├── xyz_nvme.cpp # 主对象实现 │ ├── xyz_nvme_abi.cpp # ABI导出 │ └── meson.build # 构建配置 ├── interface/ # 接口实现目录 │ ├── pcie_device.h │ ├── pcie_device.cpp │ ├── nvme.h │ ├── nvme.cpp │ ├── nvme/ │ │ ├── management.h │ │ ├── management.cpp │ │ ├── smart.h │ │ ├── smart.cpp │ │ └── ... │ ├── cooling.h │ ├── cooling.cpp │ └── meson.build ├── csr/ # 设备配置目录 │ └── [VID_DID_SVID_SSID].dds # DDS文件(设备接口定义) └── meson.build ``` ### 3.2 配置设备描述文件(DDS) DDS文件定义设备的接口和路径,是框架识别和加载驱动的关键配置。 #### 文件命名规则 ```shell 格式:14140224_PROTOCOL_[VID].dds 示例:14140224_PROTOCOL_19e5.dds 说明:VID=0x19e5,14140224是PCIe NVMe的分类代码 ``` #### DDS文件内容 以下为华为实现的完整DDS示例(共17个接口,新适配厂商可按实际支持能力裁剪): ```json { "Schema": "dds-v1", "Type": "Component", "DeviceCategory": "PCIeNVMe", "ID": "N/A", "Objects": { "PCIeNVMe": { "Path": "/bmc/dev/Systems/:SystemId/PCIeNVMe/:Id", "Interfaces": [ "bmc.dev.PCIeDevice", "bmc.dev.PCIeDevice.PCIeFunction", "bmc.dev.PCIeDevice.Oem", "bmc.dev.PCIeDevice.Status", "bmc.dev.NVMe", "bmc.dev.NVMe.Management", "bmc.dev.NVMe.ProductInfo", "bmc.dev.NVMe.MultiRecord", "bmc.dev.NVMe.Status", "bmc.dev.Cooling", "bmc.dev.NVMe.BasicManagement", "bmc.dev.NVMe.NVMeMI", "bmc.dev.NVMe.LogCollection", "bmc.dev.NVMe.Smart", "bmc.dev.NVMe.VendorSpecificSmart", "bmc.dev.Upgrade", "bmc.dev.NVMe.Oem" ] } } } ``` #### 关键字段说明 | 字段 | 说明 | 注意事项 | |------|------|---------| | `DeviceCategory` | 设备类别 | 必须是`"PCIeNVMe"` | | `ID` | 设备标识 | DDS模板中固定为`"N/A"`,由框架按实际设备填充 | | `Objects` | 对象定义 | 键名必须与ABI中的`device_name`一致 | | `Path` | 对象路径模板 | `:SystemId`、`:Id`是动态参数占位符 | | `Interfaces` | 接口列表 | 必须与`MC_OBJECT`宏中声明的接口一致 | #### 配置要点 1. **接口列表要完整**:DDS中的`Interfaces`必须包含代码中`MC_OBJECT`声明的所有接口 2. **对象名称要匹配**:`Objects`的键名(如`PCIeNVMe`)必须与ABI注册时的`device_name`一致 3. **路径格式固定**:路径格式不要修改。注意DDS中`Path`使用`:SystemId`/`:Id`占位符,与代码中`MC_OBJECT`的路径模板`"/bmc/dev/Systems/1/PCIeNVMe/${object_name}"`(单系统场景SystemId为字面量1,`${object_name}`对应`:Id`)语义对应 4. **可选接口**:如果不支持某些接口,可以删除对应的接口定义 ### 3.3 创建硬盘主对象 #### 代码示例:`xyz_nvme.h` ```cpp #ifndef XYZ_NVME_H #define XYZ_NVME_H #include #include #include #include #include #include "interface/pcie_device.h" #include "interface/nvme.h" #include "interface/nvme/management.h" #include "interface/nvme/product_info.h" #include "interface/nvme/smart.h" #include "interface/cooling.h" namespace dev { using nvme_mi_vpd_ptr = std::shared_ptr; using nvme_mi_over_mctp_ptr = std::shared_ptr; using mctp_ptr = std::shared_ptr; class xyz_nvme : public mc::engine::object { public: // MC_OBJECT宏定义:类名、对象类型、路径模式、接口列表 MC_OBJECT( xyz_nvme, "PCIeNVMe", "/bmc/dev/Systems/1/PCIeNVMe/${object_name}", (PCIeDevice)(NVMe)(NVMe_Management)(NVMe_ProductInfo)(NVMe_Status) (Cooling)(NVMe_BasicManagement)(NVMe_NVMeMI)(NVMe_Smart) ) xyz_nvme(); // 构造函数 ~xyz_nvme(); // 析构函数 // 生命周期方法 bool init(mc::mutable_dict& csr_object, const mc::dict& connector); bool start(); bool stop(); // 接口成员变量 uint8_t m_system_id; PCIeDevice m_pcie_device; NVMe m_nvme; NVMe_Management m_nvme_management; NVMe_ProductInfo m_nvme_product_info; NVMe_Status m_nvme_status; Cooling m_cooling; NVMe_BasicManagement m_nvme_basic_management; NVMe_NVMeMI m_nvme_nvme_mi; NVMe_Smart m_nvme_smart; private: bool init_nvme_mi_vpd_protocol(); bool start_mctp_protocol(); void start_vpd_update_tasks(); void start_mctp_update_tasks(); nvme_mi_vpd_ptr m_nvme_mi_vpd_obj; nvme_mi_over_mctp_ptr m_nvme_mi_over_mctp_obj; mctp* m_mctp_object; // 管理MCTP对象生命周期 // 更新间隔 mc::milliseconds m_vpd_cooling_interval = mc::milliseconds(3000); mc::milliseconds m_vpd_status_interval = mc::milliseconds(10000); mc::milliseconds m_mctp_smart_interval = mc::milliseconds(120000); }; } // namespace dev #endif // XYZ_NVME_H ``` **注意**:`MC_REFLECT`反射注册不放在头文件中,统一放在实现文件(`xyz_nvme.cpp`)末尾,见3.4节。 #### 关键说明 **1. MC_OBJECT宏的参数:** - **第1个**:类名 - **第2个**:设备类型(固定为`"PCIeNVMe"`) - **第3个**:对象路径模板(固定格式) - **第4个**:实现的接口列表(按需选择) **2. 接口选择原则:** | 接口 | 必需性 | 说明 | |------|--------|------| | `PCIeDevice`、`NVMe` | 必需 | 基础接口 | | `NVMe_Management` | 必需 | 管理接口 | | `NVMe_ProductInfo` | 可选 | 支持产品信息时添加 | | `NVMe_Status` | 可选 | 支持状态监控时添加 | | `Cooling` | 可选 | 支持温度监控时添加 | | `NVMe_Smart` | 可选 | 支持SMART信息时添加 | ### 3.4 实现硬盘主对象 #### 代码示例:`xyz_nvme.cpp` ```cpp #include "xyz_nvme.h" #include namespace dev { // 构造函数:初始化MCTP对象指针为nullptr xyz_nvme::xyz_nvme() : m_mctp_object(nullptr) { } // 析构函数:释放MCTP对象,防止内存泄漏 xyz_nvme::~xyz_nvme() { if (m_mctp_object) { delete m_mctp_object; m_mctp_object = nullptr; } } // 初始化方法:从配置文件加载硬盘属性 bool xyz_nvme::init(mc::mutable_dict& csr_object, const mc::dict& connector) { try { // 使用from_variant自动加载配置到成员变量 from_variant(csr_object, *this); ilog("xyz_nvme initialized successfully"); } catch (const std::exception& e) { elog("xyz_nvme init failed, exception: ${exception}", ("exception", e.what())); return false; } return true; } // 启动方法:启动硬盘和所有协议 bool xyz_nvme::start() { // 初始化VPD协议 if (!init_nvme_mi_vpd_protocol()) { elog("Failed to initialize VPD protocol"); return false; } // 启动MCTP协议 if (!start_mctp_protocol()) { elog("Failed to start MCTP protocol"); return false; } // 启动VPD更新任务 start_vpd_update_tasks(); // 启动MCTP更新任务 start_mctp_update_tasks(); ilog("xyz_nvme started successfully"); return true; } // 停止方法:停止硬盘并清理资源 bool xyz_nvme::stop() { // 停止所有接口的更新任务 m_cooling.stop_vpd_update_task(); m_nvme_status.stop_vpd_update_task(); m_nvme_smart.stop_mctp_update_task(); ilog("xyz_nvme stopped"); return true; } // 初始化NVMe-MI VPD协议 bool xyz_nvme::init_nvme_mi_vpd_protocol() { m_nvme_mi_vpd_obj = std::make_shared(this); // 初始化VPD对象 // ... return true; } // 启动MCTP协议:创建MCTP通信和NVMe-MI协议实例 bool xyz_nvme::start_mctp_protocol() { // 获取BDF地址 // 创建MCTP对象(赋值给成员变量) m_mctp_object = new mctp(this, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NVME_MI, ""); // 创建NVMe-MI协议实例 m_nvme_mi_over_mctp_obj = std::make_shared(*m_mctp_object); // 创建传输层并启动 // ... return true; } // 启动VPD更新任务 void xyz_nvme::start_vpd_update_tasks() { m_cooling.start_vpd_update_task(m_nvme_mi_vpd_obj, m_vpd_cooling_interval); m_nvme_status.start_vpd_update_task(m_nvme_mi_vpd_obj, m_vpd_status_interval); } // 启动MCTP更新任务 void xyz_nvme::start_mctp_update_tasks() { m_nvme_smart.start_mctp_update_task(m_nvme_mi_over_mctp_obj, m_mctp_smart_interval); } // MC_REFLECT宏:反射信息注册(放在实现文件末尾) MC_REFLECT(dev::xyz_nvme, ((m_system_id, "SystemId")) ((m_pcie_device, "bmc.dev.PCIeDevice")) ((m_nvme, "bmc.dev.NVMe")) ((m_nvme_management, "bmc.dev.NVMe.Management")) ((m_nvme_product_info, "bmc.dev.NVMe.ProductInfo")) ((m_nvme_status, "bmc.dev.NVMe.Status")) ((m_cooling, "bmc.dev.Cooling")) ((m_nvme_basic_management, "bmc.dev.NVMe.BasicManagement")) ((m_nvme_nvme_mi, "bmc.dev.NVMe.NVMeMI")) ((m_nvme_smart, "bmc.dev.NVMe.Smart"))) } // namespace dev ``` #### 关键说明 | 方法 | 职责 | |------|------| | `init()` | 加载配置文件中的属性值,使用`from_variant`自动映射 | | `start()` | 初始化协议、启动协议通信、注册回调和定时器 | | `stop()` | 清理资源 | **协议启动流程:** 1. 初始化VPD协议 2. 获取BDF(Bus/Device/Function) 3. 创建MCTP对象 4. 创建NVMe-MI协议实例 5. 为接口绑定更新任务 **华为实现的增强逻辑(可参考):** - **协议自动探测**:`start()`时先读取VPD Common Header(校验和+ClassCode),自动判别硬盘走NVMe-MI还是SFF协议,SFF场景跳过MCTP - **传输回退**:MCTP over PCIe启动失败时,回退到MCTP over SMBus(PHY地址29) - **BDF变化感知**:监听`pcie_device_bdf_changed`信号,BDF变化时自动重启MCTP协议 ### 3.5 实现接口类 #### 核心要点 接口类继承自`gen`命名空间的基类,负责具体的协议实现和数据更新。 **1. 接口类定义** ```cpp // 继承自生成的基类(双参模板) class NVMe_Smart : public mc::engine::interface { public: // 启动MCTP更新任务:创建定时器周期性更新属性 void start_mctp_update_task(nvme_mi_over_mctp_ptr nvme_mi, mc::milliseconds interval, std::function on_update_callback = nullptr); // 停止更新任务:停止并释放定时器 void stop_mctp_update_task(); // 更新方法:通过NVMe-MI协议获取数据并更新属性 void update_smart_info(); private: mc::timer_ptr m_mctp_timer; nvme_mi_over_mctp_ptr m_nvme_mi; }; // MC_REFLECT注册:指定基类(放在实现文件末尾) MC_REFLECT(dev::NVMe_Smart, (gen::NVMe_Smart), ()) ``` **2. 关键实现方法** ```cpp // 启动更新任务:创建定时器周期性更新属性 void NVMe_Smart::start_mctp_update_task(nvme_mi_over_mctp_ptr nvme_mi, mc::milliseconds interval) { m_nvme_mi = nvme_mi; m_mctp_timer = mc::make_shared(this); m_mctp_timer->timeout.connect([this]() { update_smart_info(); }); m_mctp_timer->set_single_shot(false); m_mctp_timer->start(interval); // 立即执行一次更新 update_smart_info(); } // 停止更新任务:停止并释放定时器 void NVMe_Smart::stop_mctp_update_task() { if (m_mctp_timer) { m_mctp_timer->stop(); m_mctp_timer.reset(); } } // 更新SMART信息:通过NVMe-MI协议获取并更新SMART属性 void NVMe_Smart::update_smart_info() { try { // 调用协议获取SMART信息 auto smart_data = m_nvme_mi->get_smart_info(); // 解析响应数据 // 更新属性:TemperatureCelsius = parsed_temperature TemperatureCelsius = smart_data.temperature; AvailableSparePercent = smart_data.available_spare; MediaErrors = smart_data.media_errors; } catch (const std::exception& e) { elog("Failed to update SMART info: ${error}", ("error", e.what())); } } ``` **关键要点:** - 接口类必须继承对应的`gen`基类(双参模板`mc::engine::interface<自身, gen基类>`) - 使用定时器周期性调用update方法 - update方法负责:获取数据 → 解析 → 更新属性 - 属性更新后会自动触发信号通知上层 ### 3.6 实现ABI导出 ABI(Application Binary Interface)是驱动程序与框架交互的标准接口。 #### 代码示例:`xyz_nvme_abi.cpp` ```cpp #include #include #include "xyz_nvme.h" using namespace dev; extern "C" { // ============================================ // 硬盘主对象ABI函数 // ============================================ // 创建硬盘对象:分配内存并设置基本属性 driver_handle_t create_xyz_nvme(void* service, const char* name) { if (!service || !name) { elog("create_xyz_nvme: invalid parameters"); return nullptr; } auto* nvme = new xyz_nvme(); nvme->set_service(static_cast(service)); nvme->set_object_name(name); ilog("Created xyz_nvme object: ${name}", ("name", name)); return nvme; } // 初始化硬盘对象:加载配置 status_t init_xyz_nvme(driver_handle_t device, void* csr_object, void* connector) { if (!device || !csr_object || !connector) { elog("init_xyz_nvme: invalid parameters"); return STATUS_INVALID_PARAM; } auto* nvme = static_cast(device); auto& csr = *static_cast(csr_object); auto& conn = *static_cast(connector); if (!nvme->init(csr, conn)) { elog("init_xyz_nvme failed"); return STATUS_ERROR; } return STATUS_OK; } // 启动硬盘对象:启动设备和协议 status_t start_xyz_nvme(driver_handle_t device) { if (!device) { elog("start_xyz_nvme: invalid parameters"); return STATUS_INVALID_PARAM; } auto* nvme = static_cast(device); if (!nvme->start()) { elog("start_xyz_nvme failed"); return STATUS_ERROR; } return STATUS_OK; } // 停止硬盘对象:停止设备和清理资源 status_t stop_xyz_nvme(driver_handle_t device) { if (!device) { elog("stop_xyz_nvme: invalid parameters"); return STATUS_INVALID_PARAM; } auto* nvme = static_cast(device); nvme->stop(); return STATUS_OK; } // ============================================ // 驱动注册 // ============================================ // 硬盘主对象驱动结构体:定义设备名和生命周期函数 device_driver_t xyz_nvme_device_driver = { .device_name = "PCIeNVMe", // 设备类型名(必须与DDS文件一致) .ctor = create_xyz_nvme, // 创建函数 .init = init_xyz_nvme, // 初始化函数 .start = start_xyz_nvme, // 启动函数 .stop = stop_xyz_nvme // 停止函数 }; // 驱动数组:包含所有设备类型的驱动 device_driver_t xyz_nvme_driver_array[] = { xyz_nvme_device_driver }; // 驱动注册函数:框架调用此函数获取驱动列表 status_t register_device_driver(device_driver_t** device_driver, uint8_t* count) { *device_driver = xyz_nvme_driver_array; *count = sizeof(xyz_nvme_driver_array) / sizeof(xyz_nvme_driver_array[0]); ilog("Registered xyz_nvme device driver: ${count} devices", ("count", *count)); return STATUS_OK; } } // extern "C" ``` #### 关键说明 - 所有ABI函数必须用`extern "C"`包装,确保C语言兼容 - 每个设备类型需要4个函数:`create`、`init`、`start`、`stop` - `device_name`必须与DDS文件中的对象类型匹配 - `register_device_driver`是框架调用的入口函数,通过驱动数组返回 ### 3.7 配置构建编译 #### 代码示例:`meson.build` ```meson # 源文件列表 xyz_nvme_sources = files( 'xyz_nvme.cpp', 'xyz_nvme_abi.cpp', ) # 接口实现源文件 interface_sources = files( 'interface/pcie_device.cpp', 'interface/nvme.cpp', 'interface/nvme/management.cpp', 'interface/nvme/smart.cpp', 'interface/cooling.cpp', ) # 合并源文件 all_sources = xyz_nvme_sources + interface_sources # 包含目录 include_dirs = [ include_directories('.'), include_directories('interface'), gen_inc, internal_inc ] # 静态库(用于测试与复用) libxyz_nvme_static = static_library( 'xyz_nvme', all_sources, include_directories: include_dirs, dependencies: [ dev_deps, libnvme_dep, libmctp_dep ], install: false ) # 动态库(用于部署) libxyz_nvme = shared_library( 'xyz_nvme', include_directories: include_dirs, name_prefix: 'lib', name_suffix: 'so', install: true, install_dir: drivers_install_dir, link_whole: [libxyz_nvme_static] ) ``` #### 关键说明 - 库名会成为驱动SO文件名:`libxyz_nvme.so` - `install_dir`使用`drivers_install_dir`变量(框架定义,实际安装到构建根目录的`opt/bmc/drivers`) - 依赖关系要明确列出,避免链接错误 ## 4. 最佳实践建议 ### 4.1 代码规范 #### 命名规范 | 类型 | 规范 | 示例 | |------|------|------| | 类名 | 厂商_型号 | `xyz_nvme` | | 文件名 | 与类名一致 | `xyz_nvme.h` | | 成员变量 | `m_`前缀 | `m_nvme_mi_vpd_obj` | | 常量 | 大写+下划线 | `DEFAULT_TIMEOUT` | #### 日志规范 - **启动/停止**:使用`ilog` - **错误**:使用`elog` - **调试信息**:使用`dlog` - **日志要包含上下文信息** ```cpp ilog("Starting xyz_nvme: ${name} at slot ${slot}", ("name", disk_name)("slot", slot_id)); ``` #### 错误处理 - 所有可能失败的操作都要检查返回值 - 使用`try-catch`捕获异常 - 记录详细的错误信息 ```cpp try { bool ret = operation(); if (!ret) { elog("Operation failed: ${reason}", ("reason", error_msg)); return false; } } catch (const std::exception& e) { elog("Exception caught: ${error}", ("error", e.what())); return false; } ``` ### 4.2 性能优化 #### 定时任务间隔 - 根据数据变化频率设置不同的更新间隔,避免不必要的通信开销 - **快速变化数据**:3秒(3000ms) - 温度 - **中速变化数据**:10秒(10000ms) - 状态、基础管理信息 - **慢速变化数据**:120秒(120000ms) - SMART信息、产品信息 **实际应用示例:** ```cpp // 不同接口使用不同的更新间隔 m_cooling.start_vpd_update_task(vpd_obj, mc::milliseconds(3000)); // 温度:3秒 m_nvme_status.start_vpd_update_task(vpd_obj, mc::milliseconds(10000)); // 状态:10秒 m_nvme_smart.start_mctp_update_task(mctp_obj, mc::milliseconds(120000)); // SMART:120秒 ``` #### 内存管理 - 优先使用智能指针(`shared_ptr`) - 及时清理定时器等资源 - **重要**:MCTP对象必须使用成员变量管理,防止严重内存泄漏 **MCTP对象管理:** ```cpp // 头文件声明 class xyz_nvme : public mc::engine::object { private: mctp* m_mctp_object; // 使用成员变量管理 }; // 实现文件 xyz_nvme::xyz_nvme() : m_mctp_object(nullptr) {} xyz_nvme::~xyz_nvme() { // 在析构函数中释放,防止内存泄漏 if (m_mctp_object) { delete m_mctp_object; m_mctp_object = nullptr; } } bool xyz_nvme::start_mctp_protocol() { // 赋值给成员变量,而不是局部变量 m_mctp_object = new mctp(this, phy_addr, ...); } ``` **定时器资源管理:** ```cpp // 清理定时器(mc::timer_ptr 为共享指针) if (m_timer) { m_timer->stop(); m_timer.reset(); } ``` #### 协议优化 - 批量请求减少通信次数 - 缓存不变的数据 - 失败时使用指数退避 ### 4.3 测试建议 #### 单元测试 - 测试每个接口的更新方法 - 测试异常情况处理 - 使用mock对象模拟协议 ```cpp TEST(xyz_nvme, test_init) { xyz_nvme nvme; mc::mutable_dict csr_object = {...}; mc::dict connector = {...}; EXPECT_TRUE(nvme.init(csr_object, connector)); } ``` #### 集成测试 - 测试完整的生命周期:`create` → `init` → `start` → `stop` - 测试与实际硬件的通信 - 测试长时间运行的稳定性 #### 回归测试 - 每次修改后重新测试基本功能 - 检查是否影响其他硬盘驱动 - 验证Redfish接口数据正确 ## 结语 南向硬盘驱动适配是一项系统性工作,需要对硬件特性、通信协议、软件架构都有深入理解。本文档提供了一套完整的适配流程和代码示例,但实际适配中还会遇到各种具体问题,欢迎大家积极在社区沟通交流和贡献。 --- # 网卡驱动规范 > URL: https://openubmc.cn/docs/zh/latest/component_driver/nic_adapt/nic_driver_spec.html > Language: zh # 网卡驱动规范 > [!NOTE] > 契约 SSOT:[`dmc/`](https://gitcode.com/openUBMC/component_drivers/tree/main/dmc)。总览见 [3-DeviceMgmtContract.md](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md)。 > 适配实操:[4.1 网卡驱动适配指南](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/4.1-网卡驱动适配指南.md)。 **前置阅读**: - 《部件驱动 2.0 适配方案概述》:[部件驱动开发简介](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/0-%E9%83%A8%E4%BB%B6%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91%E7%AE%80%E4%BB%8B.md) - 《部件驱动 2.0-设备驱动开发指南》:[设备驱动开发指南](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/2.2-%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97.md) ## 1. 概述 本规范定义 PCIe 形态网卡(`DeviceCategory: PCIeNicCard`)南向驱动需实现的对象树与接口组合。部件按契约实现后,可被 `devmon` 挂载到 `/bmc/dev/Systems/.../PCIeNicCard/...` 设备树。 设备特有器件通常包括: - NIC 板卡本身 - 网口(NetworkPort) - 光口上的光模块(OpticalModule) ### 入库状态 | 项 | 状态 | |----|------| | `dmc/intf`(NetworkAdapter / NetworkPort / OpticalModule / PCIe* / Cooling / Board / Fru / Upgrade) | 已有 | | `dmc/path/.../PCIeNicCard/` | 已有 [`PCIeNicCard/`](https://gitcode.com/openUBMC/component_drivers/tree/main/dmc/path/bmc/dev/PCIeNicCard) | ## 2. 设备树 ```text /bmc/dev/Systems/${SystemId}/PCIeNicCard/{NicId} └── NetworkPort/{PortId} └── OpticalModule └── Channel/{ChannelId} # CESA 表37 OpticalTransceiverChannel;DDS 可用 OpticalTransceiverChannel/${ChannelId} ``` | 对象 | path 定义 | 说明 | |------|-----------|------| | PCIeNicCard | [`PCIeNicCard.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeNicCard/PCIeNicCard.json) | 网卡主对象 | | NetworkPort | [`NetworkPort.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeNicCard/NetworkPort.json) | 网口 | | OpticalModule | [`OpticalModule.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeNicCard/OpticalModule.json) | 光模块 | | OpticalModuleChannel | [`OpticalModuleChannel.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeNicCard/OpticalModuleChannel.json) | 光模块通道(CESA 表37 必选) | > [!NOTE] > 命名说明:部分历史 gen 路径使用 `PCIeNic`,部分 DDS 子对象使用 `NicPort` / `OpticalTransceiver`。规范约定主对象名为 `PCIeNicCard`,子对象为 `NetworkPort` / `OpticalModule`。型号 DDS 可继续使用相对路径别名,但接口集合应对齐本规范。 ## 3. 对象–接口矩阵 ### 3.1 PCIeNicCard | 接口 | 必选/可选 | dmc/intf | |------|-----------|----------| | `bmc.dev.PCIeDevice` | 必选 | [`PCIeDevice.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeDevice.json) | | `bmc.dev.PCIeDevice.PCIeFunction` | 必选 | [`PCIeDevice/PCIeFunction.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeDevice/PCIeFunction.json) | | `bmc.dev.PCIeCard` | 必选 | [`PCIeCard.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeCard.json) | | `bmc.dev.NetworkAdapter` | 必选 | [`NetworkAdapter.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkAdapter.json) | | `bmc.dev.Cooling` | 必选 | [`Cooling.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Cooling.json) | | `bmc.dev.PCIeDevice.Bandwidth` | 可选 | [`PCIeDevice/Bandwidth.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeDevice/Bandwidth.json) | | `bmc.dev.PCIeDevice.HotSwap` | 可选 | [`PCIeDevice/HotSwap.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeDevice/HotSwap.json) | | `bmc.dev.PCIeDevice.Status` / `Oem` | 可选 | [`PCIeDevice/`](https://gitcode.com/openUBMC/component_drivers/tree/main/dmc/intf/bmc/dev/PCIeDevice) | | `bmc.dev.NetworkAdapter.FaultStatus` | 可选 | [`NetworkAdapter/FaultStatus.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkAdapter/FaultStatus.json) | | `bmc.dev.NetworkAdapter.LogCollection` | 可选 | [`NetworkAdapter/LogCollection.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkAdapter/LogCollection.json) | | `bmc.dev.NetworkAdapter.Oem` | 可选 | [`NetworkAdapter/Oem.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkAdapter/Oem.json) | | `bmc.dev.NetworkAdapter.Fru` | 可选 | [`NetworkAdapter/Fru.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkAdapter/Fru.json) | | `bmc.dev.NetworkAdapter.Update` | 可选 | [`NetworkAdapter/Update.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkAdapter/Update.json) | | `bmc.dev.PCIeCard.Oem` | 可选 | [`PCIeCard/Oem.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeCard/Oem.json) | | `bmc.dev.PCIeCard.Metrics` | 可选 | [`PCIeCard/Metrics.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeCard/Metrics.json) | | `bmc.dev.Board` | 必选(CESA 表34) | [`Board.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Board.json) | | `bmc.dev.Fru` | 可选 | [`Fru.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Fru.json) | | `bmc.dev.Upgrade` | 可选 | [`Upgrade.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Upgrade.json) | > [!NOTE] > 散热使用共享接口 `bmc.dev.Cooling`,**不是** `bmc.dev.NetworkAdapter.Cooling`。 ### 3.2 NetworkPort | 接口 | 必选/可选 | dmc/intf | |------|-----------|----------| | `bmc.dev.NetworkPort` | 必选 | [`NetworkPort.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkPort.json) | | `bmc.dev.NetworkPort.LinkInfo` | 必选 | [`NetworkPort/LinkInfo.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkPort/LinkInfo.json) | | `bmc.dev.NetworkPort.Metrics` | 可选 | [`NetworkPort/Metrics.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkPort/Metrics.json) | | `bmc.dev.NetworkPort.LLDPReceive` | 可选 | [`NetworkPort/LLDPReceive.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkPort/LLDPReceive.json) | | `bmc.dev.NetworkPort.DataCenterBridging` | 可选 | [`NetworkPort/DataCenterBridging.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkPort/DataCenterBridging.json) | | `bmc.dev.NetworkPort.FibreChannel` | 可选 | [`NetworkPort/FibreChannel.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkPort/FibreChannel.json) | | `bmc.dev.NetworkPort.Oem` | 可选 | [`NetworkPort/Oem.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/NetworkPort/Oem.json) | > `bmc.dev.NetworkPort.LinkInfo.LinkStatus` 按 CESA 表148 为**可写**。 ### 3.3 OpticalModule | 接口 | 必选/可选 | dmc/intf | |------|-----------|----------| | `bmc.dev.OpticalModule` | 必选 | [`OpticalModule.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/OpticalModule.json) | | `bmc.dev.Cooling` | 必选 | [`Cooling.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Cooling.json) | | `bmc.dev.OpticalModule.Status` | 可选 | [`OpticalModule/Status.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/OpticalModule/Status.json) | | `bmc.dev.OpticalModule.TemperatureCelsius` / `Voltage` / `Power` / `Current` | 可选 | [`OpticalModule/`](https://gitcode.com/openUBMC/component_drivers/tree/main/dmc/intf/bmc/dev/OpticalModule) | | `bmc.dev.OpticalModule.Diagnose` | 可选 | [`OpticalModule/Diagnose.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/OpticalModule/Diagnose.json) | | `bmc.dev.OpticalModule.Oem` | 可选 | [`OpticalModule/Oem.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/OpticalModule/Oem.json) | ### 3.4 OpticalModuleChannel | 接口 | 必选/可选 | dmc/intf | |------|-----------|----------| | `bmc.dev.OpticalModule.Channel` | 必选(CESA 表37) | [`OpticalModule/Channel.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/OpticalModule/Channel.json) | 通道是独立子对象,不挂在 OpticalModule 主对象上。规范属性名为 `BiasCurrentMilliAmps`;现网驱动仍用 `TXBiasCurrentMilliAmps`,dmc/gen 同时保留。 已入库接口的属性与方法细节请直接打开上表 intf 链接。 ## 4. 相关文档 - [3-DeviceMgmtContract.md](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md) - [4.1 网卡驱动适配指南](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/4.1-网卡驱动适配指南.md) - [4.7 使用 openUBMC Studio 进行网卡适配](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/4.7-使用openUBMC%20Studio进行网卡适配.md) ## 5. 历史 RFC - 社区公示(历史参考):[openUBMC 讨论区](https://discuss.openubmc.cn/t/topic/1740) 若与本仓库 `dmc` 冲突,以 `dmc` 为准。 --- # 南向网卡驱动适配指南 > URL: https://openubmc.cn/docs/zh/latest/component_driver/nic_adapt/south_nic_driver_adapt.html > Language: zh # 南向网卡驱动适配指南 > [!NOTE] > 本文档为按 issue 843 要求进行内容审核后的发布版,目标是为南向网卡驱动适配开发者提供“从设计到实现”的完整操作步骤。源文档基于组件仓中已有的《南向网卡驱动适配指南》内容整理,并与《部件驱动 2.0-网卡驱动规范》保持一致。 > > 相关规范: [3.1 网卡驱动规范](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3.1-%E7%BD%91%E5%8D%A1%E9%A9%B1%E5%8A%A8%E8%A7%84%E8%8C%83.md) > 相关实现指导: [4.1 网卡驱动适配指南](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/4.1-%E7%BD%91%E5%8D%A1%E9%A9%B1%E5%8A%A8%E9%80%82%E9%85%8D%E6%8C%87%E5%8D%97.md) > 总览契约: [3-DeviceMgmtContract.md](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md) 南向驱动是基于硬件组件驱动程序框架,采用分层架构设计,支持多种设备类型和通信协议。本文档面向网卡适配的设备驱动开发者,提供从设计到实现的完整开发流程,并基于现有代码实例分析,提供一篇快速适配的开发指南。 章节总览与分册选型见 [部件驱动2.0适配方案](../concept_principle/component_driver_adapt.md)。驱动需实现的接口契约见 [网卡驱动规范](./nic_driver_spec.md)。若使用 openUBMC Studio 生成模版,见 [4.7 使用 openUBMC Studio 进行网卡适配](./studio_nic_adapt.md)。 ## 1. 概述 ### 1.1 什么是南向网卡驱动适配? 南向网卡驱动适配是指在BMC系统中,为不同厂商的PCIe网卡提供统一的驱动程序接入方案,使BMC能够管理和监控网卡设备。 ### 1.2 适配后可以实现什么功能? - 获取网卡基本信息(厂商ID、设备ID、固件版本等) - 监控网卡状态(温度、链路状态、带宽等) - 管理网口(链路信息、MAC地址、LLDP等) - 监控光模块(温度、收发功率、序列号等) - 故障诊断和日志收集 ### 1.3 需要了解的关键概念 #### 设备对象 | 对象类型 | 说明 | 示例 | |---------|------|------| | **网卡主对象** | 代表整个PCIe网卡 | `PCIeNicCard` | | **网口对象** | 代表网卡上的物理网口 | `NicPort` | | **光模块对象** | 代表插在网口上的光模块 | `OpticalTransceiver` | #### 接口 - **gen命名空间**:自动生成的接口基类,定义属性 - **dev命名空间**:厂商具体实现类,实现功能 - **接口组合**:一个设备可以实现多个接口,如`PCIeDevice`、`NetworkAdapter`等 #### 协议库 - **NCSI over MCTP**:网卡控制协议,通过PCIe与网卡通信 - **SMBUS**:系统管理总线协议,用于I2C通信 - 不同厂商可能使用不同的协议扩展 --- ### 1.4 驱动分层架构 1. **分层架构**:构建了一个从接口定义到硬件交互的完整体系,接口定义层(DMC)→设备接口层→设备对象层→设备驱动层,每层职责明确,协同工作; 2. **设计理念**:接口与实现分离,先是 `dmc/`(Device Management Contract)建立接口契约,再在“设备接口层”生成/落地 C++ 接口,由各厂商提供“设备驱动层”的具体部件驱动实现; ```mermaid flowchart TD subgraph dmc["接口定义层(dmc)"] direction TB JSON_DEF["dmc/intf JSON 契约"] JSON_PCIe["PCIeDevice.json"] JSON_NA["NetworkAdapter.json"] JSON_NP["NetworkPort.json"] JSON_OM["OpticalModule.json"] JSON_DEF --> JSON_PCIe JSON_DEF --> JSON_NA JSON_DEF --> JSON_NP JSON_DEF --> JSON_OM end subgraph CODE_GEN["代码生成工具链"] Parser["JSON解析器"] Generator["C++接口代码生成器"] end subgraph devmon["设备监控系统(devmon)"] direction TB subgraph plugins["设备插件(/plugins)"] direction TB subgraph interface_layer["设备接口层"] PCIeDevice["PCIeDevice接口"] NetworkAdapter["NetworkAdapter接口"] NetworkPort["NetworkPort接口"] OpticalModule["OpticalModule接口"] PCIeCard["PCIeCard接口"] Board["Board接口"] end subgraph object_layer["设备对象层"] PCIeNicCard["PCIeNicCard对象"] NicPort["NicPort对象"] OpticalTransceiver["OpticalTransceiver对象"] end subgraph driver_layer["设备驱动层"] hisi["海思实现"] other["其他厂商实现"] end interface_layer --> object_layer object_layer --> driver_layer end end app_layer["应用层

利用插件接口
实现系统功能"] app_layer -->|"调用"| interface_layer dmc --> CODE_GEN CODE_GEN --> interface_layer JSON_PCIe -->|"定义接口"| PCIeDevice JSON_NA -->|"定义接口"| NetworkAdapter JSON_NP -->|"定义接口"| NetworkPort JSON_OM -->|"定义接口"| OpticalModule PCIeDevice -->|"组合"| PCIeNicCard PCIeCard -->|"组合"| PCIeNicCard Board -->|"组合"| PCIeNicCard NetworkAdapter -->|"组合"| PCIeNicCard NetworkPort -->|"组合"| NicPort OpticalModule -->|"组合"| OpticalTransceiver PCIeNicCard -->|"厂商实现"| hisi NicPort -->|"厂商实现"| hisi OpticalTransceiver -->|"厂商实现"| hisi ``` ## 2. 前置准备 ### 2.1 明确网卡信息 #### 必需信息 | 信息项 | 说明 | 示例 | |-------|------|------| | **VID** | Vendor ID(厂商ID) | `0x19e5` | | **DID** | Device ID(设备ID) | `0x0222` | | **SVID** | Subsystem Vendor ID | `0x19e5` | | **SSID** | Subsystem Device ID | `0x0052` | #### 协议信息 - 支持的通信协议(NCSI标准协议、厂商OEM扩展等) - 协议命令集(获取温度、链路状态等命令的定义) - 数据格式(响应数据的字节序、字段定义等) #### 硬件信息 - 网口数量 - 是否支持光模块 - 特殊功能(如DCB、LLDP等) ### 2.2 驱动代码结构熟悉 Component Driver采用分层架构设计,代码组织清晰,各个目录职责明确。理解这些目录的结构和作用是快速适配驱动的基础。 --- #### 2.2.1 整体目录结构 ```shell component_drivers/ ├── drivers/ # 设备驱动实现目录(各类硬件设备驱动) ├── gen/ # 自动生成的代码目录(接口基类) ├── libraries/ # 协议库目录(通信协议封装) ├── tests/ # 测试代码目录 ├── docs/ # 文档目录 ├── include/ # 公共头文件目录 └── meson.build # 构建配置文件 ``` --- #### 2.2.2 drivers目录 - 设备驱动实现 `drivers/`目录包含所有硬件设备的具体驱动实现,按设备类型组织。 ##### 目录结构 ```shell drivers/ ├── pcie_nic_card/ # PCIe网卡驱动(本指南重点) │ ├── hisi/ # 华为海思网卡驱动 │ │ ├── csr/ # 设备配置文件(DDS/SR) │ │ │ ├── 14140130_19e50222_19e50052.dds # Hi1822设备描述 │ │ │ ├── 14140130_19e50222_19e50052.sr # Hi1822硬件自描述信息 │ │ │ ├── 14140130_19e50222_19e500a1.dds # Hi1822另一配置 │ │ │ └── 14140130_19e50222_19e500a1.sr │ │ ├── interface/ # 厂商共用接口实现(独立 so) │ │ ├── hi182x/ # Hi182x系列网卡实现 │ │ │ ├── hi182x_card.h/.cpp # 网卡主对象(类名 hi182x_card) │ │ │ ├── hi182x_port.h/.cpp # 网口对象(类名 hi182x_port) │ │ │ ├── hi182x_om.h/.cpp # 光模块对象(类名 hi182x_optical_module) │ │ │ ├── hi182x_abi.cpp # ABI导出接口 │ │ │ └── meson.build # 构建配置 → libhisi_182x.so │ │ ├── hi182x_high/ # Hi182x 高性能型号 │ │ ├── hi1822_fc/ # Hi1822 FC 型号 │ │ └── meson.build │ ├── wangxun/ # 网迅网卡驱动(目录名 wangxun,不是 wx) │ │ ├── csr/ │ │ ├── interface/ # NCSI 路径接口实现 │ │ ├── interface_pldm/ # PLDM 路径接口实现 │ │ ├── ff50xx/ # FF50xx(NCSI over MCTP) │ │ ├── ff50xx_pldm/ # FF50xx(PLDM over MCTP) │ │ ├── rp1000/ │ │ ├── sfx00ht/ # 无光模块对象 │ │ └── meson.build │ ├── mellanox/ # Mellanox(cx4/cx5/cx6) │ ├── boardcom/ # Broadcom Emulex │ ├── grt/ # GRT │ ├── mucse/ # 沐创(n10/n20) │ ├── yusur/ # 占位(当前未接入构建) │ └── meson.build │ ├── pcie_gpu_card/ # PCIe GPU卡驱动(innosilicon/nvidia/vastai/…) ├── pcie_nvme/ # PCIe NVMe 驱动 ├── pcie_raid_card/ # PCIe RAID 卡驱动 │ ├── bus/ # 总线驱动 │ ├── i2c/ │ ├── i2c_mux/ │ ├── i2c_over_hisport/ │ ├── hisport/ │ └── meson.build │ ├── chip/ # 芯片驱动 │ ├── lm75/ │ ├── ads78/ │ ├── eeprom/ │ ├── pca9545/ │ ├── pca9555/ │ ├── complex/ │ ├── interface/ │ └── meson.build │ ├── accessor/ # 访问器驱动 ├── scanner/ # 扫描器驱动 ├── debounce/ # 防抖驱动 │ ├── average/ │ ├── median/ │ ├── continue/ │ └── binary_continue/ │ ├── internal/ # 内部实现(驱动框架基础类) │ ├── bus/ │ ├── chip/ │ └── manager.h/cpp │ └── meson.build ``` ##### 关键目录说明 | 目录 | 说明 | 用途 | |------|------|------| | **pcie_nic_card/** | PCIe网卡驱动根目录 | 按厂商组织网卡驱动 | | **hisi/csr/** | 设备配置文件目录 | 存放DDS和SR配置文件,定义设备接口和硬件自描述信息 | | **hisi/hi182x/** | Hi182x网卡实现 | 包含网卡、网口、光模块的实现代码;光模块类名为`hi182x_optical_module` | | **hisi/interface/** | 接口实现目录 | 通过`mc::engine::interface`继承gen基类,实现协议逻辑 | | **wangxun/** | 网迅网卡驱动 | 型号目录为`ff50xx`/`rp1000`等,协议类为`ncsi_over_mctp_wangxun` | | **internal/** | 内部基础框架 | 提供驱动框架的基础类 | --- #### 2.2.3 gen目录 - 自动生成的接口基类 `gen/`目录包含自动生成的接口基类定义,驱动代码继承这些基类实现功能。**注意:此目录的代码由工具自动生成,不要手动修改。** ##### 目录结构 ```shell gen/ ├── include/ # 头文件目录 │ └── device_tree/ │ ├── base.h # 基础类定义 │ ├── interface/ # 接口基类定义 │ │ ├── NetworkAdapter.h # 网络适配器接口基类 │ │ ├── NetworkAdapter/ # 网络适配器子接口 │ │ │ ├── FaultStatus.h # 故障状态接口基类 │ │ │ ├── LogCollection.h # 日志收集接口基类 │ │ │ └── Oem.h # OEM 扩展接口基类 │ │ ├── NetworkPort.h # 网口接口基类 │ │ ├── NetworkPort/ # 网口子接口 │ │ │ ├── LinkInfo.h # 链路信息接口基类 │ │ │ ├── LLDPReceive.h # LLDP接收接口基类 │ │ │ ├── DataCenterBridging.h # DCB接口基类 │ │ │ ├── Metrics.h # 流量统计接口基类 │ │ │ ├── FibreChannel.h # 光纤通道接口基类 │ │ │ └── Oem.h # OEM 扩展 │ │ ├── OpticalModule.h # 光模块接口基类 │ │ ├── OpticalModule/ # 光模块子接口 │ │ │ ├── Status.h # 光模块状态接口基类 │ │ │ ├── TemperatureCelsius.h # 光模块温度接口基类(非 Cooling) │ │ │ ├── Power.h # 光模块功率接口基类 │ │ │ ├── Voltage.h # 光模块电压接口基类 │ │ │ ├── Current.h # 光模块电流接口基类 │ │ │ ├── Channel.h # 光模块通道接口基类 │ │ │ ├── Diagnose.h # 光模块诊断接口基类 │ │ │ └── Oem.h # 光模块 OEM 接口基类 │ │ ├── Cooling.h # 温度/散热接口(bmc.dev.Cooling,网卡级) │ │ ├── PCIeDevice.h # PCIe设备接口基类 │ │ ├── PCIeDevice/ │ │ │ ├── Bandwidth.h # PCIe带宽接口基类 │ │ │ ├── Oem.h / Status.h / PCIeFunction.h │ │ ├── PCIeCard.h / PCIeCard/ # PCIe卡接口及 Oem/Metrics │ │ ├── Board.h / Fru.h # 板卡与 FRU │ │ ├── NetworkAdapter/ # FaultStatus / LogCollection / Oem │ │ ├── Gpu.h / Gpu/ / Memory.h / Processor.h / Processor/ │ │ ├── Chip.h / Chip/ / Bus/ / Debounce/ │ │ ├── Accessor.h / Scanner.h │ │ │ └── object/ # 对象组合定义 │ ├── PCIeNicCard/ # 网卡对象组合 │ │ ├── pcie_nic_card.h │ │ ├── network_port.h │ │ └── optical_module.h │ └── PCIeGpuCard/ # GPU卡对象组合 │ ├── pcie_gpu_card.h │ ├── gpu.h │ └── memory.h │ ├── src/ # 源文件目录(与include结构对应) │ └── device_tree/ │ ├── interface/ # 接口基类实现(.cpp文件) │ └── object/ # 对象组合实现(.cpp文件) │ └── meson.build ``` ##### 关键概念 | 概念 | 说明 | 示例 | |------|------|------| | **接口基类** | 定义接口的属性和方法签名 | `gen::NetworkAdapter`定义了`FirmwareVersion`、`ChipModel`等属性 | | **对象组合** | 将多个接口组合成完整对象 | 网卡对象组合了`PCIeDevice`、`NetworkAdapter`、`Board`等接口 | | **命名空间** | 所有生成的代码在`gen`命名空间下 | 驱动代码继承`gen::NetworkAdapter`实现`dev::NetworkAdapter` | | **自动生成** | 基于模型文件自动生成,不手动修改 | 通过修改模型文件(JSON)重新生成 | ##### 使用方式 驱动开发时,通过`mc::engine::interface`模板继承对应的`gen`基类并实现功能: ```cpp // 正确写法:通过 engine::interface 包装 gen 基类 class MC_API NetworkAdapter : public mc::engine::interface { public: // 实现具体功能(如启动 NCSI/SMBus 更新任务等) void start_ncsi_update_task_huawei(...); }; // 反射注册:接口类通常不显式列出 gen 基类 MC_REFLECT(dev::NetworkAdapter) ``` --- #### 2.2.4 libraries目录 - 通信协议库 `libraries/`目录包含各种通信协议的封装实现,为驱动提供标准化的协议接口。 ##### 目录结构 ```shell libraries/ ├── mctp/ # MCTP协议库(管理组件传输协议) │ ├── mctp.h / mctp.cpp │ ├── pcie_transport.h / pcie_transport.cpp │ └── meson.build │ ├── ncsi_over_mctp/ # NCSI over MCTP协议库 │ ├── ncsi_over_mctp.h/.cpp │ ├── ncsi_over_mctp_standard.h/.cpp │ ├── ncsi_over_mctp_huawei.h/.cpp # 华为扩展 │ ├── ncsi_over_mctp_wangxun.h/.cpp # 网迅扩展(文件名 wangxun,不是 wx) │ ├── ncsi_over_mctp_mellanox.h/.cpp │ ├── ncsi_over_mctp_mucse.h/.cpp │ ├── ncsi_over_mctp_grt.h/.cpp │ └── meson.build │ ├── ncsi/ # NCSI协议定义(头文件库) │ ├── ncsi_protocol.h │ ├── ncsi_huawei.h / ncsi_wangxun.h / ncsi_mellanox.h / ncsi_mucse.h / ncsi_grt.h │ ├── ncsi_socket.h / adapter.h │ └── meson.build │ ├── pldm/ / pldm_over_mctp/ # PLDM 及 PLDM over MCTP(网迅/博通等型号使用) ├── lldp/ # LLDP 解析(如 hi182x VDPCI LLDP) │ ├── smbus/ # SMBus协议库(含 smbus_postbox,GPU 等也会用到) │ ├── smbus.h/.cpp / std_smbus.h/.cpp / smbus_postbox.h/.cpp │ └── meson.build │ ├── ipmb/ / imu/ / protocol/ └── meson.build ``` ##### 协议库说明 | 协议库 | 说明 | 传输方式 | 应用场景 | |--------|------|---------|---------| | **mctp** | 管理组件传输协议(DMTF标准) | PCIe、SMBus | 作为底层传输协议,封装上层协议消息 | | **ncsi_over_mctp** | 基于MCTP的NCSI协议 | MCTP over PCIe/SMBus | 网卡管理的主要协议,获取网卡状态、配置信息 | | **ncsi** | NCSI协议定义 | - | 定义NCSI命令格式、数据结构(仅头文件) | | **pldm_over_mctp** | 基于MCTP的PLDM协议 | MCTP | 部分网迅/博通型号的带外管理 | | **lldp** | LLDP报文解析 | - | 解析邻居信息(如 hi182x) | | **smbus** | 系统管理总线协议 | I2C/SMBus | 直接读取芯片寄存器,获取温度等数据 | | **ipmb** | IPMI消息块协议 | I2C | IPMI命令传输 | | **imu** | 智能管理单元协议 | I2C/IMU | 获取PCIe配置空间信息、BDF地址 | | **protocol** | 协议基类 | - | 所有协议的通用基类,定义标准接口 | ##### 协议分层关系 ```shell 应用层: 网卡驱动代码 ↓ 协议层: NCSI over MCTP (ncsi_over_mctp_huawei/wangxun/…) 或 PLDM over MCTP ↓ 传输层: MCTP (mctp + pcie_transport) / SMBus ↓ 物理层: PCIe硬件 / SMBus硬件 ``` ##### 使用示例 ```cpp // 1. 创建MCTP对象 mctp* mctp_object = new mctp(this, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, ""); // 2. 创建NCSI协议对象 auto ncsi_huawei = std::make_shared(*mctp_object); // 3. 发送NCSI请求 mc::dict request = { {"CommandId", 0x50}, // OEM命令 {"Data", data_vec} }; auto response = ncsi_huawei->request(request); // 4. 创建SMBus对象 auto smbus_obj = mc::make_shared(this); smbus_obj->init(params); // 5. 读取SMBus数据 std::vector data = smbus_obj->read(offset, length); ``` --- #### 2.2.5 目录之间的关系 ```mermaid flowchart TB subgraph "应用层" Driver["drivers/pcie_nic_card/hisi/hi182x/
厂商驱动实现"] end subgraph "接口层" Interface["drivers/pcie_nic_card/hisi/interface/
接口实现类"] GenInterface["gen/include/device_tree/interface/
接口基类定义"] end subgraph "协议层" NCSI["libraries/ncsi_over_mctp/
NCSI协议实现"] SMBus["libraries/smbus/
SMBus协议实现"] MCTP["libraries/mctp/
MCTP传输协议"] end subgraph "框架层" Internal["drivers/internal/
驱动框架基类"] end Driver -->|继承| Interface Interface -->|继承| GenInterface Driver -->|调用| NCSI Driver -->|调用| SMBus NCSI -->|使用| MCTP Driver -->|使用| Internal style Driver fill:#e1f5ff style GenInterface fill:#fff4e1 style NCSI fill:#ffe1f5 ``` ##### 工作流程 1. **代码生成**:根据模型文件生成`gen/`目录下的接口基类 2. **接口实现**:在`drivers/*/interface/`下继承gen基类,实现具体功能 3. **驱动组装**:在`drivers/*/具体型号/`下组合接口,创建完整驱动对象 4. **协议调用**:驱动通过`libraries/`中的协议库与硬件通信 5. **框架支持**:`drivers/internal/`提供基础设施支持 ### 2.3 驱动协议架构 ```mermaid flowchart LR subgraph "设备驱动层" Driver["设备驱动
hi182x_card"] end subgraph "协议库层" MCTP["MCTP
传输协议"] NOM["NCSI over MCTP
华为扩展"] SMBus["SMBus协议"] IMU["IMU协议
IPMI接口"] end subgraph "传输层" PCIe["PCIe传输"] I2C["I2C/SMBus"] end Driver -->|网卡管理| NOM Driver -->|网卡管理| SMBus Driver -->|设备信息| IMU NOM --> MCTP MCTP --> PCIe SMBus --> I2C IMU --> I2C ``` ### 2.4 底层协议确定 在适配网卡驱动前,首先要确定网卡支持的底层通信协议。不同厂商的网卡可能支持不同的协议组合。 #### 协议类型 | 协议 | 说明 | 适用场景 | |------|------|---------| | **NCSI over MCTP over PCIe** | 通过PCIe总线进行MCTP通信 | 网卡直接连接到PCIe总线 | | **NCSI over MCTP over SMBus** | 通过SMBus/I2C进行MCTP通信 | 网卡通过SMBus桥接芯片管理 | | **SMBus直接访问** | 通过I2C直接读取芯片数据 | 获取MAC、温度等信息 | #### 厂商协议支持对比 | 厂商 | NCSI over MCTP over PCIe | NCSI over MCTP over SMBus | SMBus直接访问 | 说明 | |------|-------------------------|--------------------------|--------------|------| | 华为海思 Hi182x | ✓ | - | ✓ | 主要通过PCIe,SMBus用于带外信息获取 | | 网迅 wangxun(如 ff50xx) | - | ✓ | - | 通过SMBus桥接MCTP通信;另有 ff50xx_pldm 走 PLDM | #### 协议配置方式 ##### 方式一:NCSI over MCTP over PCIe + SMBus(华为海思Hi182x) 这种方式同时使用PCIe和SMBus两种协议: - **PCIe通道**:用于NCSI协议通信,获取网卡主要信息(MAC地址、链路状态等) - **SMBus通道**:用于直接读取芯片温度等数据 **SR文件配置示例**(参考`14140130_19e50222_19e500a1.sr`): ```json { "ManagementTopology": { "Anchor": { "Buses": [ "I2cMux_9545Chan3" ] }, "I2cMux_9545Chan3": { "Chips": [ "Chip_Hi1822", // 网卡芯片(SMBus访问) ] } }, "Objects": { // 配置芯片对象(SMBus访问参数) "Chip_Hi1822": { "OffsetWidth": 0, "AddrWidth": 1, "Address": 232, // I2C地址:0xE8 "WriteTmout": 100, "ReadTmout": 100, "HealthStatus": 0, "WriteRetryTimes": 2, "ReadRetryTimes": 0 }, "PCIeNicCard_1": { "bmc.dev.NetworkAdapter": { "Manufacturer": "Huawei", "ChipModel": "Hi1822", "NetworkPortCount": 2, "SupportedMctp": true, // 关键:通过RefChip关联Chip_Hi1822,支持SMBus访问 "RefChip": "#/Chip_Hi1822" } } } } ``` **关键配置说明:** 1. **ManagementTopology定义I2C拓扑** - 指定网卡芯片挂在哪条I2C总线上 - `Chip_Hi1822`定义芯片的I2C访问参数 2. **RefChip关联** - `bmc.dev.NetworkAdapter`接口通过`RefChip`字段引用`Chip_Hi1822` - 这样`NetworkAdapter`接口可以通过SMBus读取芯片数据(如温度) 3. **双协议工作** - PCIe协议:代码中通过MCTP over PCIe获取网卡功能信息 - SMBus协议:代码中通过`RefChip`访问芯片寄存器获取温度 **代码实现要点**(`hi182x_card.cpp`): ```cpp bool hi182x_card::start_protocol() { // 1. 启动NCSI over MCTP over PCIe协议 if (!start_ncsi_protocol()) { // BDF未就绪,注册回调等待 } // 2. 启动SMBus协议 start_smbus_protocol(); return true; } bool hi182x_card::start_smbus_protocol() { // 获取RefChip引用 register_RefChip(); // 初始化SMBus对象 m_smbus_obj = mc::make_shared(this); m_smbus_obj->init(params); // 注册读写方法,通过RefChip访问 m_smbus_obj->register_WriteRead_method([&](const std::vector& data, uint32_t len) { return m_ref_chip->invoke("bmc.dev.Chip", "BlockIOWriteRead", {data, len}) .as>(); }); // 启动各接口的SMBus更新任务 m_network_adapter.start_smbus_update_task(m_smbus_obj, m_smbus_interval); m_cooling.start_smbus_update_task(m_smbus_obj, m_smbus_interval); return true; } ``` --- ##### 方式二:NCSI over MCTP over SMBus(网迅 wangxun,以 ff50xx 为例) 这种方式通过SMBus桥接实现MCTP通信,所有数据都通过SMBus传输。 **SR文件配置示例**(参考`14140130_80881001_80880300.sr`): ```json { "ManagementTopology": { "Anchor": { "Buses": [ "I2cMux_9545Chan" ] }, "I2cMux_9545Chan": { "Chips": [ "Chip_SmbusChip" // SMBus桥接芯片 ] } }, "Objects": { // SMBus芯片配置 "Chip_SmbusChip": { "Address": 146, // I2C地址:0x92 "AddrWidth": 1, "OffsetWidth": 1, "WriteTmout": 100, "ReadTmout": 100, "HealthStatus": 0 }, // MCTP绑定配置 "MctpBinding_1": { "BmcSMBusEid": 8, // BMC的MCTP端点ID "BmcSMBusPhyAddr": 16 // BMC的物理地址 }, // MCTP端点配置 "Endpoint_1": { "TargetEid": "${Slot} |> expr($1 + 8)", // 目标端点ID(动态计算) "TargetPhyAddr": 73, // 目标物理地址 "MessageType": 2, // 消息类型:NCSI "MediumType": 128, // 介质类型:SMBus "RefChip": "#/Chip_SmbusChip" // 关联SMBus芯片 }, "PCIeNicCard_1": { "bmc.dev.NetworkAdapter": { "Manufacturer": "Beijing Wangxun Technology Co., Ltd.", "ChipModel": "SP1000A", "NetworkPortCount": 2, "SupportedMctp": true, "SupportedLldp": true // 注意:没有RefChip字段,因为不需要直接SMBus访问 } } } } ``` **关键配置说明:** 1. **Chip_SmbusChip** - 定义SMBus桥接芯片的I2C访问参数 - 这个芯片负责将MCTP消息转换为SMBus传输 2. **MctpBinding_1** - 配置BMC侧的MCTP绑定信息 - 指定BMC的EID和物理地址 3. **Endpoint_1** - 配置网卡侧的MCTP端点 - `MessageType: 2`表示NCSI消息类型 - `MediumType: 128`表示通过SMBus传输 - `RefChip`关联到SMBus芯片 4. **无RefChip** - `NetworkAdapter`接口不需要`RefChip` - 所有数据通过NCSI over MCTP over SMBus获取 **代码实现要点**(参考 `wangxun/ff50xx/ff50xx_card.cpp`): ```cpp bool ff50xx_card::start_protocol() { // 只需启动NCSI over MCTP协议 // 框架会根据SR配置自动使用SMBus传输 if (!start_ncsi_protocol()) { // BDF未就绪,注册回调等待 } return true; } bool ff50xx_card::start_ncsi_protocol() { // 创建MCTP对象(框架会根据SR配置使用SMBus传输) m_mctp_object = mc::make_shared(this, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, ""); auto ncsi_update_task = [this]() { // 创建网迅专用的NCSI协议实例(类名 ncsi_over_mctp_wangxun) m_ncsi_over_mctp_wx = std::make_shared(m_mctp_object); m_pcie_device.start_ncsi_update_task_wx(m_ncsi_over_mctp_wx, m_interval, m_package_id); m_cooling.start_ncsi_update_task_wx(m_ncsi_over_mctp_wx, m_interval, m_package_id); for (auto& port : m_network_ports) { port->start_ncsi_update_task(m_ncsi_over_mctp_wx, m_interval, m_package_id); } }; m_mctp_object->create_transport_and_endpoint( std::string(get_object_name()), ncsi_update_task); return true; } ``` --- #### 配置检查清单 **方式一(NCSI over MCTP over PCIe + SMBus):** - [ ] SR文件中定义了网卡芯片对象(如`Chip_Hi1822`) - [ ] `ManagementTopology`中配置了I2C拓扑 - [ ] `NetworkAdapter`接口中配置了`RefChip`字段 - [ ] 代码中实现了`start_smbus_protocol()`方法 - [ ] 代码中实现了SMBus更新任务 **方式二(NCSI over MCTP over SMBus):** - [ ] SR文件中定义了SMBus芯片对象(如`Chip_SmbusChip`) - [ ] 配置了`MctpBinding_1`对象 - [ ] 配置了`Endpoint_1`对象,并关联SMBus芯片 - [ ] `Endpoint_1`的`MessageType`设置为2(NCSI) - [ ] `Endpoint_1`的`MediumType`设置为128(SMBus) - [ ] 代码中只需实现NCSI协议,无需SMBus --- ### 2.5 网卡支持的能力 本节以Hi182x网卡为例,详细列举网卡驱动可以支持的各种能力,帮助开发者了解可以实现哪些功能接口。 #### 网卡级能力 Hi182x网卡主对象实现了多个接口(以下为能力概览,完整列表以 `hi182x_card.h` 的 `MC_OBJECT` 与 DDS 为准): | 能力类别 | 接口名称 | 说明 | 可获取的信息 | |---------|---------|------|-------------| | **PCIe设备信息** | `PCIeDevice` | PCIe设备基础信息 | VID/DID、BDF地址、设备名称、设备类型 | | **PCIe卡信息** | `PCIeCard` | 板卡物理信息 | 卡槽位置、序列号、插槽类型 | | **网络适配器** | `NetworkAdapter` | 网卡功能信息 | 厂商、型号、固件版本、MAC地址数量、支持的协议 | | **温度监控** | `Cooling`(`bmc.dev.Cooling`) | 网卡温度信息 | 芯片温度、温度状态 | | **故障诊断** | `NetworkAdapter_FaultStatus` | 故障状态信息 | 故障代码、健康状态、错误计数、告警信息 | | **带宽监控** | `PCIeDevice_Bandwidth` | PCIe带宽信息 | 链路速度、链路宽度、实际吞吐量、协商状态 | | **日志收集** | `NetworkAdapter_LogCollection` | 日志导出功能 | 网卡日志文件、故障诊断信息、事件记录 | | **板卡信息** | `Board` | 板卡制造信息 | 板卡序列号、部件号、制造商、生产日期 | --- #### 网口级能力 Hi182x的每个网口对象实现了以下5个接口: | 能力类别 | 接口名称 | 说明 | 可获取的信息 | |---------|---------|------|-------------| | **网口基础信息** | `NetworkPort` | 网口基本属性 | 端口ID、MAC地址、最大速率、端口类型、启用状态 | | **链路信息** | `NetworkPort_LinkInfo` | 链路状态信息 | 链路Up/Down、当前速度、双工模式、自协商状态 | | **LLDP接收** | `NetworkPort_LLDPReceive` | LLDP协议信息 | 邻居设备信息、网络拓扑、设备能力、VLAN信息 | | **DCB支持** | `NetworkPort_DataCenterBridging` | 数据中心桥接 | QoS配置、流量控制、优先级映射、带宽分配 | | **网口指标** | `NetworkPort_Metrics` | 流量统计信息 | 收发包数、字节数、错误包、丢包率 | --- #### 光模块能力 Hi182x支持光模块,每个光模块对象实现了以下6个接口: | 能力类别 | 接口名称 | 说明 | 可获取的信息 | |---------|---------|------|-------------| | **光模块基础信息** | `OpticalModule` | 光模块识别信息 | 型号、序列号、厂商、波长、传输距离、接口类型 | | **状态信息** | `OpticalModule_Status` | 光模块状态 | 在位状态、工作状态、故障状态、使能状态 | | **温度监控** | `OpticalModule_TemperatureCelsius` | 光模块温度 | 当前温度、温度告警阈值 | | **电压监控** | `OpticalModule_Voltage` | 工作电压 | 当前电压、电压范围、电压告警阈值 | | **功率监控** | `OpticalModule_Power` | 光功率信息 | 发射功率、接收功率、功率告警阈值、光衰减 | | **电流监控** | `OpticalModule_Current` | 工作电流 | 偏置电流、电流范围、电流告警阈值 | --- #### 能力获取方式 Hi182x网卡通过三种协议获取不同的信息: | 协议类型 | 获取的信息 | 更新频率 | 数据来源 | |---------|----------|----------|---------| | **NCSI over MCTP over PCIe** | 固件版本、MAC地址、链路状态、LLDP信息、DCB配置、网口流量统计、光模块信息、故障状态、带宽统计 | 5秒~180秒 | 网卡固件 | | **SMBus直接访问** | 芯片温度、故障寄存器状态 | 5秒 | 网卡芯片寄存器 | | **IMU协议** | PCIe配置空间信息、BDF地址、四元组信息 | 按需 | PCIe配置空间 | **更新频率策略:** - **快速变化数据**(5秒):温度、链路状态、故障状态、流量统计 - **慢速变化数据**(120秒):固件版本、设备信息、网卡配置 - **极慢变化数据**(180秒):带宽统计、历史数据 --- ## 3. 适配流程详解 > 假设我们要适配一个新厂商"XYZ"的网卡"xyz1000" ### 3.1 创建目录结构 在 `drivers/pcie_nic_card/` 下创建: ```shell pcie_nic_card/ └── xyz/ # 厂商目录 ├── xyz1000/ # 型号目录 │ ├── xyz1000_card.h # 主卡头文件 │ ├── xyz1000_card.cpp # 主卡实现 │ ├── xyz1000_port.h # 网口头文件 │ ├── xyz1000_port.cpp # 网口实现 │ ├── xyz1000_om.h # 光模块头文件(可选) │ ├── xyz1000_om.cpp # 光模块实现(可选) │ ├── xyz1000_abi.cpp # ABI导出 │ └── meson.build # 构建配置 ├── interface/ # 接口实现目录 │ ├── pcie_device.h │ ├── pcie_device.cpp │ ├── network_adapter.h │ ├── network_adapter.cpp │ └── meson.build ├── csr/ # 设备配置目录 │ ├── [VID_DID_SVID_SSID].dds # DDS文件(设备接口定义) │ └── [VID_DID_SVID_SSID].sr # SR文件(硬件自描述信息) └── meson.build ``` --- ### 3.2 配置设备描述文件(DDS) DDS文件定义设备的接口和路径,是框架识别和加载驱动的关键配置。 #### 文件命名规则 ```shell 格式:14140130_[VID][DID]_[SVID][SSID].dds 示例:14140130_19e50222_19e50052.dds 说明:VID=0x19e5, DID=0x0222, SVID=0x19e5, SSID=0x0052 ``` #### DDS文件内容 ```json { "Schema": "dds-v1", "Type": "Component", "DeviceCategory": "PCIeNicCard", "ID": "N/A", "Objects": { "PCIeNicCard": { "Path": "/bmc/dev/Systems/:SystemId/PCIeNicCard/:Id", "Interfaces": [ "bmc.dev.PCIeDevice", "bmc.dev.PCIeDevice.PCIeFunction", "bmc.dev.PCIeDevice.Status", "bmc.dev.PCIeDevice.Oem", "bmc.dev.PCIeCard", "bmc.dev.PCIeCard.Oem", "bmc.dev.Board", "bmc.dev.NetworkAdapter", "bmc.dev.NetworkAdapter.Oem", "bmc.dev.Cooling", "bmc.dev.NetworkAdapter.FaultStatus", "bmc.dev.PCIeDevice.Bandwidth" ] }, "NicPort": { "Path": ":Parent/NicPort/:Id", "Interfaces": [ "bmc.dev.NetworkPort", "bmc.dev.NetworkPort.LinkInfo", "bmc.dev.NetworkPort.DataCenterBridging", "bmc.dev.NetworkPort.LLDPReceive", "bmc.dev.NetworkPort.Metrics" ] }, "OpticalTransceiver": { "Path": ":Parent/OpticalTransceiver", "Interfaces": [ "bmc.dev.OpticalModule", "bmc.dev.OpticalModule.Status", "bmc.dev.OpticalModule.TemperatureCelsius", "bmc.dev.OpticalModule.Voltage", "bmc.dev.OpticalModule.Power", "bmc.dev.OpticalModule.Current" ] } } } ``` #### 关键字段说明 | 字段 | 说明 | 注意事项 | |------|------|---------| | `DeviceCategory` | 设备类别 | 必须是`"PCIeNicCard"` | | `Objects` | 对象定义 | 键名必须与ABI中的`device_name`一致 | | `Path` | 对象路径 | `:SystemId`、`:Id`是动态参数,`:Parent`表示父对象 | | `Interfaces` | 接口列表 | 必须与`MC_OBJECT`宏中声明的接口一致 | #### 配置要点 1. **接口列表要完整**:DDS中的`Interfaces`必须包含代码中`MC_OBJECT`声明的所有接口 2. **对象名称要匹配**:`Objects`的键名(如`PCIeNicCard`、`NicPort`)必须与ABI注册时的`device_name`一致 3. **路径格式固定**:主对象路径和子对象路径格式不要修改 4. **可选对象**:如果不支持光模块,可以删除`OpticalTransceiver`对象定义 --- ### 3.3 配置硬件自描述信息(SR) SR文件定义硬件拓扑、芯片配置和对象初始值,用于复杂的硬件管理场景。 #### 文件命名规则 ```shell 格式:14140130_[VID][DID]_[SVID][SSID].sr 示例:14140130_19e50222_19e50052.sr 说明:文件名必须与DDS文件一致 ``` #### SR文件结构 ```json { "FormatVersion": "5.00", "DataVersion": "5.00", "Unit": { "Type": "PCIeNicCard", "Name": "PCIeNicCard_1", "Compatible": ["xyz_vendor", "xyz_model"] }, "ManagementTopology": { // 硬件拓扑配置(I2C总线、芯片连接关系) }, "Objects": { // 对象初始配置和属性值 } } ``` #### ManagementTopology配置(I2C拓扑) 如果网卡需要通过SMBus访问,需要配置I2C拓扑: ```json "ManagementTopology": { "Anchor": { "Buses": ["I2cMux_9545Chan3"] }, "I2cMux_9545Chan3": { "Chips": [ "Chip_XYZ1000", // 网卡芯片 ] } }, "Objects": { "Chip_XYZ1000": { "OffsetWidth": 0, "AddrWidth": 1, "Address": 232, // I2C地址:0xE8 "WriteTmout": 100, "ReadTmout": 100, "HealthStatus": 0, "WriteRetryTimes": 2, "ReadRetryTimes": 0 } } ``` #### 网卡对象配置(PCIeNicCard_1) 定义网卡的初始属性值: ```json "PCIeNicCard_1": { "bmc.dev.PCIeDevice": { "DeviceName": "PCIe Card ${Slot} (XYZ1000)", "FunctionClass": 2, "VendorId": "0x1234", "DeviceId": "0x0001", "SubSystemVendorId": "0x1234", "SubSystemDeviceId": "0x0002", "Segment": 0, "SocketId": 0, "DeviceType": "MultiFunction", "SlotType": "FullLength", "FunctionProtocol": "PCIe", "FunctionType": "Physical", "ComponentType": 8, "Container": "${Container}" }, "bmc.dev.NetworkAdapter": { "Manufacturer": "XYZ Vendor", "ChipModel": "XYZ1000", "Description": "4*25GE", "ChipVendor": "XYZ", "NetworkPortCount": 4, "SupportedMctp": true, "SupportedLldp": true, "Type": 3, "RefChip": "#/Chip_XYZ1000", // 关联SMBus芯片(如果需要) "OSPowerState": 0 }, "bmc.dev.Board": { "Slot": "<=/PCIeNicCard_1[bmc.dev.PCIeDevice].Slot", "Description": "4*25GE", "Id": 255, "Type": "PCIeCard", "PartNumber": "PART1234" }, "bmc.dev.Cooling": { "TemperatureStatus": 4, "TemperatureCelsius": 0 } } ``` #### 网口对象配置(NicPort_N) 为每个网口配置初始值: ```json "NicPort_0": { "@Parent": "PCIeNicCard_1", "bmc.dev.NetworkPort": { "PortId": 0, "NetDevFuncType": 1, "MediumType": "FiberOptic", "MaxSpeedSupported": "25GE", "PermanentMACAddress": "00:00:00:00:00:00", "MACAddress": "00:00:00:00:00:00", "BDF": "" }, "bmc.dev.NetworkPort.LinkInfo": { "AutoSpeedNegotiationEnabled": false, "SpeedMbps": 4294967295, "WorkloadType": 0, "LinkStatus": 255 } } ``` **说明:**`@Parent`指定父对象,表示这个网口属于`PCIeNicCard_1`。 #### 光模块对象配置(OpticalTransceiver_N) 如果支持光模块,为每个端口配置光模块对象: ```json "OpticalTransceiver_0": { "@Parent": "NicPort_0", "bmc.dev.OpticalModule": { "ChannelNum": 1, "Presence": 0, "MediumType": "" }, "bmc.dev.OpticalModule.Status": { "PowerState": 0, "FaultState": 0, "SpeedMatch": true, "TypeMatch": true }, "bmc.dev.OpticalModule.TemperatureCelsius": { "TemperatureCelsius": 65535, "TemperatureLowerThresholdCritical": 65535, "TemperatureUpperThresholdCritical": 65535 } } ``` #### SR文件配置要点 1. **RefChip关联**:如果需要通过SMBus直接访问网卡芯片,必须在`NetworkAdapter`接口中配置`RefChip` 2. **父子关系**:使用`@Parent`字段指定对象的层次关系 3. **动态参数**:`${Slot}`等参数会在运行时替换 4. **初始值**:65535通常表示"无效值"或"未初始化" 5. **接口完整性**:SR中定义的接口必须与DDS文件中声明的接口一致 ### 3.4 创建网卡主对象 #### 代码示例:`xyz1000_card.h` ```cpp #ifndef XYZ1000_CARD_H #define XYZ1000_CARD_H #include #include #include "xyz1000_port.h" #include "interface/board.h" #include "interface/network_adapter.h" #include "interface/pcie_card.h" #include "interface/pcie_device.h" namespace dev { using ncsi_over_mctp_xyz_ptr = std::shared_ptr; class xyz1000_card : public mc::engine::object { public: // MC_OBJECT宏定义:类名、对象类型、路径模式、接口列表 MC_OBJECT( xyz1000_card, "PCIeNicCard", "/bmc/dev/Systems/1/PCIeNicCard/${object_name}", (PCIeDevice)(PCIeCard)(NetworkAdapter)(Board) ) xyz1000_card(); // 构造函数 ~xyz1000_card(); // 析构函数 // 生命周期方法 bool init(mc::mutable_dict& csr_object, const mc::dict& connector); bool start(); bool stop(); // 子设备管理 void init_network_ports(); // 接口成员变量 PCIeDevice m_pcie_device; PCIeCard m_pcie_card; NetworkAdapter m_network_adapter; Board m_board; uint8_t m_system_id; private: std::vector m_network_ports; // 协议支持 bool start_ncsi_protocol(); bool start_protocol(); ncsi_over_mctp_xyz_ptr m_ncsi_over_mctp; mc::milliseconds m_interval = mc::milliseconds(5000); mctp* m_mctp_object; // 管理MCTP对象生命周期 }; } // namespace dev // MC_REFLECT宏:反射信息注册 MC_REFLECT(dev::xyz1000_card, ((m_system_id, "SystemId")) ((m_pcie_device, "bmc.dev.PCIeDevice")) ((m_pcie_card, "bmc.dev.PCIeCard")) ((m_network_adapter, "bmc.dev.NetworkAdapter")) ((m_board, "bmc.dev.Board"))) #endif // XYZ1000_CARD_H ``` #### 关键说明 **1. MC_OBJECT宏的参数:** - **第1个**:类名 - **第2个**:设备类型(固定为`"PCIeNicCard"`) - **第3个**:对象路径模板(固定格式) - **第4个**:实现的接口列表(按需选择) **2. 接口选择原则:** | 接口 | 必需性 | 说明 | |------|--------|------| | `PCIeDevice`、`PCIeCard`、`Board` | 必需 | 基础接口 | | `NetworkAdapter` | 必需 | 网卡功能接口 | | `Cooling`(`bmc.dev.Cooling`) | 可选 | 支持温度监控时添加 | | `NetworkAdapter_FaultStatus` | 可选 | 支持故障诊断时添加 | | `PCIeDevice_Bandwidth` | 可选 | 支持带宽监控时添加 | --- ### 3.5 实现网卡主对象 #### 代码示例:`xyz1000_card.cpp` ```cpp #include "xyz1000_card.h" #include namespace dev { // 构造函数:初始化MCTP对象指针为nullptr xyz1000_card::xyz1000_card() : m_mctp_object(nullptr) { } // 析构函数:释放MCTP对象,防止内存泄漏 xyz1000_card::~xyz1000_card() { // 释放MCTP对象内存 // 取消注册OS重置回调 } // 初始化方法:从配置文件加载网卡属性 bool xyz1000_card::init(mc::mutable_dict& csr_object, const mc::dict& connector) { // 使用from_variant自动加载配置到成员变量 // 异常处理 } // 启动方法:启动网卡和所有子设备 bool xyz1000_card::start() { // 初始化子网口对象 // 启动每个网口 // 启动NCSI协议 // 启动SMBus协议(如果支持) } // 停止方法:停止网卡并清理资源 bool xyz1000_card::stop() { // 停止所有网口 // 清理定时器等资源 } // 初始化网口对象:从子对象列表中提取所有网口 void xyz1000_card::init_network_ports() { // 获取子对象列表 // 筛选出NicPort类型的对象 // 加入m_network_ports向量 } // 启动NCSI协议:创建MCTP通信和NCSI协议实例 bool xyz1000_card::start_ncsi_protocol() { // 检查BDF地址是否就绪 // 创建MCTP对象(赋值给成员变量) // 定义NCSI更新任务(lambda表达式) // 为各接口启动更新任务 // 创建传输层并启动 } // 启动协议:启动NCSI协议,如果失败则注册回调等待BDF就绪 bool xyz1000_card::start_protocol() { // 尝试启动NCSI协议 // 如果失败,注册BDF变化回调 } } // namespace dev ``` #### 关键说明 | 方法 | 职责 | |------|------| | `init()` | 加载配置文件中的属性值,使用`from_variant`自动映射 | | `start()` | 初始化子设备、启动协议通信、注册回调和定时器 | | `stop()` | 清理资源 | **协议启动流程:** 1. 获取BDF(Bus/Device/Function) 2. 创建MCTP对象 3. 创建NCSI协议实例 4. 为接口绑定更新任务 --- ### 3.6 实现网口对象 #### 代码示例:`xyz1000_port.h` ```cpp #ifndef XYZ1000_PORT_H #define XYZ1000_PORT_H #include #include #include "interface/network_port.h" #include "interface/network_port/link_info.h" namespace dev { using ncsi_over_mctp_xyz_ptr = std::shared_ptr; class xyz1000_port : public mc::engine::object { public: MC_OBJECT( xyz1000_port, "NicPort", ":Parent/NicPort/:Id", (NetworkPort)(NetworkPort_LinkInfo) ) xyz1000_port() = default; ~xyz1000_port() = default; bool init(mc::mutable_dict& csr_object, const mc::dict& connector); bool start(); bool stop(); void start_ncsi_protocol(ncsi_over_mctp_xyz_ptr ncsi_over_mctp, mc::milliseconds interval); NetworkPort m_network_port; NetworkPort_LinkInfo m_network_port_link_info; private: ncsi_over_mctp_xyz_ptr m_ncsi_over_mctp; mc::timer* m_ncsi_timer = nullptr; }; } // namespace dev MC_REFLECT(dev::xyz1000_port, ((m_network_port, "bmc.dev.NetworkPort")) ((m_network_port_link_info, "bmc.dev.NetworkPort.LinkInfo"))) #endif // XYZ1000_PORT_H ``` #### 代码示例:`xyz1000_port.cpp` ```cpp #include "xyz1000_port.h" #include namespace dev { // 初始化网口:从配置加载网口属性 bool xyz1000_port::init(mc::mutable_dict& csr_object, const mc::dict& connector) { // 使用from_variant加载配置 // 加载PortId、MAC地址等属性 } // 启动网口:执行网口启动逻辑 bool xyz1000_port::start() { // 执行网口特定的启动操作 // 打印启动日志 } // 停止网口:停止定时器并清理资源 bool xyz1000_port::stop() { // 停止NCSI定时器 // 释放定时器内存 } // 启动NCSI协议:创建定时器周期性更新网口状态 void xyz1000_port::start_ncsi_protocol(ncsi_over_mctp_xyz_ptr ncsi_over_mctp, mc::milliseconds interval) { // 保存NCSI协议对象 // 创建定时器 // 设置定时器回调(获取链路状态、流量统计等) // 启动定时器 } } // namespace dev ``` #### 关键说明 - 网口对象的路径使用`:Parent`,表示在父对象(网卡)路径下 - 定时器用于周期性更新网口状态 - 从NCSI协议获取数据并更新到接口属性 --- ### 3.7 实现接口类 #### 核心要点 接口类继承自`gen`命名空间的基类,负责具体的协议实现和数据更新。 **1. 接口类定义** ```cpp // 通过 engine::interface 继承 gen 基类(与 hisi/interface/network_adapter.h 一致) class MC_API NetworkAdapter : public mc::engine::interface { public: // 启动NCSI更新任务:创建定时器周期性更新属性 void start_ncsi_update_task(ncsi_over_mctp_xyz_ptr ncsi_over_mctp, mc::milliseconds interval); // 停止更新任务:停止并释放定时器 void stop_ncsi_update_task(); // 更新方法:通过NCSI协议获取数据并更新属性 void update_firmware_version(); void update_chip_info(); private: mc::timer* m_ncsi_timer = nullptr; ncsi_over_mctp_xyz_ptr m_ncsi_over_mctp; }; // 接口反射通常不显式列出 gen 基类 MC_REFLECT(dev::NetworkAdapter) ``` **2. 关键实现方法** ```cpp // 启动更新任务:创建定时器周期性更新属性 void NetworkAdapter::start_ncsi_update_task(ncsi_over_mctp_xyz_ptr ncsi_over_mctp, mc::milliseconds interval) { // 保存协议对象 // 创建定时器 // 设置定时器回调(调用各个update方法) // 启动定时器 // 立即执行一次更新 } // 更新固件版本:通过NCSI协议获取并更新FirmwareVersion属性 void NetworkAdapter::update_firmware_version() { // 构造NCSI请求数据 // 调用m_ncsi_over_mctp->request()发送请求 // 解析响应数据 // 更新属性:FirmwareVersion = parsed_version } ``` **关键要点:** - 接口类通过`mc::engine::interface`继承对应的`gen`基类 - 使用定时器周期性调用update方法 - update方法负责:获取数据 → 解析 → 更新属性 - 属性更新后会自动触发信号通知上层 --- ### 3.8 实现ABI导出 ABI(Application Binary Interface)是驱动程序与框架交互的标准接口。 #### 代码示例:`xyz1000_abi.cpp` ```cpp #include #include #include "xyz1000_card.h" #include "xyz1000_port.h" using namespace dev; extern "C" { // ============================================ // 网卡主对象ABI函数 // ============================================ // 创建网卡对象:分配内存并设置基本属性 driver_handle_t create_xyz1000_card(void* service, const char* name) { // 参数检查 // 创建xyz1000_card对象 // 设置service和对象名称 // 返回对象指针 } // 初始化网卡对象:加载配置 status_t init_xyz1000_card(driver_handle_t device, void* csr_object, void* connector) { // 参数检查 // 类型转换 // 调用对象的init方法 // 返回状态码 } // 启动网卡对象:启动设备和协议 status_t start_xyz1000_card(driver_handle_t device) { // 参数检查 // 调用对象的start方法 // 返回状态码 } // 停止网卡对象:停止设备和清理资源 status_t stop_xyz1000_card(driver_handle_t device) { // 参数检查 // 调用对象的stop方法 // 返回状态码 } // ============================================ // 网口对象ABI函数 // ============================================ // 创建网口对象:分配内存并设置基本属性 driver_handle_t create_xyz1000_port(void* service, const char* name) { // 参数检查 // 创建xyz1000_port对象 // 设置service和对象名称 // 返回对象指针 } // 初始化网口对象:加载配置 status_t init_xyz1000_port(driver_handle_t device, void* csr_object, void* connector) { // 参数检查 // 类型转换 // 调用对象的init方法 // 返回状态码 } // 启动网口对象:启动网口 status_t start_xyz1000_port(driver_handle_t device) { // 参数检查 // 调用对象的start方法 // 返回状态码 } // 停止网口对象:停止网口 status_t stop_xyz1000_port(driver_handle_t device) { // 参数检查 // 调用对象的stop方法 // 返回状态码 } // ============================================ // 驱动注册 // ============================================ // 网卡主对象驱动结构体:定义设备名和生命周期函数 device_driver_t xyz1000_card_device_driver = { .device_name = "PCIeNicCard", // 设备类型名(必须与DDS文件一致) .ctor = create_xyz1000_card, // 创建函数 .init = init_xyz1000_card, // 初始化函数 .start = start_xyz1000_card, // 启动函数 .stop = stop_xyz1000_card // 停止函数 }; // 网口对象驱动结构体:定义设备名和生命周期函数 device_driver_t xyz1000_port_device_driver = { .device_name = "NicPort", // 设备类型名(必须与DDS文件一致) .ctor = create_xyz1000_port, // 创建函数 .init = init_xyz1000_port, // 初始化函数 .start = start_xyz1000_port, // 启动函数 .stop = stop_xyz1000_port // 停止函数 }; // 驱动数组:包含所有设备类型的驱动 device_driver_t xyz1000_device_driver[] = { xyz1000_card_device_driver, xyz1000_port_device_driver }; // 驱动注册函数:框架调用此函数获取驱动列表 status_t register_device_driver(device_driver_t** device_driver, uint8_t* count) { // 返回驱动数组指针 *device_driver = xyz1000_device_driver; // 返回驱动数量 *count = sizeof(xyz1000_device_driver) / sizeof(xyz1000_device_driver[0]); ilog("Registered xyz1000 device driver: ${count} devices", ("count", *count)); return STATUS_OK; } } // extern "C" ``` #### 关键说明 - 所有ABI函数必须用`extern "C"`包装,确保C语言兼容 - 每个设备类型需要4个函数:`create`、`init`、`start`、`stop` - `device_name`必须与DDS文件中的对象类型匹配 - `register_device_driver`是框架调用的入口函数 --- ### 3.9 配置构建编译 #### 代码示例:`meson.build` ```meson # 源文件列表 xyz1000_sources = files( 'xyz1000_card.cpp', 'xyz1000_port.cpp', 'xyz1000_abi.cpp', ) # 接口实现源文件 interface_sources = files( 'interface/pcie_device.cpp', 'interface/network_adapter.cpp', 'interface/network_port.cpp', 'interface/network_port/link_info.cpp', ) # 合并源文件 all_sources = xyz1000_sources + interface_sources # 包含目录 include_dirs = [ include_directories('.'), include_directories('interface'), gen_inc, internal_inc ] # 静态库(用于测试) libxyz1000_static = static_library( 'xyz1000', all_sources, include_directories: include_dirs, dependencies: [ dev_deps, libncsi_over_mctp_dep, libmctp_dep ], install: false ) # 动态库(用于部署) libxyz1000 = shared_library( 'xyz1000', include_directories: include_dirs, name_prefix: 'lib', name_suffix: 'so', install: true, install_dir: drivers_install_dir, link_whole: [libxyz1000_static] ) ``` #### 关键说明 - 库名会成为驱动SO文件名:`libxyz1000.so` - `install_dir`使用`drivers_install_dir`变量(框架定义) - 依赖关系要明确列出,避免链接错误 --- ## 4. 最佳实践建议 ### 4.1 代码规范 #### 命名规范 | 类型 | 规范 | 示例 | |------|------|------| | 类名 | 厂商_型号_类型 | `xyz1000_card` | | 文件名 | 与类名一致 | `xyz1000_card.h` | | 成员变量 | `m_`前缀 | `m_network_ports` | | 常量 | 大写+下划线 | `DEFAULT_TIMEOUT` | #### 日志规范 - **启动/停止**:使用`ilog` - **错误**:使用`elog` - **调试信息**:使用`dlog` - **日志要包含上下文信息** ```cpp ilog("Starting xyz1000_card: ${name} with ${count} ports", ("name", card_name)("count", port_count)); ``` #### 错误处理 - 所有可能失败的操作都要检查返回值 - 使用`try-catch`捕获异常 - 记录详细的错误信息 ```cpp try { bool ret = operation(); if (!ret) { elog("Operation failed: ${reason}", ("reason", error_msg)); return false; } } catch (const std::exception& e) { elog("Exception caught: ${error}", ("error", e.what())); return false; } ``` --- ### 4.2 性能优化 #### 定时任务间隔 - 根据数据变化频率设置不同的更新间隔,避免不必要的通信开销 - **快速变化数据**:5秒(5000ms) - 温度、链路状态、故障状态 - **慢速变化数据**:120秒(120000ms) - 固件版本、设备信息 - **极慢变化数据**:180秒(180000ms) - 带宽统计、配置信息 **实际应用示例:** ```cpp // 不同接口使用不同的更新间隔 m_cooling.start_ncsi_update_task_huawei(ncsi, mc::milliseconds(5000)); // 温度:5秒 m_network_adapter.start_ncsi_update_task(ncsi, mc::milliseconds(120000)); // 基础信息:120秒 m_pcie_device_bandwidth.start_ncsi_update_task(ncsi, mc::milliseconds(180000)); // 带宽:180秒 ``` #### 内存管理 - 优先使用智能指针(`shared_ptr`) - 及时清理定时器等资源 - **重要**:MCTP对象必须使用成员变量管理,防止严重内存泄漏 **MCTP对象管理:** ```cpp // 头文件声明 class xyz1000_card : public mc::engine::object { private: mctp* m_mctp_object; // 使用成员变量管理 }; // 实现文件 xyz1000_card::xyz1000_card() : m_mctp_object(nullptr) {} xyz1000_card::~xyz1000_card() { // 在析构函数中释放,防止内存泄漏 if (m_mctp_object) { delete m_mctp_object; m_mctp_object = nullptr; } } bool xyz1000_card::start_ncsi_protocol() { // 赋值给成员变量,而不是局部变量 m_mctp_object = new mctp(this, phy_addr, ...); } ``` **定时器资源管理:** ```cpp // 清理定时器 if (m_timer != nullptr) { m_timer->stop(); delete m_timer; m_timer = nullptr; } ``` #### 协议优化 - 批量请求减少通信次数 - 缓存不变的数据 - 失败时使用指数退避 ### 4.3 测试建议 #### 单元测试 - 测试每个接口的更新方法 - 测试异常情况处理 - 使用mock对象模拟协议 ```cpp TEST(xyz1000_card, test_init) { xyz1000_card card; mc::mutable_dict csr_object = {...}; mc::dict connector = {...}; EXPECT_TRUE(card.init(csr_object, connector)); } ``` #### 集成测试 - 测试完整的生命周期:`create` → `init` → `start` → `stop` - 测试与实际硬件的通信 - 测试长时间运行的稳定性 #### 回归测试 - 每次修改后重新测试基本功能 - 检查是否影响其他网卡驱动 - 验证Redfish接口数据正确 ## 结语 南向网卡驱动适配是一项系统性工作,需要对硬件特性、通信协议、软件架构都有深入理解。本文档提供了一套完整的适配流程和代码示例,但实际适配中还会遇到各种具体问题,欢迎大家积极在社区沟通交流和贡献。 --- # 使用 openUBMC Studio 进行网卡适配 > URL: https://openubmc.cn/docs/zh/latest/component_driver/nic_adapt/studio_nic_adapt.html > Language: zh # 使用 openUBMC Studio 进行网卡适配 > 本文档介绍如何通过 openUBMC Studio 的模版浏览器快速生成 PCIe 网卡驱动模版,并完成基本的适配配置和出包操作。 > > 章节总览见《[部件驱动适配指南](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/4-部件驱动适配指南.md)》;完整适配流程见《[网卡驱动适配指南](./south_nic_driver_adapt.md)》。 ## 1. 克隆代码仓 将 [`component_drivers`](https://gitcode.com/openUBMC/component_drivers) 代码仓克隆到本地: ```bash git clone https://gitcode.com/openUBMC/component_drivers.git ``` 克隆完成后,使用 openUBMC Studio 打开项目根目录。 ## 2. 打开模版浏览器 在 openUBMC Studio 界面左下角,点击 **模版浏览器** 图标,打开模版浏览面板。 ## 3. 生成 PCIe 网卡驱动模版 1. 在模版浏览器中,选择 **PCIe 网卡驱动模版**。 2. 点击 **生成到文件夹** 按钮。 3. 在弹出的目标文件夹选择对话框中,选择项目中的 `drivers/pcie_nic_card/` 目录作为生成目标路径。 生成的模版文件将包含以下内容: ```shell drivers/pcie_nic_card/ └── [厂商目录]/ ├── csr/ │ ├── [默认名称].dds # 设备描述文件 │ └── [默认名称].sr # 硬件自描述信息文件 ├── interface/ # 接口实现目录 ├── [型号目录]/ # 驱动实现代码 └── meson.build ``` ## 4. 修改 SR 和 DDS 文件名 根据目标网卡的设备标识信息,将 `csr/` 目录下生成的 `.sr` 和 `.dds` 文件重命名为对应的四元组格式: ```shell 命名格式:14140130_[VID][DID]_[SVID][SSID].dds 14140130_[VID][DID]_[SVID][SSID].sr ``` 以 VID=`0x19e5`、DID=`0x0222`、SVID=`0x19e5`、SSID=`0x0052` 的网卡为例,文件名应修改为: ```shell 14140130_19e50222_19e50052.dds 14140130_19e50222_19e50052.sr ``` > [!WARNING]注意 > `.dds` 和 `.sr` 文件必须使用相同的前缀名称,框架通过文件名匹配加载对应的配置。 ## 5. 提升版本号 在编译出包之前,需要在 `mds/service.json` 中提升版本号。打开该文件,将 `version` 字段的值递增: ```json { "name": "component_drivers", "version": "1.2.167", ... } ``` > [!WARNING]注意 > 版本号需遵循语义化版本规范(主版本号.次版本号.修订号),每次出包前务必递增,避免版本冲突。 ## 6. 编译出包 在项目根目录下执行以下命令进行编译出包: ```bash bingo build ``` 编译成功后,生成的驱动库文件将输出到 conan 缓存中。 --- # GPU2.0卡适配指导 > URL: https://openubmc.cn/docs/zh/latest/component_driver/xpu_adapt/GPU_DriverSpecification2.0_Guide.html > Language: zh 本文档主要介绍如何在openUBMC上适配一张规范2.0的GPU卡。
# 南向部件驱动适配教程GPU篇 >本教程面向从事GPU适配的南向部件驱动开发者,详细阐述了从接口设计到代码实现的完整流程。 ## 目录 - [1. 概述](#1-概述) - [2. 前置准备](#2-前置准备) - [3. 适配流程](#3-适配流程) ## 1. 概述 **List of abbreviations** **缩略语清单** :
Abbreviations 缩略语 Full spelling 英文全名 Chinese explanation 中文解释
BMC Baseboard Management Controller 基板管理控制器
PCIe Peripheral Component Interconnect Express 高速外设组件互连
GPU Graphics Processing Unit 图形处理器
Component Drivers是一个基于C++17的硬件组件驱动程序框架,主要面向服务器板卡组件管理场景。详细介绍可参考本项目的overview.md文档 ## 2. 前置准备 ### 2.1 准备编译环境 可参考社区的[Docker开发环境搭建](../../installation/env_build/docker_env.md)。在完成环境搭建后,推荐通过scripts目录下的smart_build.sh完成首次编译,如果希望通过手动构建的方式,可参考本项目的[README.md文档](https://gitcode.com/openUBMC/component_drivers/blob/main/README.md) ### 2.2 了解驱动规范 驱动规范定义了驱动需要实现的接口。GPU的驱动规范可参考本项目归档的[GPU驱动规范](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3.2-xPU驱动规范.md) ### 2.3 了解工程目录 Component Drivers项目采用分层架构设计,GPU驱动适配需要了解以下关键目录结构: #### 2.3.1 项目整体结构 ```text component_drivers/ ├── docs/ # 文档 ├── drivers/ # 驱动实现目录 │ ├── pcie_gpu_card/ # GPU卡驱动 │ ├── bus/ # 总线驱动 │ └── chip/ # 芯片驱动 ├── gen/ # 自动生成的接口定义 ├── include/ # 公共头文件 ├── libraries/ # 协议库 │ └── smbus/ # SMBus协议 └── tests/ # 测试代码 ``` #### 2.3.2 GPU驱动目录结构 GPU驱动位于 `drivers/pcie_gpu_card/` 目录下,按厂商和型号组织: ```text pcie_gpu_card/ ├── innosilicon/ # 厂商目录(如:芯动科技) │ ├── awm_m11p/ # 具体GPU型号目录 │ │ ├── awm_m11p_abi.cpp # ABI导出接口 │ │ ├── awm_m11p_card.cpp # GPU卡主对象实现 │ │ ├── awm_m11p_card.h # GPU卡主对象头文件 │ │ ├── awm_m11p_gpu.cpp # GPU处理器对象实现 │ │ ├── awm_m11p_gpu.h # GPU处理器对象头文件 │ │ ├── awm_m11p_memory.cpp # GPU内存对象实现 │ │ ├── awm_m11p_memory.h # GPU内存对象头文件 │ │ └── meson.build # 构建配置 │ ├── csr/ # 设备配置目录 │ │ ├── [VID_DID_SVID_SSID].dds # 设备描述文件 │ │ └── [VID_DID_SVID_SSID].sr # 部件自描述记录 │ ├── interface/ # 接口实现目录 │ │ ├── gpu/ │ │ | ├── power.h/.cpp # GPU功耗接口实现 │ │ | └── status.h/.cpp # GPU状态接口实现 │ │ ├── gpu.h/.cpp # GPU接口实现 │ │ ├── memory.h/.cpp # 内存接口实现 │ │ ├── pcie_card.h/.cpp # PCIe卡接口实现 │ │ ├── pcie_device.h/.cpp # PCIe设备接口实现 │ │ └── processor.h/.cpp # 处理器接口实现 │ └── meson.build # 构建配置 └── meson.build # 构建配置 ``` #### 2.3.3 关键目录说明 | 目录类型 | 路径 | 说明 | 作用 | |---------|------|------|------| | **接口定义** | `gen/include/device_tree/interface/` | 自动生成的接口基类定义 | 定义GPU、Memory、PCIeDevice等接口的属性和方法签名 | | **厂商实现** | `drivers/pcie_gpu_card/[厂商]/[型号]/` | 厂商具体驱动实现 | 继承gen接口,实现GPU管理的实际功能逻辑 | | **协议库** | `libraries/` | 通信协议实现 | SMBus等协议封装,用于与GPU通信 | | **配置文件** | `drivers/pcie_gpu_card/[厂商]/csr/` | 设备配置文件 | DDS文件定义设备接口,SR文件定义硬件拓扑 | 目录关系如下: ```mermaid flowchart TD C[驱动接口基类定义
gen] D[驱动接口实现
drivers/pcie_gpu_card/interface/] A[驱动对象实现
drivers/pcie_gpu_card/厂商/型号/] B[协议库层
libraries] D -->|继承| C D -->|组合| A A -->|依赖| B ``` #### 2.3.4 GPU设备对象层次 GPU驱动中涉及的主要设备对象: | 对象类型 | 说明 | 示例类 | |---------|------|--------| | **GPU卡主对象** | 代表整个GPU卡 | `awm_m11p_card` | | **GPU处理器对象** | 代表GPU芯片本身 | `awm_m11p_gpu` | | **GPU内存对象** | 代表GPU显存 | `awm_m11p_memory` | 这些对象通过继承不同的gen接口来实现相应的功能,如PCIeDevice、Gpu、Memory等接口 ### 2.4 了解GPU支持的协议类型 不同厂商的GPU支持的带外管理协议不同,这需要开发者去向厂家了解对应的协议。一般来讲,GPU的带外管理协议是在SMBus协议基础之上实现的,例如NVIDIA GPU的SMBPBI协议。通过了解GPU的带外管理协议,就可以清楚接下来可以实现哪些接口并且如何实现它们 ## 3. 适配流程 >以适配芯动科技的风华1号为例 ### 3.1 创建目录 在 `drivers/pcie_gpu_card/` 下创建如下目录与文件: ```text pcie_gpu_card/ ├── innosilicon/ # 厂商目录(如:芯动科技) │ ├── awm_m11p/ # 具体GPU型号目录 │ │ ├── awm_m11p_abi.cpp # ABI导出接口 │ │ ├── awm_m11p_card.cpp # GPU卡主对象实现 │ │ ├── awm_m11p_card.h # GPU卡主对象头文件 │ │ ├── awm_m11p_gpu.cpp # GPU处理器对象实现 │ │ ├── awm_m11p_gpu.h # GPU处理器对象头文件 │ │ ├── awm_m11p_memory.cpp # GPU内存对象实现 │ │ ├── awm_m11p_memory.h # GPU内存对象头文件 │ │ └── meson.build # 构建配置 │ ├── csr/ # 设备配置目录 │ │ ├── [VID_DID_SVID_SSID].dds # 设备描述文件 │ │ └── [VID_DID_SVID_SSID].sr # 部件自描述记录 │ ├── interface/ # 接口实现目录 │ │ ├── gpu/ │ │ | ├── power.h/.cpp # GPU功耗接口实现 │ │ | └── status.h/.cpp # GPU状态接口实现 │ │ ├── gpu.h/.cpp # GPU接口实现 │ │ ├── memory.h/.cpp # 内存接口实现 │ │ ├── pcie_card.h/.cpp # PCIe卡接口实现 │ │ ├── pcie_device.h/.cpp # PCIe设备接口实现 │ │ └── processor.h/.cpp # 处理器接口实现 │ └── meson.build # 构建配置 └── meson.build # 构建配置 ``` 说明: - `awm_m11p_card` 为GPU卡主对象,组合并管理GPU处理器与内存等子对象; - `awm_m11p_gpu` 为GPU处理器对象,承载 `Gpu`、`Gpu.Status`、`Gpu.Power` 等接口实现; - `awm_m11p_memory` 为显存对象,实现 `Memory` 相关接口; - `interface/` 下的文件继承 `gen/include/device_tree/interface/` 中对应基类,负责协议交互与属性更新; - `csr/` 目录中的 `.dds` 与 `.sr` 文件分别定义对象/接口与硬件管理拓扑; - `meson.build` 用于声明源文件、依赖与安装目标(最终生成 `lib.so`)。 ### 3.2 配置设备描述文件 #### 文件命名规则 ```text 格式:14140130_[VID][DID]_[SVID][SSID].dds 示例:14140130_19e50222_19e50052.dds 说明:VID=0x19e5, DID=0x0222, SVID=0x19e5, SSID=0x0052 ``` #### DDS文件内容 ```json { "Schema": "dds-v1", "Type": "Component", "DeviceCategory": "PCIeGpuCard", "ID": "1fe01010_1fe01010", "Objects": { "PCIeGpuCard": { "Path": "/bmc/dev/Systems/:SystemId/PCIeGpuCard/:Id", "Interfaces": [ "bmc.dev.PCIeDevice", "bmc.dev.PCIeCard" ] }, "GraphicsController": { "Path": ":Parent/GraphicsController/:Id", "Interfaces": [ "bmc.dev.Processor", "bmc.dev.Gpu", "bmc.dev.Gpu.Power", "bmc.dev.Gpu.Status" ] }, "Memory": { "Path": ":Parent/Memory/:Id", "Interfaces": [ "bmc.dev.Memory" ] } } } ``` #### 关键字段说明 | 字段 | 说明 | 注意事项 | |------|------|---------| | `DeviceCategory` | 设备类别 | 必须是`"PCIeGpuCard"` | | `Objects` | 对象定义 | 键名必须与ABI中的`device_name`一致 | | `Path` | 对象路径 | `:SystemId`、`:Id`是动态参数,`:Parent`表示父对象 | | `Interfaces` | 接口列表 | 必须与自动生成接口头文件中`MC_OBJECT`宏中声明的接口一致 | #### 配置要点 1. **接口列表要完整**:`Interfaces`必须包含代码中`MC_OBJECT`声明的所有接口 2. **对象名称要匹配**:`Objects`的键名(如`PCIeGpuCard`)必须与ABI注册时的`device_name`一致 3. **路径格式固定**:主对象路径和子对象路径格式不要修改 ### 3.3 配置部件自描述记录 SR文件定义硬件拓扑、芯片配置和对象初始值,用于复杂的硬件管理场景。 #### 文件命名规则 ```text 格式:14140130_[VID][DID]_[SVID][SSID].sr 示例:14140130_19e50222_19e50052.sr 说明:文件名必须与DDS文件一致 ``` #### SR文件结构 ```json { "FormatVersion": "5.00", "DataVersion": "5.00", "Unit": { "Type": "PCIeGpuCard", "Name": "PCIeGpuCard_1", "Compatible": ["awm_m11p"] }, "ManagementTopology": { // 硬件拓扑配置(I2C总线、芯片连接关系) }, "Objects": { // 对象初始配置和属性值 } } ``` #### Unit配置(部件单元) | 字段 | 说明 | 注意事项 | |------|------|---------| | `Type` | 部件类别标识 | 必须是`"PCIeGpuCard"` | | `Name` | 部件主管理对象名称 | 一般是`"PCIeGpuCard_1"`,必须与`"Objects"`下的一致,在同一文件中必须唯一 | | `Compatible` | 兼容性标识数组 | 必须与`pcie_gpu_card/innosilicon/awm_m11p/meson.build`中指定的驱动名称一致,一般使用型号名称,支持多个兼容的设备型号 | #### ManagementTopology配置(I2C拓扑) 一般GPU卡通过SMBus提供带外能力 ```json "ManagementTopology": { "Anchor": { "Buses": [ "I2cMux_Chan" ] }, "I2cMux_Chan": { "Chips": [ "Chip_M11P" // GPU提供带外管理能力的芯片 ] } }, "Objects": { "Chip_M11P": { "Address": 158, // I2C地址:0x9E "AddrWidth": 1, "OffsetWidth": 1, "WriteTmout": 100, "ReadTmout": 100, "HealthStatus": 0 } } ``` #### GPU卡对象配置(PCIeGpuCard_1) 定义GPU卡的初始属性值: ##### bmc.dev.PCIeDevice | 属性 | 说明 | 建议实现方式 | |------|------|------------| | DeviceName | PCIe设备名称 | 通常会包含槽位号和型号 | | FunctionClass | 功能分类 | GPU卡固定为3 | | VendorId | 制造商Id | 按需配置 | | DeviceId | 设备Id | 按需配置 | | SubSystemVendorId | 子厂商Id | 按需配置 | | SubSystemDeviceId | 子设备Id | 按需配置 | | Slot | 槽位号 | 固定配`"${Slot}"` | | DeviceType | 设备类型 | 取值参考Redfish标准规范中PCIeDevice资源的同名属性 | | SlotType | PCIe设备所在槽位的类型 | 取值参考Redfish标准规范中PCIeDevice资源的同名属性 | | FunctionProtocol | PCIe功能协议 | 取值参考Redfish标准规范中PCIeDevice资源的同名属性,对于GPU卡,固定配`"PCIe"` | | FunctionType | PCIe功能类型 | 取值参考Redfish标准规范中PCIeDevice资源的同名属性,对于GPU卡,固定配`"Physical"` | | ComponentType | PCIe设备部件类型 | PCIe卡固定为8 | | Container | 容纳此PCIe设备的Component对象名称,由上级连接器传入 | 固定配`"${Container}"` | | GroupPosition | 资源协作路径信息,由上级连接器传入、拼接而成,可作为对象唯一标识 | 固定配`"PCIeDevice_1_${GroupPosition}"` | ##### bmc.dev.PCIeCard | 属性 | 说明 | 建议实现方式 | |------|------|------------| | Name | 产品名称 | 按需配置 | | Model | 产品型号 | 按需配置 | | Manufacturer | 厂商 | 按需配置 | | PartNumber | 部件编码 | 按需配置 | | Description | 描述 | 按需配置 | | BoardName | 单板名称 | 按需配置 | #### GPU对象配置(GraphicsController_1) ##### bmc.dev.Processor | 属性 | 说明 | 建议实现方式 | |------|------|------------| | SystemId | 系统ID | 一般配置1 | | Id | 处理器ID | 一般配置1 | | Presence | 在位状态 | 一般配置1 | | Manufacturer | 厂商 | 按需配置 | | Model | 型号 | 按需配置 | | Location | 位置信息 | 引用父对象PCIeGpuCard_1.Location | ##### bmc.dev.Gpu | 属性 | 说明 | 建议实现方式 | |------|------|------------| | TemperatureCelsius | GPU温度 | 一般需要通过带外管理协议获取,本例通过配置Scanner实现 | ##### bmc.dev.Gpu.Power | 属性 | 说明 | 建议实现方式 | |------|------|------------| | PowerWatts | 功耗 | 配置默认值0 | | PowerBrakeState | 功耗限制状态 | 配置默认值255 | | ExternalPowerSufficient | 外部供电是否充足 | 配置默认值255 | ##### bmc.dev.Gpu.Status | 属性 | 说明 | 建议实现方式 | |------|------|------------| | ECCModeEnabled | ECC模式当时使能状态 | 配置默认值255 | | ECCModePendingEnabled | ECC模式重启后使能状态 | 配置默认值255 | | ResetRequired | 是否需要重置 | 配置默认值255 | | DoubleBitErrorPageCount | 双bit失效故障页计数 | 配置默认值0 | | SingleBitErrorPageCount | 单bit失效故障页计数 | 配置默认值0 | #### 内存对象配置(Memory_1) ##### bmc.dev.Memory | 属性 | 说明 | 建议实现方式 | |------|------|------------| | DimmNum | 内存Id | 一般配置1 | | Manufacturer | 厂商 | 按需配置 | #### SR文件配置要点 1. **父子关系**:使用`@Parent`字段指定对象的层次关系 2. **动态参数**:`${Slot}`等参数会在运行时替换 3. **初始值**:255通常表示"无效值"或"未初始化" 4. **接口完整性**:SR中定义的接口必须与DDS文件中声明的接口一致 ### 3.4 创建GPU卡主对象 参考 [`awm_m11p_card.h`](https://gitcode.com/openUBMC/component_drivers/blob/main/drivers/pcie_gpu_card/innosilicon/awm_m11p/awm_m11p_card.h): ```cpp #ifndef __AWM_M11P_CARD_H__ #define __AWM_M11P_CARD_H__ #include "interface/pcie_card.h" #include "interface/pcie_device.h" #include namespace dev { class awm_m11p_card : public mc::engine::object { public: // MC_OBJECT宏定义:类名、对象类型、路径模式、接口列表 MC_OBJECT(awm_m11p_card, "PCIeGpuCard", "/bmc/dev/Systems/1/PCIeGpuCard/${object_name}", (PCIeDevice)(PCIeCard)) awm_m11p_card() = default; // 构造函数 ~awm_m11p_card() = default; // 析构函数 // 生命周期方法 bool start(); bool stop(); bool init(mc::mutable_dict& csr_object, const mc::dict& connector); bool replace_dynamic_property(mc::mutable_dict& object, const mc::dict& connector); // 接口成员变量 PCIeDevice m_pcie_device; PCIeCard m_pcie_card; uint8_t SystemId; }; } // namespace dev #endif // __AWM_M11P_CARD_H__ ``` #### 关键说明 **1. 头文件包含:** `"interface/pcie_card.h"`包含``,该路径实际指向`gen/include/device_tree/interface/`下的同名文件。这是因为在根目录下的meson.build有一句`include_directories('gen/include'),`,gen/include目录被添加到了编译系统的include路径中。其他的头文件包含同理 **2. MC_OBJECT宏的参数:** - **第1个**:类名 - **第2个**:设备类型(固定为`"PCIeGpuCard"`) - **第3个**:对象路径模板(固定格式) - **第4个**:实现的接口列表(按需选择) **3. 接口选择原则:** | 接口 | 必需性 | 说明 | |------|--------|------| | `PCIeDevice`、`PCIeCard` | 必需 | 基础接口 | ### 3.5 实现GPU卡主对象 参考 [`awm_m11p_card.cpp`](https://gitcode.com/openUBMC/component_drivers/blob/main/drivers/pcie_gpu_card/innosilicon/awm_m11p/awm_m11p_card.cpp): ```cpp #include "awm_m11p_card.h" #include #include #include #include namespace dev { // 启动方法:启动GPU卡任务,本示例不涉及 bool awm_m11p_card::start() { return true; } // 停止方法:停止GPU卡任务并清理资源,本示例不涉及 bool awm_m11p_card::stop() { return true; } // 在运行时替换SR配置文件中的动态占位符为实际值,bmc.dev.PCIeDevice接口下存在需要替换的动态占位符 bool awm_m11p_card::replace_dynamic_property(mc::mutable_dict& object, const mc::dict& connector) { m_pcie_device.replace_dynamic_property(object, connector); return true; } // 初始化方法,调用replace_dynamic_property,确保对象初始化时使用的是替换后的实际值 bool awm_m11p_card::init(mc::mutable_dict& csr_object, const mc::dict& connector) { try { replace_dynamic_property(csr_object, connector); from_variant(csr_object, *this); } catch (const std::exception& e) { elog("awm_m11p_card init failed, exception: ${exception}", ("exception", e.what())); return false; } return true; } } // namespace dev MC_REFLECT(dev::awm_m11p_card, ((SystemId, "SystemId"))((m_pcie_device, "bmc.dev.PCIeDevice"))((m_pcie_card, "bmc.dev.PCIeCard"))) ``` #### 关键说明 | 方法 | 职责 | |------|------| | `init()` | 加载配置文件中的属性值,使用`from_variant`自动映射 | | `start()` | 启动方法,如果有轮询任务,应当在本函数启动 | | `stop()` | 停止方法,如果有轮询任务,应当在本函数停止 | | `replace_dynamic_property()` | 在运行时替换SR配置文件中的动态占位符为实际值 | ### 3.5 实现GPU对象 参考 [`awm_m11p_gpu.cpp`](https://gitcode.com/openUBMC/component_drivers/blob/main/drivers/pcie_gpu_card/innosilicon/awm_m11p/awm_m11p_gpu.cpp): ```cpp #include "awm_m11p_gpu.h" #include "mc/log.h" namespace dev { // 启动方法:启动GPU任务,本示例不涉及 bool awm_m11p_gpu::start() { return true; } // 停止方法:停止GPU任务并清理资源,本示例不涉及 bool awm_m11p_gpu::stop() { return true; } // 初始化方法 bool awm_m11p_gpu::init(mc::mutable_dict& config, const mc::dict& connector) { try { from_variant(config, *this); } catch (const std::exception& e) { elog("awm_m11p_gpu init failed, exception: ${exception}", ("exception", e.what())); return false; } return true; } // 恢复默认属性 bool awm_m11p_gpu::reset_default_properties() { m_processor.Presence = false; m_gpu.InfoRomVersion = ""; m_gpu.BuildDate = ""; m_gpu.UUID = ""; m_gpu.Utilization = 0; m_gpu.TemperatureCelsius = 0; m_gpu_power.PowerWatts = 0; m_gpu_power.PowerBrakeState = 255; m_gpu_power.ExternalPowerSufficient = 255; m_gpu_status.ECCModeEnabled = 255; m_gpu_status.ECCModePendingEnabled = 255; m_gpu_status.ResetRequired = 255; return true; } } // namespace dev MC_REFLECT(dev::awm_m11p_gpu, ((m_processor, "bmc.dev.Processor"))((m_gpu, "bmc.dev.Gpu"))( (m_gpu_power, "bmc.dev.Gpu.Power"))((m_gpu_status, "bmc.dev.Gpu.Status"))) ``` #### 关键说明 | 方法 | 职责 | |------|------| | `reset_default_properties()` | 恢复默认属性 | ### 3.6 实现接口类 - interface目录按接口定义层级分布 - 接口类继承自`gen`命名空间的基类,负责具体的协议实现和数据更新 - 由于本示例中的GPU并未涉及复杂协议,因此接口类并不需要做什么修改 - 通用的接口,如bmc.dev.PCIeDevice,对于所有PCIe设备都会涉及,因此需要考虑放到公共目录,避免重复代码 - 轮询任务通常在接口类实现,以下是网卡的一个案例 ```cpp void NetworkAdapter::start_ncsi_update_task_huawei(ncsi_over_mctp_hw_ptr ncsi_over_mctp, mc::milliseconds interval) { // 创建定时器实例 m_ncsi_timer = new mc::core::timer(this); // 记录协议实体地址,当驱动对象实现层在调用接口类时完成赋值 m_ncsi_over_mctp_huawei = ncsi_over_mctp; // 具体的轮询动作 m_ncsi_timer->timeout.connect([this]() { update_firmware_version_by_ncsi(); }); m_ncsi_timer->set_single_shot(false); // 启动轮询 m_ncsi_timer->start(interval); } void NetworkAdapter::stop_ncsi_update_task() { if (m_ncsi_timer) { // 停止轮询 m_ncsi_timer->stop(); // 删除定时器实例 delete m_ncsi_timer; m_ncsi_timer = nullptr; } if (m_ncsi_over_mctp_huawei) { m_ncsi_over_mctp_huawei = nullptr; } } ``` ### 3.7 实现ABI导出 ABI(Application Binary Interface)是驱动程序与框架交互的标准接口 参考 [`awm_m11p_abi.cpp`](https://gitcode.com/openUBMC/component_drivers/blob/main/drivers/pcie_gpu_card/innosilicon/awm_m11p/awm_m11p_abi.cpp): ```cpp #include "awm_m11p_card.h" #include "awm_m11p_gpu.h" #include "awm_m11p_memory.h" #include "devmon/driver_abi.h" #include "mc/log.h" #include #include #ifndef DEVICE_DRIVER_NAME #define DEVICE_DRIVER_NAME "awm_m11p" #endif using namespace dev; extern "C" { // ============================================ // GPU卡对象ABI函数 // ============================================ // 创建GPU卡对象:分配内存并设置基本属性 driver_handle_t create_awm_m11p_card(void* service, const char* name) { // 参数检查 // 创建awm_m11p_card对象 // 设置service和对象名称 // 返回对象指针 } // 初始化GPU卡对象:加载配置 status_t init_awm_m11p_card(driver_handle_t device, void* csr_object, void* connector) { // 参数检查 // 类型转换 // 调用对象的init方法 // 返回状态码 } // 启动GPU卡对象:启动设备和协议 status_t start_awm_m11p_card(driver_handle_t device) { // 参数检查 // 调用对象的start方法 // 返回状态码 } // 停止GPU卡对象:停止设备和清理资源 status_t stop_awm_m11p_card(driver_handle_t device) { // 参数检查 // 调用对象的stop方法 // 返回状态码 } // ============================================ // GPU对象ABI函数 // ============================================ // 创建GPU对象:分配内存并设置基本属性 driver_handle_t create_awm_m11p_gpu(void* service, const char* name) { // 参数检查 // 创建awm_m11p_card对象 // 设置service和对象名称 // 返回对象指针 } // 初始化GPU对象:加载配置 status_t init_awm_m11p_gpu(driver_handle_t device, void* csr_object, void* connector) { // 参数检查 // 类型转换 // 调用对象的init方法 // 返回状态码 } // 启动GPU对象:启动设备和协议 status_t start_awm_m11p_gpu(driver_handle_t device) { // 参数检查 // 调用对象的start方法 // 返回状态码 } // 停止GPU对象:停止设备和清理资源 status_t stop_awm_m11p_gpu(driver_handle_t device) { // 参数检查 // 调用对象的stop方法 // 返回状态码 } // ============================================ // 内存对象ABI函数 // ============================================ // 创建内存对象:分配内存并设置基本属性 driver_handle_t create_awm_m11p_memory(void* service, const char* name) { // 参数检查 // 创建awm_m11p_card对象 // 设置service和对象名称 // 返回对象指针 } // 初始化内存对象:加载配置 status_t init_awm_m11p_memory(driver_handle_t device, void* csr_object, void* connector) { // 参数检查 // 类型转换 // 调用对象的init方法 // 返回状态码 } // 启动内存对象:启动设备和协议 status_t start_awm_m11p_memory(driver_handle_t device) { // 参数检查 // 调用对象的start方法 // 返回状态码 } // 停止内存对象:停止设备和清理资源 status_t stop_awm_m11p_memory(driver_handle_t device) { // 参数检查 // 调用对象的stop方法 // 返回状态码 } // ============================================ // 驱动注册 // ============================================ device_driver_t awm_m11p_card_device_driver = {.device_name = "PCIeGpuCard", // 设备类型名(必须与DDS文件一致) .ctor = create_awm_m11p_card, .init = init_awm_m11p_card, .start = start_awm_m11p_card, .stop = stop_awm_m11p_card}; device_driver_t awm_m11p_gpu_device_driver = {.device_name = "GraphicsController", // 设备类型名(必须与DDS文件一致) .ctor = create_awm_m11p_gpu, .init = init_awm_m11p_gpu, .start = start_awm_m11p_gpu, .stop = stop_awm_m11p_gpu}; device_driver_t awm_m11p_memory_device_driver = {.device_name = "Memory", // 设备类型名(必须与DDS文件一致) .ctor = create_awm_m11p_memory, .init = init_awm_m11p_memory, .start = start_awm_m11p_memory, .stop = stop_awm_m11p_memory}; // 驱动数组:包含所有设备类型的驱动 device_driver_t awm_m11p_driver[] = {awm_m11p_card_device_driver, awm_m11p_gpu_device_driver, awm_m11p_memory_device_driver}; // 驱动注册函数:框架调用此函数获取驱动列表 status_t register_device_driver(device_driver_t** device_driver, uint8_t* count) { *device_driver = awm_m11p_driver; *count = sizeof(awm_m11p_driver) / sizeof(awm_m11p_driver[0]); return STATUS_OK; } } ``` - 所有ABI函数必须用`extern "C"`包装,确保C语言兼容 - 每个设备类型需要4个函数:`create`、`init`、`start`、`stop` - `device_name`必须与DDS文件中的对象类型匹配 - `register_device_driver`是框架调用的入口函数 ### 3.8 配置构建系统 参考 [`meson.build`](https://gitcode.com/openUBMC/component_drivers/blob/main/drivers/pcie_gpu_card/innosilicon/awm_m11p/meson.build): ```meson # 源文件列表 awm_m11p_sources = files( 'awm_m11p_abi.cpp', 'awm_m11p_card.cpp', 'awm_m11p_gpu.cpp', 'awm_m11p_memory.cpp', ) + interface_sources # 动态库(用于部署) libawm_m11p = shared_library( 'awm_m11p', awm_m11p_sources, include_directories: include_dirs + innosilicon_interface_inc, dependencies: [dev_deps], name_prefix: 'lib', name_suffix: 'so', install: true, install_dir: drivers_install_dir, ) # 指定部署路径 if build_tests and meson_build custom_target( 'copy_libawm_m11p', output: 'copy_libawm_m11p', command: ['cp', libawm_m11p.full_path(), drivers_install_dir], depends: libawm_m11p, build_by_default: true, ) endif ``` #### 关键说明 - 库名会成为驱动SO文件名:`libawm_m11p.so`,注意和CSR配置一致 - 依赖关系要明确列出,避免链接错误 ### 3.9 编写开发者测试 #### 单元测试 - 在`tests/drivers`路径下新增`pcie_gpu_card/innosilicon/awm_m11p`目录 - 在此目录下新增`test_awm_m11p_abi.cpp` - 代码框架可以参考[test_hi182x_abi.cpp](https://gitcode.com/openUBMC/component_drivers/blob/main/tests/drivers/pcie_nic_card/hisi/hi182x/test_hi182x_abi.cpp) ```cpp class hi182x_test_service : public mc::engine::service { public: hi182x_test_service(const std::string& name) : mc::engine::service(name) { } }; // 该类继承自TestWithEngine,用于测试Hi182x网卡驱动的ABI接口 class Hi182xAbiTest : public mc::test::TestWithEngine { public: // 测试套件初始化(所有测试用例执行前调用一次) static void SetUpTestSuite() { // 调用基类的SetUpTestSuite初始化测试引擎 TestWithEngine::SetUpTestSuite(); // 初始化并启动测试服务 m_test_service.init(); m_test_service.start(); // 动态加载Hi182x驱动库 load_driver(); } // 测试套件清理(所有测试用例执行后调用一次) static void TearDownTestSuite() { // 停止测试服务 m_test_service.stop(); // 关闭动态库句柄,释放资源 if (m_driver_handle != nullptr) { dlclose(m_driver_handle); m_driver_handle = nullptr; } // 清理测试引擎资源 TestWithEngine::TearDownTestSuite(); } // 单个测试用例初始化(每个测试用例执行前调用) void SetUp() override { } // 单个测试用例清理(每个测试用例执行后调用) void TearDown() override { } // 动态加载驱动库并注册设备驱动 static void load_driver() { // 使用dlopen动态加载驱动库,RTLD_LAZY表示延迟绑定符号 m_driver_handle = dlopen("./opt/bmc/drivers/libhisi_182x.so", RTLD_LAZY); if (m_driver_handle == nullptr) { MC_THROW(mc::system_exception, "Failed to load driver: ${error}", ("error", dlerror())); } // 从动态库中查找并获取register_device_driver函数 register_device_driver_func func = reinterpret_cast( dlsym(m_driver_handle, "register_device_driver")); MC_ASSERT_THROW(func, mc::bad_function_call_exception, "Failed to get export_device_driver function: ${error}", ("error", dlerror())); // 调用驱动注册函数,获取设备驱动列表 device_driver_t* devices = nullptr; uint8_t devices_count = 0; status_t ret = func(&devices, &devices_count); MC_ASSERT_THROW(ret == STATUS_OK, mc::bad_function_call_exception, "Failed to get device driver manager: ${error}", ("error", ret)); // 清空并重新填充设备驱动映射表 m_devices.clear(); // 预分配空间,提高性能 m_devices.reserve(devices_count); // 遍历所有设备驱动类型,存储到映射表中(key为device_name,value为device_driver_t) for (uint8_t i = 0; i < devices_count; i++) { auto device_driver = std::make_shared(devices[i]); m_devices.emplace(device_driver->device_name, device_driver); } } // 连接器(connector)用于传递上级设备的信息给子设备 mc::dict create_test_connector(uint8_t system_id, uint8_t position, uint8_t slot) { return mc::dict{{"SystemId", system_id}, {"Position", position}, {"Slot", slot}}; } // 测试服务实例,提供引擎服务环境 static hi182x_test_service m_test_service; // 设备驱动映射表,key为设备类型名(如"PCIeNicCard"),value为设备驱动信息 static std::unordered_map> m_devices; // 动态库句柄,用于dlopen/dlclose操作 static void* m_driver_handle; }; // ========== 静态成员变量定义 ========== // 初始化测试服务实例,服务名称为"bmc.kepler.test_hi182x" // 该服务为测试提供引擎服务环境,支持设备对象的创建和管理 hi182x_test_service Hi182xAbiTest::m_test_service{"bmc.kepler.test_hi182x"}; // 初始化设备驱动映射表(默认为空) // 在SetUpTestSuite中通过load_driver()填充,存储所有注册的设备驱动类型 // key: 设备类型名称(如"PCIeNicCard"、"NicPort"、"OpticalTransceiver") // value: 设备驱动信息(包含ctor、init、start、stop等函数指针) std::unordered_map> Hi182xAbiTest::m_devices; // 初始化动态库句柄为nullptr // 在SetUpTestSuite中通过dlopen加载驱动库后设置 // 在TearDownTestSuite中通过dlclose释放 void* Hi182xAbiTest::m_driver_handle = nullptr; ``` - 代码框架编写完后,接下来按需编写测试用例,建议覆盖init/create/start/stop各阶段,并覆盖相应的异常场景 ## 结语 GPU驱动适配当前并未涉及到复杂协议,未来在适配各家厂商GPU的时候可能仍会遇到各种各样的问题,欢迎驱动开发者们积极在社区沟通交流,共同建设南向设备驱动规范。 --- # GPU卡驱动规范 > URL: https://openubmc.cn/docs/zh/latest/component_driver/xpu_adapt/gpu_driver_spec.html > Language: zh # GPU 驱动规范 > 契约 SSOT:[`dmc/`](https://gitcode.com/openUBMC/component_drivers/tree/main/dmc)。总览见 [3-DeviceMgmtContract.md](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md)。 > 适配实操:[4.2 GPU驱动适配指南](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/4.2-GPU驱动适配指南.md)。 > 方案概述:[《部件驱动接入》概述](../concept_principle/component_driver_adapt.md)。 ## 1. 概述 本规范定义加速卡类设备(当前以 **PCIe GPU 卡** 为主,`DeviceCategory: PCIeGpuCard`)南向驱动需实现的对象树与接口组合,后续同类加速器(xPU)扩展时可参照本规范;对象路径与接口命名当前仍以 `PCIeGpuCard` / `bmc.dev.Gpu` 落地。 设备特有器件通常包括: - xPU/GPU 板卡本身 - 卡上处理器(Gpu / Processor) - 卡上或紧密集成的 Memory ### 入库状态 | 项 | 状态 | |----|------| | `dmc/path/.../PCIeGpuCard/` | 已有 | | `dmc/intf` 通用 PCIe* / Board | 已有 | | `dmc/intf`:`bmc.dev.Gpu` / `Processor` / `Memory`(及 Metrics/Cooling/Power/Status) | 已有 | ## 2. 设备树 ```text /bmc/dev/Systems/${SystemId}/PCIeGpuCard/{CardId} ├── Gpu/{GpuId} └── Memory/{MemoryId} ``` | 对象 | path 定义 | 说明 | |------|-----------|------| | PCIeGpuCard | [`dmc/path/bmc/dev/PCIeGpuCard/PCIeGpuCard.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeGpuCard/PCIeGpuCard.json) | 加速卡主对象 | | Gpu | [`dmc/path/bmc/dev/PCIeGpuCard/Gpu.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeGpuCard/Gpu.json) | 卡上 GPU/处理器 | | Memory | [`dmc/path/bmc/dev/PCIeGpuCard/Memory.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeGpuCard/Memory.json) | 卡上内存 | > **命名说明**:部分 gen 对象名使用 `GraphicsController`,DMC path 使用子对象名 `Gpu`。实现侧映射时以 DMC path 与接口集合为准。 ## 3. 对象–接口矩阵 ### 3.1 PCIeGpuCard | 接口 | 必选/可选 | dmc/intf | |------|-----------|----------| | `bmc.dev.PCIeDevice` | 必选 | [`PCIeDevice.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeDevice.json) | | `bmc.dev.PCIeDevice.PCIeFunction` | 必选 | [`PCIeDevice/PCIeFunction.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeDevice/PCIeFunction.json) | | `bmc.dev.PCIeDevice.Status` | 必选 | [`PCIeDevice/Status.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeDevice/Status.json) | | `bmc.dev.PCIeCard` | 必选 | [`PCIeCard.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeCard.json) | | `bmc.dev.PCIeCard.Metrics` | 必选 | [`PCIeCard/Metrics.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeCard/Metrics.json) | | `bmc.dev.PCIeDevice.*`(Bandwidth/Oem 等) | 可选 | [`PCIeDevice/`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/PCIeDevice/) | | `bmc.dev.Board` | 可选 | [`Board.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Board.json) | ### 3.2 Gpu(见 path 声明) | 接口 | 必选/可选 | dmc/intf | |------|-----------|----------| | `bmc.dev.Processor` | 必选 | [`Processor.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Processor.json) | | `bmc.dev.Processor.Metrics` | 必选 | [`Processor/Metrics.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Processor/Metrics.json) | | `bmc.dev.Gpu` | 必选 | [`Gpu.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Gpu.json) | | `bmc.dev.Gpu.Power` | 可选 | [`Gpu/Power.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Gpu/Power.json) | | `bmc.dev.Gpu.Status` | 可选 | [`Gpu/Status.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Gpu/Status.json) | path 引用见 [`Gpu.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeGpuCard/Gpu.json)。 ### 3.3 Memory(见 path 声明) | 接口 | 必选/可选 | dmc/intf | |------|-----------|----------| | `bmc.dev.Memory` | 必选 | [`Memory.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Memory.json) | | `bmc.dev.Memory.Metrics` | 可选 | [`Memory/Metrics.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Memory/Metrics.json) | | `bmc.dev.Cooling` | 可选 | [`Cooling.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/intf/bmc/dev/Cooling.json) | path 引用见 [`Memory.json`](https://gitcode.com/openUBMC/component_drivers/blob/main/dmc/path/bmc/dev/PCIeGpuCard/Memory.json)。 ## 4. 相关文档 - [3-DeviceMgmtContract.md](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/3-DeviceMgmtContract.md) - [4.2 GPU驱动适配指南](https://gitcode.com/openUBMC/component_drivers/blob/main/docs/4.2-GPU驱动适配指南.md) - 特性设计示例:`docs/26.06/openUBMC支持NVIDIA多型号GPU驱动详细设计说明书.md` 等 ## 5. 历史 RFC - [社区公示(历史参考)](https://discuss.openubmc.cn/t/topic/1735) --- # 软件可靠性设计原则 > URL: https://openubmc.cn/docs/zh/latest/contributing/code_submission/design_spec/software_common_dfr.html > Language: zh # 背景介绍 ## 设计DFR技术 DFR(Design for Reliability,可靠性设计)是指在产品开发过程中,通过一系列的技术活动,消除产品的潜在缺陷和薄弱环节,防止故障发生,以确保满足规定的固有可靠性要求。DFR的目的是确保产品在预定使用环境下能够稳定、可靠地工作,减少故障发生的概率,提高产品的使用寿命和用户的满意度。在许多情况下,DFR发生在设计阶段,而且是在制作物理原型之前,其通常可作为整体卓越设计(DFX,Design for eXcellence)战略的一部分。成功的DFR需要将产品设计和流程规划集成到被称为并行工程的统一交互式活动中。 ## 软件DFR 产品开发一般涉及软件和硬件结合,不同领域有各自的DFR技术和设计原则。本文着重介绍通用的软件DFR设计原则。 从openUBMC业务软件的运行环境及业务软件本身来看,可通过以下标签进行划分:系统资源、系统环境、业务进程、业务线程、网络通信、文件管理、数据库、主备管理、数据管理、固件升级、日志、用户操作。 ### 系统资源 系统资源包括CPU、内存、目录空间、磁盘IO、网络IO、文件句柄等关键资源。系统资源容易出现过载、资源受限等问题,需要对关键指标做监控。 - 【要求】关键的系统资源指标需要有过载检测; - 【要求】系统公共资源需要有统计机制,如CPU、内存占用、磁盘IO、网络IO,统计精细到进程粒度; - 【要求】内存受限系统要提供内存泄漏检测机制; - 【要求】共享资源需要有隔离机制,避免资源独占或互相影响。共享资源包括总线、共享内存、共享存储、共享队列、分布式锁、系统调用等; - 【要求】目录需要限制最大占用空间; - 【建议】过载状态下记录系统资源统计记录日志; - 【建议】过载状态下业务丢弃数据记录日志; - 【建议】检测关键目录剩余空间,低于阈值时告警并提供清理或垃圾回收机制。 ### 系统环境 系统环境变化,如系统重启、系统挂死、时钟跳变等,需要有对应处理措施。 - 【要求】业务软件必须有时间跳变的处理措施; - 【要求】业务软件例测周期不得依赖于系统时间; - 【要求】限制短时内复位次数。 ### 业务进程 业务进程异常,如进程创建失败、异常退出、挂死等,要有对应处理措施。 - 【要求】重要业务进程需要有守护进程; - 【要求】守护进程要有感知自身卡死的能力,如watchdog; - 【要求】业务进程要有进程级独立重启恢复能力; - 【要求】业务进程异常退出后可自动重启恢复; - 【要求】业务进程故障可感知并由对应的恢复措施,故障不限于进程崩溃、D/T/Z状态、死循环、内存/fd/thread资源泄泄漏; - 【要求】进程重启不产生不合理异常,如误告警; - 【要求】大颗粒业务处理需要有资源占用控制机制,如切分业务处理防止CPU持续冲高; - 【建议】进程启动过程保护,避免故障导致进程启动失败。 ### 业务线程 业务线程异常,如线程创建失败、异常退出、挂死、线程过多等,要有对应处理措施。 - 【要求】显示临时线程的最大创建数量; - 【要求】确保线程退出后资源完全释放; - 【要求】重要业务线程要有异常检测和恢复机制,如心跳设计; - 【建议】批量任务执行时应容忍单个任务失败。 ### 网络通信 网络通信异常,如会话过多、会话挂死、丢包、乱序、非法消息、消息过载、消息超时、连接超时等,要有对应处理措施。 - 【要求】端侧应对网络通信异常做预防和异常处理; - 【要求】网络请求必须设置超时时间; - 【要求】网络请求失败时应作重试,并设置最大重试次数; - 【要求】接收网络数据后要有合法性、完整性校验; - 【建议】特殊网络数据要有数据一致性校验机制,如多节点同步数据、实时数据; - 【要求】限制最大网络通信连接数量,对超限情况要有恢复机制; - 【要求】网络消息接收和处理要有限流机制,如限定接收队列长度、触发网络反压等; - 【建议】网络消息异常检测、限流应该在消息接收处理的上游环节完成; - 【要求】异常报文在检测到异常所在的处理阶段丢弃,不能把异常报文传递给下游。 ### 文件管理 文件涉及的异常情况包括文件丢失、文件超大、文件受损、文件操作失败等。 - 【要求】重要文件丢失、损坏时影响不扩散,不影响系统业务或导致系统重启; - 【要求】文件读写必须考虑数据损坏及其容错,如读写失败; - 【要求】重要文件应该有备份和恢复机制; - 【要求】大文件存储需要限定其最大空间占用; - 【要求】频繁更新的文件必须flash写入量过大问题并由消减措施,如限流、限制最大写入量等; - 【要求】防止重要文件因目录空间满导致文件操作失败; - 【建议】大文件隔离存放在空间固定的目录下。 ### 数据库 数据库操作异常包括连接失败、连接资源耗尽、性能下降、表项过多、查询超时、匹配项过多、flash写入量过大、文件损坏、数据篡改、主备不一致等。 - 【要求】支持数据库状态监控; - 【要求】频繁更新的持久化数据写入要有缓存机制; - 【要求】支持数据库大小或数据条目数量上限限制; - 【要求】支持数据删除策略,泛指数据持续增加而不删除; - 【要求】flash写保护生效时禁止持久化数据库写操作; - 【要求】使用分页等限制检索量的功能,防止查询结果集过大。如联表查询,易产生大量匹配项,影响系统IO性能、数据库性能和占用大量系统资源; - 【建议】支持数据库所在分区的空间余量大小检测‘ - 【建议】数据库写入增加回读校验和重试机制; - 【建议】支持数据库可用性和性能监控,支持数据库关键资源监控,不限于监听器状态、进程状态、表空间、大表水位、日志空间、连接数、锁资源数。 ### 主备管理 主备管理要注意主备通信丢失、主备不一致、主备故障、倒换等场景。 - 【要求】支持备用单元故障检测,避免静默故障; - 【要求】保持运行时主备间配置数据和运行数据的一致性; - 【要求】避免出现双主、双备状态; - 【要求】支持主备间通信及其通信检测,主备间通信中断时告警; - 【要求】支持升主前健康检查; - 【要求】支持自动倒换,主用设备故障时备用设备自动升主并接管业务; - 【要求】支持倒换抑制,避免反复倒换; - 【要求】提供手动倒换手段作为异常逃生通道。 ### 数据管理 数据管理要注意输入、数据受损、数据老化、冗余存储、数据恢复、数据关联等场景。 - 【要求】重要数据支持备份,且主用数据被破坏时备份数据能启动; - 【要求】保证数据合法性,避免外部输入数据异常导致系统异常。合法性是指数据类型和数值有效; - 【要求】保证数据完整性,避免外部输入数据异常导致系统异常。完整性是指逻辑、结构和时序上不存在错误; - 【要求】重要数据定期备份(时间冗余),支持周期性全量、增量备份,误删除或受损数据可通过备份恢复; - 【要求】重要数据多副本备份(空间冗余),受损数据可通过备份恢复; - 【建议】重要数据的冗余备份数据保持一致性。 ### 固件升级 固件升级涉及升级包检查、升级前异常检查、升级后验证、升级失败回退、升级不影响业务等。 - 【要求】软件升级或补丁操作不中断业务; - 【强制】升级前对软件环境、硬件环境做健康检查,检查失败不做升级; - 【要求】升级前对升级包做完整性和合法性检查,检查失败不做升级; - 【强制】支持升级过程故障保护,升级过程限制对升级有影响的后台任务、维护操作等,避免升级失败; - 【要求】支持固件升级、生效与业务互斥处理,避免升级过程业务出现非预期异常,如误告警; - 【强制】支持升级过程出现重大异常时快速回退。 ### 日志 日志相关异常包括日志刷屏、资源过载、flash写入量过大等。 - 【要求】flash写保护生效时禁止写入持久化日志; - 【要求】频繁触发的日志记录要有限流机制,限流机制覆盖系统或进程反复重启场景; - 【强制】日志类文件必须有滚动清楚旧数据的机制; - 【要求】应用层进程或服务的日志避免在关键分区存放,如根分区; - 【要求】日志记录不影响系统稳定运行; - 【要求】第三方库、组件日志记录要有限流机制; - 【建议】日志文件隔离存放在有空间大小限制的目录下; - 【建议】日志有单独分区存放,避免被其他数据覆盖。 ### 用户操作 用户操作涉及用户配置、删除操作和批量用户操作。 - 【强制】支持配置数据合法性检查; - 【强制】支持对用户输入的防御和保护,如用户输入的合法性、有效性检查,重复提交、异常输入不影响系统正常运行; - 【要求】防止用户直接删除或修改配置文件; - 【要求】关键数据高危操作支持二次确认机制; - 【要求】限制单个用户可创建任务的最大数量。 --- # openUBMC社区C++语言编码规范 > URL: https://openubmc.cn/docs/zh/latest/contributing/code_submission/encoding_spec/cpp_coding_standards.html > Language: zh # openUBMC社区C++语言编码规范 ## 1 概述 ### 1.1 目的 参考该规范之前,希望您具有相应的C++语言基础能力,而不是通过该文档来学习C++语言。 1. 了解C++语言的ISO标准; 2. 熟知C++语言的基本语言特性,包括C++ 03/11/14/17相关特性; 3. 了解C++语言的标准库; ### 1.2 总体原则 代码需要在保证功能正确的前提下,满足**可读、可维护、安全、可靠、可测试、高效、可移植**的特征要求。 ### 1.3 重点关注 1. 约定C++语言的编程风格,比如命名,排版等。 2. C++语言的模块化设计,如何设计头文件,类,接口和函数。 3. C++语言相关特性的优秀实践,比如常量,类型转换,资源管理,模板等。 4. 现代C++语言的优秀实践,包括C++11/14/17中可以提高代码可维护性,提高代码可靠性的相关约定。 5. 本规范优先适用于C++17版本。 ### 1.4 约定 **规则**:编程时必须遵守的约定(must) **建议**:编程时应该遵守的约定(should) 本规范适用通用C++标准, 如果没有特定的标准版本,适用所有的版本(C++03/11/14/17)。 ### 1.5 例外 无论是'规则'还是'建议',都必须理解该条目这么规定的原因,并努力遵守。 但是,有些规则和建议可能会有例外。 在不违背总体原则,经过充分考虑,有充足的理由的前提下,可以适当违背规范中约定。 例外破坏了代码的一致性,请尽量避免。'规则'的例外应该是极少的。 下列情况,应以风格一致性原则优先: **修改开源代码、第三方代码时,应该遵守开源代码、第三方代码已有规范,保持风格统一。** ## 2 命名 ### 2.1 通用命名 | 类型 | 命名风格 | | ---------------------------------------- | --------- | | 类类型、结构体类型、枚举类型、联合体类型等类型定义,类的成员变量| 大驼峰 | | 函数(包括全局函数,作用域函数,成员函数) | snake_case | | 全局变量(包括全局和命名空间域下的变量,类静态变量)、局部变量、函数参数、struct/union的成员变量 | snake_case | | 宏,常量(const),枚举值,goto 标签 | 全大写,下划线分割 | 注意: 上表中__常量__是指全局作用域、namespace域、类的静态成员域下,以 const或constexpr 修饰的基本数据类型、枚举、字符串类型的变量,不包括数组和其他类型变量。 上表中__变量__是指除常量定义以外的其他变量。 ### 2.2 文件命名 #### 规则2.2.1 C++文件以.cpp结尾,头文件以.h结尾 我们推荐使用.h作为头文件的后缀,这样头文件可以直接兼容C和C++。 我们推荐使用.cpp作为实现文件的后缀,这样可以直接区分C++代码,而不是C代码。 ### 2.3 函数命名 函数命名统一使用snake_case风格,一般采用动词或者动宾结构。 ### 2.4 类型命名 类型命名采用大驼峰命名风格。 所有类型命名——类、结构体、联合体、类型定义(typedef)、枚举——使用相同约定,例如: ```cpp // classes, structs and unions class UrlTable { ... class UrlTableTester { ... struct UrlTableProperties { ... union Packet { ... // typedefs using PropertiesMap = std::map; // enums enum UrlTableErrors { ... ``` 对于命名空间的命名,建议使用大驼峰: ```cpp // namespace namespace OsUtils { namespace FileUtils { } } ``` #### 建议2.4.1 避免滥用 typedef或者#define 对基本类型起别名 除有明确的必要性,否则不要用 typedef/#define 对基本数据类型进行重定义。 优先使用``头文件中的基本类型: | 有符号类型 | 无符号类型 | 描述 | | -------- | --------- | ---------------- | | int8_t | uint8_t | 宽度恰为8的有/无符号整数类型 | | int16_t | uint16_t | 宽度恰为16的有/无符号整数类型 | | int32_t | uint32_t | 宽度恰为32的有/无符号整数类型 | | int64_t | uint64_t | 宽度恰为64的有/无符号整数类型 | | intptr_t | uintptr_t | 足以保存指针的有/无符号整数类型 | ### 2.5 变量命名 通用变量命名采用snake_case风格,包括全局变量、函数形参、局部变量。 ```cpp std::string table_name; // Good: 推荐此风格 std::string tableName; // Bad: 禁止此风格 std::string tablename; // Bad: 禁止此风格 std::string path; // Good: 只有一个单词时,snake_case为全小写 ``` #### 规则2.5.1 全局变量应增加 'g_' 前缀,静态变量命名不需要加特殊前缀 全局变量是应当尽量少使用的,使用时应特别注意,所以加上前缀用于视觉上的突出,促使开发人员对这些变量的使用更加小心。 - 全局静态变量命名与全局变量相同。 - 函数内的静态变量命名与普通局部变量相同。 - 类的静态成员变量和普通成员变量相同。 ```cpp int g_active_connect_count; void func() { static int packet_count = 0; ... } ``` #### 规则2.5.2 类的成员变量命名以大驼峰风格 ```cpp class Foo { private: std::string FileName; }; ``` 对于struct/union的成员变量,仍采用snake_case的命名方式,与局部变量命名风格一致。 ### 2.6 宏、常量、枚举命名 宏、枚举值采用全大写,下划线连接的格式。 全局作用域内,有名和匿名namespace内的 const 常量,类的静态成员常量,全大写,下划线连接。 ```cpp #define MAX(a, b) (((a) < (b)) ? (b) : (a)) // 仅对宏命名举例,并不推荐用宏实现此类功能 enum TintColor { // 注意,枚举类型名用大驼峰,其下面的取值是全大写,下划线相连 RED, DARK_RED, GREEN, LIGHT_GREEN }; int func(...) { const unsigned int buffer_size = 100; // 函数局部常量 char *p = new char[buffer_size]; ... } namespace Utils { const unsigned int DEFAULT_FILE_SIZE_KB = 200; // 全局常量 } ``` ## 3 格式 ### 3.1 缩进 #### 规则3.1.1 使用空格进行缩进,每次缩进4个空格 只允许使用空格(space)进行缩进,每次缩进为 4 个空格。不允许使用Tab符进行缩进。 当前几乎所有的集成开发环境(IDE)都支持配置将Tab符自动扩展为4空格输入;请配置你的IDE支持使用空格进行缩进。 namespace 大括号内的代码不随嵌套层级增加缩进,与 namespace 关键字保持对齐;多级 namespace 嵌套时同理。 ### 3.2 大括号 #### 规则3.2.1 使用 K&R 缩进风格 __K&R风格__ 换行时,函数(不包括lambda表达式)左大括号另起一行放行首,并独占一行;其他左大括号跟随语句放行末。 右大括号独占一行,除非后面跟着同一语句的剩余部分,如 do 语句中的 while,或者 if 语句的 else/else if,或者逗号、分号。 如: ```cpp struct MyType { // 跟随语句放行末,前置1空格 ... }; int foo(int a) { // 函数左大括号独占一行,放行首 if (...) { ... } else { ... } } ``` 推荐这种风格的理由: - 代码更紧凑; - 相比另起一行,放行末使代码阅读节奏感上更连续; - 符合后来语言的习惯,符合业界主流习惯; - 现代集成开发环境(IDE)都具有代码缩进对齐显示的辅助功能,大括号放在行尾并不会对缩进和范围产生理解上的影响。 函数体为空时,左大括号同样另起一行: ```cpp class MyClass { public: MyClass() : Value(0) {} private: int Value; }; ``` lambda 表达式的左大括号跟随语句放行末;即使 lambda 体很短,也不要将整个 lambda 写在同一行: ```cpp thread_pool.queue_work([local] { process(local); }); ``` ### 3.3 函数声明和定义 #### 规则3.3.1 函数声明和定义的返回类型和函数名在同一行;函数参数列表超出行宽时要换行并合理对齐 在声明和定义函数的时候,函数的返回值类型应该和函数名在同一行;如果行宽度允许,函数参数也应该放在一行;否则,函数参数应该换行,并进行合理对齐。 参数列表的左圆括号总是和函数名在同一行,不要单独一行;右圆括号总是跟随最后一个参数。 换行举例: ```cpp ReturnType function_name(ArgType param_name1, ArgType param_name2) // Good:全在同一行 { ... } ReturnType very_very_very_long_function_name(ArgType param_name1, // 行宽不满足所有参数,进行换行 ArgType param_name2, // Good:和上一行参数对齐 ArgType param_name3) { ... } ReturnType long_function_name(ArgType param_name1, ArgType param_name2, // 行宽限制,进行换行 ArgType param_name3, ArgType param_name4, ArgType param_name5) // Good: 换行后 4 空格缩进 { ... } ReturnType really_really_really_really_long_function_name( // 行宽不满足第1个参数,直接换行 ArgType param_name1, ArgType param_name2, ArgType param_name3) // Good: 换行后 4 空格缩进 { ... } ``` ### 3.4 函数调用 #### 规则3.4.1 函数调用入参列表应放在一行,超出行宽换行时,保持参数进行合理对齐 函数调用时,函数参数列表放在一行。参数列表如果超过行宽,需要换行并进行合理的参数对齐。 左圆括号总是跟函数名,右圆括号总是跟最后一个参数。 换行举例: ```cpp ReturnType result = function_name(param_name1, param_name2); // Good:函数参数放在一行 ReturnType result = function_name(param_name1, param_name2, // Good:保持与上方参数对齐 param_name3); ReturnType result = function_name(param_name1, param_name2, param_name3, param_name4, param_name5); // Good:参数换行,4 空格缩进 ReturnType result = very_very_very_long_function_name( // 行宽不满足第1个参数,直接换行 param_name1, param_name2, param_name3); // 换行后,4 空格缩进 ``` 如果函数调用的参数存在内在关联性,按照可理解性优先于格式排版要求,对参数进行合理分组换行。 ```cpp // Good:每行的参数代表一组相关性较强的数据结构,放在一行便于理解 int result = deal_with_structure_like_params(left.x, left.y, // 表示一组相关参数 right.x, right.y); // 表示另外一组相关参数 ``` ### 3.5 if语句 #### 规则3.5.1 if语句必须要使用大括号 我们要求if语句都需要使用大括号,即便只有一条语句。 理由: - 代码逻辑直观,易读; - 在已有条件语句代码上增加新代码时不容易出错; - 对于在if语句中使用函数式宏时,有大括号保护不易出错(如果宏定义时遗漏了大括号)。 ```cpp if (object_is_not_exist) { // Good:单行条件语句也加大括号 return create_new_object(); } ``` #### 规则3.5.2 禁止 if/else/else if 写在同一行 条件语句中,若有多个分支,应该写在不同行。 如下是正确的写法: ```cpp if (some_conditions) { do_something(); ... } else { // Good: else 与 if 在不同行 ... } ``` 下面是不符合规范的案例: ```cpp if (some_conditions) { ... } else { ... } // Bad: else 与 if 在同一行 ``` ### 3.6 循环语句 #### 规则3.6.1 循环语句必须使用大括号 和条件表达式类似,我们要求for/while循环语句必须加上大括号,即便循环体是空的,或循环语句只有一条。 ```cpp for (int i = 0; i < some_range; i++) { // Good: 使用了大括号 do_something(); } ``` ```cpp while (condition) { // Good:循环体是空,使用大括号 } ``` ```cpp while (condition) { continue; // Good:continue 表示空逻辑,使用大括号 } ``` 坏的例子: ```cpp for (int i = 0; i < some_range; i++) do_something(); // Bad: 应该加上括号 ``` ```cpp while (condition); // Bad:使用分号容易让人误解是while语句中的一部分 ``` ### 3.7 switch语句 #### 规则3.7.1 switch 语句的 case/default 与 switch 关键字对齐,不额外缩进 switch 语句的缩进风格如下,case/default 与 switch 关键字保持对齐,case 内的语句相对 case 缩进一层: ```cpp switch (var) { case 0: // Good: case 与 switch 对齐 do_something1(); // Good: case 内语句缩进一层 break; case 1: { // Good: 带大括号格式 do_something2(); break; } default: break; } ``` ```cpp switch (var) { case 0: // Bad: case 相对 switch 多缩进了一层 do_something(); break; default: // Bad: default 相对 switch 多缩进了一层 break; } ``` ### 3.8 表达式 #### 建议3.8.1 表达式换行要保持换行的一致性,运算符放行末 较长的表达式,不满足行宽要求的时候,需要在适当的地方换行。一般在较低优先级运算符或连接符后面截断,运算符或连接符放在行末。 运算符、连接符放在行末,表示“未结束,后续还有”。 例: // 假设下面第一行已经不满足行宽要求 ```cpp if ((current_value > threshold) && // Good:换行后,逻辑操作符放在行尾 some_condition) { do_something(); ... } int result = really_really_long_variable_name1 + // Good really_really_long_variable_name2; ``` 表达式换行后,注意保持合理对齐,或者4空格缩进。参考下面例子 ```cpp int sum = long_variable_name1 + long_variable_name2 + long_variable_name3 + long_variable_name4 + long_variable_name5 + long_variable_name6; // Good: 4空格缩进 int sum = long_variable_name1 + long_variable_name2 + long_variable_name3 + long_variable_name4 + long_variable_name5 + long_variable_name6; // Good: 保持对齐 ``` ### 3.9 变量赋值 #### 规则3.9.1 多个变量定义和赋值语句不允许写在一行 每行只有一个变量初始化的语句,更容易阅读和理解。 ```cpp int max_count = 10; bool is_completed = false; ``` 下面是不符合规范的示例: ```cpp int max_count = 10; bool is_completed = false; // Bad:多个变量初始化需要分开放在多行,每行一个变量初始化 int x, y = 0; // Bad:多个变量定义需要分行,每行一个 int point_x; int point_y; ... point_x = 1; point_y = 2; // Bad:多个变量赋值语句放同一行 ``` 例外:for 循环头、if 初始化语句(C++17)、结构化绑定语句(C++17)中可以声明和初始化多个变量。这些语句中的多个变量声明有较强关联,如果强行分成多行会带来作用域不一致,声明和初始化割裂等问题。 ### 3.10 初始化 初始化包括结构体、联合体、及数组的初始化 #### 规则3.10.1 初始化换行时要有缩进,并进行合理对齐 结构体或数组初始化时,如果换行应保持4空格缩进。 从可读性角度出发,选择换行点和对齐位置。 ```cpp const int rank[] = { 16, 16, 16, 16, 32, 32, 32, 32, 64, 64, 64, 64, 32, 32, 32, 32 }; ``` ### 3.11 指针与引用 #### 建议3.11.1 指针类型`*`应跟随变量名或类型,两侧空格保持一致 指针命名: `*`靠左靠右都可以,但是不要两边都有或者都没有空格。 ```cpp int* p = nullptr; // Good int *p = nullptr; // Good int*p = nullptr; // Bad int * p = nullptr; // Bad ``` 例外:当变量被 const 修饰时,"`*`" 无法跟随变量,此时也不要跟随类型。 ```cpp const char * const VERSION = "V100"; ``` #### 建议3.11.2 引用类型`&`应跟随变量名或类型,两侧空格保持一致 引用命名:`&`靠左靠右都可以,但是不要两边都有或者都没有空格。 ```cpp int i = 8; int* pi = nullptr; int& p = i; // Good int &p = i; // Good int*& rp = pi; // Good,指针的引用,*& 一起跟随类型 int *&rp = pi; // Good,指针的引用,*& 一起跟随变量名 int* &rp = pi; // Good,指针的引用,* 跟随类型,& 跟随变量名 int & p = i; // Bad int&p = i; // Bad ``` ### 3.12 编译预处理 #### 规则3.12.1 编译预处理的`#`统一放在行首,嵌套时`#`可进行缩进 编译预处理的"#"统一放在行首,即使编译预处理的代码是嵌入在函数体中的,"#"也应该放在行首。 #### 规则3.12.2 避免使用宏 宏会忽略作用域,类型系统以及各种规则,容易引发问题。应尽量避免使用宏定义,如果必须使用宏,要保证宏名的唯一性。 在C++中,有许多方式来避免使用宏: - 用const或enum定义易于理解的常量 - 用namespace避免名字冲突 - 用inline函数避免函数调用的开销 - 用template函数来处理多种类型 在文件头保护宏、条件编译、日志记录等必要场景中可以使用宏。 #### 规则3.12.3 禁止使用宏来表示常量 宏是简单的文本替换,在预处理阶段完成,运行报错时直接报相应的值;跟踪调试时也是显示值,而不是宏名; 宏没有类型检查,不安全; 宏没有作用域。 #### 规则3.12.4 禁止使用函数式宏 定义函数式宏前,应考虑能否用函数替代。对于可替代场景,建议用函数替代宏。 函数式宏的缺点如下: - 函数式宏缺乏类型检查,不如函数调用检查严格 - 宏展开时宏参数可能被多次求值(或未被求值),容易产生非预期结果 - 宏没有独立的作用域 - 宏的技巧性太强,例如#的用法和无处不在的括号,影响可读性 - 在特定场景中必须用编译器对宏的扩展语法,如GCC的statement expression,影响可移植性 - 宏在预编译阶段展开后,在其后编译、链接和调试时都不可见;而且包含多行的宏会展开为一行。函数式宏难以调试、难以打断点,不利于定位问题 - 对于包含大量语句的宏,在每个调用点都要展开。如果调用点很多,会造成代码空间的膨胀 函数没有宏的上述缺点。但是,函数相比宏,最大的劣势是执行效率不高(增加函数调用的开销和编译器优化的难度)。 为此,可以在必要时使用内联函数。内联函数跟宏类似,也是在调用点展开。不同之处在于内联函数是在编译时展开。 内联函数兼具函数和宏的优点: - 内联函数执行严格的类型检查 - 内联函数的参数求值只会进行一次 - 内联函数就地展开,没有函数调用的开销 - 内联函数比函数优化得更好 对于性能要求高的产品代码,可以考虑用内联函数代替函数。 例外: 在日志记录场景中,需要通过函数式宏保持调用点的文件名(__FILE__)、行号(__LINE__)等信息。 ### 3.13 空格和空行 #### 规则3.13.1 水平空格应该突出关键字和重要信息,避免不必要的留白 水平空格应该突出关键字和重要信息,每行代码尾部不要加空格。总体规则如下: - if, switch, case, do, while, for等关键字之后加空格; - 小括号内部的两侧,不要加空格; - 大括号内部两侧有无空格,左右必须保持一致; - 一元操作符(& * + - ~ !)之后不要加空格; - 二元操作符(= + - < > * / % | & ^ <= >= == !=)左右两侧加空格 - 三目运算符(? :)符号两侧均需要空格 - 前置和后置的自增、自减(++ --)和变量之间不加空格 - 结构体成员操作符(. ->)前后不加空格 - 逗号(,)前面不加空格,后面增加空格 - 模板类型与尖括号(<>)之间不要添加空格,如 `vector`;`template` 关键字与尖括号之间保留1空格,如 `template ` - 域操作符(::)前后不要添加空格 - 冒号(:)前后根据情况来判断是否要添加空格 常规情况: ```cpp void foo(int b) { // Good:大括号前应该留空格 int i = 0; // Good:变量初始化时,=前后应该有空格,分号前面不要留空格 int buf[BUF_SIZE] = {0}; // Good:大括号内两侧都无空格 } ``` 函数定义和函数调用: ```cpp int result = foo(arg1,arg2); ^ // Bad: 逗号后面需要增加空格 int result = foo( arg1, arg2 ); ^ ^ // Bad: 函数参数列表的左括号后面不应该有空格,右括号前面不应该有空格 ``` 指针和取地址 ```cpp x = *p; // Good:*操作符和指针p之间不加空格 p = &x; // Good:&操作符和变量x之间不加空格 x = r.y; // Good:通过.访问成员变量时不加空格 x = r->y; // Good:通过->访问成员变量时不加空格 ``` 操作符: ```cpp x = 0; // Good:赋值操作的=前后都要加空格 x = -5; // Good:负数的符号和数值之前不要加空格 ++x; // Good:前置和后置的++/--和变量之间不要加空格 x--; if (x && !y) // Good:布尔操作符前后要加上空格,! 操作和变量之间不要空格 v = w * x + y / z; // Good:二元操作符前后要加空格 v = w * (x + z); // Good:括号内的表达式前后不需要加空格 int a = (x < y) ? x : y; // Good: 三目运算符,? 和 : 前后需要添加空格 ``` 循环和条件语句: ```cpp if (condition) { // Good:if关键字和括号之间加空格,括号内条件语句前后不加空格 ... } else { // Good:else关键字和大括号之间加空格 ... } while (condition) { // Good:while关键字和括号之间加空格,括号内条件语句前后不加空格 } for (int i = 0; i < some_range; ++i) { // Good:for关键字和括号之间加空格,分号之后加空格 ... } switch (condition) { // Good: switch 关键字后面有1空格 case 0: // Good:case语句条件和冒号之间不加空格 ... break; ... default: ... break; } ``` 模板和转换 ```cpp // 尖括号(< and >) 不与空格紧邻, < 前没有空格, > 和 ( 之间也没有. vector x; y = static_cast(x); // 在类型与指针操作符之间留空格也可以, 但要保持一致. vector x2; ``` 域操作符 ```cpp std::cout; // Good: 命名空间访问,不要留空格 int MyClass::get_value() const // Good: 对于成员函数定义,不要留空格 { ... } ``` 冒号 ```cpp // 添加空格的场景 // Good: 类的派生需要留有空格 class Sub : public Base { }; // 构造函数初始化列表需要留有空格 MyClass::MyClass(int var) : SomeVar(var) { do_something(); } // 位域表示也留有空格 struct XX { char a : 4; char b : 5; char c : 4; }; ``` ```cpp // 不添加空格的场景 // Good: 对于public:, private:这种类访问权限的冒号不用添加空格 class MyClass { public: MyClass(int var); private: int SomeVar; }; // 对于switch-case的case和default后面的冒号不用添加空格 switch (value) { case 1: do_something(); break; default: break; } ``` 注意:当前的集成开发环境(IDE)可以设置删除行尾的空格,请正确配置。 #### 建议3.13.1 合理安排空行,保持代码紧凑 减少不必要的空行,可以显示更多的代码,方便代码阅读。下面有一些建议遵守的规则: - 根据上下内容的相关程度,合理安排空行; - 函数内部、类型定义内部、宏内部、初始化表达式内部,不使用连续空行 - 不使用连续 **3** 个空行,或更多 - 大括号内的代码块行首之前和行尾之后不要加空行,但namespace的大括号内不作要求。 ```cpp int foo() { ... } int bar() // Bad:最多使用连续2个空行。 { ... } if (...) { // Bad:大括号内的代码块行首不要加入空行 ... // Bad:大括号内的代码块行尾不要加入空行 } int foo(...) { // Bad:函数体内行首不要加空行 ... } ``` ### 3.14 类 #### 规则3.14.1 类访问控制块的声明依次序是 public:, protected:, private:,缩进和 class 关键字对齐 ```cpp class MyClass : public BaseClass { public: // 注意没有缩进 MyClass(); // 标准的4空格缩进 explicit MyClass(int var); ~MyClass() {} void some_function(); void some_function_that_does_nothing() {} void set_var(int var) { SomeVar = var; } int get_var() const { return SomeVar; } private: bool some_internal_function(); int SomeVar; int SomeOtherVar; }; ``` 在各个部分中,建议将类似的声明放在一起, 并且建议以如下的顺序: 类型 (包括 typedef, using 和嵌套的结构体与类), 常量, 工厂函数, 构造函数, 赋值运算符, 析构函数, 其它成员函数, 数据成员。 #### 规则3.14.2 构造函数初始化列表放在同一行或按四格缩进并排多行 ```cpp // 如果所有变量能放在同一行: MyClass::MyClass(int var) : SomeVar(var) { do_something(); } // 如果不能放在同一行, // 必须置于冒号后, 并缩进4个空格 MyClass::MyClass(int var) : SomeVar(var), SomeOtherVar(var + 1) // Good: 逗号后面留有空格 { do_something(); } // 如果初始化列表需要置于多行, 需要逐行对齐 MyClass::MyClass(int var) : SomeVar(var), // 缩进4个空格 SomeOtherVar(var + 1) { do_something(); } ``` ## 4 注释 一般的,尽量通过清晰的架构逻辑,好的符号命名来提高代码可读性;需要的时候,才辅以注释说明。 注释是为了帮助阅读者快速读懂代码,所以要从读者的角度出发,**按需注释**。 注释内容要简洁、明了、无二义性,信息全面且不冗余。 **注释跟代码一样重要。** 写注释时要换位思考,用注释去表达此时读者真正需要的信息。在代码的功能、意图层次上进行注释,即注释解释代码难以表达的意图,不要重复代码信息。 修改代码时,也要保证其相关注释的一致性。只改代码,不改注释是一种不文明行为,破坏了代码与注释的一致性,让阅读者迷惑、费解,甚至误解。 ### 4.1 注释风格 在 C++ 代码中,使用 `/*` `*/`和 `//` 都是可以的。 按注释的目的和位置,注释可分为不同的类型,如文件头注释、函数头注释、代码注释等等; 同一类型的注释应该保持统一的风格。 注意:本文示例代码中,大量使用 '//' 后置注释只是为了更精确的描述问题,并不代表这种注释风格更好。 ### 4.2 文件头注释 #### 规则4.2.1 文件头注释必须包含版权许可 ```cpp /* * Copyright (c) 2026 Huawei Technologies Co., Ltd. * openUBMC is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * http://license.coscl.org.cn/MulanPSL2 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ ``` ### 4.3 函数头注释 #### 规则4.3.1 禁止空有格式的函数头注释 并不是所有的函数都需要函数头注释; 函数签名无法表达的信息,加函数头注释辅助说明; 函数头注释统一放在函数声明或定义上方,使用如下风格之一: 使用`//`写函数头 ```cpp // 单行函数头 int func1(void); // 多行函数头 // 第二行 int func2(void); ``` 使用`/* */`写函数头 ```cpp /* 单行函数头 */ int func1(void); /* * 另一种单行函数头 */ int func2(void); /* * 多行函数头 * 第二行 */ int func3(void); ``` 函数尽量通过函数名自注释,按需写函数头注释。 不要写无用、信息冗余的函数头;不要写空有格式的函数头。 函数头注释内容可选,但不限于:功能说明、返回值,性能约束、用法、内存约定、算法实现、可重入的要求等等。 模块对外头文件中的函数接口声明,其函数头注释,应当将重要、有用的信息表达清楚。 例: ```cpp /* * 返回实际写入的字节数,-1表示写入失败 * 注意,内存 buf 由调用者负责释放 */ int write_string(const char *buf, int len); ``` 坏的例子: ```cpp /* * 函数名:write_string * 功能:写入字符串 * 参数: * 返回值: */ int write_string(const char *buf, int len); ``` 上面例子中的问题: - 参数、返回值,空有格式没内容 - 函数名信息冗余 - 关键的 buf 由谁释放没有说清楚 ### 4.4 代码注释 #### 规则4.4.1 代码注释放于对应代码的上方或右边 #### 规则4.4.2 注释符与注释内容间要有1空格;右置注释与前面代码至少1空格 代码上方的注释,应该保持对应代码一样的缩进。 选择并统一使用如下风格之一: 使用`//` ```cpp // 这是单行注释 do_something(); // 这是多行注释 // 第二行 do_something(); ``` 使用`/* */` ```cpp /* 这是单行注释 */ do_something(); /* * 另一种方式的多行注释 * 第二行 */ do_something(); ``` 代码右边的注释,与代码之间,至少留1空格,建议不超过4空格。 通常使用已配置为空格扩展的 Tab 键即可实现 1-4 空格的缩进。 选择并统一使用如下风格之一: ```cpp int foo = 100; // 放右边的注释 int bar = 200; /* 放右边的注释 */ ``` 右置格式在适当的时候,上下对齐会更美观。 对齐后的注释,离左边代码最近的那一行,保证1-4空格的间隔。 例: ```cpp const int A_CONST = 100; /* 相关的同类注释,可以考虑上下对齐 */ const int ANOTHER_CONST = 200; /* 上下对齐时,与左侧代码保持间隔 */ ``` 当右置的注释超过行宽时,请考虑将注释置于代码上方。 #### 规则4.4.3 不用的代码段直接删除,不要注释掉 被注释掉的代码,无法被正常维护;当企图恢复使用这段代码时,极有可能引入易被忽略的缺陷。 正确的做法是,不需要的代码直接删除掉。若再需要时,考虑移植或重写这段代码。 这里说的注释掉代码,包括/*、*/和//,还包括 #if 0, #ifdef NEVER_DEFINED 等等。 ## 5 头文件 ### 5.1 头文件职责 头文件是模块或文件的对外接口,头文件的设计体现了大部分的系统设计。 头文件中适合放置接口的声明,不适合放置实现(内联函数除外)。对于cpp文件中内部才需要使用的函数、宏、枚举、结构定义等不要放在头文件中。 头文件应当职责单一。头文件过于复杂,依赖过于复杂还是导致编译时间过长的主要原因。 #### 建议5.1.1 每一个.cpp文件应有一个对应的.h文件,用于声明需要对外公开的类与接口 通常情况下,每个.cpp文件都有一个相应的.h,用于放置对外提供的函数声明、宏定义、类型定义等。 如果一个.cpp文件不需要对外公布任何接口,则其就不应当存在。 例外:__程序的入口(如main函数所在的文件),单元测试代码,动态库代码。__ 示例: ```cpp // foo/include/Foo.h #ifndef FOO_INCLUDE_FOO_H #define FOO_INCLUDE_FOO_H class Foo { public: Foo(); void fun(); private: int Value; }; #endif ``` ```cpp // Foo.cpp #include "Foo.h" namespace { // Good: 对内函数的声明放在.cpp文件的头部,并声明为匿名namespace或者static限制其作用域 void bar() { } } ... void Foo::fun() { bar(); } ``` ### 5.2 头文件依赖 #### 规则5.2.1 禁止头文件循环依赖 头文件循环依赖,指 a.h 包含 b.h,b.h 包含 c.h,c.h 包含 a.h, 导致任何一个头文件修改,都导致所有包含了a.h/b.h/c.h的代码全部重新编译一遍。 而如果是单向依赖,如a.h包含b.h,b.h包含c.h,而c.h不包含任何头文件,则修改a.h不会导致包含了b.h/c.h的源代码重新编译。 头文件循环依赖直接体现了架构设计上的不合理,可通过优化架构去避免。 #### 规则5.2.2 头文件必须编写`#define`保护,防止重复包含 为防止头文件被重复包含,所有头文件都应当使用 #define 保护;不要使用 #pragma once 定义包含保护符时,应该遵守如下规则: 1)保护符使用唯一名称; 2)不要在受保护部分的前后放置代码或者注释,文件头注释除外。 示例:假定timer模块的timer.h,其目录为timer/include/timer.h,应按如下方式保护: ```cpp #ifndef TIMER_INCLUDE_TIMER_H #define TIMER_INCLUDE_TIMER_H ... #endif ``` #### 规则5.2.3 禁止通过声明的方式引用外部函数接口、变量 只能通过包含头文件的方式使用其他模块或文件提供的接口。 通过 extern 声明的方式使用外部函数接口、变量,容易在外部接口改变时可能导致声明和定义不一致。 同时这种隐式依赖,容易导致架构腐化。 不符合规范的案例: // a.cpp内容 ```cpp extern int fun(); // Bad: 通过extern的方式使用外部函数 void bar() { int i = fun(); ... } ``` // b.cpp内容 ```cpp int fun() { // Do something } ``` 应该改为: // a.cpp内容 ```cpp #include "b.h" // Good: 通过包含头文件的方式使用其他.cpp提供的接口 void bar() { int i = fun(); ... } ``` // b.h内容 ```cpp int fun(); ``` // b.cpp内容 ```cpp int fun() { // Do something } ``` 例外,有些场景需要引用其内部函数,但并不想侵入代码时,可以 extern 声明方式引用。 如: 针对某一内部函数进行单元测试时,可以通过 extern 声明来引用被测函数; 当需要对某一函数进行打桩、打补丁处理时,允许 extern 声明该函数。 #### 规则5.2.4 禁止在extern "C"中包含头文件 在 extern "C" 中包含头文件,有可能会导致 extern "C" 嵌套,部分编译器对 extern "C" 嵌套层次有限制,嵌套层次太多会编译错误。 在C,C++混合编程的情况下,在extern "C"中包含头文件,可能会导致被包含头文件的原有意图遭到破坏,比如链接规范被不正确地更改。 示例,存在a.h和b.h两个头文件: // a.h内容 ```cpp ... #ifdef __cplusplus void foo(int); #define A(value) foo(value) #else void A(int); #endif ``` // b.h内容 ```cpp ... #ifdef __cplusplus extern "C" { #endif #include "a.h" void b(); #ifdef __cplusplus } #endif ``` 使用C++预处理器展开b.h,将会得到 ```cpp extern "C" { void foo(int); void b(); } ``` 按照 a.h 作者的本意,函数 foo 是一个 C++ 自由函数,其链接规范为 "C++"。 但在 b.h 中,由于 `#include "a.h"` 被放到了 `extern "C"` 的内部,函数 foo 的链接规范被不正确地更改了。 例外: 如果在 C++ 编译环境中,想引用纯C的头文件,这些C头文件并没有 `extern "C"` 修饰。非侵入式的做法是,在 `extern "C"` 中去包含C头文件。 #### 建议5.2.1 尽量避免使用前置声明,而是通过`#include`来包含头文件 前置声明(forward declaration)通常指类、模板的纯粹声明,没伴随着其定义。 - 优点: 1. 前置声明能够节省编译时间,多余的 #include 会迫使编译器展开更多的文件,处理更多的输入。 2. 前置声明能够节省不必要的重新编译的时间。 #include 使代码因为头文件中无关的改动而被重新编译多次。 - 缺点: 1. 前置声明隐藏了依赖关系,头文件改动时,用户的代码会跳过必要的重新编译过程。 2. 前置声明可能会被库的后续更改所破坏。前置声明模板有时会妨碍头文件开发者变动其 API. 例如扩大形参类型,加个自带默认参数的模板形参等等。 3. 前置声明来自命名空间`std::` 的 symbol 时,其行为未定义(在C++11标准规范中明确说明)。 4. 前置声明了不少来自头文件的 symbol 时,就会比单单一行的 include 冗长。 5. 仅仅为了能前置声明而重构代码(比如用指针成员代替对象成员)会使代码变得更慢更复杂。 6. 很难判断什么时候该用前置声明,什么时候该用`#include`,某些场景下面前置声明和`#include`互换以后会导致意想不到的结果。 所以我们尽可能避免使用前置声明,而是使用#include头文件来保证依赖关系。 ## 6 作用域 ### 6.1 命名空间 #### 建议6.1.1 对于cpp文件中不需要导出的变量,常量或者函数,请使用匿名namespace封装或者用static修饰 在C++11标准规范中,使用`static`修饰文件作用域的变量、函数等被标记为deprecated特性(该弃用标记在C++17中已移除),所以更推荐使用匿名namespace。 主要原因如下: 1. static在C++中已经赋予了太多的含义,静态函数成员变量,静态成员函数,静态全局变量,静态函数局部变量,每一种都有特殊的处理。 2. static只能保证变量,常量和函数的文件作用域,但是namespace还可以封装类型等。 3. 统一namespace来处理C++的作用域,而不需要同时使用static和namespace来管理。 4. C++11 起已允许具有内部链接的实体作为模板实参,`static` 修饰与匿名 namespace 在模板实例化上已无差别,统一使用匿名 namespace 更简洁。 但是不要在 .h 中使用匿名namespace或者static。 ```cpp // Foo.cpp namespace { const int MAX_COUNT = 20; void internal_fun() {} void Foo::fun() { int i = MAX_COUNT; internal_fun(); } ``` #### 规则6.1.1 不要在头文件中或者#include之前使用using导入命名空间 说明:使用using导入命名空间会影响后续代码,易造成符号冲突,所以不要在头文件以及源文件中的#include之前使用using导入命名空间。 示例: ```cpp // 头文件a.h namespace NamespaceA { int fun(int); } ``` ```cpp // 头文件b.h namespace NamespaceB { int fun(int); } using namespace NamespaceB; void g() { fun(1); } ``` ```cpp // 源代码a.cpp #include "a.h" using namespace NamespaceA; #include "b.h" int main() { g(); // using namespace NamespaceA在#include "b.h"之前,引发歧义:NamespaceA::fun,NamespaceB::fun调用不明确 } ``` 对于在头文件中使用using导入单个符号或定义别名,允许在模块自定义名字空间中使用,但禁止在全局名字空间中使用。 ```cpp // foo.h #include using fancy::string; // Bad,禁止向全局名字空间导入符号 namespace Foo { using fancy::string; // Good,可以在模块自定义名字空间中导入符号 using MyVector = fancy::vector; // Good,C++11可在自定义名字空间中定义别名 } ``` ### 6.2 全局函数和静态成员函数 #### 建议6.2.1 优先使用命名空间来管理全局函数,如果和某个class有直接关系的,可以使用静态成员函数 说明:非成员函数放在名字空间内可避免污染全局作用域, 也不要用类+静态成员方法来简单管理全局函数。 如果某个全局函数和某个类有紧密联系, 那么可以作为类的静态成员函数。 如果你需要定义一些全局函数,给某个cpp文件使用,那么请使用匿名namespace来管理。 ```cpp namespace MyNamespace { int add(int a, int b); } class File { public: static File create_temp_file(const std::string& file_name); }; ``` ### 6.3 全局常量和静态成员常量 #### 建议6.3.1 优先使用命名空间来管理全局常量,如果和某个class有直接关系的,可以使用静态成员常量 说明:全局常量放在命名空间内可避免污染全局作用域, 也不要用类+静态成员常量来简单管理全局常量。 如果某个全局常量和某个类有紧密联系, 那么可以作为类的静态成员常量。 如果你需要定义一些全局常量,只给某个cpp文件使用,那么请使用匿名namespace来管理。 ```cpp namespace MyNamespace { const int MAX_SIZE = 100; } class File { public: static const std::string SEPARATOR; }; ``` ### 6.4 全局变量 #### 建议6.4.1 尽量避免使用全局变量,考虑使用单例模式 说明:全局变量是可以修改和读取的,那么这样会导致业务代码和这个全局变量产生数据耦合。 ```cpp int g_counter = 0; // a.cpp g_counter++; // b.cpp g_counter++; // c.cpp cout << g_counter << endl; ``` 使用单实例模式 ```cpp class Counter { public: static Counter& get_instance() { static Counter counter; return counter; } // 单实例实现简单举例 void increase() { Value++; } void print() const { std::cout << Value << std::endl; } private: Counter() : Value(0) {} int Value; }; // a.cpp Counter::get_instance().increase(); // b.cpp Counter::get_instance().increase(); // c.cpp Counter::get_instance().print(); ``` 实现单例模式以后,实现了全局唯一一个实例,和全局变量同样的效果,并且单实例提供了更好的封装性。 例外:有的时候全局变量的作用域仅仅是模块内部,这样进程空间里面就会有多个全局变量实例,每个模块持有一份,这种场景下是无法使用单例模式解决的。 ## 7 类 ### 7.1 构造,拷贝构造,赋值和析构函数 构造,拷贝,移动和析构函数提供了对象的生命周期管理方法: - 构造函数(constructor): `X()` - 拷贝构造函数(copy constructor):`X(const X&)` - 拷贝赋值操作符(copy assignment):`operator=(const X&)` - 移动构造函数(move constructor):`X(X&&)` *C++11以后提供* - 移动赋值操作符(move assignment):`operator=(X&&)` *C++11以后提供* - 析构函数(destructor):`~X()` #### 规则7.1.1 类的成员变量必须显式初始化 说明:如果类有成员变量,没有定义构造函数,又没有定义默认构造函数,编译器将自动生成一个构造函数,但编译器生成的构造函数并不会对成员变量进行初始化,对象状态处于一种不确定性。 例外: - 如果类的成员变量具有默认构造函数,那么可以不需要显式初始化。 示例:如下代码没有构造函数,私有数据成员无法初始化: ```cpp class Message { public: void process_out_msg() { //… } private: unsigned int MsgID; unsigned int MsgLength; unsigned char* MsgBuffer; std::string SomeIdentifier; }; Message message; // message成员变量没有初始化 message.process_out_msg(); // 后续使用存在隐患 // 因此,有必要定义默认构造函数,如下: class Message { public: Message() : MsgID(0), MsgLength(0), MsgBuffer(nullptr) { } void process_out_msg() { // … } private: unsigned int MsgID; unsigned int MsgLength; unsigned char* MsgBuffer; std::string SomeIdentifier; // 具有默认构造函数,不需要显式初始化 }; ``` #### 建议7.1.1 成员变量优先使用声明时初始化(C++11)和构造函数初始化列表初始化 说明:C++11的声明时初始化可以一目了然的看出成员初始值,应当优先使用。如果成员初始化值和构造函数相关,或者不支持C++11,则应当优先使用构造函数初始化列表来初始化成员。相比起在构造函数体中对成员赋值,初始化列表的代码更简洁,执行性能更好,而且可以对const成员和引用成员初始化。 ```cpp class Message { public: Message() : MsgLength(0) // Good,优先使用初始化列表 { MsgBuffer = nullptr; // Bad,不推荐在构造函数中赋值 } private: unsigned int MsgID{0}; // Good,C++11中使用 unsigned int MsgLength; unsigned char* MsgBuffer; }; ``` #### 规则7.1.2 为避免隐式转换,将单参数构造函数声明为explicit 说明:单参数构造函数如果没有用explicit声明,则会成为隐式转换函数。 示例: ```cpp class Foo { public: explicit Foo(const string& name): Name(name) { } private: string Name; }; void process_foo(const Foo& foo) {} int main(void) { std::string test = "test"; process_foo(test); // 编译不通过 return 0; } ``` 上面的代码编译不通过,因为`process_foo`需要的参数是Foo类型,传入的string类型不匹配。 如果将Foo构造函数的explicit关键字移除,那么调用`process_foo`传入的string就会触发隐式转换,生成一个临时的Foo对象。往往这种隐式转换是让人迷惑的,并且容易隐藏Bug,得到了一个不期望的类型转换。所以对于单参数的构造函数是要求explicit声明。 #### 规则7.1.3 如果不需要拷贝构造函数、赋值操作符 / 移动构造函数、赋值操作符,请明确禁止 说明:如果用户不定义,编译器默认会生成拷贝构造函数和拷贝赋值操作符, 移动构造和移动赋值操作符(移动语义的函数C++11以后才有)。 如果我们不要使用拷贝构造函数,或者赋值操作符,请明确拒绝: 1. 将拷贝构造函数或者赋值操作符设置为private,并且不实现: ```cpp class Foo { private: Foo(const Foo&); Foo& operator=(const Foo&); }; ``` 2. 使用C++11提供的delete, 请参见后面现代C++的相关章节。 3. 推荐继承NoCopyable、NoMovable,禁止使用DISALLOW_COPY_AND_MOVE,DISALLOW_COPY,DISALLOW_MOVE等宏。 ```cpp class Foo : public NoCopyable, public NoMovable { }; ``` NoCopyable和NoMovable的实现: ```cpp class NoCopyable { public: NoCopyable() = default; NoCopyable(const NoCopyable&) = delete; NoCopyable& operator=(const NoCopyable&) = delete; }; class NoMovable { public: NoMovable() = default; NoMovable(NoMovable&&) noexcept = delete; NoMovable& operator = (NoMovable&&) noexcept = delete; }; ``` #### 规则7.1.4 拷贝构造和拷贝赋值操作符应该是成对出现或者禁止 拷贝构造函数和拷贝赋值操作符都是具有拷贝语义的,应该同时出现或者禁止。 ```cpp // 同时出现 class Foo { public: ... Foo(const Foo&); Foo& operator=(const Foo&); ... }; // 同时default, C++11支持 class Foo { public: Foo(const Foo&) = default; Foo& operator=(const Foo&) = default; }; // 同时禁止, C++11可以使用delete class Foo { private: Foo(const Foo&); Foo& operator=(const Foo&); }; ``` #### 规则7.1.5 移动构造和移动赋值操作符应该是成对出现或者禁止 在C++11中增加了move操作,如果需要某个类支持移动操作,那么需要实现移动构造和移动赋值操作符。 移动构造函数和移动赋值操作符都是具有移动语义的,应该同时出现或者禁止。 ```cpp // 同时出现 class Foo { public: ... Foo(Foo&&); Foo& operator=(Foo&&); ... }; // 同时default, C++11支持 class Foo { public: Foo(Foo&&) = default; Foo& operator=(Foo&&) = default; }; // 同时禁止, 使用C++11的delete class Foo { public: Foo(Foo&&) = delete; Foo& operator=(Foo&&) = delete; }; ``` #### 规则7.1.6 禁止在构造函数和析构函数中调用虚函数 说明:在构造函数和析构函数中调用当前对象的虚函数,会导致未实现多态的行为。 在C++中,一个基类一次只构造一个完整的对象。 示例:类Base是基类,Sub是派生类 ```cpp class Base { public: Base(); virtual void log() = 0; // 不同的派生类调用不同的日志文件 }; Base::Base() // 基类构造函数 { log(); // 调用虚函数log } class Sub : public Base { public: void log() override; }; ``` 当执行如下语句: `Sub sub;` 会先执行Sub的构造函数,但首先调用Base的构造函数,由于Base的构造函数调用虚函数log,此时log还是基类的版本,只有基类构造完成后,才会完成派生类的构造,从而导致未实现多态的行为。 同样的道理也适用于析构函数。 #### 规则7.1.7 多态基类中的拷贝构造函数、拷贝赋值操作符、移动构造函数、移动赋值操作符必须为非public函数或者为delete函数 如果把一个派生类对象直接赋值给基类对象,会发生切片,只拷贝或者移动了基类部分,损害了多态行为。 【反例】 如下代码中,基类没有定义拷贝构造函数或拷贝赋值操作符,编译器会自动生成这两个特殊成员函数, 如果派生类对象赋值给基类对象时就发生切片。可以将此例中的拷贝构造函数和拷贝赋值操作符声明为delete,编译器可检查出此类赋值行为。 ```cpp class Base { public: Base() = default; virtual ~Base() = default; ... virtual void fun() { std::cout << "Base" << std::endl; } }; class Derived : public Base { ... void fun() override { std::cout << "Derived" << std::endl; } }; void foo(const Base &base) { Base other = base; // 不符合:发生切片 other.fun(); // 调用的是Base类的fun函数 } ``` ```cpp Derived d; foo(d); // 传入的是派生类对象 ``` ### 7.2 继承 #### 规则7.2.1 基类的析构函数应该声明为virtual,不准备被继承的类需要声明为final 说明:只有基类析构函数是virtual,通过多态调用的时候才能保证派生类的析构函数被调用。 示例:基类的析构函数没有声明为virtual导致了内存泄漏。 ```cpp class Base { public: virtual std::string get_version() = 0; ~Base() { std::cout << "~Base" << std::endl; } }; ``` ```cpp class Sub : public Base { public: Sub() : Numbers(nullptr) {} ~Sub() { delete[] Numbers; std::cout << "~Sub" << std::endl; } int init() { const size_t number_count = 100; Numbers = new (std::nothrow) int[number_count]; if (Numbers == nullptr) { return -1; } ... } std::string get_version() override { return std::string("hello!"); } private: int* Numbers; }; ``` ```cpp int main(int argc, char* args[]) { Base* b = new Sub(); delete b; return 0; } ``` 由于基类Base的析构函数没有声明为virtual,当对象被销毁时,只会调用基类的析构函数,不会调用派生类Sub的析构函数,导致内存泄漏。 例外: NoCopyable、NoMovable这种没有任何行为,仅仅用来做标识符的类,可以不定义虚析构也不定义final。 #### 规则7.2.2 禁止为虚函数声明缺省参数值 说明:在C++中,虚函数是动态绑定的,但函数的缺省参数却是在编译时就静态绑定的。这意味着你最终执行的函数是一个定义在派生类,但使用了基类中的缺省参数值的虚函数。为了避免虚函数重载时,因参数声明不一致给使用者带来的困惑和由此导致的问题,规定所有虚函数均不允许声明缺省参数值。 示例:虚函数display缺省参数值text是由编译时刻决定的,而非运行时刻,没有达到多态的目的: ```cpp class Base { public: virtual void display(const std::string& text = "Base!") { std::cout << text << std::endl; } virtual ~Base() {} }; class Sub : public Base { public: void display(const std::string& text = "Sub!") override { std::cout << text << std::endl; } ~Sub() override {} }; int main() { Base* base = new Sub(); Sub* sub = new Sub(); ... base->display(); // 程序输出结果: Base! 而期望输出:Sub! sub->display(); // 程序输出结果: Sub! delete base; delete sub; return 0; } ``` #### 规则7.2.3 禁止重新定义继承而来的非虚函数 如果在派生类中重新定义继承的非虚函数,当把派生类当成基类来使用时,将调用到基类的函数,达不到多态的目的 示例: ```cpp class Base { public: void fun(); }; class Sub : public Base { public: void fun(); }; Sub* sub = new Sub(); Base* base = sub; sub->fun(); // 调用子类的fun base->fun(); // 调用父类的fun //... ``` ### 7.3 多重继承 在实际开发过程中使用多重继承的场景是比较少的,因为多重继承使用过程中有下面的典型问题: 1. 菱形继承所带来的数据重复,以及名字二义性。因此,C++引入了virtual继承来解决这类问题; 2. 即便不是菱形继承,多个父类之间的名字也可能存在冲突,从而导致的二义性; 3. 如果子类需要扩展或改写多个父类的方法时,造成子类的职责不明,语义混乱; 4. 相对于委托,继承是一种白盒复用,即子类可以访问父类的protected成员, 这会导致更强的耦合。而多重继承,由于耦合了多个父类,相对于单根继承,这会产生更强的耦合关系。 多重继承具有下面的优点: 多重继承提供了一种更简单的组合来实现多种接口或者类的组装与复用。 所以,只有下面几种情况下面才允许使用多重继承。 #### 建议7.3.1 使用多重继承来实现接口分离与多角色组合 如果某个类需要实现多重接口,可以通过多重继承把多个分离的接口组合起来,类似 scala 语言的 traits 混入。 ```cpp class Role1 {}; class Role2 {}; class Role3 {}; class Object1 : public Role1, public Role2 { // ... }; class Object2 : public Role2, public Role3 { // ... }; ``` 在C++标准库中也有类似的实现样例: ```cpp class basic_istream {}; class basic_ostream {}; class basic_iostream : public basic_istream, public basic_ostream { }; ``` ### 7.4 重载 #### 建议7.4.1 重载操作符要有充分理由,且不要改变操作符原有语义 重载操作符要有充分理由,而且不要改变操作符原有语义,例如不要使用 ‘+’ 操作符来做减运算。 操作符重载令代码更加直观,但也有一些不足: - 混淆直觉,误以为该操作和内建类型一样是高性能的,忽略了性能降低的可能; - 问题定位时不够直观,按函数名查找比按操作符显然更方便。 - 重载操作符如果行为定义不直观(例如将‘+’ 操作符来做减运算),会让代码产生混淆。 - 赋值操作符的重载引入的隐式转换会隐藏很深的bug。可以定义类似equals()、copy_from()等函数来替代=,==操作符。 ## 8 函数 ### 8.1 函数设计 #### 规则8.1.1 避免函数过长,函数不超过50行(非空非注释) 函数应该可以一屏显示完 (50行以内),只做一件事情,而且把它做好。 过长的函数往往意味着函数功能不单一,过于复杂,或过分呈现细节,未进行进一步抽象。 例外:某些实现算法的函数,由于算法的聚合性与功能的全面性,可能会超过50行。 即使一个长函数现在工作的非常好, 一旦有人对其修改, 有可能出现新的问题, 甚至导致难以发现的bug。 建议将其拆分为更加简短并易于管理的若干函数,以便于他人阅读和修改代码。 ### 8.2 内联函数 #### 建议8.2.1 内联函数不超过10行(非空非注释) **说明**:内联函数具有一般函数的特性,它与一般函数不同之处只在于函数调用的处理。一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换。 内联函数只适合于只有 1~10 行的小函数。对一个含有许多语句的大函数,函数调用和返回的开销相对来说微不足道,也没有必要用内联函数实现,一般的编译器会放弃内联方式,而采用普通的方式调用函数。 如果内联函数包含复杂的控制结构,如循环、分支(switch)、try-catch 等语句,一般编译器将该函数视同普通函数。 虚函数在通过基类指针或引用进行动态调用时通常无法内联,但通过对象直接静态调用时仍可内联;递归函数一般难以内联。 ### 8.3 函数参数 #### 建议8.3.1 函数参数使用引用取代指针 **说明**:引用比指针更安全,因为它一定非空,且一定不会再指向其他目标;引用不需要检查非法的NULL指针。 如果是基于老平台开发的产品,则优先顺从原有平台的处理方式。 选择 const 避免参数被修改,让代码阅读者清晰地知道该参数不被修改,可大大增强代码可读性。 例外:当传入参数为编译期长度未知的数组时,可以使用指针而不是引用。 #### 建议8.3.2 使用强类型参数,避免使用void* 尽管不同的语言对待强类型和弱类型有自己的观点,但是一般认为c/c++是强类型语言,既然我们使用的语言是强类型的,就应该保持这样的风格。 好处是尽量让编译器在编译阶段就检查出类型不匹配的问题。 使用强类型便于编译器帮我们发现错误,如下代码中注意函数 foo_list_add_node 的使用: ```cpp struct FooNode { struct List link; int foo; }; struct BarNode { struct List link; int bar; }; void foo_list_add_node(void *node) // Bad: 这里用 void * 类型传递参数 { FooNode *foo = static_cast(node); list_append(&g_foo_list, &foo->link); } void make_the_list() { FooNode *foo = nullptr; BarNode *bar = nullptr; ... foo_list_add_node(bar); // Wrong: 这里本意是想传递参数 foo,但错传了 bar,却没有报错 } ``` 1. 可以使用模板函数来实现参数类型的变化。 2. 可以使用基类指针来实现多态。 #### 建议8.3.3 函数的参数个数不超过5个 函数的参数过多,会使得该函数易于受外部变化的影响,从而影响维护工作。函数的参数过多同时也会增大测试的工作量。 如果超过可以考虑: - 看能否拆分函数 - 看能否将相关参数合在一起,定义结构体 ## 9 C++其他特性 ### 9.1 常量与初始化 不变的值更易于理解、跟踪和分析,所以应该尽可能地使用常量代替变量,定义值的时候,应该把const作为默认的选项。 #### 规则9.1.1 不允许使用宏来表示常量 **说明**:宏是简单的文本替换,在预处理阶段时完成,运行报错时直接报相应的值;跟踪调试时也是显示值,而不是宏名;宏没有类型检查,不安全;宏没有作用域。 ```cpp #define MAX_MSISDN_LEN 20 // 不好 // C++请使用const常量 const int MAX_MSISDN_LEN = 20; // 好 // 对于C++11以上版本,可以使用constexpr constexpr int MAX_MSISDN_LEN = 20; ``` #### 建议9.1.1 一组相关的整型常量应定义为枚举 **说明**:枚举比`#define`或`const int`更安全。编译器会检查参数值是否位于枚举取值范围内,避免错误发生。 ```cpp // 好的例子: enum Week { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }; enum Color { RED, BLACK, BLUE }; void colorize_calendar(Week today, Color color); colorize_calendar(BLUE, SUNDAY); // 编译报错,参数类型错误 // 不好的例子: const int SUNDAY = 0; const int MONDAY = 1; const int BLACK = 0; const int BLUE = 1; bool colorize_calendar(int today, int color); colorize_calendar(BLUE, SUNDAY); // 不会报错 ``` 当枚举值需要对应到具体数值时,须在声明时显式赋值。否则不需要显式赋值,以避免重复赋值,降低维护(增加、删除成员)工作量。 ```cpp // 好的例子:S协议里定义的设备ID值,用于标识设备类型 enum DeviceType { DEV_UNKNOWN = -1, DEV_DSMP = 0, DEV_ISMG = 1, DEV_WAPPORTAL = 2 }; ``` 程序内部使用,仅用于分类的情况,不应该进行显式的赋值。 ```cpp // 好的例子:程序中用来标识会话状态的枚举定义 enum SessionState { INIT, CLOSED, WAITING_FOR_RESPONSE }; ``` 应当尽量避免枚举值重复,如必须重复也要用已定义的枚举来修饰 ```cpp enum RTCPType { RTCP_SR = 200, RTCP_MIN_TYPE = RTCP_SR, RTCP_RR = 201, RTCP_SDES = 202, RTCP_BYE = 203, RTCP_APP = 204, RTCP_RTPFB = 205, RTCP_PSFB = 206, RTCP_XR = 207, RTCP_RSI = 208, RTCP_PUBPORTS = 209, RTCP_MAX_TYPE = RTCP_PUBPORTS }; ``` #### 规则9.1.2 不允许使用魔鬼数字 所谓魔鬼数字即看不懂、难以理解的数字。 魔鬼数字并非一个非黑即白的概念,看不懂也有程度,需要自行判断。 例如数字 12,在不同的上下文中情况是不一样的: type = 12; 就看不懂,但 `months_count = years_count * 12`; 就能看懂。 数字 0 有时候也是魔鬼数字,比如 `status = 0`; 并不能表达是什么状态。 解决途径: 对于局部使用的数字,可以增加注释说明 对于多处使用的数字,必须定义 const 常量,并通过符号命名自注释。 禁止出现下列情况: 没有通过符号来解释数字含义,如`const int ZERO = 0` 符号命名限制了其取值,如 `const int XX_TIMER_INTERVAL_300MS = 300`,直接使用`XX_TIMER_INTERVAL_MS`来表示该常量是定时器的时间间隔。 #### 规则9.1.3 常量应该保证单一职责 **说明**:一个常量只用来表示一个特定功能,即一个常量不能有多种用途。 ```cpp // 好的例子:协议A和协议B,手机号(MSISDN)的长度都是20。 const unsigned int A_MAX_MSISDN_LEN = 20; const unsigned int B_MAX_MSISDN_LEN = 20; // 或者使用不同的名字空间: namespace Namespace1 { const unsigned int MAX_MSISDN_LEN = 20; } namespace Namespace2 { const unsigned int MAX_MSISDN_LEN = 20; } ``` #### 规则9.1.4 禁止用memcpy_s、memset_s初始化非POD对象 **说明**:`POD`全称是`Plain Old Data`,是C++ 98标准(ISO/IEC 14882, first edition, 1998-09-01)中引入的一个概念,`POD`类型主要包括`int`, `char`, `float`,`double`,`enumeration`,`void`,指针等原始类型以及聚合类型,不能使用封装和面向对象特性(如用户定义的构造/赋值/析构函数、基类、虚函数等)。 由于非POD类型比如非聚合类型的class对象,可能存在虚函数,内存布局不确定,跟编译器有关,滥用内存拷贝可能会导致严重的问题。 说明:`memcpy_s`、`memset_s`是微软或C11 Annex K提供的安全函数,并非标准C++;在标准C++环境中应使用`std::memcpy`、`std::memset`,或直接通过构造函数完成初始化。 即使对聚合类型的class,使用直接的内存拷贝和比较,破坏了信息隐蔽和数据保护的作用,也不提倡`memcpy_s`、`memset_s`操作。 关于`POD`的详细定义,请参考C++标准对平凡类型(trivial)与标准布局类型(standard-layout type)的说明。 #### 建议9.1.2 变量使用时才声明并初始化 **说明**:变量在使用前未赋初值,是常见的低级编程错误。使用前才声明变量并同时初始化,非常方便地避免了此类低级错误。 在函数开始位置声明所有变量,后面才使用变量,作用域覆盖整个函数实现,容易导致如下问题: * 程序难以理解和维护:变量的定义与使用分离。 * 变量难以合理初始化:在函数开始时,经常没有足够的信息进行变量初始化,往往用某个默认的空值(比如零)来初始化,这通常是一种浪费,如果变量在被赋于有效值以前使用,还会导致错误。 遵循变量作用域最小化原则与就近声明原则, 使得代码更容易阅读,方便了解变量的类型和初始值。特别是,应使用初始化的方式替代声明再赋值。 ```cpp // 不好的例子:声明与初始化分离 string name; // 声明时未初始化:调用缺省构造函数 name = "zhangsan"; // 再次调用赋值操作符函数;声明与定义在不同的地方,理解相对困难 // 好的例子:声明与初始化一体,理解相对容易 string name("zhangsan"); // 调用构造函数 ``` ### 9.2 表达式 #### 规则9.2.1 含有变量自增或自减运算的表达式中禁止再次引用该变量 含有变量自增或自减运算的表达式中,如果再引用该变量,其结果在C++标准中未明确定义。各个编译器或者同一个编译器不同版本实现可能会不一致。 为了更好的可移植性,不应该对标准未定义的运算次序做任何假设。 注意,运算次序的问题不能使用括号来解决,因为这不是优先级的问题。 示例: ```cpp x = b[i] + i++; // Bad: b[i]运算跟 i++,先后顺序并不明确。 ``` 正确的写法是将自增或自减运算单独放一行: ```cpp x = b[i] + i; i++; // Good: 单独一行 ``` 函数参数 ```cpp func(i++, i); // Bad: 传递第2个参数时,不确定自增运算有没有发生 ``` 正确的写法 ```cpp i++; // Good: 单独一行 x = func(i, i); ``` #### 规则9.2.2 switch语句要有default分支 大部分情况下,switch语句中要有default分支,保证在遗漏case标签处理时能够有一个缺省的处理行为。 特例: 如果switch条件变量是枚举类型,并且 case 分支覆盖了所有取值,则加上default分支处理有些多余。 现代编译器都具备检查是否在switch语句中遗漏了某些枚举值的case分支的能力,会有相应的warning提示。 ```cpp enum Color { RED = 0, BLUE }; // 因为switch条件变量是枚举值,这里可以不用加default处理分支 switch (color) { case RED: do_red_thing(); break; case BLUE: do_blue_thing(); ... break; } ``` #### 建议9.2.1 表达式的比较,应当遵循左侧倾向于变化、右侧倾向于不变的原则 当变量与常量比较时,如果常量放左边,如 if (MAX == v) 不符合阅读习惯,而 if (MAX > v) 更是难于理解。 应当按人的正常阅读、表达习惯,将常量放右边。写成如下方式: ```cpp if (value == MAX) { } if (value < MAX) { } ``` 也有特殊情况,如:`if (MIN < value && value < MAX)` 用来描述区间时,前半段是常量在左的。 不用担心将 '==' 误写成 '=',因为`if (value = MAX)` 会有编译告警,其他静态检查工具也会报错。让工具去解决笔误问题,代码要符合可读性第一。 #### 建议9.2.2 使用括号明确操作符的优先级 使用括号明确操作符的优先级,防止因默认的优先级与设计思想不符而导致程序出错;同时使得代码更为清晰可读,然而过多的括号会分散代码使其降低了可读性。下面是如何使用括号的建议。 - 二元及以上操作符, 如果涉及多种操作符,则应该使用括号 ```cpp x = a + b + c; /* 操作符相同,可以不加括号 */ x = foo(a + b, c); /* 逗号两边的表达式,不需要括号 */ x = 1 << (2 + 3); /* 操作符不同,需要括号 */ x = a + (b / 5); /* 操作符不同,需要括号 */ x = (a == b) ? a : (a - b); /* 操作符不同,需要括号 */ ``` ### 9.3 类型转换 避免使用类型分支来定制行为:类型分支来定制行为容易出错,是企图用C++编写C代码的明显标志。这是一种很不灵活的技术,要添加新类型时,如果忘记修改所有分支,编译器也不会告知。使用模板和虚函数,让类型自己而不是调用它们的代码来决定行为。 建议避免类型转换,我们在代码的类型设计上应该考虑到每种数据的数据类型是什么,而不是应该过度使用类型转换来解决问题。在设计某个基本类型的时候,请考虑: - 是无符号还是有符号的 - 是适合float还是double - 是使用int8,int16,int32还是int64,确定整形的长度 但是我们无法禁止使用类型转换,因为C++语言是一门面向机器编程的语言,涉及到指针地址,并且我们会与各种第三方或者底层API交互,他们的类型设计不一定是合理的,在这个适配的过程中很容易出现类型转换。 例外:在调用某个函数的时候,如果我们不想处理函数结果,首先要考虑这个是否是你的最好的选择。如果确实不想处理函数的返回值,那么可以使用(void)转换来解决。 #### 规则9.3.1 如果确定要使用类型转换,请使用由C++提供的类型转换,而不是C风格的类型转换 **说明**: C++提供的类型转换操作比C风格更有针对性,更易读,也更加安全,C++提供的转换有: - 类型转换: 1. `dynamic_cast`:主要用于继承体系下行转换,`dynamic_cast`具有类型检查的功能,请做好基类和派生类的设计,避免使用dynamic_cast来进行转换。 2. `static_cast`:和C风格转换相似可做值的强制转换,或上行转换(把派生类的指针或引用转换成基类的指针或引用)。该转换经常用于消除多重继承带来的类型歧义,是相对安全的。如果是纯粹的算术转换,那么请使用后面的大括号转换方式。 3. `reinterpret_cast`:用于转换不相关的类型。`reinterpret_cast`强制编译器将某个类型对象的内存重新解释成另一种类型,这是一种不安全的转换,建议尽可能少用`reinterpret_cast`。 4. `const_cast`:用于移除对象的`const`属性,使对象变得可修改,这样会破坏数据的不变性,建议尽可能少用。 - 算术转换: (C++11开始支持) 对于那种算术转换,并且类型信息没有丢失的,比如float到double, int32到int64的转换,推荐使用大括号的初始方式。 ```cpp double d{ some_float }; int64_t i{ some_int32 }; ``` #### 建议9.3.1 避免使用`dynamic_cast` 1. `dynamic_cast`依赖于C++的RTTI, 让程序员在运行时识别C++类对象的类型。 2. `dynamic_cast`的出现一般说明我们的基类和派生类设计出现了问题,派生类破坏了基类的契约,不得不通过`dynamic_cast`转换到子类进行特殊处理,这个时候更希望来改善类的设计,而不是通过`dynamic_cast`来解决问题。 #### 建议9.3.2 避免使用`reinterpret_cast` **说明**:`reinterpret_cast`用于转换不相关类型。尝试用`reinterpret_cast`将一种类型强制转换另一种类型,这破坏了类型的安全性与可靠性,是一种不安全的转换。不同类型之间尽量避免转换。 #### 建议9.3.3 避免使用`const_cast` **说明**:`const_cast`用于移除对象的`const`和`volatile`性质。 使用const_cast转换后的指针或者引用来修改const对象,行为是未定义的。 ```cpp // 不好的例子 const int i = 1024; int* p = const_cast(&i); *p = 2048; // 未定义行为 ``` ```cpp // 不好的例子 class Foo { public: Foo() : i(3) {} void fun(int v) { i = v; } private: int i; }; int main(void) { const Foo f; Foo* p = const_cast(&f); p->fun(8); // 未定义行为 } ``` ### 9.4 资源分配和释放 #### 规则9.4.1 单个对象释放使用delete,数组对象释放使用delete [] 说明:单个对象删除使用delete, 数组对象删除使用delete [],原因: - 调用new所包含的动作:从系统中申请一块内存,并调用此类型的构造函数。 - 调用new[n]所包含的动作:申请可容纳n个对象的内存,并且对每一个对象调用其构造函数。 - 调用delete所包含的动作:先调用相应的析构函数,再将内存归还系统。 - 调用delete[]所包含的动作:对每一个对象调用析构函数,再释放所有内存 如果new和delete的格式不匹配,结果是未知的。对于非class类型, new和delete不会调用构造与析构函数。 错误写法: ```cpp const int MAX_ARRAY_SIZE = 100; int* number_array = new int[MAX_ARRAY_SIZE]; ... delete number_array; number_array = nullptr; ``` 正确写法: ```cpp const int MAX_ARRAY_SIZE = 100; int* number_array = new int[MAX_ARRAY_SIZE]; ... delete[] number_array; number_array = nullptr; ``` #### 建议9.4.1 使用 RAII 特性来帮助追踪动态分配 说明:RAII是“资源获取就是初始化”的缩语(Resource Acquisition Is Initialization),是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。 RAII 的一般做法是这样的:在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。这种做法有两大好处: - 我们不需要显式地释放资源。 - 对象所需的资源在其生命期内始终保持有效。这样,就不必检查资源有效性的问题,可以简化逻辑、提高效率。 示例:使用RAII不需要显式地释放互斥资源。 ```cpp class LockGuard { public: explicit LockGuard(LockType& lock_type) : Lock(lock_type) { Lock.acquire(); } ~LockGuard() { Lock.release(); } private: LockType& Lock; }; bool update() { LockGuard lock_guard(mutex); if (...) { return false; } else { // 操作数据 } return true; } ``` ### 9.5 标准库 STL标准模板库在不同产品使用程度不同,这里列出一些基本规则和建议,供各团队参考。 #### 规则9.5.1 不要保存std::string的c_str()返回的指针 说明:在C++标准中并未规定string::c_str()指针持久有效,因此特定STL实现完全可以在调用string::c_str()时返回一个临时存储区并很快释放。所以为了保证程序的可移植性,不要保存string::c_str()的结果,而是在每次需要时直接调用。 示例: ```cpp void fun1() { std::string name = "demo"; const char* text = name.c_str(); // 表达式结束以后,name的生命周期还在,指针有效 // 如果中间调用了string的非const成员函数,导致string被修改,比如operator[], begin()等 // 可能会导致text的内容不可用,或者不是原来的字符串 name = "test"; name[1] = '2'; // 后续使用text指针,其字符串内容不再是"demo" } void fun2() { std::string name = "demo"; std::string test = "test"; const char* text = (name + test).c_str(); // 表达式结束以后,+号产生的临时对象被销毁,指针无效 // 后续使用text指针,其已不再指向合法内存空间 } ``` 例外:在少数对性能要求非常高的代码中,为了适配已有的只接受const char*类型入参的函数,可以临时保存string::c_str()返回的指针。但是必须严格保证string对象的生命周期长于所保存指针的生命周期,并且保证在所保存指针的生命周期内,string对象不会被修改。 #### 建议9.5.1 使用std::string代替char* 说明:使用string代替`char*`有很多优势,比如: 1. 不用考虑结尾的’\0’; 2. 可以直接使用+, =, ==等运算符以及其它字符串操作函数; 3. 不需要考虑内存分配操作,避免了显式的new/delete,以及由此导致的错误; 需要注意的是,在C++11之前,部分STL实现中的`std::string`基于写时复制(Copy-On-Write)策略,存在线程安全以及在与动态库交互时产生悬挂指针等隐患。C++11起标准要求`std::string`连续存储并禁止COW实现,上述问题已不再适用。建议使用C++11及以后的标准库实现。 例外: 当调用系统或者其它第三方库的API时,针对已经定义好的接口,只能使用`char*`。但是在调用接口之前都可以使用string,在调用接口时使用string::c_str()获得字符指针。 当在栈上分配字符数组当作缓冲区使用时,可以直接定义字符数组,不要使用string,也没有必要使用类似`vector`等容器。 #### 规则9.5.2 禁止使用auto_ptr 说明:`std::auto_ptr`是C++98引入的智能指针,在C++11中被标记为弃用(deprecated),并在C++17中被正式移除。`std::auto_ptr`具有隐式的所有权转移行为,如下代码: ```cpp auto_ptr p1(new T); auto_ptr p2 = p1; ``` 当执行完第2行语句后,p1已经不再指向第1行中分配的对象,而是变为nullptr。正因为如此,auto_ptr不能被置于各种标准容器中。 转移所有权的行为通常不是期望的结果。对于必须转移所有权的场景,也不应该使用隐式转移的方式。这往往需要程序员对使用auto_ptr的代码保持额外的谨慎,否则出现对空指针的访问。 使用auto_ptr常见的有两种场景,一是作为智能指针传递到产生auto_ptr的函数外部,二是使用auto_ptr作为RAII管理类,在超出auto_ptr的生命周期时自动释放资源。 对于第1种场景,可以使用std::shared_ptr来代替。 对于第2种场景,可以使用C++11标准中的std::unique_ptr来代替。其中std::unique_ptr是std::auto_ptr的代替品,支持显式的所有权转移。 例外: 本规范优先适用于C++17,`std::auto_ptr`在该标准中已被移除,原则上不存在新的使用场景。仅当维护仍基于C++11之前标准的存量代码、且需要转移所有权时,可以暂时保留`std::auto_ptr`,但建议对其进行封装,并禁用封装类的拷贝构造函数和赋值运算符,以使该封装类无法用于标准容器。 #### 建议9.5.2 使用新的标准头文件 说明: 使用C++的标准头文件时,请使用``这样的,而不是``这种的。 ### 9.6 const的用法 在声明的变量或参数前加上关键字 const 用于指明变量值不可被篡改 (如 `const int foo` ). 为类中的函数加上 const 限定符表明该函数不会修改类成员变量的状态 (如 `class Foo { int bar(char c) const; };`)。 const 变量, 数据成员, 函数和参数为编译时类型检测增加了一层保障, 便于尽早发现错误。因此, 我们强烈建议在任何可能的情况下使用 const。 有时候,使用C++11的constexpr来定义真正的常量可能更好。 #### 规则9.6.1 对于指针和引用类型的形参,如果是不需要修改的,请使用const 不变的值更易于理解/跟踪和分析,把const作为默认选项,在编译时会对其进行检查,使代码更牢固/更安全。 ```cpp class Foo; void print_foo(const Foo& foo); ``` #### 规则9.6.2 对于不会修改成员变量的成员函数请使用const修饰 尽可能将成员函数声明为 const。 访问函数应该总是 const。只要不修改数据成员的成员函数,都声明为const。 对于虚函数,应当从设计意图上考虑继承链上的所有类是否需要在此虚函数中修改数据成员,而不是仅关注单个类的实现。 ```cpp class Foo { public: // ... void print_value() const // const修饰成员函数,不会修改成员变量 { std::cout << Value << std::endl; } int get_value() const // const修饰成员函数,不会修改成员变量 { return Value; } private: int Value; }; ``` #### 建议9.6.1 初始化后不会再修改的成员变量定义为const ```cpp class Foo { public: Foo(int length) : DataLength(length) {} private: const int DataLength; }; ``` ### 9.7 异常 #### 建议9.7.1 C++11中,如果函数不会抛出异常,声明为`noexcept` **理由** 1. 如果函数不会抛出异常,声明为`noexcept`可以让编译器最大程度的优化函数,如减少执行路径,提高错误退出的效率。 2. `vector`等STL容器,为了保证接口的健壮性,如果保存元素的`move运算符`没有声明为`noexcept`,则在容器扩张搬移元素时不会使用`move机制`,而使用`copy机制`,带来性能损失的风险。如果一个函数不能抛出异常,或者一个程序并没有截获某个函数所抛出的异常并进行处理,那么这个函数可以用新的`noexcept`关键字对其进行修饰,表示这个函数不会抛出异常或者抛出的异常不会被截获并处理。例如: ```cpp extern "C" double sqrt(double) noexcept; // 永远不会抛出异常 // 即使可能抛出异常,也可以使用 noexcept // 这里不准备处理内存耗尽的异常,简单地将函数声明为noexcept std::vector my_computation(const std::vector& v) noexcept { std::vector res = v; // 可能会抛出异常 // do something return res; } ``` > [!WARNING]注意 > 若 `noexcept` 函数确实抛出异常(例如上面示例中内存分配失败),程序会直接调用 `std::terminate` 终止,调用方无法捕获或处理。因此仅在确认函数不会抛出异常(或异常确实无法处理)时才声明为 `noexcept`,切勿对可能抛异常且需要处理异常的函数随意标注。 **示例** ```cpp RetType function(Type params) noexcept; // 最大的优化 RetType function(Type params); // 更少的优化 // std::vector 的 move 操作需要声明 noexcept class Foo1 { public: Foo1(Foo1&& other); // no noexcept }; std::vector a1; a1.push_back(Foo1()); a1.push_back(Foo1()); // 触发容器扩张,搬移已有元素时调用copy constructor class Foo2 { public: Foo2(Foo2&& other) noexcept; }; std::vector a2; a2.push_back(Foo2()); a2.push_back(Foo2()); // 触发容器扩张,搬移已有元素时调用move constructor ``` **注意** 默认构造函数、析构函数、`swap`函数,`move操作符`都不应该抛出异常。 ### 9.8 宏 在C++语言中,我们强烈建议尽可能少使用复杂的宏 - 对于常量定义,请按照前面章节所述,使用const或者枚举; - 禁止使用函数式宏,优先使用内联函数,模板函数等进行替换。 ```cpp // 不推荐使用函数式宏 #define MULTIPLY(a, b) ((a) * (b)) // 请使用模板函数,内联函数等来替换。 template T multiply(T a, T b) { return a * b; } ``` **例外**:一些通用且成熟的应用,如:对 new, delete 的封装处理,可以保留对宏的使用。 ## 10 现代C++特性 随着 ISO 在2011年发布 C++11 语言标准,以及2017年12月发布 C++17(ISO/IEC 14882:2017),现代C++(C++11/14/17等)增加了大量提高编程效率、代码质量的新语言特性和标准库。 本章节描述了一些可以帮助团队更有效率的使用现代C++,规避语言陷阱的指导意见。 ### 10.1 代码简洁性和安全性提升 #### 建议10.1.1 合理使用`auto` **理由** * `auto`可以避免编写冗长、重复的类型名,也可以保证定义变量时初始化。 * `auto`类型推导规则复杂,需要仔细理解。 * 如果能够使代码更清晰,继续使用明确的类型,且只在局部变量使用`auto`。 **示例** ```cpp // 避免冗长的类型名 std::map::iterator iter = m.find(val); ``` ```cpp // 使用 auto 避免冗长的类型名 auto iter = m.find(val); ``` ```cpp // 避免重复类型名 class Foo {...}; Foo* p = new Foo; ``` ```cpp // 使用 auto 避免重复类型名 auto p = new Foo; ``` ```cpp // 普通变量可以不初始化 int x; ``` ```cpp // auto 定义的变量必须初始化,否则编译失败 auto x; ``` auto 的类型推导可能导致困惑: ```cpp auto a = 3; // int const auto ca = a; // const int const auto& ra = a; // const int& auto aa = ca; // int, 忽略 const 和 reference auto ila1 = { 10 }; // std::initializer_list auto ila2{ 10 }; // int(C++17起,单元素直接列表初始化推导为int) auto&& ura1 = x; // int& auto&& ura2 = ca; // const int& auto&& ura3 = 10; // int&& const int b[10] = {0}; auto arr1 = b; // const int* auto& arr2 = b; // const int(&)[10] ``` 如果没有注意 `auto` 类型推导时忽略引用,可能引入难以发现的性能问题: ```cpp std::vector v; auto s1 = v[0]; // auto 推导为 std::string,拷贝 v[0] ``` 如果使用`auto`定义接口,如头文件中的常量,可能因为开发人员修改了值,而导致类型发生变化。 #### 规则10.1.1 在重写虚函数时请使用`override`或`final`关键字 **理由** `override`和`final`关键字都能保证函数是虚函数,且重写了基类的虚函数。如果子类函数与基类函数原型不一致,则产生编译告警。`final`还保证虚函数不会再被子类重写。 使用`override`或`final`关键字后,如果修改了基类虚函数原型,但忘记修改子类重写的虚函数,在编译期就可以发现。也可以避免有多个子类时,重写虚函数的修改遗漏。 **示例** ```cpp class Base { public: virtual void foo(); virtual void foo(int var); void bar(); }; class Derived : public Base { public: void foo() const override; // 编译失败: Derived::foo 和 Base::foo 原型不一致,不是重写 void foo() override; // 正确: Derived::foo 重写 Base::foo void foo(int var) final; // 正确: Derived::foo(int) 重写 Base::foo(int),且Derived的派生类不能再重写此函数 void bar() override; // 编译失败: Base::bar 不是虚函数 }; ``` **总结** 1. 基类首次定义虚函数,使用`virtual`关键字 2. 子类重写基类虚函数(包括析构函数),使用`override`或`final`关键字(但不要两者一起使用),并且不使用`virtual`关键字 3. 非虚函数,`virtual`、`override`和`final`都不使用 #### 规则10.1.2 使用`delete`关键字删除函数 **理由** 相比于将类成员函数声明为`private`但不实现,`delete`关键字更明确,且适用范围更广。 **示例** ```cpp class Foo { private: // 只看头文件不知道拷贝构造是否被删除 Foo(const Foo&); }; class Foo { public: // 明确删除拷贝赋值函数 Foo& operator=(const Foo&) = delete; }; ``` `delete`关键字还支持删除非成员函数 ```cpp template void process(T value); template <> void process(void) = delete; ``` #### 规则10.1.3 使用`nullptr`,而不是`NULL`或`0` **理由** 长期以来,C++没有一个代表空指针的关键字,这是一件很尴尬的事: ```cpp #define NULL ((void *)0) char* str = NULL; // 错误: void* 不能自动转换为 char* void(C::*pmf)() = &C::func; if (pmf == NULL) { // 错误: void* 不能自动转换为指向成员函数的指针 } ``` 如果把`NULL`定义为`0`或`0L`,可以解决上面的问题。 或者在需要空指针的地方直接使用`0`。但这引入另一个问题,代码不清晰,特别是使用`auto`自动推导: ```cpp auto result = find(id); if (result == 0) { // find() 返回的是 指针 还是 整数? // do something } ``` `0`字面上是`int`类型(`0L`是`long`),所以`NULL`和`0`都不是指针类型。 当重载指针和整数类型的函数时,传递`NULL`或`0`都调用到整数类型重载的函数: ```cpp void f(int); void f(int*); f(0); // 调用 f(int),而非 f(int*) f(NULL); // 调用 f(int),而非 f(int*) ``` 另外,`sizeof(NULL) == sizeof(void*)`并不一定总是成立的,这也是一个潜在的风险。 总结: 直接使用`0`或`0L`,代码不清晰,且无法做到类型安全;使用`NULL`无法做到类型安全。这些都是潜在的风险。 `nullptr`的优势不仅仅是在字面上代表了空指针,使代码清晰,而且它不再是一个整数类型。 `nullptr`是`std::nullptr_t`类型,而`std::nullptr_t`可以隐式的转换为所有的原始指针类型,这使得`nullptr`可以表现成指向任意类型的空指针。 ```cpp void f(int); void f(int*); f(nullptr); // 调用 f(int*) auto result = find(id); if (result == nullptr) { // find() 返回的是 指针 // do something } ``` #### 规则10.1.4 使用`using`而非`typedef` 在`C++11`之前,可以通过`typedef`定义类型的别名。没人愿意多次重复`std::map>`这样的代码。 ```cpp typedef std::map> SomeType; ``` 类型的别名实际是对类型的封装。而通过封装,可以让代码更清晰,同时在很大程度上避免类型变化带来的散弹式修改。 在`C++11`之后,提供`using`,实现`声明别名(alias declarations)`: ```cpp using SomeType = std::map>; ``` 对比两者的格式: ```cpp typedef Type Alias; // Type 在前,还是 Alias 在前 using Alias = Type; // 符合'赋值'的用法,容易理解,不易出错 ``` 如果觉得这点还不足以切换到`using`,我们接着看看`模板别名(alias template)`: ```cpp // 定义模板的别名,一行代码 template using MyAllocatorVector = std::vector>; MyAllocatorVector data; // 使用 using 定义的别名 template class MyClass { private: MyAllocatorVector Data; // 模板类中使用 using 定义的别名 }; ``` 而`typedef`不支持带模板参数的别名,只能"曲线救国": ```cpp // 通过模板包装 typedef,需要实现一个模板类 template struct MyAllocatorVector { typedef std::vector> type; }; MyAllocatorVector::type data; // 使用 typedef 定义的别名,多写 ::type template class MyClass { private: typename MyAllocatorVector::type Data; // 模板类中使用,除了 ::type,还需要加上 typename }; ``` #### 规则10.1.5 禁止使用std::move操作const对象 从字面上看,`std::move`的意思是要移动一个对象。而const对象是不允许修改的,自然也无法移动。因此用`std::move`操作const对象会给代码阅读者带来困惑。 在实际功能上,`std::move`会把对象转换成右值引用类型;对于const对象,会将其转换成const的右值引用。由于极少有类型会定义以const右值引用为参数的移动构造函数和移动赋值操作符,因此代码实际功能往往退化成了对象拷贝而不是对象移动,带来了性能上的损失。 **错误示例:** ```cpp std::string g_string; std::vector g_string_list; void func() { const std::string my_string = "String content"; g_string = std::move(my_string); // bad:并没有移动my_string,而是进行了复制 const std::string another_string = "Another string content"; g_string_list.push_back(std::move(another_string)); // bad:并没有移动another_string,而是进行了复制 } ``` ### 10.2 智能指针 #### 规则10.2.1 拥有所有权的类成员应使用`std::unique_ptr`或`std::shared_ptr`管理,仅借用时使用原始指针 **理由** `std::unique_ptr`独占所有权、`std::shared_ptr`共享所有权,都会在生命周期结束时自动释放资源,避免显式`new`/`delete`导致的内存泄露。仅在明确不拥有对象(借用/观察)时,才使用原始指针或引用。 对于单例、类成员等明确拥有所有权的场景,应优先使用`std::unique_ptr`(配合`std::make_unique`创建)管理资源,而不是裸指针加手动`delete`。 **示例** ```cpp class Foo; class Base { public: Base() = default; virtual ~Base() = default; private: std::unique_ptr FooPtr{}; }; ``` **例外** 1. 返回创建的对象时,需要自定义销毁函数的,可以使用智能指针。 ```cpp class User; class Foo { public: // 自定义 deleter 时,deleter 类型应为函数指针 void(*)(User*) std::unique_ptr create_unique_user() { User* user = new User(); return std::unique_ptr(user, [](User *u) { u->close(); delete u; }); } std::shared_ptr create_shared_user() // 返回创建的对象,供多方引用 { return std::make_shared(); } }; ``` 2. 返回创建的对象且对象需要被多方引用时,可以使用shared_ptr。 #### 规则10.2.2 使用`std::make_unique`而不是`new`创建`unique_ptr` **理由** 1. `make_unique`提供了更简洁的创建方式 2. 保证了复杂表达式的异常安全 **示例** ```cpp // 不好:两次出现 MyClass,重复导致不一致风险 std::unique_ptr ptr(new MyClass(0, 1)); // 好:只出现一次 MyClass,不存在不一致的可能 auto ptr = std::make_unique(0, 1); ``` 重复出现类型可能导致非常严重的问题,且很难发现: ```cpp // 编译正确,但new和delete不配套 std::unique_ptr ptr(new uint8_t[10]); std::unique_ptr ptr2(new uint8_t); // 非异常安全: 编译器可能按如下顺序计算参数: // 1. 分配 Foo 的内存, // 2. 构造 Foo, // 3. 调用 bar, // 4. 构造 unique_ptr. // 如果 bar 抛出异常, Foo 不会被销毁,产生内存泄露。 f(unique_ptr(new Foo()), bar()); // 异常安全: 调用函数不会被打断. f(make_unique(), bar()); ``` **例外** `std::make_unique`不支持自定义`deleter`。 在需要自定义`deleter`的场景,建议在自己的命名空间实现定制版本的`make_unique`。 使用`new`创建自定义`deleter`的`unique_ptr`是最后的选择。 #### 规则10.2.3 使用`std::make_shared`而不是`new`创建`shared_ptr` **理由** 使用`std::make_shared`除了类似`std::make_unique`一致性等原因外,还有性能的因素。 `std::shared_ptr`管理两个实体: * 控制块(存储引用计数,`deleter`等) * 管理对象 `std::make_shared`创建`std::shared_ptr`,会一次性在堆上分配足够容纳控制块和管理对象的内存。而使用`std::shared_ptr(new MyClass)`创建`std::shared_ptr`,除了`new MyClass`会触发一次堆分配外,`std::shared_ptr`的构造函数还会触发第二次堆分配,产生额外的开销。 **例外** 类似`std::make_unique`,`std::make_shared`不支持定制`deleter` ### 10.3 Lambda #### 建议10.3.1 需要捕获局部变量或编写局部函数时,使用`lambda` **理由** 函数无法捕获局部变量或在局部范围内声明;如果需要这些东西,尽可能选择`lambda`,而不是手写的`functor`。 另一方面,`lambda`和`functor`不会重载;如果需要重载,则使用函数。 如果`lambda`和函数都可以的场景,则优先使用函数;尽可能使用最简单的工具。 **示例** ```cpp // 编写一个只接受 int 或 string 的函数 // -- 重载是自然的选择 void f(int); void f(const string&); // 需要捕获局部状态,或出现在语句或表达式范围 // -- lambda 是自然的选择 vector v = lots_of_work(); for (int task_num = 0; task_num < max; ++task_num) { pool.run([task_num, &v] { ... }); } pool.join(); ``` #### 规则10.3.1 当`lambda`会逃逸出函数外面时,禁止按引用捕获局部变量 **理由** 非局部范围使用`lambda`包括返回值,存储在堆上,或者传递给其它线程。局部的指针和引用不应该在它们的范围外存在。`lambda`按引用捕获就是把局部对象的引用存储起来。如果这会导致超过局部变量生命周期的引用存在,则不应该按引用捕获。 **示例** ```cpp // 不好 void foo() { int local = 42; // 按引用捕获 local. // 当函数返回后,local 不再存在, // 因此 process() 的行为未定义! thread_pool.queue_work([&] { process(local); }); } // 好 void foo() { int local = 42; // 按值捕获 local。 // 因为拷贝,process() 调用过程中,local 总是有效的 thread_pool.queue_work([local] { process(local); }); } ``` #### 建议10.3.2 如果捕获`this`,则显式捕获所有变量 **理由** 在成员函数中的`[=]`看起来是按值捕获。但因为是隐式的按值获取了`this`指针,并能够操作所有成员变量,数据成员实际是按引用捕获的,一般情况下建议避免。如果的确需要这样做,明确写出对`this`的捕获。 **示例** ```cpp class MyClass { public: void foo() { int i = 0; auto lambda = [=]() { // 不好: 看起来像是拷贝/按值捕获,成员变量实际上是按引用捕获 use(i, Data); }; Data = 42; lambda(); // 调用 use(42); Data = 43; lambda(); // 调用 use(43); auto lambda2 = [i, this]() { // 好,显式指定按值捕获,最明确,最少的混淆 use(i, Data); }; } private: int Data = 0; }; ``` #### 建议10.3.3 避免使用默认捕获模式 **理由** lambda表达式提供了两种默认捕获模式:按引用(&)和按值(=)。 默认按引用捕获会隐式的捕获所有局部变量的引用,容易导致访问悬空引用。相比之下,显式的写出需要捕获的变量可以更容易的检查对象生命周期,减小犯错可能。 默认按值捕获会隐式的捕获this指针,且难以看出lambda函数所依赖的变量是哪些。如果存在静态变量,还会让阅读者误以为lambda拷贝了一份静态变量。 因此,通常应当明确写出lambda需要捕获的变量,而不是使用默认捕获模式。 **错误示例** ```cpp auto func() { int addend = 5; static int base_value = 3; return [=]() { // 实际上只复制了addend ++base_value; // 修改会影响静态变量的值 return base_value + addend; }; } ``` **正确示例** ```cpp auto func() { int addend = 5; static int base_value = 3; return [addend, base_value = base_value]() mutable { // 使用C++14的捕获初始化拷贝一份变量 ++base_value; // 修改自己的拷贝,不会影响静态变量的值 return base_value + addend; }; } ``` 参考:《Effective Modern C++》:Item 31: Avoid default capture modes. ### 10.4 接口 #### 建议10.4.1 不涉及所有权的场景,使用`T*`或`T&`作为参数,而不是智能指针 **理由** 1. 只在需要明确所有权机制时,才通过智能指针转移或共享所有权. 2. 通过智能指针传递,限制了函数调用者必须使用智能指针(如调用者希望传递`this`)。 3. 传递共享所有权的智能指针存在运行时的开销。 **示例** ```cpp // 接受任何 int* void f(int*); // 只能接受希望转移所有权的 int void g(unique_ptr); // 只能接受希望共享所有权的 int void g(shared_ptr); // 不改变所有权,但需要特定所有权的调用者 void h(const unique_ptr&); // 接受任何 int void h(int&); // 不好 void f(shared_ptr& w) { // ... use(*w); // 只使用 w -- 完全不涉及生命周期管理 // ... } ``` --- # openUBMC社区通用编码规范 > URL: https://openubmc.cn/docs/zh/latest/contributing/code_submission/encoding_spec/general_coding_standards.html > Language: zh # openUBMC社区通用编码规范 ## 1 概述 --- - 本规范适用于openUBMC社区代码开发,目的是引导社区开发者养成良好的编程习惯,编写出风格统一、容易阅读、安全可靠的代码 - 本规范同样适用于指导openUBMC社区门禁和工具开发 ## 2 代码风格 --- ### 2.1 命名 #### P.01 标识符的命名遵循阅读习惯 符合英文阅读习惯的命名将明显提高代码可读性。命名贴近英文语法,使代码更容易阅读 ```lua 【正例】 if found then ... end 【反例】 if is_found then ... end ``` #### P.02 变量命名尽量简短,前提是不影响阅读理解 变量应在其作用域中无二义性,在不影响阅读理解的前提下,命名应该尽量简短 ```lua 【正例】 local function print_error_msg() local msg ... end 【反例】 local function print_error_msg() local error_msg ... end ``` #### G.NAM.B01 标识符满足openUBMC标识符命名规范 结合openUBMC的业务特点和现状,针对Lua语言的标识符命名制定了如下规范: 表1.1 openUBMC Lua语言标识符命名规范 | 类别 | 规定命名风格 | 正确示例 | | ----------- |------------------ | --------------------------------------------------| | 仓库名 | snake_case风格 | libmc_lua | | 组件名 | snake_case风格 | key_mgmt | | 文件 | snake_case风格 | project_file.lua | | 模块 | snake_case风格 | local module_name = {} | | 类 | snake_case风格 | local class_name = {} | | RPC方法 | 大驼峰风格 | function module_name:SetName() | | RPC方法参数 | 大驼峰风格 | function module_name:SetName(ExampleName) | | 函数 | snake_case风格 | local function func_name() | | 全局变量 | snake_case风格 | var_name = 0 | | 局部变量 | snake_case风格 | local var_name = 0 | | 函数参数 | snake_case风格 | local function set_name(example_name) | | 常量 | 全大写,下划线分割 | local DEFAULT_PORT = 8080 | | 枚举类型 | snake_case风格 | local enum_name = {} | | 枚举值 | 全大写,下划线分割 | local enum_name = { MODE_RED = 0, MODE_GREEN = 1 }| | 表名 | snake_case风格 | local table_name = {} | | 表索引 | snake_case风格 | local table_name = { table_index = 'example' } | 注:表中未包含的其他标识符命名,建议统一使用snake_case #### G.NAM.B02 函数和参数的命名能够正确描述功能 - 命名被认为是软件开发过程中最困难,也是最重要的事情之一 - 符号命名要简洁、准确,符合阅读习惯,容易理解 #### G.NAM.B03 标识符拼写正确,符合通用习惯缩写 表1.2 常用英文缩写对照表 |完整单词|缩写|完整单词|缩写|完整单词|缩写|完整单词|缩写| |---|---|---|---|---|---|---|---| |action|act|address|addr|argument|arg|asynchronous|async| |attribute|attr|average|avg|buffer|buf|calculate|calc| |class|cls|column|col|command|cmd|compare|cmp| |configuration|cfg|context|ctx|control|ctrl|count|cnt| |current|cur|decrease|dec|define|def|delete|del| |descriptor|desc|destination|dest|directory|dir|division|div| |document|doc|driver|drv|environment|env|error|err| |ethernet|eth|execute|exec|expression|expr|frequency|freq| |function|func|generate|gen|hexdecimal|hex|identification|id| |image|img|increase|inc|index|idx|information|info| |initial|init|interface|intf|length|len|library|lib| |management|mgmt|maximum|max|message|msg|minimum|min| |module|mod|multiple|multi|number|num|object|obj| |package|pkg|parameter|param|password|pwd|physical|phy| |pointer|ptr|position|pos|previous|prev|process|proc| |public|pub|receive|rcv|reference|ref|register|reg| |repository|repo|response|resp|result|ret|second|sec| |sequence|seq|serial number|sn|source|src|standard|std| |string|str|synchronize|sync|system|sys|temperature|temp| |temporary|tmp|value|val|variable|var|vector|vec| |version|ver|voltage|volt||||| ### 2.2 注释 #### P.03 注释跟代码一样重要,应按需注释 #### G.CMT.B01 较为晦涩的代码、特殊处理场景代码要尽量详尽的进行注释 - ​ 难理解的代码,建议在注释中简述相关知识说明,比如增加协议字段格式、自定义配置文件格式等方便理解代码处理逻辑 - ​ 代码中的特殊处理,尽量介绍清楚背景、业务场景、处理逻辑等;也可以在README中增加功能详细说明 - ​ 当需要规避周边组件(硬件、开源第三方软件等)的问题时,必须添加注释并且注明规避背景、规避原因和影响范围 ## 3 编程实践 --- ### 3.1 表 #### P.04 禁止弱引用表与__gc元方法混用 - openUBMC基于LuaJIT开发,LuaJIT只完全兼容Lua 5.1。当弱引用表与__gc元方法混用时可能会引发无法预期的错误 ```lua 【反例】 local table_a = setmetatable({}, {__mode = 'kv', __gc = function() ... end}) -- Bad, 弱引用表与__gc元方法混用 ``` #### G.TBL.B01 Lua 表不支持直接比较,需要比较所有的Key和Value是否相同 可以使用框架`utils.table_compare`库函数完成Lua 表的比较 ```lua 【反例】 local table_a = {} local table_b = {} ... if table_a == {} then -- Bad ... end if table_a == table_b then -- Bad ... end 【正例】 local table_a = {} local table_b = {} ... if utils.table_compare(table_a, {}) then -- Good ... end if utils.table_compare(table_a, table_b) then -- Good ... end if next(table_a) == nil then -- Good ... end ``` #### G.TBL.B02 表使用的时候需要保证先构造成员变量然后使用,避免多线程下出现访问nil ```lua 【反例】 -- 线程一 local value = { ['Type'] = 'ABC' } -- 线程二 -- 可能先于线程一执行,value.Type为nil导致程序抛错 table_a[value.Type] = 1 【正例】 -- 划分到同一个线程先后执行,保证成员变量已构造 local value = { ['Type'] = 'ABC' } table_a[value.Type] = 1 ``` #### G.TBL.B03 使用ipairs有序遍历数组,使用pairs遍历不连续的数组 - 不论遍历的是数组还是字典,pairs均不保证遍历的顺序,它依赖于表内部的哈希实现。 - 要有序遍历数组,使用ipairs遍历。这里的有序是指从下标1开始依次访问,下标必须连续。table的键值如果包含字母则不属于数组的范畴,更谈不上有序。 - 要完整遍历不连续的数组,使用pairs遍历 ```lua 【反例】 local a = { 1, 2, 3, 4, 5 } for k, v in pairs(a) do print(v) -- Bad, 使用pairs遍历,不保证顺序 end local b = { [1] = '1', ['a'] = 'a' } for k, v in ipairs(b) do print(v) -- Bad, 使用ipairs遍历,未完整遍历所有数据 end 【正例】 local a = {1, 2, 3, 4, 5} for k, v in ipairs(a) do print(v) -- Good, 使用ipairs遍历有序数组 end local b = { [1] = '1', ['a'] = 'a' } for k, v in pairs(b) do print(v) -- Good, 使用pairs遍历所有元素,但不保证顺序 end ``` #### G.TBL.B04 使用#对表取长度应当先确保表是一个序列且未包含其他类型键值 - 如果表的__len元方法没有给出,表的长度只在表是一个序列时有定义 - 序列指表的正数键集等于 {1..n} ```lua 【反例】 local a = { [2] = 1, [3] = 2 } -- Bad,正数健集{2,3},缺少键值1,a不是序列 local b = { [1] = 1, [3] = 2, [4] = 3 } -- Bad,正数键集{1,3,4},键值不连续。禁止对不连续的数组表求长度,结果不可预测 local c = { [-1] = 1, [0] = 2, [1] = 3, [2] = 4, ['s'] = 5 } -- Bad,正数健集{1,2},c是序列,但不推荐使用#取长度,容易误认为其他键值也参与长度计算 【正例】 local d = { [1] = 1, [2] = 2, [3] = 3, } -- Good,正数键集{1,2,3},d是序列,且未包含其他类型键值,#d是预期的3 ``` #### G.TBL.B05 使用remove方法删除表中元素应当先确保表是一个序列且未包含其他类型键值,否则应当使用将元素置为nil的方式删除 - 序列指表的正数键集等于 {1..n} ```lua 【反例】 local a = { [2] = 1, [3] = 2 } table.remove(a, 2) -- Bad,报错bad argument #1 to 'remove' (position out of bounds) 【正例】 local a = { [1] = 1, [2] = 2, [3] = 3 } table.remove(a, 2) -- Good,成功删除键为2的元素,删除后该表为{[1] = 1, [2] = 3} local b = { [2] = 1, [3] = 2 } b[2] = nil -- Good,成功删除键为2的元素,删除后该表为{[3] = 2} ``` _**注意:使用t[i] = nil会导致数组下标不连续,使用table.remove才会自动调整数组下标**_ #### G.TBL.B06 通过pairs遍历表时,循环体中不能同时对表做插入和删除操作 ```lua 【反例】 local a = { 1, 2, 3 } for k, v in pairs(a) do a[k] = nil a[k + 3] = v -- Bad,报错invalid key to 'next' end ``` #### G.TBL.B07 使用Lua弱引用表时确保表外有对变量进行引用,或变量垃圾回收不影响业务功能 - Lua弱引用表(`__mode = 'kv'`或`__mode = 'k'`或`__mode = 'v'`)作为键/值保存在表中的变量不会增加其引用计数,当变量在表外没有被引用时会被垃圾回收 ```lua 【反例】 -- 弱引用表db_objs用来存放db对象 local db_objs = setmetatable({}, {__mode = 'kv'}) function add_db_obj(obj) -- 将需要持久化的obj添加到待持久化的对象列表db_objs中 db_objs[obj] = context.get_context() or context.new() -- 由于db_objs是弱引用表,离开当前函数作用域之后obj可能被垃圾回收 end local function save_all_objs() for obj, ctx in pairs(db_objs) do -- 遍历db_objs时,表中对象可能已经被垃圾回收,造成数据丢失 obj:save() end end 【正例】 -- 弱引用表g_obj_pool的作用是提供缓存池,避免频繁重复创建对象 local g_obj_pool = setmetatable({}, {__mode = 'kv'}) local function new_obj() local obj = table.remove(g_obj_pool) if not obj then -- 表中对象已被垃圾回收时可以重新创建,不影响业务功能 return new_object() end -- 表中对象没有被垃圾回收时可以重复利用,避免频繁创建新对象的消耗 return obj end ``` #### G.TBL.B08 应用插件机制的场景下,推荐使用深拷贝的方式传递table类型参数 - table类型的参数在传入插件处理后,可能会在插件内部被修改。如果该参数后续在组件内需要继续使用,可能会引起异常 - Lua不支持声明const类型的入参,因此推荐使用深拷贝的方式(utils.table_copy)传递table类型参数到插件 ```lua 【反例】 function plugin_method.set_property(parameter) local ok, rsp = pcall(func, parameter) -- Bad,table参数直接传入插件 ... end 【正例】 function plugin_method.set_property(parameter) local input_location = utils.table_copy(parameter) -- Good,深拷贝一份table参数传入插件 local ok, rsp = pcall(func, parameter) ... end ``` #### G.TBL.B09 高频调用场景中禁止通过赋空表的方式实现表的清空 - 赋空表会申请新的内存,在高频调用场景中会导致内存无法及时GC,产生内存碎片,最终导致内存持续增长 - 可以通过两种方式实现:1、依次对表的变量赋nil;2、使用封装的table_cache类 ```lua local table_cache = require 'mc.table_cache' local instance = table_cache.new() -- 实例化 local config = instance:allocate() -- 申请空表 instance:deallocate(config) -- 销毁 ``` ### 3.2 函数 #### G.FUN.B01 信号处理函数应该轻量 - 信号处理函数处理时间过长可能会引起程序非预期结果,使用时应谨慎 - 不允许在信号处理函数中添加延时函数,如skynet.sleep #### G.FUN.B02 循环体中避免定义local变量,放在循环体外定义,可以减少内存申请 ```lua 【反例】 for i = 1, #array do local a a = array[i].number ... end 【正例】 local a for i = 1, #array do a = array[i].number ... end ``` #### G.FUN.B03 使用Lua闭包特性,避免在高频调用函数中申请local变量 - 循环体和高频调用函数中定义`local`变量,会反复申请内存,增加`Lua GC`机制负担,当`GC`无法及时回收时,会导致内存占用持续增加。 #### G.FUN.B04 禁止将_作为函数入参 _作为Lua中的占位符,与其他变量并无区别,默认值为nil,未通过local显式申明的情况下为全局变量。以占位符作为函数入参,可能引起异常 ```lua 【反例】 local res, _ = func(cmd, _, request.data_out) -- Bad, _可能已作为全局变量被赋值 ... function func(cmd, data_in, data_out) if data_in then -- 如果data_in非空,执行额外命令 ... end end 【正例】 local res, _ = func(cmd, nil, request.data_out, nil) -- Good, 直接通过nil占位 ``` ### 3.3 程序块 #### G.CHK.B01 Lua除法运算使用'//'时,结果会向下取整。使用'/'时,结果为浮点数 ```lua 【示例】 local a = 5 / 2 local b = 5 // 2 print('a = ', a) -- 输出为 a = 2.5 print('b = ', b) -- 输出为 b = 2 ``` #### G.CHK.B02 任意基本类型变量都可以进行'=='和'~='比较,但只有数值类型变量可以进行'>'、'<'、'>='、'<='比较 ```lua 【反例】 if a > b then -- a、b为字符串类型 ... end ``` #### G.CHK.B03 Lua中基本数据类型是值类型,table是引用类型。对新的值类型变量赋值不会改变原始值 ```lua -- 错误示例 local flag = table[Id] if flag ~= 0 then ... end flag = 1 -- 对flag赋值不会改变table[Id] ``` #### G.CHK.B04 对变量使用#取长度前,须确保变量为string/table类型或者有__len()元方法 - Lua中string/table类型(特指序列,参见G.TBL.B04说明)对#有定义,非string类型可以通过__len元方法修改取长度的操作行为 ```lua 【反例】 if #v.SRVersion > 0 then -- Bad,未确保变量为table或string类型,程序可能抛错 ... end 【正例】 if type(v.SRVersion) == 'string' and #v.SRVersion > 0 then -- Good,先确保变量为string类型再取长度 ... end ``` #### G.CHK.B05 北向接口Script和Plugin编码时,使用cjson接口保证字典和数组的有序性 - 北向接口通常要求字典和数组的有序性,使用Lua的table默认无序,可能导致接口返回结果不符合预期 - 在北向提供的Sript和Plugin机制中,建议使用框架提供的cjson接口json_object_new_array/json_object_new_object,保证返回结果的有序性 ```lua 【反例】 function get_selLogEntries(processObj) local eventList = processObj.EventList local selLogEntries = {} for i, v in pairs(eventList) do selLogEntries[i] = { -- Bad, 使用Lua的table,无序 ["eventid"] = eventList[i].RecordId, ["subjecttype"] = "TODO", ["eventdesc"] = eventList[i].Description, } end return selLogEntries end 【正例】 function get_selLogEntries(processObj) local eventList = processObj.EventList local selLogEntries = cjson.json_object_new_array() -- Good, 使用cjson接口保证数据的有序性 for i, v in pairs(eventList) do selLogEntries[i] = cjson.json_object_new_object() selLogEntries[i].eventid = eventList[i].RecordId selLogEntries[i].subjecttype = 'TODO' selLogEntries[i].eventdesc = eventList[i].Description end return selLogEntries end ``` #### G.CHK.B06 使用string.find匹配字符串时,应注意plain参数的正确使用 - `string.find`用于在指定的目标字符串中搜索指定的模式,函数的完整声明为`string.find(s, pattern [, init [, plain]])` - `string.find`具有两个可选参数,第3个参数是一个索引,用于说明从目标字符串的哪个位置开始搜索。第4个参数是一个布尔值,用于说明是否进行简单搜索(plain search) - `plain`参数不传时,默认为`false`,表示进行模式匹配,如果传入`true`,则进行简单搜索,使用时应注意是否与实际查询情况相符 - 如果没有第3个参数,则不能传入第4个可选参数 ```lua 【示例】 -- 从uri中匹配文件后缀名.ISO -- plain参数设置为true,表示进行简单搜索,不进行模式匹配,'.'不会被视为特殊字符 -- 如果需要传入第4个参数,第3个参数必须也传入,1表示从第1个字符开始搜索 local start_pos = string.find(uri, '.ISO', 1, true) ``` #### G.CHK.B07 使用字符串匹配时,应注意与标准正则匹配规则的差异 - Lua使用“%”进行转义,而标准正则使用“\”进行转义 - Lua不支持大小写不敏感模式 #### G.CHK.B08 使用字符串变量时,应注意单双引号的使用 - 如果字符串中有双引号,要用单引号包括;如果字符串中有单引号,要用双引号包括 - 字符串不能又包含单引号又包含双引号 #### G.CHK.B09 使用`A and B or C`进行三目运算时,应避免`B`取值为false - 当`B`取值为false时,无论`A`为真或假,三目运算的结果都为`C`,不符合预期 - 针对`B`取值可能为false的场景,使用`if...else`表达式 ```lua 【反例】 local res1 = (val_a == 1) and false or true -- Bad,结果恒为true local res2 = (val_a == 1) and (val_b == 1) or true -- Bad,当不满足val_b == 1时,结果恒为true 【正例】 local res1 = (val_a ~= 1) local res2 if val_a == 1 then res2 = (val_b == 1) else res2 = true end ``` #### G.CHK.B10 不推荐使用Lua的goto语句 - goto将程序的控制点转移到一个标签处,Lua机制会检测跳转到的新作用域内的变量是否全部初始化,如果跳过了初始化则会报错 - 这违反了Lua 5.3+的标签作用域规则(ISO/IEC 2375:2017 §3.3.8),实际执行时将触发"undefined label 'xxx'"错误(Lua 5.3+严格模式) #### G.CHK.B11 资源消耗大的高频日志打印应当先判断日志级别 - 在高频日志打印中如果存在cjson.encode、table.concat等资源消耗大的操作,会对BMC性能造成一定影响 - 可以通过判断当前的日志级别来避免不必要的资源消耗操作 ```lua 【示例】 -- 如果当前日志级别小于INFO,则不会进入分支执行 cjson.encode if log:getLevel() >= log.INFO then log:info('RefVolumes:%s RefDrives:%s.', cjson.encode(array_obj.RefVolumes), cjson.encode(array_obj.RefDrives)) end ``` ### 3.4 多线程 #### G.MTH.B01 openUBMC使用skynet框架,在Lua中创建协程只能使用skynet.fork,禁止使用coroutine - skynet框架消息处理服务使用了Lua的coroutine来调度各个服务处理消息,在skynet框架中的服务应该使用skynet.fork创建子任务,由skynet统一调度。直接使用Lua的coroutine会和skynet框架的coroutine冲突,产生不可预期的结果。 #### G.MTH.B02 使用skynet.wait/skynet.wakeup对协程进行挂起、唤醒操作时,避免中途有其他挂起协程的操作 - 当协程使用`skynet.wait`/`skynet.wakeup`对协程进行挂起、唤醒操作时,假如插入其他挂起协程的操作,如`skynet.sleep`,协程唤醒可能与预期不一致 ```lua 【反例】 function func() local co = coroutine.running() local function check() ... -- 此处的skynet.wakeup可能唤醒的是skynet.sleep挂起的协程,非代码预期情况 skynet.wakeup(co) end -- 创建协程,在协程中唤醒co skynet.fork(check) -- skynet.sleep相当于skynet.wait(),挂起当前协程 skynet.sleep(10) -- 预期在此处挂起和唤醒当前协程 skynet.wait() co = nil end 【正例】 function func() local co = coroutine.running() local function check() ··· -- 唤醒的为skynet.wait()挂起的协程,与预期相符 skynet.wakeup(co) end skynet.fork(function() skynet.fork(check) -- skynet.sleep挂起新协程,不会影响原协程 skynet.sleep(10) end) -- 把创建协程与skynet.sleep的操作放在新协程中,当前skynet.wait()正常挂起 skynet.wait() co = nil end ``` #### G.MTH.B03 禁止在ORM对象中通过skynet创建协程 - ORM(Object Relational Mapping)是openUBMC实现的一种OOP范式。 - 当ORM对象卸载时,通过skynet创建的协程不会跟随对象消亡。如果协程中存在访问对象的行为,可能会导致程序发生异常。 - 可以通过self:next_tick替代skynet创建协程 ```lua 【反例】 function c_network_adapter:set_npu_max_sfp_temp() local ops = c_optical_module.collection:fetch({NetworkAdapterId = self.NodeId}) skynet.fork(function() -- Bad,通过skynet.fork创建协程 while true do self:update_npu_max_sfp_temp(ops) end end) end 【正例】 function c_network_adapter:set_npu_max_sfp_temp() local ops = c_optical_module.collection:fetch({NetworkAdapterId = self.NodeId}) self:next_tick(function() -- Good,通过ORM自带方法创建协程 while true do self:update_npu_max_sfp_temp(ops) end end) end ``` #### G.MTH.B04 避免重复初始化同一个文件锁 - 通过flock函数对某文件加完互斥锁之后,当文件锁被再次初始化时(代码流程可能会重复调用初始化函数),文件描述符会发生变化 - 锁释放时操作的是变化后的文件描述符,文件未成功解锁,当再次加锁时就会导致代码流程死锁 ```c /* 示例 */ int32 db_init(void) { // 确保只初始化一次 if (db_is_inited()) { return RET_OK; } // 初始化文件锁 g_db_lock = open(DB_SYNC_FILE, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); ... } ``` ### 3.5 数据库 #### G.DBS.B01 数据库批量插入数据时,应使用事务机制进行批量提交 - openUBMC使用的sqlite数据库基于B+树结构存储数据,每次插入/删除一条数据时,都可能涉及周边数据节点和上级索引节点的调整,频繁的结构调整导致写入量远大于数据量,实测插入200条数据,数据总大小300KB,写入量会放大到20M。 - 当批量写入数据库操作达到5条及以上时,应该使用事务机制进行批量提交。 - 事务机制由框架`db:tx`回调函数实现,`db:tx`使用sqlite的事务机制,将回调中的所有数据库操作作为一个事务处理, 具体实现为:先执行`BEGIN`,再执行回调函数,如果回调中的数据库操作执行成功,则执行`COMMIT`将修改写入数据库,如果执行失败则执行`ROLLBACK`回滚操作。 - `db:tx()`方法在操作失败时会抛错,建议使用pcall调用。 - 批量操作中如果有一个操作失败会回滚全部操作,建议将相关性强的操作放到一起。 ```lua 【反例】 local_db:delete(local_db['Power']):exec() for _, v in pairs(power_table) do local power_row_data = local_db['Power'](saved_data) power_row_data:save() -- Bad, 在循环中进行数据库插入 end 【正例】 local ok, err = pcall(local_db.db.tx, local_db.db, function () local_db:delete(local_db.Power):exec() for _, v in pairs(power_table) do local_db.Power(v):save() -- Good, 将数据库插入放在事务中执行 end end) ``` #### G.DBS.B02 避免使用枚举类型的属性作为持久化数据库表的主键 - 当枚举类型的属性作为主键时,扩展场景下新增枚举值,当升级新版本并且数据库表中添加了包含新增枚举值的记录,再回退到旧版本,持久化数据加载并校验时会由于找不到新增的枚举值而失败,从而引发兼容性问题 - 建议根据主键实际的数据类型进行定义即可,具有可扩展性和兼容性 ```json 【反例】 "properties": { "Id": { "baseType": "Enum", "$ref": "types.json#/defs/EnumType", "primaryKey": true }, ... } 【正例】 "properties": { "Id": { "baseType": "U8", "primaryKey": true }, ... } ``` #### G.DBS.B03 对于自建数据库,需要有可靠性修复机制,避免业务功能受损 - 此处的自建数据库是指组件内部通过sqlite库指定路径创建的数据库,不同于通过MDS定义由框架创建的数据库 - 数据库完整性校验可通过sqlite命令"PRAGMA quick_check" ```c /* 示例 */ #define SQLITE3_PATH "/usr/sbin/sqlite3" /* DEST_DB_PATH为被校验的数据库路径 */ FILE *ptr = popen(SQLITE3_PATH " " DEST_DB_PATH " \"PRAGMA integrity_check\"", "r"); if (ptr == NULL) { debug_log(DLOG_ERROR, "[%s] excute integrity check failed", __FUNCTION__); return ret; } (void)vos_fgets_s(buf, sizeof(buf) - 1, ptr); if (strncasecmp(buf, "ok", strlen("ok")) == 0) { // 返回ok表示成功,否则都是有问题 ret = RET_OK; } else { debug_log(DLOG_ERROR, "[%s] check failed, buf = %s", __FUNCTION__, buf); } pclose(ptr); return ret; ``` - 数据库修复可通过sqlite命令".dump"先导出历史命令,然后在新创建数据库文件中执行.dump导出的历史sql命令 ```c /* 示例 */ #define SQLITE3_PATH "/usr/sbin/sqlite3" // 导出数据库内容,DEST_DB_PATH为被修复的数据库路径,TEMP_SQL_PATH为导出的历史命令 gint32 ret = snprintf_s(cmd_str, sizeof(cmd_str), sizeof(cmd_str) - 1, "%s %s .dump > %s", SQLITE3_PATH, DEST_DB_PATH, TEMP_SQL_PATH); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = cmd_str; argv[3] = NULL; ret = vos_system_s(argv[0], argv); // 重建一个数据库,TEMP_DB_PATH为重建的临时数据库 ret = snprintf_s(cmd_str, sizeof(cmd_str), sizeof(cmd_str) - 1, "%s %s < %s", SQLITE3_PATH, TEMP_DB_PATH, TEMP_SQL_PATH); ret = vos_system_s(argv[0], argv); // 用重建的数据库替换原来的数据库 (void)vos_file_copy(DEST_DB_PATH, TEMP_DB_PATH); ``` #### G.DBS.B04 禁止变更已持久化的枚举属性的取值范围 - 如果已持久化的枚举属性的取值范围发生变更,BMC版本升降级都可能会出现从数据库中加载未定义的枚举值的场景,此时会由于校验不通过而导致加载失败 - 以下是一个属性示例,该属性为string类型,已通过enum关键字定义了取值范围,并且为掉电持久化 ```json "AuthenticationProtocol": { "baseType": "String", "usage": [ "PoweroffPer" ], "readOnly": false, "enum": [ "SHA256", "SHA512" ] } ``` #### G.DBS.B05 禁止通过路径访问数据库 - 允许通过路径访问数据库则默许了本组件可以访问其他组件管理的数据库,这可能会造成多线程或多进程并行访问数据库的场景,最终导致数据库出现异常 - 开发者应当重新设计代码方案以避免这种场景 ```lua 【错误示例】 -- 以下通过路径直接访问了pcie_device组件的复位持久化数据库,可能会造成数据库异常 local Databases = require 'database' local db = Databases('/opt/bmc/pram/persistence.local/pcie_device.db') local vm = db:prepare(sql_cmd) ``` ### 3.6 其他 #### P.05 禁止使用对象名处理业务流程 - 包括但不限于对象名称比对、对象名分段解析等处理 - 对象名及命名规则无法保证不发生变化,不能作为资源协作接口之间的约束 ```lua 【反例】 -- 截取position后两位做为slot,若sr配置变化,则可能出现功能问题。Slot属性改为在sr配置即可 object.Slot = tonumber(string.sub(position, -2)) ``` #### P.06 合理设计调试打印、日志代码 - 代码中的调试、日志部分,作为问题定位辅助手段,应尽量少,不可以喧宾夺主 - 一个模块尽量只在出入口或异常时记录调试、日志信息,其中间行为过程尽量通过白盒测试保证可靠性 #### G.OTH.B01 日志打印满足openUBMC日志规范要求 ```txt Error:程序运行过程中的错误信息,当前处理必须中止,并向上抛出错误,比如无法连接数据库,解析JSON字符串失败、文件创建失败 Warning:程序运行过程中有负面影响的信息或事件,当前处理还可以继续,但是可能会有更严重的故障发生,比如内存占用率高于指定阈值,某处理过程超过了预期耗时,flash写入量超标等 Notice:程序运行过程中的重要信息或事件,对程序运行没有负面影响,比如收到了某个关键的系统信号/事件,定时任务成功的完成执行、程序开始监听某个端口等 Info:程序运行过程中的一般信息或事件,重要性比Notice级别低,比如某个任务的某个部分完成执行 Debug:程序运行过程的详细信息,比如报文数据,函数调用轨迹(入口、出口)等 ``` #### G.OTH.B02 使用mc.logging库中格式化日志输出函数,格式化符'%d'和'%u'的输出值必须为整型值 ```lua local log = require 'mc.logging' local c = 5 / 2 local d = 5 // 2 log:info('c = %d', c) -- Bad, c = 2.5 程序会抛异常 log:info('d = %d', d) -- Good, d = 2 ``` #### G.OTH.B03 推荐以%s对number类型的变量进行打印,可避免该变量在异常情况下为nil时导致的程序抛错 ```lua 【示例】 log:error('fail count = %s', a) -- a为number类型,即使为nil也能正常运行 ``` #### G.OTH.B04 禁止使用系统时间来计算时间间隔 - 系统时间可能发生跳变(例如从NTP服务器同步时间),会导致时间间隔计算不准确。系统时间只能用于时刻记录。常用获取系统时间的函数如下: | 名称 | 简要说明 | | --------------------------- | ------------------------------------------------ | | vos.vos_get_cur_time_stamp()|对C函数time(0)的封装,单位s | | os.time() |没有入参时,返回系统当前时间 | | utils.time_ms() |对C函数clock_gettime的封装,时钟类型为CLOCK_REALTIME| - 运行时间不会发生跳变,可以用来计算时间间隔。常用获取运行时间的函数如下: | 名称 | 简要说明 | | ----------------- | ----------------------------------- | | vos.vos_tick_get()|基于jiffies计算系统运行时间,单位ms | | skynet.now() |返回当前进程的运行时间,单位0.01s | #### G.OTH.B05 调用C库返回的字符串使用lua_pushlstring替代lua_pushstring,可避免包含0x00的字符串被截断 - `lua_pushstring`:将指针 s 指向的零结尾的字符串压栈 - `lua_pushlstring`:将指针 s 指向的长度为len的字符串压栈,字符串内可以是任意二进制数据,包括零字符 ```C 【反例】 char *s; // 省略部分代码 lua_pushstring(L, s); 【正例】 char *s; // 省略部分代码 lua_pushlstring(L, s, len); // len为数据长度 ``` #### G.OTH.B06 禁止使用0XXX表示8进制数 - Lua不支持像C语言的方式表示8进制数 ```lua 【反例】 utils.chmod(file_path, 0640) 【正例】 utils.chmod(file_path, utils.S_IRUSR | utils.S_IWUSR | utils.S_IRGRP) -- 0640权限 ``` #### G.OTH.B07 禁止对有热插拔场景的csr对象使用单例模式 - 对有热插拔场景的csr对象使用单例模式,当该对象被卸载之后再次分发时,由于单例对象已被创建过则不会再次创建,此时单例对象里的参数仍为上一次的脏数据,会导致业务代码出现异常。 #### G.OTH.B08 使用skynet.queue队列进行处理时应考虑范围是否合理,避免使用全局队列 - 使用skynet.queue队列控制任务顺序执行时,应注意队列包含的任务范围应尽量小,避免使用全局队列,队列混用时容易导致阻塞时间过长,引发性能问题 ```lua 【反例】 local queue = require 'skynet.queue' local cs = queue() -- 全局队列 local s = class() function s:fun1() cs(funa, ...) end function s:fun2() cs(funb, ...) -- funa和funb共用全局队列,funa的执行也会对funb产生影响;不同的s实例对象之间的funa与funb执行也会互相影响;队列混用容易导致阻塞时间长,引发性能问题 end 【正例】 local queue = require 'skynet.queue' local s = class() function s:ctor() self.cs_a = queue() self.cs_b = queue() -- 不同对象以及不同函数的队列分开声明,避免互相影响 end function s:fun1() self.cs_a(funa, ...) end function s:fun2() self.cs_b(funb, ...) end ``` #### G.OTH.B09 使用sed命令禁止带有硬编码行号 - 原文件行号一旦发生变化,可能导致修改内容错位 - 对于文件内容的修改应当通过查找或者插入文件首/文件尾实现 ```lua 【反例】 self.run("sed -i '12 i\ chown root:root /dev/shm/dbus/.dbus' rundbus.sh") -- Bad,通过行号查找 【正例】 self.run("sed -i '$ i\chown root:root /dev/shm/dbus/.dbus' rundbus.sh") -- Good,基于行尾查找 ``` #### G.OTH.B10 跨skynet服务调用若需要获取执行结果应使用skynet.call而非skynet.send - skynet.call为同步阻塞式调用,执行skynet.call能获取到执行情况及返回值结果 - skynet.send为异步非阻塞式调用,无论目标服务是否存在或是否能执行成功该调用都能执行成功 ```lua 【反例】 local ok, ret = pcall(function () return skynet.send('main', 'lua', 'exec_function', parameter) -- Bad,无论是否存在main服务或exec_function是否执行成功,pcall返回结果恒为true end) 【正例】 local ok, ret = pcall(function () return skynet.call('main', 'lua', 'exec_function', parameter) -- Good,当main服务不存在或exec_function执行异常,pcall能正常捕获,ret也能正常接收到执行返回值 end) ``` ## 4 异常处理 ### 4.1 断言 #### G.AST.B01 正式代码禁止使用断言 **【规则说明】** 通常,断言函数用于评估边界条件并暴露问题,以便在代码中进行定位和修复。断言对于调试很有用。在大多数语言中,断言在代码的发布版本中都是关闭的。在Lua语言中没有明显的调试和发布模式,这意味着程序中的断言会导致错误。除非正确对错误进行处理,否则会出现程序硬退出。下面两个函数都会抛出异常: - `error(message [, level])`:打印出`message`后,会终止程序运行。 - `assert(v [, messafe])`:即`v`是假(`nil`或`false`)时,调用`error`函数,否则返回所有所有参数。其中`message`默认值是`"assertion failed!"` 。 除以下例外场景,其他场合禁止使用`error`和`assert`函数: - 当前错误引擎机制依赖`error`函数,在错误引擎相关代码中可以使用`error`函数抛异常 - 集成测试或单元测试中允许使用error或assert函数 #### G.AST.B02 使用pcall或xpcall来调用可能抛异常的函数 **【规则说明】** 一些skynet库函数大量使用了`assert`断言,为了避免异常情况下程序退出,应该使用pcall或xpcall来调用这些库函数。例如skynet的socket库和websocket库,均大量使用`assert`断言。 ```lua function socket.read(id, sz) local s = socket_pool[id] assert(s) ... end function websocket.write(id, data, fmt, masking_key) local ws_obj = assert(ws_pool[id]) fmt = fmt or "text" assert(fmt == "text" or fmt == "binary") write_frame(ws_obj, fmt, data, masking_key) end ``` - `pcall(f, arg1, arg2, ...)`:以一种"保护模式"来调用第一个参数,能够捕获执行中的任何错误。 - `xpcall(f, msgh, arg1, arg2, ...)`:相比`pcall`增加了一个msgh参数,作为错误处理回调函数。 #### G.AST.B03 函数的异常处理不能混用return和抛异常两种方法 - 函数的异常处理要么使用return来返回异常状态;要么使用error错误引擎抛出错误。不可两种方法混用,容易导致接口使用错误。 ## 5 SR配置 ### 5.1 字符串操作 #### G.SR.STR.B01 string.format的参数不允许使用表达式 SR语法限制。当string.format的参数为表达式时,不返回表达式的结果 ```lua 【反例】 "Name": "${Slot} |> string.format('Cpu%sChannel0', $1 * 2)" -- Bad, string.format的参数使用了表达式。若${Slot}为1,结果为"Cpu1 * 2Channel0" 【正例】 "Name": "${Slot} |> expr($1 * 2) |> string.format('Cpu%sChannel0', $1)" -- Good, 将表达式的结果作为string.format的参数。若${Slot}为1,结果为"Cpu2Channel0" ``` --- # openUBMC社区安全编码规范 > URL: https://openubmc.cn/docs/zh/latest/contributing/code_submission/encoding_spec/secure_coding_standards.html > Language: zh # openUBMC社区安全编码规范 **概念解释** 【**提权**】:安全常用术语,一个用户能通过某种非预期的方式,突破该用户的权限设计,完成正常情况下无法完成的某些操作,就称为**提权**。 【**外部输入**】:来自进程之外的数据就称为外部输入,包括: - 文件(包括data分区的程序配置文件); - 注册表; - 网络报文和北向接口; - 环境变量; - 命令行输入; - 用户态数据(对于内核程序而言); - 进程间通信(包括管道、消息队列、socket、RPC等); - 函数参数(对于全局API而言); - 来自硬件的数据(如芯片寄存器,PMBus/SMBus/MCTP接收的数据等)。 【**外部可控**】:安全常用术语,是指能够被外部用户控制其数据内容的外部输入。外部可控分成以下两种,我们在编码时都需要考虑: - 直接外部可控:数据本身是直接来自外部用户的某种输入,例如来自接口调用、网络报文等; - 间接外部可控:外部用户无法直接控制数据内容,但是通过利用其他安全漏洞之后,就能够间接修改数据内容,这种称为间接外部可控。例如`/etc/passwd`文件内容不是外部用户可以直接输入的,但是当软件存在任意文件写漏洞时,攻击者就可以控制`/etc/passwd`文件的内容,因此间接外部可控也存在潜在的风险。 **【skynet】**:一种轻量级开源服务端框架,当前openUBMC主要基于skynet框架进行组件app开发。 ## 1 公共原则 ### P.SEC.B01 禁止组件自行封装私有安全检查函数 **【规则说明】** 安全检查函数,如检查文件路径、检查shell命令注入字符等,具有一定的专业性,组件自己封装,容易出现场景遗漏等问题,也不利于长期维护。因此各组件应该优先使用框架提供的公共安全检查函数(详见G.SEC.FIL.B02),如果识别到框架能力不满足,则应向社区反馈需求。 ## 2 注入缺陷 注入缺陷包括很多种类型,包括命令注入、代码注入、SQL注入、日志注入等,对系统安全的威胁非常大,可能造成任意指令执行、提权、信息泄露等。其漏洞原理是很多文本型语言的控制字符和数据字符混合在一起,并且控制字符成对出现,攻击者如果能够输入任意字符,他就能够输入控制字符闭合开发者的控制字符,再插入攻击者的语法注入恶意语句。 ### G.SEC.INJ.B01 禁止使用os.execute、io.popen函数 **【规则说明】** 使用os.execute、io.popen函数执行shell命令会出现概率性进程卡死的问题,因此openUBMC禁止使用这两个函数。在需要执行某个shell命令的场景,优先看是否可以直接使用C库函数(例如调用C库chmod函数来替代Linux chmod命令)来实现,如果不能,应该使用`vos.system_s`函数来执行shell命令。 **【案例一】** ```lua -- 错误示例,使用os.execute可能导致进程卡死 os.execute('cp /tmp/config.json /dev/shm/config.json') -- 正确示例,使用vos.system_s执行shell命令 vos.system_s('/bin/cp', '/tmp/config.json', '/dev/shm/config.json') ``` ### G.SEC.INJ.B02 以/bin/sh或者/bin/bash作为命令解释器时,需要对vos.system_s函数进行命令注入参数检查 **【规则说明】** `vos.system_s`是openUBMC封装的供Lua程序调用的C函数库。如果该函数指定的命令解释器(即函数的第一个参数)是`/bin/sh`或者`/bin/bash`则存在命令注入风险,则需要对命令参数进行命令注入检查,框架已经提供公共检查函数`check_shell_special_character_s`。 **【例外项】** 如果`vos.system_s`函数的参数均为硬编码,不包括可能是外部输入的内容,则可以不校验。 **【案例一】** ```lua -- 错误示例: vos.system_s('/bin/sh', '-c', 'cp', src_dir, '/tmp/test') -- 假设src_dir是外部输入 -- 正确示例: 不使用/bin/sh作为命令解释器 vos.system_s('/bin/cp', src_dir, 'dest_dir') -- 假设src_dir是外部输入 -- 正确示例:使用/bin/sh作为命令解释器,但是有对参数进行校验 local utils_file = require 'utils.file' if utils_file.check_shell_special_character_s(src_dir) ~= 0 then return end vos.system_s('/bin/sh', '-c', 'cp', src_dir, '/tmp/test') -- 假设src_dir是外部输入 ``` ### G.SEC.INJ.B03 执行shell命令时,查找、匹配等操作条件要精准 **【规则说明】** 执行shell命令时,对文件、进程、用户等的查找,匹配等操作要按照实际查找对象的类型进行查找,防止存在进程仿冒、用户仿冒等情况出现。 ```c // 错误示例:原始代码, 在满足进程信息包含sshd的情况下,可以构造特殊输入(例如传入'00'),从而杀掉其他sshd进程 snprintf_s(cmd_str, MAX_CMD_LENGTH, MAX_CMD_LENGTH - 1, "ps -ef | grep -w \"%s\" | grep -w sshd | grep -vw \"/usr/sbin/sshd\" | \ cut -c 10-15 | xargs kill -9 > /dev/null 2>&1", escaped_user); // 正确示例:按用户名查找 snprintf_s(cmd_str, MAX_CMD_LENGTH, MAX_CMD_LENGTH - 1, "ps -ef | grep -w sshd |awk '{print $2,$9}'|grep -w \'%s\' |awk '{print $1}'| \ xargs kill -9 > /dev/null 2>&1", escaped_user); ``` ### G.SEC.INJ.B04 外部输入作为require、load、loadfile、dofile、loadstring等函数参数时,需要进行白名单校验 **【规则说明】** `require`、`load`、`loadfile`、`dofile`、`loadstring`等函数可以执行指定路径代码文件或指定字符串的代码块,存在代码注入风险,严禁将可能包含外部输入的数据直接作为这些函数的参数。如果必须使用,应该对参数进行白名单校验,确保执行内容安全可控。以下是Lua语言中存在代码注入风险的危险函数介绍。 ```lua require - 原型:require([modulename]) - 解释:用于加载一个模块代码,如果代码文件是一个代码块,则会执行该代码库。require会搜索目录加载文件,并且会判断是否文件已经加载避免重复加载同一文件 。 load - 原型:load (chunk [, chunkname [, mode [, env]]]) - 解释:load实现Lua 的反射机制,加载一个代码块,如果chunk是一个字符串,代码块就是这个字符串,chunk也可以是一个函数,通过函数调用获取代码块。如果chunk是一个字符串,且外部可控的话则存在安全风险,攻击者可以通过控制chunk导致一个代码注入。 loadfile - 原型:loadfile ([filename [, mode [, env]]]) - 解释:通load相似,只是代码块是从文件中获取,如果文件内容可以外部控制,仍然存在代码注入风险。 dofile - 原型:dofile([filename]) - 解释:加载文件中的代码,如果filename可控,则可以通过新增一个Lua脚本,将filename指定到新增脚本实现代码注入,如果文件内容可控则可以直接修改文件内容,导致代码注入问题。 loadstring - 原型:loadstring(string [,chunkname]) - 解释:函数会从所给的字符串中来加载程序块并运行,如果省略参数`chunkname`,那么它默认为所给的字符串。 ``` ### G.SEC.INJ.B05 执行自定义SQL语句需要进行预编译 **【规则说明】** 某些复杂数据库操作,无法通过libmc封装的简单接口,如`select`、`update`、`insert`来完成,需要使`exec`函数执行自定义的SQL语句。如果这些自定义的SQL拼接了外部输入,则存在SQL注入的风险,预编译可以有效消除此风险。 **【例外项】** 如果自定义SQL语句是硬编码,不存在外部输入的内容,则可以不进行预编译。 ```lua -- 错误示例:自定义SQL语句未进行预编译,存在SQL注入风险 local cmd = 'select * from tb_test where level = ' .. level -- 假设level是外部输入 db:exec(cmd) -- 正确示例 local cmd = 'select * from tb_test where level = ?' local vm = db:prepare(cmd) -- 通过框架封装的prepare函数执行预编译 vm:bind_values(level) vm:step() vm:finalize() ``` ### G.SEC.INJ.B06 在通过字符串拼装Lua脚本进行执行的场景,需要在check_shell_special_character_s的检查后根据脚本场景额外校验特殊字符 【规则说明】 在如worker机制中通过字符串拼装Lua脚本进行执行的场景,还需根据该脚本场景再排除包含可能提前闭环内层函数并注入命令的字符,如“'”、“)”、“ ”(Lua语法中使用空格即可作为命令分隔符,无需使用换行或“;”、“)”) ### G.SEC.INJ.B07 skynet.sleep函数入参必须是整数 【规则说明】 skynet.sleep函数入参必须是整数,如果传入浮点数,会抛出异常 ```lua -- 假设变量ms的单位是毫秒,则: -- 正确示例: skynet.sleep(ms // 10) -- 错误示例: skynet.sleep(ms / 10) ``` ### G.SEC.INJ.B08 使用框架提供的worker模块做线程操作时,禁止使用string.format方式在代码中拼接参数 【规则说明】 使用框架提供的worker模块(local worker = require ‘worker.core’)做线程操作时,禁止使用string.format方式在代码中拼接参数 ```lua 【反例】 -- 正常new_path参数:/var/log/tmp.log。 -- 异常new_path参数:/var/log/tmp.log’);print('hello 异常场景下,会造成任意lua代码攻击 work:start(string.format([[ local file_sec = require 'utils.file' file_sec.copy_file_s('%s', '%s') ]], tmp_path, new_path)) 【正例】 work:start([[ local file_sec = require 'utils.file' local tmp_path = worker:recv() local new_path = worker:recv() file_sec.copy_file_s(tmp_path, new_path) ]]) work:send(tmp_path, true) work:send(new_path, true) ``` ## 3 文件操作 Lua提供的文件操作函数,和C语言一样,也存在通过软链接或`../`进行路径跨域。文件操作时未对不可信的路径进行标准化和校验或者校验不充分,导致路径遍历问题,被攻击者越权读写文件。 ### G.SEC.FIL.B01 创建文件或目录之后,需显式修改文件或目录的权限和属主 **【规则说明】** 遵循最小权限原则,及时修改文件权限和属主,避免因文件权限过大被低权限用户修改而存在安全风险。 ### G.SEC.FIL.B02 对于路径外部可控的文件进行任何操作前必须校验路径是否合法 **【规则说明】** 对于外部可控的文件路径,攻击者可以指定一个软链接路径或者通过`../`来实现路径跨越,从而造成任意文件的访问。为了防范这类风险,在文件的**创建、删除、读写、复制、移动、修改权限或属主**等操作之前,必须先进行**路径标准化并校验路径是否在预期的目录下**,否则容易造成提权、任意文件读写、任意文件删除、信息泄露等安全风险。 针对不同场景的文件路径校验需求,openUBMC封装了C语言和Lua语言版本的文件安全操作库。 ```c // C语言版本 // 文件安全打开,返回文件描述符,打开文件前会校验文件是否是绝对化路径,及是否存在软链接,是否在指定路径 gint32 open_s(const gchar *pathname, guint32 flags, mode_t mode, const gchar *path_header); // 文件安全打开,返回文件对象指针,打开文件前会校验文件是否是绝对路径,及是否存在软链接,是否在指定路径下 FILE *fopen_s(const gchar *path, const gchar *mode, const gchar *path_header); // 文件关闭接口,与open_s配套使用 gint fclose_s(FILE *fp); // 文件关闭接口,与fopen_s配套使用 gint close_s(gint32 fd); // 判断文件路径是否有效,是否在指定路径下,一般用于文件导入场景 gint32 check_real_path_s(const gchar *file_path, const gchar *path_header); // 在文件打开前,对文件路径的校验,判断文件路径是否是绝对路径以及是否存在软链接,是否在指定路径下,适用于文件导出场景 gint32 check_realpath_before_open_s(const gchar *file_path, const gchar *path_header); // 适用于文件已经打开后,对文件操作前路径的一致性校验,判断文件路径是否是绝对化路径以及是否存在软链接,是否在指定路径下 gint32 check_realpath_after_open_s(const gint32 fd, const gchar *file_path, const gchar *path_header); // 支持文件移动(源文件移动到目标文件,保留源文件的内容和属性,源文件删除),仅包括文件内容,打开文件进行路径和软链接检查 gint32 move_file_s(const gchar *src_path, const gchar *dest_path); // 支持文件完整拷贝接口,包括文件内容、文件属性(属主、创建时间、修改事件、访问时间等),打开文件进行路径和软链接检查 gint32 copy_file_s(const gchar *src_path, const gchar *dest_path); // 支持文件拷贝接口,仅包括文件内容,打开文件进行路径和软链接检查 gint32 copy_file_content_s(const gchar *src_path, const gchar *dest_path); // 支持文件读接口,打开文件需要进行路径和软链接检查 gint32 read_file_s(const gchar *file_name, void *buf, size_t size); // 支持文件读接口,打开文件需要进行路径和软链接检查 gint32 write_file_s(const gchar *file_name, const void *buf, size_t size); // access函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int access_s(const char *pathname, int mode); // chdir函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int chdir_s(const char *path); // opendir函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 DIR *opendir_s(const char *name); // open函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 gint32 open_s(const gchar *pathname, guint32 flags, mode_t mode, const gchar *path_header); // pathconf函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 long pathconf_s(const char *path, int name); // stat函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int stat_s(const char *pathname, struct stat *statbuf); // chmod函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int chmod_s(const char *pathname, mode_t mode); // chown函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int chown_s(const char *pathname, uid_t owner, gid_t group); // execl函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int execl_s(const char *pathname, const char *arg, ...); // execlp函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int execlp_s(const char *file, const char *arg, ...); // execle函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int execle_s(const char *pathname, const char *arg, ...); // execv函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int execv_s(const char *pathname, char *const argv[]); // execvp函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int execvp_s(const char *file, char *const argv[]); // link函数的安全版本,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,检验失败返回-1 int link_s(const char *oldpath, const char *newpath); ``` ```lua -- Lua语言版本 -- 文件安全打开,返回文件描述符,打开文件前会校验文件是否是绝对化路径,及是否存在软链接,是否在指定路径下。本函数返回的对象不支持seek方法,在需要使用seek方法指定写入点的特殊场景下,不能使用open_s替代原始的open函数,而是应该在open函数打开前使用check_realpath_before_open_s校验路径 open_s(filename, mode [, path_header]) -- 判断文件路径是否有效,是否在指定路径下,一般用于文件导入的场景 check_real_path_s(file_path [, path_header]) -- 在文件打开前,对文件路径的校验,判断文件路径是否是绝对路径以及是否存在软链接,是否在指定路径下,适用于文件导出场景 check_realpath_before_open_s(file_path [, path_header]) -- 适用于文件已经打开后,对文件操作前路径的一致性校验,判断文件路径是否是绝对化路径以及是否存在软链接,是否在指定路径下 check_realpath_after_open_s([file], file_path [, path_header]) -- 支持文件移动(源文件移动到目标文件,保留源文件的内容和属性,源文件删除),仅包括文件内容,打开文件进行路径和软链接检查 move_file_s(src_path, dest_path) -- 支持文件完整拷贝接口,包括文件内容、文件属性(属主、创建时间、修改事件、访问时间等),打开文件进行路径和软链接检查 copy_file_s(src_path, dest_path) -- 支持文件拷贝接口,仅包括文件内容,打开文件进行路径和软链接检查 copy_file_content_s(src_path, dest_path) -- 支持文件读接口,读取指定字节数据,打开文件需要进行路径和软链接检查 read_file_s(file_name, size) -- 支持文件写接口,写入指定数据,打开文件需要进行路径和软链接检查 write_file_s(file_name, data) -- os.execute的安全版本,用于防命令注入执行shell命令,执行前会校验外部输入的字符串是否包含可能导致shell命令注入的特殊字符,检验失败会抛出错误,特殊字符包含"||", ";", "&&", "$", "|", "&", ">>", ">", "<", "`", "\", "!", "\n" execute_s(cmd) -- vos.system_s的安全版本,用于执行shell命令,执行前会校验外部输入的字符串是否包含可能导致shell命令注入的特殊字符,检验失败会抛出错误,特殊字符包含"||", ";", "&&", "$", "|", "&", ">>", ">", "<", "`", "\", "!", "\n" check_before_system_s(cmd_path [, cmdstring]) -- chmod的安全版本,用于修改文件权限,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,校验失败会返回-1 chmod_s(path, fd_mode) -- chown的安全版本,用于修改文件的属主和属组,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,校验失败会返回-1 chown_s(path, owner, group) -- chdir的安全版本,用于切换目录,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,校验失败会抛出错误 chdir_s(dir_path) -- stat的安全版本,用于显示文件或文件系统的详细信息,执行前会判断文件路径是否是绝对化路径以及是否存在软链接,校验失败会抛出错误 stat_s(path) ``` **【案例一】** ```lua -- 错误示例: function export_event(list, path) -- 省略部分代码 utils.remove(path) -- 错误,未对path进行校验 end -- 正确示例: function export_event(list, path) if check_realpath_before_open_s(path, '/tmp') ~= 0 then return -- path是非预期路径,不能直接删除 end utils.remove(path) -- 正确,已对path进行校验 -- 省略部分代码 end ``` ### G.SEC.FIL.B03 解压缩包操作需要进行完备的校验,防止zip炸弹 **【规则说明】** 解压前需要判断: - 压缩包文件路径是否为软链接; - 压缩包文件大小; - 压缩包内被压缩文件的总数; - 解压后的文件总大小; - 压缩包内压缩文件名是否包含`../`(如果使用`unzip`命令解压,则无需校验`../`); - 解压得到的文件中是否包括软链接。 框架已提供包含上述检查的安全解压接口,在解压操作时使用对应接口进行操作; - `secure_tar_unzip`: 对tar压缩文件格式的压缩包进行解压 - `unzip_s`: 对zip压缩文件格式的压缩包进行解压 **【案例一】** ```lua -- 解压tar格式文件 -- 函数声明:secure_tar_unzip(file_path, dest_path, max_unzip_file_size, max_file_num) local utils = require 'mc.utils' local ok = utils.secure_tar_unzip(file_path, dest_path, max_unzip_file_size, max_file_num) if not ok then log:error('secure_tar_unzip failed') end ``` **【案例二】** ```lua -- 解压zip格式文件 -- 函数声明:unzip_s(file_path, dest_path, max_unzip_file_size, max_file_num) local utils = require 'mc.utils' local ok = utils.unzip_s(file_path, dest_path, max_unzip_file_size, max_file_num) if not ok then log:error('unzip_s failed') end ``` ### G.SEC.FIL.B04 往同一路径下解压文件,需要做重入判断,禁止允许并发解压 **【规则说明】** 如果允许同一个路径下并发解压,则可以构造两个特殊的压缩包,利用解压过程中残留的文件,进行任意文件写,可以导致沙箱被破解。 ### G.SEC.FIL.B05 使用外部导入的文件之前,需判断文件属主是否与执行导入操作的用户一致 **【规则说明】** 安全要求,导入之前先判断文件属主是否与触发导入操作的用户一致,可以避免高权限用户上传的文件被低权限用户使用。 **【案例一】** ```lua local function check_owner(ctx, file_path) local uid = get_uid_gid_by_name(ctx) -- 通过上下文获取当前用户的uid local file_owner = utils_core.stat_s(file_path).st_uid if file_owner ~= uid then log:error('file owner(%d) is not match current user(%d)', file_owner, uid) utils.remove_file(file_path) return false end return true end ``` ### G.SEC.FIL.B06 高权限用户严禁执行低权限用户可修改的shell脚本 **【规则说明】** 如果高权限用户执行低权限用户具备写权限的脚本文件,那么低权限用户只要修改脚本内容,就可以在高权限用户执行该脚本的时候,借助高权限用户来执行恶意命令。具体来说,包括以下两种场景: - 直接使用:高权限用户直接执行低权限用户可修改的脚本文件; - 间接使用:高权限用户执行的是低权限用户不可修改的脚本文件,但是该脚本里面会执行某些低权限用户可修改的脚本文件。 ### G.SEC.FIL.B07 不要在共享目录中创建和存放临时文件 **【规则说明】** 共享目录是指其它非特权用户可以访问的目录。程序的临时文件应当是程序自身独享的,任何将自身临时文件置于共享目录的做法,将导致其他共享用户获得该程序的额外信息,产生信息泄露。因此,不要在任何共享目录创建仅由程序自身使用的临时文件。 临时文件通常用于辅助保存不能驻留在内存中的数据或存储临时的数据,也可用作进程间通信的一种手段(通过文件系统传输数据)。例如,一个进程在共享目录中创建一个临时文件,该文件名可能使用了众所周知的名称或者一个临时的名称,然后就可以通过该文件在进程间共享信息。这种通过在共享目录中创建临时文件的方法实现进程间共享的做法很危险,因为共享目录中的这些文件很容易被攻击者劫持或操纵。 临时文件(例如升级包、证书文件等)必须先拷贝到非共享目录(例如从`/tmp`目录拷贝到`/data`或者`/dev/shm`下)再进行校验 。 ### G.SEC.FIL.B08 建议将远程文件下载到本地目录后再进行处理 **【规则说明】** 部分远程文件通过将目录挂载后直接在挂载目录上进行操作,此时远程服务器不可控,攻击者可在完成文件校验后竞争替换远程服务器上的文件实现绕过。 ## 4 外部输入 使用外部输入数据时,处理上面指出的命令注入、代码注入、路径跨越风险外,还需要注意以下问题。 ### G.SEC.EXT.B01 禁止外部输入直接作为循环上限 **【规则说明】** 以外部输入作为循环上限时,可能会由于范围过大而索引不到结果,引发异常。 ### G.SEC.EXT.B02 禁止外部输入直接作为除数 **【规则说明】** Lua同C语言要求,除法或求余操作中,一旦发生除0的情况,将产生异常。 ### G.SEC.EXT.B03 外部输入作为表索引时,对索引结果要判空后再使用 **【规则说明】** 以外部输入作为表索引或者数组下标时,需要对索引结果判空再使用,否则如果对得到的`nil`值进行操作,可能引发异常。 **【案例一】** ```lua -- 错误示例 -- 根据cmd_type加载具体的消息处理类 function func(type) -- 错误,应该对handlers[cmd_type]判空后再使用,否则传入一个不存在的索引值,会触发程序断言失败 self.handler_func = handlers[type].func end -- 正确示例 function func(type) local handler = handlers[type] if not handler then return end self.handler_func = handler.func end ``` ### G.SEC.EXT.B04 公共函数中禁止日志打印可能是外部输入的参数取值 **【规则说明】** 公共函数打印外部输入参数,容易造成信息泄露风险,且代码排查时难以识别。例如,一个检验文件路径是否合法的公共函数中,如果打印了此路径;那么调用者不小心将包含密码的远程文件路径传入了,就会导致敏感信息泄露。 特别要注意一些公共机制回调函数,如配置导入回调不要无条件打印参数值;以及一些开源软件日志配置中,要注意不能打印可能是敏感信息的部分。 ### G.SEC.EXT.B05 对于外部输入进行直接校验,不要对二次计算后的结果进行间接校验 **【规则说明】** 对外部输入的运算结果进行校验容易出现整数翻转或整数溢出截断,造成安全风险,因此应当对外部输入本身进行直接校验。 **【案例一】** `data_cnt`是外部消息控制的,在校验报文长度时没有直接校验,而是对一个乘法和加法运算结果进行校验,这就导致攻击者通过构造特殊的`data_cnt`取值,使得计算结果`data_len`超过`unsigned int`的最大范围,出现整数溢出截断成一个较小的数,从而使下面的长度校验能够通过,但是实际使用`data_cnt`时又会出现越界读写。 ```c int HandleMsg(unsigned int data_cnt, unsigned int msg_len) { unsigned int data_len = sizeof(MSG_INFO_S) + data_cnt * sizeof(Data_S); // 校验消息长度是否满足要求 if (data_len > msg_len) { return -1; } for (int i = 0; i < data_cnt; i++) { ...... // 省略部分代码 } } ``` ## 5 敏感信息 openUBMC涉及的敏感信息包括但不限于:openUBMC用户密码、会话token、包含密码的远程文件传输URL、包含密码的虚拟媒体挂载地址、SMTP登录密码、SNMP团体名、SNMP加密密码、SP升级的ImageURI和SignalURI、SP系统部署配置中的CDKey和RootPwd、NTP组秘钥、KerberOs密钥表、证书私钥、证书加密密码、加密密钥(包括根密钥、主密钥和工作密钥)、Redfish事件订阅请求头、VNC密码、BIOS密码、LDAP绑定密码(BindDNPsw)、SSH Host key。 ### G.SEC.SEN.B01 敏感信息明文禁止泄露 **【规则说明】** 敏感信息泄露行为包括:打印到日志、在接口响应体或错误消息中明文返回、在UI界面上(包括命令行和Web)明文显示、明文存储到文件系统(含内存文件系统)、明文存储到数据库。 ### G.SEC.SEN.B02 北向接口映射器配置中,对于可能是敏感信息的请求参数,需要增加Sensitive标识 **【规则说明】** 为了避免在cli命令或者接口错误响应消息中回显用户输入的敏感信息,需要在映射器配置中增加Sensitive标识。增加该标识后,可以自动隐藏敏感信息具体值。 **【案例一】** ```json { "Type": "PATCH", "ReqBody": [ { "Name": "SenderPassword", "Type": "string", "Sensitive": true // 发送密码是敏感信息,需要在回显中隐藏具体值 } ] } ``` ### G.SEC.SEN.B03 后台组件错误引擎抛错时,禁止在message中返回敏感信息 **【规则说明】** 后台组件在处理错误引擎抛错时,如果参数值是敏感信息,则不能直接传入抛错函数,而应该使用6个*替代,避免在北向接口回显中打印出来。 **【案例一】** ```lua -- 错误案例: if url:len() > 255 then error(base_messages.PropertyValueFormatError(url, '%Url')) -- 错误:url可能是敏感信息 end -- 正确案例: if url:len() > 255 then error(base_messages.PropertyValueFormatError('******', '%Url')) -- 正确:隐藏了敏感信息 end ``` ## 6 资源泄露 ### G.SEC.LEA.B01 C库中须保证内存正确释放 **【规则说明】** 在封装给Lua调用的C/C++动态库中,使用C/C++库函数创建的资源,仍需跟正常C/C++程序一样,在使用完毕后,需要进行资源释放,否则存在资源泄露。 ### G.SEC.LEA.B02 注意正确调用开源软件的资源申请和释放函数 - 通过Lua重新封装的开源软件API,在调用时同样要注意资源的申请和释放 - 比如,若调用了某个封装了SSL_CTX_new的Lua函数,则必须相应地调用封装了SSL_CTX_free的接口 ### G.SEC.LEA.B03 资源的申请和释放必须成对 以下为openUBMC框架封装的资源申请释放常用Lua接口: - 数据库的预处理语句与销毁预处理语句 ```lua local vm = db:prepare('SELECT COUNT(*) FROM t_record') ... vm:finalize() ``` - 空表的申请与释放语句 ```lua local table_cache = require 'mc.table_cache' local tbl_cache = table_cache.new() -- 申请一个空表 local data = tbl_cache:allocate() ... -- 释放这个表 tbl_cache:deallocate(data) ``` ## 7 其他 ### G.SEC.OTH.B01 禁止封装会调用到阻塞性API的C库给Lua代码直接调用 **【规则说明】** C库中调用阻塞性API,如`sleep`、`usleep`、`accept`、`recv`、`send`等,直接在Lua代码中调用该C库函数会阻塞skynet的worker线程,导致该进程下所有skynet服务任务调度出现异常,进而导致相关资源协作接口访问阻塞、组件心跳丢失被框架重启等问题。推荐做法为:调用框架提供的worker库,创建一个worker线程,将阻塞操作在worker线程中执行 ### G.SEC.OTH.B02 禁止在Lua代码中直接调用执行时间较长的shell脚本 **【规则说明】** 在Lua代码中直接执行时间较长的shell脚本(如配置网络、压缩/解压缩大文件)也会阻塞skynet的worker线程,影响同**G.SEC.OTH.B01**。解决方法也是使用框架提供的worker机制来执行shell脚本。 ### G.SEC.OTH.B03 禁止在app启动函数中执行耗时较长或者耗时不确定的操作 **【规则说明】** 在app启动函数中执行耗时较长或者耗时不确定的操作(例如阻塞性等待其他组件上资源协作接口),可能导致启动超时,服务被框架重启。此类操作建议异步执行,不阻塞启动过程。 ### G.SEC.OTH.B04 创建skynet协程操作外部可控时,必须控制协程创建的最大数量 **【规则说明】** 同时创建过多的skynet协程,会导致app内存暴涨直至出现OOM(Out Of Memery),如果协程创建操作外部可控,则会造成DOS攻击,因此必须限制最大并发数量。 ### G.SEC.OTH.B05 如果某个外部可控的操作存在较多内存分配,则须保证及时GC **【规则说明】** 某个外部可控的操作存在较多内存分配,例如查询BIOS配置、查询BIOS属性注册表、导入根证书等,可以考虑在操作结束后主动进行GC,避免因为Lua虚拟机自动GC不及时导致OOM。 _**添加`collectgarbage`调用会引起CPU占用升高,请在sig例会评审通过后再添加**_ ### G.SEC.OTH.B06 使用libcurl发起的请求,必须显式设置超时时间和连接超时时间,避免网络异常情况下线程阻塞 ```c \* 示例 *\ CURL *curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); // 连接超时时间10s curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); // 设置超时时间60s curl_easy_perform(curl); ``` --- # 贡献攻略 > URL: https://openubmc.cn/docs/zh/latest/contributing/contribution_intro.html > Language: zh 关于社区贡献相关详细说明,请参考《[贡献攻略](https://www.openubmc.cn/zh/contribution)》。 --- # 简介 > URL: https://openubmc.cn/docs/zh/latest/contributing/doc_submission/Introduction.html > Language: zh 本文介绍 openUBMC 文档的生产发布流程与文档仓的组织架构,同时提供每本手册在文档仓中的具体存放位置。 - 文档中心将社区文档按社区使用指南、开发者指南和测试指南模块进行划分: - 社区使用指南:社区体验地图、贡献指南、版本说明。 - 开发者指南:快速入门、开发指南、参考指南、工具指南、API文档、术语表。 - 测试指南:快速入门、开发与技术常见问题。 - 发布机制: - 每个场景及工具模块均有对应目录结构文件(_menu.json)。这些配置文件均存于 openUBMC/docs 仓,由 DOC SIG 集中管理。 - 各文档的责任 SIG 需将文档目录结构文件引用,添加到所属场景或工具模块的目录结构文件中,使文档可在对应模块下呈现。 - 文档生产: - openUBMC的文档生产在 openUBMC/docs 仓以及各 SIG 组的 docs 仓中进行。 - 各 SIG 在文档仓中维护的文件包括:文档内容文件和目录结构文件(_menu.json)。其中,文档内容文件用来存放文档实际内容,文档目录结构文件用来维护文档章节呈现结构。 在文档仓中,docs 目录下的内容会展示于官网,其下设有 zh 和 en 两个子目录,分别用以存放中文文档与英文文档,文档目录结构严格参照官网呈现的目录层级规划设置。此外,文档仓还设有 archive 目录,用来存放暂不适合推广,或尚不成熟的文档。待文档完善且满足发布需求时,再将其移至 docs 目录,以便在官网展示。 ```text ├─docs │ ├─public │ ├─en │ └─zh ├─archive ``` --- # 文档仓目录结构说明 > URL: https://openubmc.cn/docs/zh/latest/contributing/doc_submission/directory_structure.html > Language: zh # 手册 文档中心有17本手册:快速入门、认识openUBMC、安装部署、构建升级、部件驱动接入、硬件适配、特性开发、接口定制、迁移、整机集成、测试验证、问题定位、社区贡献、常用工具、调试命令/工具、参考和常见问题,分别对应 docs 仓内 docs/zh/ 目录下的 getting_started、overview、installation、build_upgrade、component_driver、hardware、feature_dev、interface、migration、integration、testing、troubleshooting、contributing、common_tools、debug_tools、reference 和 general_faq 子目录。 文档仓手册相关目录结构示例如下: ```text ├─docs │ ├─tools │ ├─en │ └─zh │ ├─getting_started │ ├─overview │ ├─installation │ ├─build_upgrade │ ├─component_driver │ ├─hardware │ ├─feature_dev │ ├─interface │ ├─migration │ ├─integration │ ├─testing │ ├─troubleshooting │ ├─contributing │ ├─common_tools │ ├─debug_tools │ ├─reference │ └─general_faq ``` # 目录 各手册下均有具体的目录划分。以部件驱动接入手册为例,其进一步细分为部件驱动接入导读、概念原理、快速上手、总体指导等一级目录。 文档仓部件驱动接入目录结构示例如下: ```text ├─docs │ ├─tools │ ├─en │ └─zh │ └─component_driver │ ├─concept_principle │ ├─general_guide │ ├─nic_adapt │ ├─hdd_adapt │ ├─xpu_adapt │ └─fan_power_adapt ``` 部分一级目录会进一步细分出二级目录,以部件驱动接入手册中的总体指导目录为例,其下进一步划分出二级目录,分别为网卡驱动规范、南向网卡驱动适配指南、openUBMC Studio网卡适配指南等。 文档仓服务器下特性开发的目录结构示例如下: ```text ├─docs │ ├─en │ └─zh │ ├─getting_started │ ├─overview │ ├─installation │ ├─build_upgrade │ ├─hardware │ ├─component_driver │ ├─concept_principle │ ├─general_guide │ ├─nic_adapt │ ├─nic_driver_spec │ ├─south_nic_driver_adapt │ └─studio_nic_adapt ``` # 文档 每本手册分别对应文档仓的一个文件夹。每本手册包含一个或多个文档内容文件(`.md`文件)。 文档仓服务器下快速入门手册的文档目录结构示例如下: ```text ├─docs │ ├─tools │ ├─en │ └─zh │ ├─getting_started │ ├─explore_openubmc.md │ ├─quick_start │ ├─env_introduction.md │ ├─build_your_own_bmc.md │ ├─document_intro.md │ └─glossary.md │ ├─overview │ ├─installation │ ├─build_upgrade ``` --- # 文档写作规范 > URL: https://openubmc.cn/docs/zh/latest/contributing/doc_submission/documentation_writing_specifications.html > Language: zh 本写作规范针对 openUBMC docs 仓的文档结构、内容元素和语言风格提出规范要求,确保 openUBMC 文档具备一致风格。 开发者开始 openUBMC 文档写作前,建议先了解本规范内容,**欢迎提出改进意见**。 # 文档结构规范 特性手册内容一般包括概述、背景介绍、操作类文档(安装与部署、使用指南)、常见问题和附录,开发者可以根据项目实际情况增加或删减。 以[openUBMC 项目为例](https://openubmc.cn/docs/zh/development/quick_start/explore_openubmc.html),可以参考如下内容: ## 概述 一句话介绍特性定义与功能,一句话说明读者对象。 【举例】 ```markdown BMC Studio CLI (bingo) 是BMC Studio的CLI命令行,常用于组建构建、产品构建等命令执行。本文档介绍bingo的具体使用方式。 ``` ## 背景介绍 背景介绍类文档写明特性背景与简介、架构说明等。常见文档标题:`认识xxx`。 ### 操作类文档 - 环境要求 执行此操作需要准备的软硬件环境、权限以及其它约束条件。 【举例】 ```markdown 硬件要求:xxx处理器。 软件要求:openUBMC xx版本、root权限。 ``` - 操作步骤 操作步骤文档包含**安装与部署**、**使用方法**等说明内容。 具体的操作步骤,需要注意如下事项: - 建议一步一个操作步骤,不建议多个操作步骤合并在一个步骤中描写。 - 如果操作可选,要明确可选条件。 - 开发步骤中,涉及调用接口(例如使用了或者 SQL 语句),需要对使用的接口进行说明。 - 结果验证 说明如何验证操作结果正确。如果验证操作与步骤强相关,可以在步骤中描述。例如,执行 SQL 语句的返回信息。 ### 附录 附录可包含术语与缩略语介绍。 # 内容元素规范 ## 命名 对于新增文档,请在对应的文件目录下新增 MarkDown 文档(即以 .md 结尾的文件)。 【规则】新增文档名称不能与已有文档重名,如果有请重新命名。 【规则】文档需要以**英文**命名。 【规则】文件名中不能包含括号,会导致文件目录无法正常显示。可以将括号修改为可识别的下划线(\-)或者中划线(-)。 【举例】 ```text bmc_studio_tool.md #新增‘BMC Studio 用户指南’文档 ``` ## 标题 【规则】标题尽量采用简洁的语句概况反映章节的中心内容,注意不要省略必要的信息。 【规则】操作类文档标题尽量用动宾结构(例如:申请权限);相同级别,相同类型的标题结构保持一致。 【规则】标题不使用标点符号结尾,标题中尽量采用圆括号来表示补充说明,标题中不能出现特殊字符,如“?”。 【规则】标题与正文使用 1 整行换行隔开。 【规则】标题使用 “#” 空格连接标题名,标题级别一次只能增加一个级别且第一个标题应该是顶层标题。 【举例】 ```markdown # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题 ``` ## 正文 【使用方法】 - 斜体:使用一个星号(\*)表示斜体。 ```txt *斜体文本* ``` - 粗体:使用两个星号(\*\*)表示粗体。 ```txt **粗体文本** ``` - 粗斜体:使用3个星号(\*\*\*)表示粗斜体。 ```txt ***粗斜体文本*** ``` - 转义:对特定内容使用转义符 \。 ```txt \<转义的标记符号> ``` 【规则】该转义的字符必须严格用转义符 \ 。 【规则】如果有连续两个转义符,转义符之间要有空格 \{ \}。 ## 空格 【规则】编辑文档时中文和英文之间**建议**加空格,页面展示更美观,请保持全文一致。如果是产品名词如 “豆瓣FM”,请按照官方定义格式书写。 例如:openUBMC 是一款架构领先、开发友好、开放标准的算力设备开源管理软件。 【规则】中文和数字之间加空格。 【规则】数字和单位之间不加空格。 【规则】全角标点与其他字符之间不加空格。 例如:刚刚成为了 openUBMC 的 maintainer,好开心。 ## 图片 【使用方法】 ```bash ![alt 属性文本](图片地址) ![alt 属性文本](图片地址 "可选标题") ``` 【规则】图片统一存放到文档同级目录下的 images 文件夹中。例如,[openUBMC 项目](https://openubmc.cn/docs/zh/development/quick_start/explore_openubmc.html)中的手册中使用的图片,统一存储在 [openUBMC 项目对应手册中的images](https://gitcode.com/openUBMC/docs/tree/main/docs/zh/getting_started/images) 路径下。该文件夹下的文件引用图片时,使用相对引用。 【规则】请使用原创图片,避免存在知识产权侵权风险。 【规则】图文配合使用,切忌图文分离。 【规则】图片格式首选 png,此外也接受 jpg。图片的高不超过 640px,宽不超过 393px,图片大小建议不超过 150K。 【规则】中文用中文插图,英文用英文插图。 【规则】图片路径不能包含中文。 【规则】如果是截图,请在允许的范围内只保留有用的信息。图形中需要突出的关键信息,可增加红色框线或者文字备注说明。 ## 代码块 代码示例说明了如何实现特定功能,开发人员使用代码示例来编写和调试代码。 【规则】代码的逻辑和语法正确。 【规则】代码的输入和输出尽可能的分开。 【规则】保证代码中关键步骤要有注释说明。 【规则】文中行内代码和命令行使用 1 对反引号,如:`代码块`。 【规则】块级代码使用 3 个顿号或 4 个空格(不能用 TAB 键)缩进,且上下均用整行隔开。 【举例】 - 行内代码 ```txt `printf()` 函数 ``` - 块级代码 ```python #!/usr/bin/env python3 print("Hello, World!"); ``` ```c #include int main(void) { printf("Hello world\n"); } ``` ## 列表 - 无序列表:无序列表使用星号(**\***)、加号(**+**)或是减号(**-**)作为列表标记,这些标记后面要添加一个空格,然后再填写内容。同一个无序列表,建议使用同一个符号。 ```txt * 第一项 * 第二项 * 第三项 + 第一项 + 第二项 + 第三项 - 第一项 - 第二项 - 第三项 ``` - 有序列表:有序列表使用数字并加上 **.** 号来表示。 ```txt 1. 第一项 2. 第二项 3. 第三项 ``` - 嵌套列表:列表嵌套只需在子列表中的选项前面添加四个空格(注意不是Tab键)即可。 ```txt 1. 第一项: - 第一项嵌套的第一个元素 - 第一项嵌套的第二个元素 2. 第二项: - 第二项嵌套的第一个元素 - 第二项嵌套的第二个元素 ``` 【规则】有明显先后逻辑顺序情况请使用有序列表,并列关系、多选一情况请使用无序列表。 【规则】当项目列表是术语、短语时,统一不加标点符号。 【规则】当项目列表是句子时,统一加句号。 【规则】特殊情况下如果不能避免出现短语和句子混合的情况,统一加句号。 【规则】项目列表前几项以分号结尾,最后一项以句号结尾的形式也可以接受。 ## 注释符号 文档中会出现以下注释符号,代表不同的使用场景和提示程度。如果需要提示用户注意的信息,可以根据重要程度选择对应的注释符号。 | 注释符号 | 用途/含义 | 使用方法 | |--------|------------------------------------------------------------------|-----------------------------------------------------------------------------| | 注意 | 如未按该注意事项操作,可能会导致任务中断或结果异常,但是可恢复。 | `> [!WARNING]注意`
`> 正文内容` | | 说明 | 提供帮助提示或有用的参考信息。 | `> [!NOTE]说明`
`> 正文内容` | > [!NOTE]说明 > > - 请根据文档具体场景选择对应的注释符号,并按照使用方法正确使用样式。方括号内是英文感叹号。 > - 说明/注意样式内可嵌套有序/无需列表,但不建议表格和代码块。 > - 为避免样式断开,需要保证 `>`连续。 > - 说明/注意内容避免过长,可考虑写在正文或者分段,请不要添加过多样式内空行。 ## 链接 【规则】链接需要确保指向的目标文件存在,否则会造成链接跳转不正常,不建议使用 HTML 的链接样式。 【举例】 ```markdown - 网站链接 这是一个链接 [菜鸟教程](https://www.runoob.com)。 - 相对路径 [文档开发流水线门禁](./ci_rules.md) ``` ## 表格 【规则】markdown 文档中请使用以下方式创建表格,不建议使用 HTML 的表格样式。 【举例】 | 表头1 | 表头2 | | ---------- | -------- | | 单元格1 | 单元格2 | | 单元格4 | 单元格4 | 【使用方法】 设置表格的对齐方式: - -: 设置内容和标题栏居右对齐。 - :- 设置内容和标题栏居左对齐。 - :-: 设置内容和标题栏居中对齐。 【规则】当表格内一列全部是术语、短语时,统一不加标点符号。 【规则】当表格内一列全部是句子时,统一加句号。 【规则】特殊情况下如果不能避免出现短语和句子混合的情况,统一加句号。 ## 标点符号 【规则】单位与数字之间不建议加空格,比如 50m,10kg,64Kbit/s。 【规则】对于有序/无序列表,如果是长句子,建议统一以句号结尾,如果是短语,结尾可不用标点。**重点是前后一致,要么都加,要么都不加**。 【规则】中文文档使用全角标点。 【规则】数字使用半角字符。 【规则】感叹号使用场景为可能引发严重后果的操作或设备安全、人身安全的警告。其他场景不允许使用感叹号。 【规则】文内引用其他文档时添加书名号,同时建议增加引用文档的跳转链接。例如:构建 openUBMC 系统,方法参考《[构建你的BMC](https://openubmc.cn/docs/zh/development/quick_start/build_your_own_bmc.html)》。 # 语言风格规范 【规则】提交内容必须是与 openUBMC 特性相关内容。 【规则】内容不能包含敏感信息、有强烈的种族歧视或性别歧视的内容。 【规则】提交的内容必须是原创内容,不得侵犯他人知识产权。 【规则】提交的内容必须客观、真实,不允许使用夸大宣传等词汇。 **文档贡献中不受欢迎的行为** 短时间内通过自动化,提交大量的PR,提交大量的处理诸如拼写错误,语法错误,日期错误,语句不通顺等“无害的错误”的修正。 --- # 常见问题文档写作模板 > URL: https://openubmc.cn/docs/zh/latest/contributing/doc_submission/documentation_writing_templates/faq_writing_template.html > Language: zh 一个FAQ一般由三部分组成: FAQ = 问题现象 + 可能原因 + 处理措施 问题分为复杂问题和简单问题,部分简单问题中,标题已经说清楚了“问题现象”和“可能原因”,就可以省略重复部分。 一般FAQ分为以下两类: - 故障处理类 - 咨询类(含特性原理/规格 /概念咨询、功能使用咨询) # 故障处理类 ## 标题:一句话简要描述问题的最终现象 ### 问题现象 从用户角度出发,描述用户可感知的报错 。包括:问题出现的场景、现象、条件等。 (复杂问题可选)如有问题复现的完整操作流程,也在这个小标题下呈现。 ### 可能原因(可选) 明确问题的根因。如果不同的原因对应不同的解决措施,需明确分点列举。 ### 解决措施 - Step-by-step方式写作,保证可执行性。 - 以“动宾句式”的操作步骤为主,有时 候还需要说明“操作目的”与当前步骤的“操作现象”。 - 理清逻辑关系(合理分层),并列关系采用无序列表,顺序关系(前后有依赖关系)采用有序列表。 ### 代码示例(可选) 展示核心代码,提供可运行的代 码片段。 如果是步骤执行代码,可与解决措施中的步骤合并。 ### 参考链接(可选) 附指南/API参考/Sample等赋能套件的资料链接,方便开发者拓展阅读。 # 咨询类 ## 标题:以用户的疑问点切入,需要含有具体的特性关键词 无需分隔子标题,直接答复实现方案、对应的规格约束等。如果有代码示例辅助解释,可以直接在解决方案后提供简单的示例代码片段。 ### 参考链接(可选) 附指南/API参考/Sample等赋能套件的资料链接,方便开发者拓展阅读。 --- # 故障处理文档写作模板 > URL: https://openubmc.cn/docs/zh/latest/contributing/doc_submission/documentation_writing_templates/troubleshooting_writing_template.html > Language: zh # xx类故障 如果故障有多种类型,或者涉及多个组件,需按照类型或者组件先进行分类,便于快速查找相应的故障处理指导。如果单个组件的故障类型比较多也可以先按照不同的组件进行分类,组件中再按照不同的故障类型进行分类。 ## xxx故障处理 ### 现象描述(必选) 故障现象的详细描述,说明什么情况或条件下会产生什么故障。 ### 对系统的影响(必选) 描述当前故障产生后,对系统的影响程度。对系统没有任何影响可写为“无”。 描述时应该让客户能判断下一步是否需要采取措施,不宜写得太模糊。比如:“可能影响业务”则不够清晰,应说明什么情况下影响业务,是中断业务还是业务质量下降。 描述系统自处理过程,描述系统内部在发生此告故障时是如何处理的。只写对客户有用的信息。比如:描述发生当前故障后,系统进行的一些保护性措施,如进行虚拟机迁移等。如果没有系统自处理过程,可以不写。 ### 可能原因(必选) 发生当前故障的所有可能原因,要分析全面,避免遗漏。每条原因用一句话简短描述,根据可能性从高到低排序。 如果仅有一个原因,则使用p标记直接说明原因; 如果有多个原因,使用无序列表描述,格式如下: - 可能原因 1。 - 可能原因 2。 - 可能原因 3。 ### 排查思路(可选) 如果当前故障处理过程比较复杂(处理步骤超过15步),且故障通常由多个可能的原因导致(可能原因大于3个),需要逐一进行排查确认时,必需提供处理当前故障时整体的故障排查思路和排查思路说明图。排查思路总体可以分为两类:并列排查和顺序排查。 - 并列排查:排查步骤根据原因的可能性进行排序,高频原因先排查,排查所有可能原因仍无法解决,再引导用户联系技术支持。 - 顺序排查:排查步骤按照一定的逻辑顺序排查,或由简单步骤到复杂步骤排查。 **【样例】** 图 1-1 备份失败排查思路(并列排查) ![image](../../images/documentation_writing_templates/backup_fail.png) 图 1-2 网站无法访问排查思路(顺序排查) ![image](../../images/documentation_writing_templates/website_no_access.png) ### 前提条件(可选) 描述进行具体的故障处理操作前需要完成工作、获取的信息、准备的工具等先决条件。如已获取故障节点的IP地址,登录的账户密码等。 ### 操作步骤(必选) 处理步骤写作原则: 1. 采用step by step方式写作,一个步骤一个动作。步骤要具体、可操作,例如:不能写“检查xx状态是否正常”,要写“执行xx命令检查xx状态是否正常”。 2. 原则上针对每一个可能原因都要给出对应的排查方法和处理方法,直到故障处理结束或者联系技术支持。处理步骤顺序与可能原因顺序一致。 3. 对于多种原因的故障处理,允许步骤跳转,但必须有超链接指明跳转的哪一步。 4. 处理步骤不能太简单,允许部分可能原因没有处理方法,但是不能所有可能原因都没有处理方法;不允许还没排查就直接让联系技术支持处理,原则上步骤不小于3步。 5. 对业务有影响的操作步骤,在操作之前给出警示或者注意。 6. 涉及参数、命令的操作,给出在什么地方或通过什么命令,完成什么事情。 7. 需要等待的步骤,在处理步骤中给出等待的时间。 8. 无法恢复故障,需要联系技术支持时,需要让用户收集故障或日志信息。收集的信息要明确,步骤可执行,下载的日志内容要有说明。 9. 处理步骤中原则上不建议参考其他手册或章节,必须一次性按照处理步骤能够清除该故障,如果故障非常复杂,必须参考其他手册或章节,则按照下述方法处理。 - 参考其他产品文档的某个章节时,如果该产品资料单独上网,则必须给出“手册名称+章节名称”。 - 参考本文档附录或者FAQ,该附录或FAQ必须跟单部件的故障处理手册一起打包发布。 **【样例】** 步骤 1 在Service OM界面,选择“监控 > 告警 > 告警列表”,查看是否有关于重新安装主机的告警。 - 是,执行xx。 - 否,执行xx。 步骤 2 执行以下命令,恢复xx。 nova ext-resize-revert server migration_id 步骤 3 检查xxx。 - 是,处理完毕。 - 否,执行步骤4。 步骤 4 通过xxx方法收集故障信息,联系技术支持处理。 ---结束 --- # 目录结构文件格式 > URL: https://openubmc.cn/docs/zh/latest/contributing/doc_submission/file_format.html > Language: zh 每本手册的每篇文档均需要在该手册文件夹中的`_toc.yaml`文件中配置目录结构。《快速入门》手册的`_toc.yaml`文件示例如下: ```json label: 快速入门 sections: - label: 探索openUBMC href: ./explore_openubmc.md - label: openUBMC快速入门 sections: - label: 开发环境快速搭建 href: ./quick_start/env_introduction.md - label: 构建你的BMC href: ./quick_start/build_your_own_bmc.md - label: 文档导读 href: ./document_intro.md - label: 术语表 href: ./glossary.md ``` - label:目录/文档名称。 - href:目录/文档相对路径。 --- # AI辅助编程技巧 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/ai_assisted_programming_guide.html > Language: zh 本文档介绍openUBMC开发中使用AI辅助编程的社区特定技巧,帮助开发者更高效地进行BMC软件开发。 # 技巧1:配置Context7 MCP Server ## 背景 在openUBMC开发中,我们推荐使用Context7 MCP Server作为AI辅助编程的核心组件。Context7基于Model Context Protocol (MCP),能够深度理解openUBMC项目结构和代码逻辑,提供更精准的代码建议和生成。 openUBMC社区文档已经进入Context7,AI能够更好地理解openUBMC的架构、API和开发规范。 **参考资源**: - [Context7官方文档](https://context7.com/docs) - [Model Context Protocol规范](https://modelcontextprotocol.io/) ## Cursor配置Context7 MCP Server ### 步骤1:Cursor MCP配置 1. **配置MCP服务器** **方式一:文件配置** 在Cursor配置目录创建`mcp.json`文件: - Windows: `%APPDATA%\Cursor\User\mcp.json` - macOS: `~/Library/Application Support/Cursor/User/mcp.json` - Linux: `~/.config/Cursor/User/mcp.json` **方式二:Cursor界面配置** 在Cursor配置中,进入【MCP】->【Add new global MCP server】,添加Context7 MCP服务器配置。 2. **配置Context7 MCP服务** **方式一:NPX方式(推荐)** ```json { "mcpServers": { "context7": { "command": "npx", "args": [ "-y", "@upstash/context7-mcp@latest" ] } } } ``` **方式二:Streamable HTTP方式** ```json { "mcpServers": { "context7": { "url": "https://mcp.context7.com/mcp" } } } ``` ### 步骤2:验证配置 1. **检查MCP连接状态** - 打开Cursor命令面板(Ctrl/Cmd + Shift + P) - 输入"MCP"进入Open MCP Setting查看MCP服务器状态 - 确认Context7服务器已连接 ### 步骤3:在编程中使用MCP 在编程辅助中触发MCP查询,在提示中指定使用MCP/Context7: 在Cursor的Composer模式(代码生成)或Chat模式中,总是添加"use context7"或"query MCP server for [specific doc]"到你的提示开头。 **示例提示**: - "use context7: 根据我的项目文档,帮我实现一个新功能:调用account模块的xxx接口完成xxx,使用最新API。" - "query MCP server: 解释项目中[特定文件/模块]的用法,并生成示例代码。" 这会强制AI通过MCP服务器查询Context7中的文档,而不是依赖其内置知识,确保响应基于你的最新文档。 **结合Cursor的其他功能**: - 使用@docs或@codebase来结合本地代码和MCP查询,例如:"@docs use context7: 查找项目中数据库schema的文档。" - 在规则(Rules)中设置默认:去Settings > Rules,添加一条规则如"Always use MCP for doc queries",让AI自动优先MCP。 --- *更多AI辅助编程技巧将随着社区实践持续更新。* --- # ASAN使用教程 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/asan_tool/ASAN_guide.html > Language: zh # ASAN使用教程 ## 1. 需要在单板上配置的环境变量 ```shell export ASAN_OPTIONS=halt_on_error=0:log_path=/home/asan/log:detect_leaks=1 export UBSAN_OPTIONS=halt_on_error=0:log_path=/home/asan/log:detect_leaks=1 export LSAN_OPTIONS=exitcode=0:use_unaligned=1:leak_check_at_exit=1:verbosity=1:log_threads=1 export PATH=$PATH:/home/asan export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/asan ``` ## 2. 修改编译选项 增加如下选项: ```shell -fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize-recover=address,all -fno-var-tracking -fno-omit-frame-pointer -fno-stack-protector -static-libasan ``` ## 3. 导入ASAN库文件 路径:`/opt/hcc_arm64le/aarch64-linux-gnu/lib64/` 需要两个文件:`libubsan.so.0.0.0`和`libasan.so.4.0.0` 修改名称为`libubsan.so.0`和`libasan.so.4`,放到单板`/home/asan`目录下。 ## 4. 修改App注册信号处理函数 因为ASAN内存泄漏只在进程结束时检查,所以常驻进程需要增加退出接口。 ```c int __lsan_do_leak_check(); LOCAL void redfish_exit_for_asan(int sig) { debug_log(DLOG_ERROR, "start appname exit for asan!"); __lsan_do_leak_check(); vos_task_delay(5000UL); exit(0); debug_log(DLOG_ERROR, "end appname exit for asan!"); } ``` 在init函数中增加注册:`signal(44, redfish_exit_for_asan);` ## 5. 编译App 需要使用带符号表的App进行检测。 ## 6. 确认App执行权限 内存泄漏检测会用到ptrace连接到线程进行内存泄漏检测。 ptrace当前rtos权限限制,只有root用户有权限使用。所以要去掉App降权限操作。 ## 7. 导入App到单板,使用root用户执行 复现问题,使用如下命令启动App: ```bash LD_PRELOAD=/home/asan/libasan.so.4:/home/asan/libubsan.so.0:$LD_LIBRARY_PATH ./kvm_vmm & ``` ## 8. 触发内存泄漏检测 执行:`kill -s 44 pid` 触发内存泄漏检测。 ## 9. 查看日志 在`/home/asan/`目录下查看日志,查看`log.pid`文件。 **其他编译选项说明:** 如下两个参数同时使用,会一个输出到log日志,一个输出到当前窗口: ```shell -fsanitize=address -fsanitize=undefined ``` 如下选项链接静态库使用: ```shell -static-libasan ``` ## 其他说明 ### 规避SEGV错误 增加环境变量:`handle_segv=0` ```shell export ASAN_OPTIONS=halt_on_error=0:use_sigaltstack=0:fast_unwind_on_fatal=1:fast_unwind_on_check=1:fast_unwind_on_malloc=1:malloc_context_size=15:dump_instruction_bytes=1:quarantine_size=4194304:log_path=/mbsc/maintain_log/asan.log:allow_user_segv_handler=1:intercept_tls_get_addr=0:detect_leaks=0:suppressions=$SUPP_FILE:print_suppressions=0:alloc_dealloc_mismatch=0:use_unaligned=1:new_delete_type_mismatch=0 ``` **ASAN_OPTIONS参数说明:** - ASAN_OPTIONS是Address-Sanitizer的运行选项环境变量 - log_path是执行检查报告的输出路径 - alloc_dealloc_mismatch:申请内存与释放内存不匹配,=0表示关闭 - new_delete_type_mismatch:new与delete申请释放类型不匹配,例如new[]的内存用delete释放,=0表示关闭 ```shell export LSAN_OPTIONS=exitcode=0:use_unaligned=1 ``` **LSAN_OPTIONS参数说明:** LSAN_OPTIONS是LeakSanitizer运行选项的环境变量,而LeakSanitizer是ASAN的内存泄漏检测模块。 ## App实践示例 ### 需要的编译选项 ```shell -fsanitize=address -fsanitize-recover=address,all -fno-var-tracking -fno-omit-frame-pointer -fno-stack-protector -O0 ``` **注意:** `-fsanitize-recover`这个选项必须加上,否则检测到一个错误就直接退出。 ### 环境变量 ```shell export ASAN_OPTIONS=halt_on_error=false:detect_leaks=1 ``` 也可以指定日志路径: ```shell export ASAN_OPTIONS=halt_on_error=false:detect_leaks=1:log_path=/home/asan ``` **说明:** `halt_on_error`是配合`-fsanitize-recover`一起起作用的,保证检测到错误后继续运行。 ### 执行方式 在编译完成后,如果使用CLion执行会直接报错退出,需要用命令行执行,才能正确显示ASAN信息。 ### 检测classtree中的内存泄漏示例 进行了10次加载与释放,每次泄漏了121个objects,242bytes的内存。最后定位到是hashtable没有释放内存。 **提示:** `g_hash_table_new_full`如果使用int作为key,有两种写法: - 一种是`g_direct_hash+GINT_TO_POINTER`(这种不需要释放内存) - 一种是`g_int_hash`(需要释放) ### 使用ASAN库 使用的时候,需要指定ASAN的lib库: ```shell LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/9/libasan.so ./security_policy ``` ### 所有环境变量 ```shell ASAN_OPTIONS=halt_on_error=false:detect_leaks=1;LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/9/libasan.so ``` --- # 使用Asan定位内存泄漏问题 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/asan_tool/Asan_identify_memory_leaks.html > Language: zh Asan是一种内存错误检测工具,可以帮助我们定位内存泄漏问题。本文以devmon组件为例,介绍如何使用Asan工具定位内存泄漏问题 ## Asan简介 关于Asan工具,可以查看[ASAN使用教程](./ASAN_guide.md)进行初步了解 ## 使用Asan定位内存泄漏问题流程 以devmon为例([devmon示例](https://gitcode.com/openUBMC/devmon/pull/171/diffs)),使用Asan的流程为:加上Asan相关编译选项、打包Asan相关的库、修改systemd配置,通过log_path指定Asan日志输出位置,其他组件也可以参考做类似修改集成Asan。下面分步骤进行介绍 ### 加上Asan相关编译选项 可以参考devmon示例中conanfile.py添加的代码,进行添加 ```python # 如果启用了 ASan,添加编译和链接选项 # if self.options.get_safe("asan", False): print("Enable ASan flags for Meson build") # 将 ASan 标志分开添加,避免 Meson 将它们当作单个参数 asan_compile_flags = [ "-fsanitize=address", "-fsanitize-recover=address,all", "-fno-omit-frame-pointer", "-fno-stack-protector", "-O1" ] for flag in asan_compile_flags: tc.extra_cflags.append(flag) tc.extra_cxxflags.append(flag) tc.extra_ldflags.append("-fsanitize=address") # 设置 ASan 相关环境变量 if self.settings.arch == "armv8": # 交叉编译环境,设置 ASan 库路径 toolchain_libdir = "/opt/hcc_arm64le/aarch64-target-linux-gnu/lib64" if os.path.exists(toolchain_libdir): tc.extra_ldflags.append(f"-Wl,-rpath-link,{toolchain_libdir}") ``` ### 打包Asan相关的库 可以参考devmon示例中conanfile.py的_package_asan_libs方法的修改,进行添加 ```python def _package_asan_libs(self): """打包 AddressSanitizer 运行时库""" import subprocess print("Packaging AddressSanitizer runtime libraries...") # 确定目标库目录 if self.settings.arch == "armv8" or self.settings.arch == "x86_64": target_libdir = os.path.join(self.package_folder, "usr/lib64") else: target_libdir = os.path.join(self.package_folder, "usr/lib") os.makedirs(target_libdir, exist_ok=True) # 根据架构查找 ASan 库 asan_lib_paths = [] if self.settings.arch == "armv8": # 交叉编译环境 toolchain_libdir = "/opt/hcc_arm64le/aarch64-target-linux-gnu/lib64" if os.path.exists(toolchain_libdir): # 查找 libasan.so* for file in os.listdir(toolchain_libdir): if file.startswith("libasan.so"): asan_lib_paths.append(os.path.join(toolchain_libdir, file)) elif self.settings.arch == "x86_64": # 本地编译环境 # 尝试通过 gcc 查找 libasan 路径 try: result = subprocess.run( ["gcc", "-print-file-name=libasan.so"], capture_output=True, text=True, timeout=10 ) if result.returncode == 0 and result.stdout.strip(): libasan_path = result.stdout.strip() if os.path.exists(libasan_path): # 获取目录并查找所有相关文件 libasan_dir = os.path.dirname(libasan_path) for file in os.listdir(libasan_dir): if file.startswith("libasan.so"): asan_lib_paths.append(os.path.join(libasan_dir, file)) except Exception as e: print(f"Warning: Failed to find libasan: {e}") # 复制 ASan 库到包中 if asan_lib_paths: for lib_path in asan_lib_paths: if os.path.isfile(lib_path): print(f" Copying {lib_path} to {target_libdir}") copy(self, os.path.basename(lib_path), src=os.path.dirname(lib_path), dst=target_libdir) elif os.path.islink(lib_path): # 处理符号链接 link_target = os.readlink(lib_path) link_name = os.path.basename(lib_path) target_link = os.path.join(target_libdir, link_name) if not os.path.exists(target_link): os.symlink(link_target, target_link) print(f" Created symlink {target_link} -> {link_target}") print(f"Successfully packaged {len(asan_lib_paths)} ASan library files") else: print("Warning: No ASan libraries found to package") ``` ### 修改systemd配置,通过log_path指定Asan日志输出位置 可以参考devmon示例中devmon.service中进行的修改,进行添加 ```shell Environment="ASAN_OPTIONS=abort_on_error=1:detect_leaks=1:verbosity=1:log_path=/data/asan.log" Environment="LD_PRELOAD=/usr/lib64/libasan.so.4" ``` --- # busctl 命令使用介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/busctl_cmds/Busctl_command.html > Language: zh # busctl 命令使用介绍 ## 1. 背景 目前openUBMC组件基于D-Bus开发,所有的进程间公共资源在D-Bus中进行管理。对组件而言,使用预定义的资源树进行解耦,降低组件间依赖。busctl是systemd提供的一个D-Bus操作工具,可以用来帮助我们直接对每个组件的属性、方法进行操作,以此观察组件的业务功能是否正常。 **相关资料:** - [busctl中文手册](http://www.jinbuguo.com/systemd/busctl.html) - openUBMC通信机制(sdbus) - [D-Bus说明书](https://dbus.freedesktop.org/doc/dbus-specification.html) - [dbus-python指导](https://dbus.freedesktop.org/doc/dbus-python/tutorial.html) - [D-Bus入门指导](https://thebigdoc.readthedocs.io/en/latest/dbus/dbus.html) ## 2. 概念介绍 - **D-Bus**:一种协议,实现了进程间通信的两种方式(RPC、发布/订阅),我们使用的是其中一种实现sdbus。 - **总线**:一种应用于进程间通信的机制。一般有两个总线,分别为系统总线和会话总线,前者由系统与后台进程使用,后者由普通进程创建,用于进程间传递消息与远程调用。我们使用会话总线(busctl需要使用`--user`参数)。 - **服务**:每个进程提供的对象合集,标识一个D-Bus连接。 - **对象**:看起来像一个Linux路径,每个对象路径提供不同的接口。 - **接口**:通过接口挂载一组方法和属性。 - **方法**:具体实现业务逻辑的方法,例如新建用户。 - **属性**:标识一个属性值,可以设置为只读或者读写。 - **签名**:对应方法和属性的参数类型。 ![alt text](../images/busctl_cmds/Busctl_command/image.png) ![alt text](../images/busctl_cmds/Busctl_command/image-1.png) ## 3. 环境准备 busctl命令运行需要依赖环境的D-Bus运行,涉及两个环境变量需要设置: ```bash # 在环境上执行如下命令 source /etc/profile # 或者也可以只执行如下环境变量的预置 export $(cat /dev/shm/dbus/.dbus) # 环境变量类似这样: # DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-WaRKgV2RBe,guid=627192aff1f4bf50b871be0562272a36 # DBUS_SESSION_BUS_PID=1719 ``` D-Bus运行的情况可以使用`ps`命令查看。 ## 4. 命令介绍 整体命令包括查询信息、设置属性、调用方法几类。根据相关签名,可以构造对应数据,涉及数组类型数据的,参数传递时,第一个参数是数组长度n,后续n个参数是对应的数组内容,其中byte数组对应的是对应的int数值。 ### 4.1 查看服务提供的所有对象资源路径 ```bash busctl --user tree ``` ### 4.2 查看对象资源的方法和属性 ```bash busctl --user introspect bmc.kepler.iam /bmc/kepler/AccountService/Accounts/2 busctl --user introspect bmc.kepler.iam /bmc/kepler/SessionService/Sessions ``` ### 4.3 设置对象属性 ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/Accounts/3 bmc.kepler.AccountService.ManagerAccount UserName s test3333 ``` ### 4.4 获取对象属性 ```bash busctl --user get-property bmc.kepler.iam /bmc/kepler/AccountService/Accounts/2 bmc.kepler.AccountService.ManagerAccount UserName ``` ### 4.5 方法调用示例 ```bash # 新建账户 busctl --user call bmc.kepler.iam /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts New a{sv}ysayyay 3 Interface s Web UserName s Administrator ClientAddr s 127.0.0.1 7 test7 11 65 100 109 105 110 64 57 48 48 48 48 4 1 2 # 新建会话 busctl --user call bmc.kepler.iam /bmc/kepler/SessionService/Sessions bmc.kepler.SessionService.Sessions NewSession a{ss}sayyssy 0 Administrator 11 65 100 109 105 110 64 57 48 48 48 48 0 LocaliBMC 192.168.1.1 0 # 时区设置 busctl --user set-property bmc.kepler.bmc_time /bmc/kepler/Managers/1 bmc.kepler.Managers.Time TimeZoneName s -- "-11:59" # 网络IP设置 busctl --user call bmc.kepler.bmc_network /bmc/kepler/bmc_network bmc.kepler.bmc_network SetIpMaskGateway sss 255.255.252.0 xx.xx.16.1 ``` ## 5. 签名类型 [签名的参数对应GVariant定义](https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/glib/glib-GVariant.html#GVariant) ```c 新建账户 busctl --user call bmc.kepler.iam /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts New a{sv}ysayyay 3 Interface s Web UserName s Administrator ClientAddr s 127.0.0.1 7 test7 11 65 100 109 105 110 64 57 48 48 48 48 4 1 2 新建会话 busctl --user call bmc.kepler.iam /bmc/kepler/SessionService/Sessions bmc.kepler.SessionService.Sessions NewSession a{ss}sayyssy 0 Administrator 11 65 100 109 105 110 64 57 48 48 48 48 0 LocaliBMC 192.168.1.1 0 时区设置 busctl --user set-property bmc.kepler.bmc_time /bmc/kepler/Managers/1 bmc.kepler.Managers.Time TimeZoneName s -- "-11:59" 网络ip设置 busctl --user call bmc.kepler.bmc_network /bmc/kepler/bmc_network bmc.kepler.bmc_network SetIpMaskGateway sss 255.255.252.0 xx.xx.16.1 ``` ## 签名类型 [签名的参数对应gvariant定义](https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/glib/glib-GVariant.html#GVariant) ```c typedef enum { G_VARIANT_CLASS_BOOLEAN = 'b', G_VARIANT_CLASS_BYTE = 'y', G_VARIANT_CLASS_INT16 = 'n', G_VARIANT_CLASS_UINT16 = 'q', G_VARIANT_CLASS_INT32 = 'i', G_VARIANT_CLASS_UINT32 = 'u', G_VARIANT_CLASS_INT64 = 'x', G_VARIANT_CLASS_UINT64 = 't', G_VARIANT_CLASS_HANDLE = 'h', G_VARIANT_CLASS_DOUBLE = 'd', G_VARIANT_CLASS_STRING = 's', G_VARIANT_CLASS_OBJECT_PATH = 'o', G_VARIANT_CLASS_SIGNATURE = 'g', G_VARIANT_CLASS_VARIANT = 'v', G_VARIANT_CLASS_MAYBE = 'm', G_VARIANT_CLASS_ARRAY = 'a', G_VARIANT_CLASS_TUPLE = '(', G_VARIANT_CLASS_DICT_ENTRY = '{' } GVariantClass; ``` **GVariant类型的取值范围:** | 类型 | 说明 | |------|------| | `G_VARIANT_CLASS_BOOLEAN` | The GVariant is a boolean. | | `G_VARIANT_CLASS_BYTE` | The GVariant is a byte. | | `G_VARIANT_CLASS_INT16` | The GVariant is a signed 16 bit integer. | | `G_VARIANT_CLASS_UINT16` | The GVariant is an unsigned 16 bit integer. | | `G_VARIANT_CLASS_INT32` | The GVariant is a signed 32 bit integer. | | `G_VARIANT_CLASS_UINT32` | The GVariant is an unsigned 32 bit integer. | | `G_VARIANT_CLASS_INT64` | The GVariant is a signed 64 bit integer. | | `G_VARIANT_CLASS_UINT64` | The GVariant is an unsigned 64 bit integer. | | `G_VARIANT_CLASS_HANDLE` | The GVariant is a file handle index. | | `G_VARIANT_CLASS_DOUBLE` | The GVariant is a double precision floating point value. | | `G_VARIANT_CLASS_STRING` | The GVariant is a normal string. | | `G_VARIANT_CLASS_OBJECT_PATH` | The GVariant is a D-Bus object path string. | | `G_VARIANT_CLASS_SIGNATURE` | The GVariant is a D-Bus signature string. | | `G_VARIANT_CLASS_VARIANT` | The GVariant is a variant. | | `G_VARIANT_CLASS_MAYBE` | The GVariant is a maybe-typed value. | | `G_VARIANT_CLASS_ARRAY` | The GVariant is an array. | | `G_VARIANT_CLASS_TUPLE` | The GVariant is a tuple. | | `G_VARIANT_CLASS_DICT_ENTRY` | The GVariant is a dictionary entry. | ## 6. 常用命令示例 ### 6.1 Trust组件命令 #### 查看证书服务资源信息 ```bash busctl --user introspect bmc.kepler.trust /bmc/kepler/CertificateService ``` #### 导入CA证书 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService ImportCert a{ss}issu 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 0 URI /tmp/ca.crt 0 busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService ImportCert a{ss}issu 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 0 text ./redfish/test/integration/.test_temp_data/RootCA.crt 0 ``` #### 查看CA证书 ```bash busctl --user introspect bmc.kepler.trust /bmc/kepler/Managers/1/Certificates/1 busctl --user get-property bmc.kepler.trust /bmc/kepler/Managers/1/Certificates/1 bmc.kepler.CertificateService.Certificate Subject ``` #### 查看SSL证书 ```bash busctl --user introspect bmc.kepler.trust /bmc/kepler/Managers/1/NetworkProtocol/HTTPS/Certificates/1 busctl --user get-property bmc.kepler.trust /bmc/kepler/Managers/1/NetworkProtocol/HTTPS/Certificates/1 bmc.kepler.CertificateService.Certificate Subject ``` #### 导入带私钥的SSL证书 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService ImportCertWithKey a{ss}sss 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 URI /tmp/cert.p12 123456 busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService ImportCertWithKey a{ss}sss 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 URI "https://75.255.11.115:18082/openssl3/v5/server_chain.p12" 123456 ``` **注意:** 有时需要重设BMC时间,否则证书因时间不正确无法导入: ```bash date -s "2023-05-30 00:00:00" ``` #### 开始生成CSR ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService StartGenerateCSR a{ss}ssssss 0 CN '' '' '' '' HW ``` #### 检查生成CSR的状态 查看CSR任务即可: ```bash busctl --user introspect bmc.kepler.trust /bmc/kepler/CertificateService/TaskService/Tasks/ ``` #### 导入CSR签名的证书 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService ImportCert a{ss}issu 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 1 /tmp/ssl.cert 0 ``` #### 获取证书链信息 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService GetCertChainInfo a{ss}iu 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 0 4 ``` #### 导出证书私钥到FIFO管道 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService ExportCertKeyByFIFO a{ss}i 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 1 ``` #### 导入吊销列表 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService ImportCRL a{ss}ssu 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 URI /tmp/test.crl 0 ``` #### 删除吊销列表 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/Managers/1/Certificates/1 bmc.kepler.CertificateService.Certificate DeleteCRL a{ss} 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 ``` #### 加密套件相关 **查看加密套件方法:** ```bash busctl --user introspect bmc.kepler.trust /bmc/kepler/Managers/1/Security/TlsConfig/CipherSuits ``` **查看具体某个加密套件属性:** ```bash busctl --user introspect bmc.kepler.trust /bmc/kepler/Managers/1/Security/TlsConfig/CipherSuits/2 ``` **修改加密套件:** ```bash busctl --user call bmc.kepler.trust /bmc/kepler/Managers/1/Security/TlsConfig/CipherSuits bmc.kepler.Managers.Security.TlsConfig.CipherSuits SetSslCipherSuit a{ss}aiab 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 2 1 2 2 1 0 ``` #### 获取证书路径 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService GetCertPath a{ss}i 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 0 ``` #### 设置SSL证书生成算法 ```bash busctl --user set-property bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService SSLCertAlgorithm y 1 ``` #### 修改证书过期告警时间 ```bash busctl --user set-property bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService CertOverdueWarnDays u 89 ``` #### 设置默认证书名称 ```bash busctl --user call bmc.kepler.trust /bmc/kepler/CertificateService bmc.kepler.CertificateService SetDefaultSSLCertSubject a{ss}sss 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 CN 'Huawei IT Product CA' Huawei ``` #### 查看用户ID为2的信息 ```bash busctl --user introspect bmc.kepler.iam /bmc/kepler/AccountService/Accounts/2 ``` #### 查看会话基本属性信息 ```bash busctl --user introspect bmc.kepler.iam /bmc/kepler/SessionService ``` #### 查看账户基本属性信息 ```bash busctl --user introspect bmc.kepler.iam /bmc/kepler/AccountService ``` #### 设置用户ID为2的用户提示修改首次登录密码 ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/Accounts/2 bmc.kepler.AccountService.ManagerAccount FirstLoginPolicy y 1 busctl --user get-property bmc.kepler.iam /bmc/kepler/AccountService/Accounts/2 bmc.kepler.AccountService.ManagerAccount FirstLoginPolicy ``` #### 设置用户ID为2的用户强制修改首次登录密码 ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/Accounts/2 bmc.kepler.AccountService.ManagerAccount FirstLoginPolicy y 2 ``` #### 关闭所有用户的首次登录提示(暂不适用) ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService bmc.kepler.AccountService.Security InitialPasswordPromptEnable b 0 ``` #### 打开所有用户的首次登录提示(暂不适用) ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService bmc.kepler.AccountService.Security InitialPasswordPromptEnable b 1 ``` #### 设置用户名 ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/Accounts/3 bmc.kepler.AccountService.ManagerAccount UserName s a ``` #### 设置锁定次数 ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService bmc.kepler.AccountService.Security AccountLockoutThreshold i 4 busctl --user get-property bmc.kepler.iam /bmc/kepler/AccountService bmc.kepler.AccountService.Security AccountLockoutThreshold ``` #### 会话超时设置 ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/SessionService/GUI bmc.kepler.SessionService SessionTimeout u 300 busctl --user get-property bmc.kepler.iam /bmc/kepler/SessionService/GUI bmc.kepler.SessionService SessionTimeout ``` #### 设置逃生用户 ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService bmc.kepler.AccountService.Security EmergencyLoginAccountId y 9 ``` #### 查询会话列表 ```bash busctl --user tree bmc.kepler.iam ``` 其中,`/bmc/kepler/SessionService/Sessions`下面展示了所有的会话信息。 #### 新建用户 ```bash busctl --user call bmc.kepler.iam /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts New a{ss}ysayyay 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 5 dzTJZkOsQL 14 65 56 100 50 109 105 110 64 104 119 49 50 35 36 4 7 64 8 16 4 1 128 2 ``` #### 设置用户角色 ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/Accounts/7 bmc.kepler.AccountService.ManagerAccount RoleId y 4 ``` #### 删除会话 ```bash busctl --user call bmc.kepler.iam /bmc/kepler/SessionService/Sessions/{id} bmc.kepler.SessionService.Session SessionDelete a{ss}y 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 0 ``` #### 设置密码 ```bash busctl --user call bmc.kepler.iam /bmc/kepler/AccountService/Accounts/2 bmc.kepler.AccountService.ManagerAccount ChangePwd a{ss}ay 3 Interface Web UserName Administrator ClientAddr 127.0.0.1 xx xx xx xx xx xx xx xx xx xx xx xx ``` #### 设置LDAP的UserDomain ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/LDAP/LDAPController/1 bmc.kepler.AccountService.LDAP.LDAPController UserDomain s "CN=test,DC=huawei,DC=com" busctl --user introspect bmc.kepler.iam /bmc/kepler/AccountService/LDAP/LDAPController/1 bmc.kepler.AccountService.ManagerAccount RoleId y 4 ``` #### SNMP相关 **设置长团体名使能(读写团体名使能RwCommunityEnabled):** ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity LongCommunityEnabled b false ``` **查询长团体名使能:** ```bash busctl --user get-property bmc.kepler.iam /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity LongCommunityEnabled ``` **获取团体名:** ```bash busctl --user call bmc.kepler.iam /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity GetSnmpCommunity a{ss} 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 ``` **设置团体名:** ```bash busctl --user call bmc.kepler.iam /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity SetRoCommunity a{ss}s 3 Interface Busctl UserName Administrator ClientAddr 127.1.2.1 xxxxxx ``` **设置SNMP登录规则:** ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/Accounts/20 bmc.kepler.AccountService.ManagerAccount LoginRuleIds as 1 Rule2 ``` **设置登录规则使能:** ```bash busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/Rules/2 bmc.kepler.AccountService.Rule Enabled b 1 busctl --user set-property bmc.kepler.iam /bmc/kepler/AccountService/Rules/2 bmc.kepler.AccountService.Rule IpRule s 12.12.12.12 ``` **校验登录规则:** ```bash busctl --user call bmc.kepler.iam /bmc/kepler/AccountService/Authorization bmc.kepler.AccountService.Authorization LoginRuleCheck a{ss}s 3 Interface Busctl UserName Administrator ClientAddr 127.1.2.1 ``` ### 6.3 其他组件命令 #### 升级相关 **获取升级状态:** ```bash busctl --user call bmc.kepler.firmware_mgmt /bmc/kepler/UpdateService bmc.kepler.UpdateService GetUpgradeStatus a{ss}u 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 1 ``` **开始升级(最后一个参数是文件路径):** ```bash busctl --user call bmc.kepler.firmware_mgmt /bmc/kepler/UpdateService bmc.kepler.UpdateService StartUpgrade a{ss}sa{ss} 3 Interface B UserName Administrator ClientAddr 127.0.0.1 '/tmp/openUBMC.hpm' 0 ``` **AC重启:** ```bash busctl --user call bmc.kepler.fructrl /bmc/kepler/Systems/1/FruCtrl/FruCtrl_1_0_0004 bmc.kepler.Systems.FruCtrl PowerCtrl a{ss}ss 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 ACCycle Unknown ``` **强制复位BMC:** ```bash busctl --user call bmc.kepler.maca /bmc/kepler/MacaService bmc.kepler.SystemControl ForceReset a{ss} 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 ``` **将串口切换到BMC:** 系统默认会将串口切换到OS侧,升级后可通过以下命令将串口切换到BMC,一键设置,永久有效: ```bash busctl --user call bmc.kepler.bmc_soc /bmc/kepler/Managers/1/SerialManagement/SerialManagement_1_00 bmc.kepler.Managers.SerialManagement SetConnectStatus a{ss} 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 ``` #### soctrl组件 **导入伙伴根hash:** ```bash busctl --user call bmc.kepler.soctrl /bmc/kepler/Managers/1/SOC/SecureCore bmc.kepler.Managers.SOC.SecureCore.SecureBoot ImportCustomCertificateHash a{ss} 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 ``` **导出伙伴根hash:** ```bash # PKCS格式 busctl --user call bmc.kepler.soctrl /bmc/kepler/Managers/1/SOC/SecureCore bmc.kepler.Managers.SOC.SecureCore.SecureBoot ExportCustomCertificateHash a{ss}i 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 0 # PSS格式 busctl --user call bmc.kepler.soctrl /bmc/kepler/Managers/1/SOC/SecureCore bmc.kepler.Managers.SOC.SecureCore.SecureBoot ExportCustomCertificateHash a{ss}i 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 1 ``` **禁用安全启动校验:** ```bash busctl --user call bmc.kepler.soctrl /bmc/kepler/Managers/1/SOC/SecureCore bmc.kepler.Managers.SOC.SecureCore.SecureBoot DisableBootVerification a{ss} 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 ``` **导出维修凭证:** ```bash busctl --user call bmc.kepler.soctrl /bmc/kepler/Managers/1/SOC/SecureCore bmc.kepler.Managers.SOC.SecureCore.SecureBoot ExportRepairCredentials a{ss} 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 ``` **导入维修凭据:** ```bash busctl --user call bmc.kepler.soctrl /bmc/kepler/Managers/1/SOC/SecureCore bmc.kepler.Managers.SOC.SecureCore.SecureBoot ImportRepairCredentials a{ss}ay 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 0 ``` #### FileTransfer组件 **下载文件:** ```bash busctl --user call bmc.kepler.file_transfer /bmc/kepler/Managers/1/FileTransfer bmc.kepler.Managers.FileTransfer StartTransfer a{ss}ssuuuu 3 Interface Busctl UserName Administrator ClientAddr 127.0.0.1 https://127.0.0.1:8443/data/trust/cert/ca/7a31456c.0 file:///tmp/test.crt 100000 1000 10000 384 ``` **查看FileTransfer服务资源:** ```bash busctl --user tree bmc.kepler.file_transfer busctl --user introspect bmc.kepler.file_transfer /bmc/kepler/Managers/1/FileTransfer/Tasks/0 ``` **禁用证书校验:** ```bash busctl --user set-property bmc.kepler.file_transfer /bmc/kepler/Managers/1/FileTransfer bmc.kepler.Managers.FileTransfer HttpsTransferCertVerification b false ``` #### maca组件 **设置日志级别:** ```bash busctl --user set-property bmc.kepler.maca /bmc/kepler/maca/MicroComponent bmc.kepler.MicroComponent.Debug DlogLevel s info ``` --- # 使用busctl手动发送smbus报文获取响应 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/busctl_cmds/busctl_smbus.html > Language: zh 以网卡为例,smbus的收发对应一个Chip,如下: ![image](../images/busctl_cmds/busctl_smbus/chip_info_1.png) ![image](../images/busctl_cmds/busctl_smbus/chip_info_2.png) 查询环境上该Chip ![image](../images/busctl_cmds/busctl_smbus/query_chip.png) 可发现其存在诸多方法 ![image](../images/busctl_cmds/busctl_smbus/view_resource_tree_method.png) WriteRead用于smbus,ComboWriteRead用于stdsmbus ![image](../images/busctl_cmds/busctl_smbus/WriteRead.png) 使用比较简单,传入data和期望读取长度即可 例如获取mac地址的请求为00 00 04 04 00 00 00 00 30 00 00 00 1E A1 83 2C 期望读取长度为64,则构造出busctl命令如下: ```bash busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Complex/Chip_Hi1822_0101010202 bmc.kepler.Chip.BlockIO WriteRead a{ss}ayu 0 0x10 00 00 04 04 00 00 00 00 0x30 00 00 00 0x1E 0xA1 0x83 0x2C 0x40 ```c 可获取到响应: ![image](../images/busctl_cmds/busctl_smbus/get_response.png) 手动发送结果,与代码正常收发保持一致: ![image](../images/busctl_cmds/busctl_smbus/manual_send_result.png) --- # 调试工具介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/http_debug_tool/debugging_tools.html > Language: zh 以下工具是常见的 BMC 调试工具,建议需要调试北向接口的开发者使用,本文档仅提供相关工具的外部链接,请按需安装。 ## ipmitool ipmitool是一款开源的流行IPMI工具,常用于与BMC通过IPMI协议进行访问。具体获取方法请参考[ipmitool Github主页](https://github.com/ipmitool/ipmitool)。 ## Postman Postman是一款免费的Rest API调试工具,常用于调试Rest API接口。具体获取方法请参考[Postman官网](https://www.postman.com)。 使用Postman工具进行HTTP协议接口测试的方法,以及调试过程中遇到的常见问题定位方法,请参考[HTTP接口调试指南](./http_interface_debug_guide.md)。 使用HTTP工具与openUBMC进行交互,包括使用POSTMAN和curl发送Redfish/Web REST请求,请参考[HTTP工具使用指导](./http_tool_user_guide.md)。 --- # HTTP接口调试指南 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/http_debug_tool/http_interface_debug_guide.html > Language: zh 本文档介绍HTTP协议接口(Web REST/Redfish)调试过程中遇到的常见问题定位方法,以及使用Postman工具进行接口测试的方法。 # 接口调试常见问题定位方法 ## 检查映射配置基本语法问题 在进行HTTP接口调试前,建议先检查接口映射配置是否存在基本的语法问题。openUBMC提供了映射器配置检查工具,可以在开发阶段自动发现配置错误。 ### 使用bingo build检查配置 在rackmount项目下执行`bingo build`命令时,会自动运行映射器配置检查工具,为开发者检查映射配置的基本用法正确性。 ```bash # 进入rackmount项目目录 cd /path/to/rackmount # 执行构建命令(会自动触发配置检查) bingo build ``` ### 配置检查内容 映射器配置检查工具会验证以下内容: | 检查项 | 说明 | | :----------- | :------------ | | 映射配置语法 | 检查配置文件是否符合格式规范 | | 字段完整性 | 检查必填字段是否存在 | | 引用有效性 | 检查映射配置中的引用是否存在 | | 功能检查 | 检查Uri是否全局唯一、动态槽位号合法性等 | | 脚本和插件有效性 | 检查映射配置中Script和Plugin关键字引用的脚本文件或插件文件及函数是否存在、入参个数是否相同 | > **注意**:配置检查工具只能发现基本的语法和结构问题,无法发现运行时的逻辑错误。配置检查通过后,仍需要在实际环境中测试接口功能。 ## 如何在实际环境中调试 在调试接口之前,首先需要了解映射配置在环境中的执行顺序,这有助于快速定位问题发生的环节。 ### 映射配置执行顺序 ```mermaid flowchart TD Start([请求到达]) --> ResExist[ResourceExist校验Uri合法性] ResExist -->|失败| ResExistErr[返回404资源不存在] ResExist -->|成功| ReqBody[校验ReqBody] ReqBody -->|失败| ReqBodyErr[返回400请求非法] ReqBody -->|成功| ProcessFlow[按映射配置顺序依次执行ProcessingFlow] ProcessFlow --> PFlowLoop{还有ProcessingFlow?} PFlowLoop -->|是| ExecuteFlow[执行下一个ProcessingFlow] ExecuteFlow --> PFlowLoop PFlowLoop -->|否| CheckMethod{请求方法?} CheckMethod -->|PATCH| GetGetConfig[获取对应GET接口的RspBody配置] CheckMethod -->|其他方法| GetRspConfig[获取当前接口的RspBody配置] GetGetConfig --> FillRspBody[按RspBody配置填充响应体] GetRspConfig --> FillRspBody FillRspBody --> SendResponse[发送响应给客户端] SendResponse --> End([请求完成]) ``` 映射配置按以下顺序执行: 1. **ResourceExist校验Uri合法性** - 校验请求的URI路径是否在映射配置中存在 - 如果不存在,返回404错误 2. **校验ReqBody** - 校验请求体是否符合映射配置中定义的格式 - 如果格式不正确,返回400错误 3. **按映射配置顺序依次执行ProcessingFlow** - 按照配置文件中ProcessingFlow的顺序依次执行 - 每个ProcessingFlow中的Statements按顺序执行 - 支持调用脚本或插件处理业务逻辑 4. **按RspBody的映射配置填充响应体** - 根据RspBody配置从资源树获取数据填充响应体 - **PATCH接口特殊处理**:PATCH接口的RspBody按对应GET接口的配置填充 - 其他方法(GET/POST/DELETE)使用当前接口的RspBody配置 ### 针对性调试方法 调试时应按照上述执行顺序,在每个环节检查可能出现的问题: #### 调试`ProcessingFlow`/`Statements`中的值 如果需要查看`ProcessingFlow`/`Statements`中的某个值是否正确,可以将该值配置到响应体中进行查看: ```json { "RspBody": { "debug_value": { "StatementsA": "${Statements/a()}", "ProcessingFlow1": "${ProcessingFlow[1]/Destination/List}" } } } ``` 发送请求后,从响应体中查看`debug_value`字段的值,确认`ProcessingFlow`/`Statements`是否正确执行。 #### 调试插件中的值 如果需要查看插件中某个变量的值,可以使用`log`函数将其打印到日志中: ```lua local log = require 'mc.logging' local cjson = require 'cjson' -- 插件代码示例 function process(input) { local tmp_value ... -- your code -- 打印到日志 -- 如果是lua table可以用cjson提供的encode函数转换成string快速打印 -- 在日志等级后添加_easy可以防止日志限流导致日志未打印或打印不全 log:error_easy('tmp_value=%s', cjson.encode(tmp_value)) ... } ``` 然后在BMC端查看日志: ```bash # 查看web_backend或redfish日志 tail -f /var/log/app.log | grep "tmp_value" ``` #### 调试脚本中的值 脚本中的值无法直接打印到日志,调试时可以采用以下方法: 1. **临时将脚本改为插件**:将脚本代码复制到插件中,使用`log`打印调试 2. **调试完成后改回脚本**:确认逻辑正确后,将插件改回脚本形式 示例步骤: ```json // 原脚本配置(无法打印日志) "Type": "Script", "Formula": "your_script.lua" // 临时改为插件(可以打印日志),将脚本文件复制到插件目录下 "Type": "Plugin", "Formula": "orchestrator.your_script.func(Input)" ``` 在插件代码中添加log日志。调试完成后,将插件改回脚本配置,删除或注释掉log语句。 ## 判断请求是否到达BMC 在进行HTTP接口调试之前,首先需要了解HTTP请求在BMC中的执行顺序,这有助于快速定位问题发生的环节。 ### HTTP请求在BMC中的执行顺序 ```mermaid flowchart LR Client[客户端] -->|1-请求| Nic[网卡] Nic -->|2-数据包| Iptables[iptables防火墙] Iptables -->|3-转发| Nginx[nginx反向代理] Nginx -->|4-代理| Backend[后台组件] Backend -->|5-响应| Nginx Nginx -->|6-返回| Iptables Iptables -->|7-返回| Nic Nic -->|8-响应| Client ``` HTTP请求在BMC中的完整执行路径如下: | 阶段 | 组件 | 说明 | 常见问题 | | :--- | :--- | :--- | :--- | | **1** | 网卡 | 接收客户端发送的网络数据包 | 网络不通、防火墙拦截 | | **2** | iptables | 防火墙规则校验,决定是否放行 | 端口未开放、规则拒绝 | | **3** | nginx | 反向代理,解析请求并转发 | nginx未启动、配置错误 | | **4** | 后台组件 | 业务逻辑处理(web_backend/redfish) | 服务异常、处理超时 | | **5-8** | 原路返回 | 响应数据按相反路径返回给客户端 | 同上 | ### 各环节出现问题排查方法 怀疑请求在某环节丢失时,可以按照下面的方法进行排查定位: #### 第一步:检查网卡接收(tcpdump抓包) 使用tcpdump在网卡层面抓包,确认请求是否到达BMC网卡。 ```bash # 抓取HTTPS流量(默认端口443) tcpdump -i any port 443 -n -A # 抓取特定客户端的流量(以192.168.1.100为例) tcpdump -i any host 192.168.1.100 -n # 抓取HTTP流量(默认端口80) tcpdump -i any port 80 -n -A # 将抓包结果保存到文件,使用Wireshark分析 tcpdump -i any port 443 -w /tmp/capture.pcap ``` **判断依据**: - 如果能抓到包:说明请求到达了网卡,继续下一步检查 - 如果抓不到包:说明网络层面有问题,检查网络连通性、防火墙等 #### 第二步:检查iptables防火墙规则 确认iptables规则是否允许HTTP/HTTPS对应端口的流量通过(以443端口为例)。 ```bash # 查看iptables规则 iptables -L -n -v # 查看INPUT链规则(入站流量) iptables -L INPUT -n -v --line-numbers # 检查443端口是否开放 iptables -L INPUT -n -v | grep 443 # 检查是否有拒绝规则 iptables -L INPUT -n -v | grep DROP iptables -L INPUT -n -v | grep REJECT ``` 可以比较发送前后端口流量记录,用于判断请求是否到iptables。 **判断依据**: - 如果有ACCEPT规则允许HTTP/HTTPS端口:说明防火墙配置正确 - 如果有DROP/REJECT规则:说明被防火墙拦截 - 如果没有相关规则:检查默认策略是否为ACCEPT #### 第三步:检查nginx日志 nginx日志会记录所有到达nginx的请求,是判断请求是否到达nginx的关键依据。一般判断请求是否被nginx收到,查看`access_log`即可。 **环境日志路径**: - **access日志**:`/dev/shm/log/web/access_log` - **error日志**:`/dev/shm/log/web/error_log` **一键收集日志路径**: - **access日志**:`3rdDump/access_log` - **error日志**:`3rdDump/error_log` ```bash # 实时查看access日志 tail -f /dev/shm/log/web/access_log # 查看最近的请求记录 tail -n 50 /dev/shm/log/web/access_log # 按条件筛选日志(查找特定IP或URI) grep "192.168.1.100" /dev/shm/log/web/access_log grep "/redfish/v1" /dev/shm/log/web/access_log # 查看error日志 tail -n 100 /dev/shm/log/web/error_log ``` **access日志格式说明**: ```txt $remote_addr - $remote_user [$time_iso8601] $msec $request_time "$request_method $uri $server_protocol" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"; ``` **示例日志**: ```log 192.168.1.100 - - [2026-02-04T20:47:32+00:00] 1770238052.558 0.429 "GET /redfish/v1/Managers/1/LogServices/OperateLog/Entries HTTP/1.1" 200 12345 "-" "PostmanRuntime/7.32.1" "-" ``` 从日志中可以获取: - 客户端IP地址 - 请求时间 - 请求方法和URI - 响应状态码 - 响应字节数 - User-Agent信息 **判断依据**: - 如果access日志有记录:说明请求通过了nginx,继续检查后台组件 - 如果access日志无记录:说明请求没有到达nginx,检查nginx服务状态 - 如果error日志有错误:查看错误信息定位问题 #### 第四步:检查后台组件日志 后台组件(web_backend/redfish)负责实际的业务逻辑处理。 ```bash # 查看运行日志是否有异常 tail -f /var/log/app.log ``` **判断依据**: - 如果日志正常:说明后台组件处理正常 - 如果有错误日志:根据错误信息定位问题 #### 第五步:检查服务进程状态 检查相关服务是否正常运行。 ```bash # 检查nginx进程状态 # 一般会有1个master进程,2个worker进程 ps -aux | grep nginx # 检查后台组件所属进程状态 ps -aux | grep interface # 检查nginx端口监听状态 netstat -tlnp | grep -E "80|443" ``` ### 排查流程总结 根据上述检查结果,可以快速定位问题: | 现象 | 可能原因 | 下一步操作 | | :--- | :--- | :--- | | tcpdump抓不到包 | 网络不通/防火墙拦截 | 检查网络连通性、防火墙规则 | | 抓到包但nginx无日志 | nginx服务异常 | 检查nginx服务状态、配置 | | nginx有日志但后台无日志 | 后台服务异常 | 检查后台服务状态、日志 | | 日志正常但客户端超时 | 响应返回路径问题 | 检查iptables出站规则,检查日志是否有访问超时 | --- # Postman工具使用指南 Postman是一款功能强大的API测试工具,支持HTTP协议的各种请求方法,非常适合用于Web REST和Redfish接口的调试测试。 ## 安装Postman Postman提供多平台支持: - **桌面版**:从官网下载安装 - **浏览器插件版**:支持Chrome浏览器 ## Postman基本界面介绍 ![image](../images/http_debug_tool/http_interface_debug_guide/Postman_interface.png) Postman主界面包含以下主要部分: 1. **请求方法选择**:GET、POST、DELETE、PATCH等 2. **URL输入框**:输入请求的完整URL 3. **Authorization标签页**:配置认证信息 4. **Headers标签页**:配置请求头 5. **Body标签页**:配置请求体 6. **响应区域**:查看服务器返回的响应 7. **代码片段图标**(``):点击可生成各种编程语言的请求代码(如cURL、JavaScript、Python等),方便将请求集成到代码中 8. **Cookies标签页**:管理请求相关的Cookie,可以查看、添加或编辑Cookie,Postman会自动保存和管理服务端返回的Cookie信息 ## Web REST接口测试 ### Login登录 Web REST接口使用X-CSRF-Token进行认证,首先需要调用登录接口获取Token。 **登录接口信息**: - **URL**:`https:///UI/Rest/Login` - **方法**:POST - **Content-Type**:application/json **请求示例**: 1. 在Postman中创建新请求,设置以下参数: - **Method**: POST - **URL**: `http://192.168.1.100/UI/Rest/Login` 2. 设置请求头(Headers): ```txt Content-Type: application/json ``` 3. 设置请求体(Body),选择raw中的JSON格式: ```json { "UserName": "Administrator", "Password": "admin123", "Type": "Local", "Domain": "AutomaticMatching" } ``` 4. 发送请求,成功返回示例: ```json { "Session": { "SessionID": "987654321aaa", "UserID": "2", "LoginTime": "2026-02-03T18:00:00+00:00", "UserName": "Administrator", "IP": "12.34.56.78", "Role": [ "Administrator" ] }, "DaysBeforeExpiration": 4294967295, "InsecurePromptEnabled": "Off", "LastLoginTime": "2026-02-03T17:55:00+00:00", "LastLoginIP": "12.34.56.78", "XCSRFToken": "abcdef1234567890abcdef1234567890" } ``` 5. 保存返回的`XCSRFToken`,后续请求需要使用。 ### 使用X-CSRF-Token访问接口 获取Token后,在后续的Web REST请求中需要携带Token进行认证。 **配置方式:在Headers中添加Token** 在Headers标签页添加: ```txt X-CSRF-Token: abcdef1234567890abcdef1234567890 ``` **请求示例**: ```txt GET https://192.168.1.100/UI/Rest/Services/PortConfig Headers: X-CSRF-Token: abcdef1234567890abcdef1234567890 ``` ### Token过期处理 Web REST的Token有时效性(可以登录web页面在服务管理-Web服务查看/修改超时时长),当Token过期时,接口会返回401状态码。此时需要重新调用Login接口获取新Token。 ### Cookie会话管理 openUBMC的Web REST接口实际采用Cookie/SessionId+Token共同认证的方式。当调用Login登录后,服务端会将响应头`Set-Cookie`字段的值置为当前激活会话的信息,服务端可以在响应体`Cookies`字段获取这些信息,特别是`SessionId`字段。获取`Cookies`各字段的值后,在后续的Web Rest请求中需要在请求头中携带`Cookie: SessionId=xxx`进行认证。 Token和Cookie是关联的,Token进行API鉴权,Cookie维持会话状态;Token告诉服务器“这个请求有API访问权限”,而Cookie告诉服务器“这个用户会话有效”。 > 那为什么使用Postman时我们不需要显式传入Cookie呢? > > 发送Login登录成功后,点击Postman页面的`Cookies`按钮,可以查看Postman维护的向各个环境发送请求的Cookies信息,查看这个页面刚才登录成功的环境的Cookies信息,可以发现保存的信息中SessionId的值与Login登录成功后返回的Cookies信息相同。每次向服务端发送登录请求成功,Postman会保存服务端IP-会话信息,并在你后续访问中自动携带,因此不需要用户手动显式传入。 ## Redfish接口测试 Redfish接口支持两种认证方式:Basic Auth(用户密码认证)和Session认证。 ### 方法1:Basic Auth认证 Basic Auth是最简单的认证方式,每次请求都携带用户名和密码。 **配置方式**: 1. 在Postman中创建新请求 2. 进入Authorization标签页,配置如下: - **Type**: `Basic Auth` - **Username**: 输入BMC用户名(如admin) - **Password**: 输入密码 3. Postman会自动在请求头中添加`Authorization`字段 **请求示例**: ```txt GET https://192.168.1.100/redfish/v1/Managers Authorization: Basic YWRtaW46YWRtaW4xMjM= ``` **注意事项**: - Basic Auth会将用户名密码进行Base64编码传输,非加密 - 建议在HTTPS环境下使用 - 适合简单的接口测试场景 ### 方法2:Session认证 Session认证更安全,通过创建会话获取Token,后续请求使用该Token。 #### Step 1:创建Session **创建Session接口信息**: - **URL**:`https:///redfish/v1/SessionService/Sessions` - **方法**:POST - **Content-Type**:application/json **请求配置**: 1. 使用Basic Auth方式(参考上面方法1) 2. 设置请求头: ```txt Content-Type: application/json ``` 3. 设置请求体: ```json { "UserName": "Administrator", "Password": "admin123" } ``` 4. 发送请求,成功返回示例(状态码201): ```json { "@odata.context": "/redfish/v1/$metadata#Session.Session", "@odata.id": "/redfish/v1/SessionService/Sessions/123456789aaa", "@odata.type": "#Session.v1_7_2.Session", "Id": "123456789aaa", "Name": "User Session", "ClientOriginIPAddress": "12.34.56.78", "CreatedTime": "2026-02-03T18:00:00+00:00", "Roles": [ "Administrator" ], "SessionType": "Redfish", "OemSessionType": "Redfish", "Oem": { "openUBMC": { "UserAccount": "Administrator", "LoginTime": "2026-02-03T18:00:00+00:00", "UserIP": "12.34.56.78", "UserTag": "Redfish", "MySession": true, "UserId": 2, "UserValidDays": null, "AccountInsecurePromptEnabled": false, "UserRole": [ "Administrator" ] } } } ``` 5. 从响应头`Headers`中获取Token: - 响应头字段:`X-Auth-Token` #### Step 2:使用Session Token访问接口 获取Session Token后,在后续请求中使用。 **配置方式**: 在Headers标签页添加: ```txt X-Auth-Token: <你的Session Token值> ``` **请求示例**: ```txt GET https://192.168.1.100/redfish/v1/Systems/1 Headers: X-Auth-Token: ``` #### Step 3:删除Session 测试完成后,建议删除Session释放资源。 **删除Session接口**: - **URL**:`https://`(从创建Session的响应体`@odata.id`中获取) - **方法**:DELETE - **Headers**: 携带X-Auth-Token ### Postman环境变量使用 为了简化Token管理,可以使用Postman的环境变量功能。 1. **创建环境变量** - 点击右上角眼睛图标 - 点击"Add"创建新环境 - 添加变量:`bmc_ip`、`username`、`password`、`redfish_token` 2. **在请求中使用变量** ```txt URL: https://{{bmc_ip}}/redfish/v1/Systems/1 ``` --- # Postman高级调试技巧 ## 查看响应状态码 Postman响应区域顶部显示状态码,常用状态码: | 状态码 | 说明 | | :----------- | :------------ | | 200 | 请求成功 | | 201 | 资源创建成功 | | 400 | 请求非法 | | 401 | 认证失败 | | 403 | 权限不足 | | 404 | 资源不存在 | | 500 | 服务器内部错误 | | 502 | 网关错误 | ## 查看响应时间 Postman显示请求的响应时间(在状态码旁边),可以用于性能分析: - 正常请求:通常在几百毫秒内 - 超过1秒:可能存在性能问题 - 超过30秒:可能触发超时 ## 使用Collection组织请求 将相关请求组织到Collection中: 1. 点击左侧Collections 2. 创建新Collection(如"BMC Web REST"、"BMC Redfish") 3. 将请求添加到Collection中 4. 可以设置Collection级别的变量和认证 ## 使用Console控制台查看完整请求和响应 Postman Console控制台是一个强大的调试工具,可以查看请求和响应的完整详细信息,包括所有请求头、响应头、请求体、响应体等。 ### 打开Console控制台 有两种方式打开Console控制台: 1. 点击左下角的**Console**图标(类似终端的图标) 2. 使用快捷键 `Ctrl + Alt + C`(Windows/Linux)或 `Cmd + Option + C`(Mac) ### Console控制台的主要功能 Console控制台会记录所有请求的详细信息,包括: | 信息类型 | 说明 | | :----------- | :------------ | | **Request** | 完整的请求数据,包括请求行、请求头、请求体 | | **Response** | 完整的响应数据,包括状态码、响应头、响应体 | | **Headers** | 所有请求头和响应头的详细信息 | | **Body** | 请求体和响应体的完整内容 | | **Timeline** | 请求各阶段的时间消耗 | | **Cookies** | 请求和响应中的Cookie信息 | ### 使用场景 **场景1:查看自动添加的请求头** Postman会自动添加某些请求头(如`User-Agent`、`Content-Length`等),这些在主界面可能不显示。Console可以看到所有实际发送的请求头。 ```txt 示例Console输出: Request Headers: User-Agent: PostmanRuntime/7.32.1 Accept: */* Cache-Control: no-cache Postman-Token: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Host: 192.168.1.100 Accept-Encoding: gzip, deflate, br Connection: keep-alive ``` **场景2:查看完整的响应头** 某些调试信息(如会话Token、CORS相关)在响应头中,Console可以完整显示。 ```txt 示例Console输出: Response Headers: HTTP/1.1 201 Created Server: nginx/1.18.0 Date: Tue, 03 Feb 2026 10:30:15 GMT Content-Type: application/json Content-Length: 1234 Connection: keep-alive X-Auth-Token: abcdef1234567890abcdef1234567890 Set-Cookie: SessionId=987654321aaa; Path=/; HttpOnly ``` **场景3:调试请求失败原因** 当请求失败时,Console会显示详细的错误信息,帮助定位问题。 ```txt 示例Console输出(连接失败): Error: connect ETIMEDOUT at Object._errnoException (util.js:1024:11) at _exceptionWithHostPort (util.js:1046:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1182:14) ``` **场景4:性能分析** Timeline视图显示请求各阶段的时间消耗: - **DNS Lookup**:DNS解析时间 - **Connecting**:建立TCP连接时间 - **TLS Handshake**:TLS握手时间(HTTPS) - **Sending**:发送请求数据时间 - **Waiting**:服务器处理时间 - **Receiving**:接收响应数据时间 ### Console与主界面的区别 | 特性 | 主界面响应区 | Console控制台 | | :----------- | :------------ | :------------ | | 显示内容 | 仅响应体 | 完整的请求和响应 | | 历史记录 | 仅当前请求 | 所有请求的历史记录 | | 请求头 | 仅手动添加的 | 包括自动添加的所有请求头 | | 响应头 | 简化显示 | 完整显示 | | 时间信息 | 简单的总耗时 | 详细的时间线分析 | | 错误信息 | 简单提示 | 详细的错误堆栈 | ### 调试技巧 1. **开启日志记录**:在发送请求前打开Console,确保能捕获完整的请求信息 2. **使用过滤功能**:Console支持按关键词过滤日志,快速找到相关信息 3. **查看原始请求**:Console可以查看实际发送的原始请求,与预期进行对比 4. **分析性能瓶颈**:通过Timeline视图分析请求慢的原因(是网络慢还是服务器处理慢) --- # 注意事项 1. **HTTPS证书问题**:如果BMC使用自签名证书,Postman会提示证书错误,可以在Settings中关闭SSL证书验证(仅供测试环境使用) 2. **Token过期**:注意Token的有效期,过期后需要重新获取 3. **并发请求限制**:BMC对并发请求数量有限制(当前最多支持4路并发),避免同时发送过多请求导致请求等待时间过长。nginx读取数据超过15分钟连接会超时,断开连接并返回502错误码 4. **接口版本**:注意Redfish接口的版本,不同版本的接口可能存在差异 5. **权限要求**:某些操作需要特定权限,确保使用的账户具有相应权限 6. **日志记录**:调试时注意查看BMC端日志,结合Postman响应进行问题定位 7. **请求超时设置**:在Postman Settings中可以设置请求超时时间,默认为0(无限制) --- # HTTP 工具使用指导 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/http_debug_tool/http_tool_user_guide.html > Language: zh # HTTP 工具使用指导 ## 概述 本文档介绍如何使用 HTTP 工具与 openUBMC 进行交互,包括使用 POSTMAN 和 curl 发送 Redfish/Web REST 请求。通过这些工具,用户可以方便地管理和监控 BMC 设备。 ## 认识 RESTful API ### RESTful API 简介 REST (Representational State Transfer) 是一种软件架构风格,RESTful API 基于 HTTP 协议,使用标准的 HTTP 方法(GET、POST、PUT、PATCH、DELETE)对资源进行操作。 openUBMC 提供了完整的 Redfish API 和 Web REST API,支持以下功能: - 系统信息查询 - 设备配置管理 - 传感器数据读取 - 日志查询 - 用户管理 - 网络配置 ### HTTP 方法说明 | 方法 | 描述 | 用途 | |-----|------|------| | GET | 获取资源 | 查询设备信息、状态、配置 | | POST | 创建资源 | 创建新资源、执行 Action | | PUT | 完整更新资源 | 完全替换资源内容 | | PATCH | 部分更新资源 | 修改资源的部分属性 | | DELETE | 删除资源 | 删除指定资源 | ### 认证方式 openUBMC 支持以下认证方式: - **Basic Auth** - 基本认证,使用用户名和密码 - **Session Auth** - 会话认证,先登录获取会话令牌 ## 使用 POSTMAN 发送请求 ### 认识 POSTMAN POSTMAN 是一款功能强大的 API 开发和测试工具,提供图形化界面,支持各种 HTTP 方法、认证方式、环境变量等功能,是测试 Redfish/Web REST API 的理想工具。 ### 环境要求 - 操作系统:Windows - 软件:POSTMAN 桌面版或浏览器插件 - 网络:能够访问 BMC IP 地址 ### 安装 POSTMAN #### Windows 系统 1. 访问 POSTMAN 官网: 2. 下载 Windows 版本安装包。 3. 运行安装程序,按提示完成安装。 ### 配置 POSTMAN 环境 #### 创建环境变量 1. 打开 POSTMAN。 2. 点击 "Manage Environments" 图标。 3. 点击 "Add" 创建新环境。 4. 添加以下变量: | 变量名 | 初始值 | 说明 | |--------|--------|------| | bmc_ip | 192.168.1.100 | BMC IP 地址 | | username | admin | 登录用户名 | | password | admin | 登录密码 | #### 配置认证 1. 打开任意请求。 2. 切换到 "Authorization" 标签页。 3. 选择认证类型: **Basic Auth 配置**: - Type:Basic Auth - Username:`{username}` - Password:`{password}` ### 常用 API 请求示例 #### 查询系统信息 **GET 请求**: 1. 创建新请求,方法选择 "GET"。 2. URL 输入:`https://{bmc_ip}/redfish/v1/Systems`。 3. 配置认证。 4. 点击 "Send" 发送请求。 **响应示例**: ```json { "@odata.context": "/redfish/v1/$metadata#ComputerSystemCollection.ComputerSystemCollection", "@odata.id": "/redfish/v1/Systems", "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection", "Name": "Computer System Collection", "Members@odata.count": 1, "Members": [ { "@odata.id": "/redfish/v1/Systems/1" } ] } ``` #### 创建会话 **POST 请求**: URL:`https://{bmc_ip}/redfish/v1/SessionService/Sessions` 请求体: ```json { "UserName": "{username}", "Password": "{password}" } ``` **响应示例**: ```json { "@odata.context": "/redfish/v1/$metadata#Session.Session", "@odata.type": "#Session.v1_7_2.Session", "@odata.id": "/redfish/v1/SessionService/Sessions/7a64142bdf0be39d8b5c37dc", "Name": "User Session", "Id": "7a64142bdf0be39d8b5c37dc", "ClientOriginIPAddress": "xx.xx.xx.xx", "CreatedTime": "2026-03-14T01:59:47+00:00", "Roles": [ "Administrator" ], "SessionType": "Redfish", "OemSessionType": "Redfish", "Oem": { "Self": { "UserAccount": "admin", "LoginTime": "2026-03-14T01:59:47+00:00", "UserId": 2, "UserValidDays": null, "AccountInsecurePromptEnabled": false, "UserIP": "xx.xx.xx.xx", "UserTag": "Redfish", "MySession": true, "UserRole": [ "Administrator" ] } } } ``` 返回的Header中的 X-Auth-Token 值,后续请求可在请求头中使用 X-Auth-Token 携带对应值来达到session认证的效果。 #### 修改配置 **PATCH 请求**: URL:`https://{bmc_ip}/redfish/v1/Managers/{ManagerId}/NetworkProtocol` 请求头: ```bash # If-Match的值为GET该接口返回的Header中的ETag属性的值 If-Match=W/"xxxxxxxx" ``` 请求体: ```json { "SNMP": { "ProtocolEnabled": true } } ``` **响应示例**: ```json { "@odata.context": "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol", "@odata.id": "/redfish/v1/Managers/1/NetworkProtocol", "@odata.type": "#ManagerNetworkProtocol.v1_9_0.ManagerNetworkProtocol", "Name": "Manager Network Protocol", "Id": "NetworkProtocol", ... "SNMP": { ... "ProtocolEnabled": true }, ... } ``` #### 执行 Action **POST 请求**: URL:`https://{bmc_ip}/redfish/v1/Systems/{SystemId}/Actions/ComputerSystem.Reset` 请求体: ```json { "ResetType": "ForceRestart" } ``` **响应示例**: ```json { "error": { "code": "Base.1.0.GeneralError", "message": "A general error has occurred. See ExtendedInfo for more information.", "@Message.ExtendedInfo": [ { "@odata.type": "#Message.v1_0_0.Message", "MessageId": "Base.1.0.Success", "RelatedProperties": [], "Message": "Successfully Completed Request", "MessageArgs": [], "Severity": "OK", "Resolution": "None" } ] } } ``` #### 删除资源 **DELETE 请求**: URL:`https://{bmc_ip}/redfish/v1/SessionService/Sessions/{SessionId}` **响应示例**: ```json { "error": { "code": "Base.1.0.GeneralError", "message": "A general error has occurred. See ExtendedInfo for more information.", "@Message.ExtendedInfo": [ { "@odata.type": "#Message.v1_0_0.Message", "MessageId": "Base.1.0.Success", "RelatedProperties": [], "Message": "Successfully Completed Request", "MessageArgs": [], "Severity": "OK", "Resolution": "None" } ] } } ``` ## 使用 curl 发送请求 ### 认识 curl curl 是一个命令行工具,用于发送 HTTP 请求。它支持多种协议、认证方式,功能强大,适合在脚本中使用。 ### 环境要求 - 操作系统:Linux、macOS、Windows(需要安装) - 网络:能够访问 BMC IP 地址 ### 安装 curl #### Linux 系统 ```bash # Ubuntu/Debian sudo apt-get install curl # CentOS/RHEL sudo yum install curl ``` ### 常用 curl 参数 | 参数 | 说明 | |-----|------| | -X | 指定 HTTP 方法 | | -H | 添加请求头 | | -d | 发送 POST 数据 | | -u | 指定用户名和密码 | | -b | 发送 Cookie | | -c | 保存 Cookie | | -k | 跳过 SSL 证书验证 | | -i | 显示响应头 | | -v | 显示详细通信过程 | | -o | 保存响应到文件 | ### 常用 API 请求示例 #### 使用 Basic Auth 认证 **GET 请求**: ```bash curl -X GET \ -u admin:admin \ -k \ https://{bmc_ip}/redfish/v1/Systems ``` **响应示例**: ```json { "@odata.context": "/redfish/v1/$metadata#ComputerSystemCollection.ComputerSystemCollection", "@odata.id": "/redfish/v1/Systems", "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection", "Name": "Computer System Collection", "Members@odata.count": 1, "Members": [ { "@odata.id": "/redfish/v1/Systems/1" } ] } ``` #### 使用 Session 认证 **创建会话**: ```bash curl -X POST \ -H "Content-Type: application/json" \ -d '{"UserName":"admin","Password":"admin"}' \ -k \ -i \ https://{bmc_ip}/redfish/v1/SessionService/Sessions ``` 可以在返回的请求头中获取到 X-Auth-Token 的值,后续可通过请求头携带该 token 来实现通过 session 认证 **使用会话发送请求**: ```bash curl -X GET \ -H "X-Auth-Token: xxxxxxxx" \ -k \ https://{bmc_ip}/redfish/v1/Systems ``` **删除会话**: ```bash curl -X DELETE \ -H "X-Auth-Token: xxxxxxxx" \ -k \ https://{bmc_ip}/redfish/v1/SessionService/Sessions/{SessionId} ``` #### 修改配置 ```bash curl -X PATCH \ -u admin:admin \ -H "Content-Type: application/json" \ -H 'If-Match: W/"xxxxxxxx"' \ -d '{"SNMP":{"ProtocolEnabled":true}}' \ -k \ https://{bmc_ip}/redfish/v1/Managers/{ManagerId}/NetworkProtocol ``` If-Match的值为GET该接口返回的Header中的ETag属性的值 #### 执行 Action ```bash curl -X POST \ -u admin:admin \ -H "Content-Type: application/json" \ -d '{"ResetType":"ForceRestart"}' \ -k \ https://{bmc_ip}/redfish/v1/Systems/{SystemId}/Actions/ComputerSystem.Reset ``` ### 结果验证 执行 curl 命令后,应返回 JSON 格式的响应数据。如果返回错误信息,请检查: 1. 网络连接是否正常:`ping {bmc_ip}` 2. 认证信息是否正确。 3. URL 路径是否正确。 4. 请求体格式是否正确。 5. BMC 服务是否正常运行。 ## 常见问题 ### SSL 证书验证失败 **问题现象**:返回 "SSL certificate problem" 错误 **解决方法**: 1. 添加 `-k` 参数跳过证书验证 2. 或者导入 BMC 的 SSL 证书到系统信任库 ### 认证失败 **问题现象**:返回 401 Unauthorized 错误 **解决方法**: 1. 检查用户名和密码是否正确 2. 检查 Token 是否过期 3. 确认认证方式配置正确 ### 请求超时 **问题现象**:请求长时间无响应 **解决方法**: 1. 检查网络连接 2. 增加 curl 的超时时间:`--max-time 60` 3. 检查 BMC 服务状态 ### JSON 解析错误 **问题现象**:返回的 JSON 格式不正确 **解决方法**: 1. 使用 `jq` 工具格式化输出 2. 检查响应头中的 Content-Type 3. 确认 BMC 返回的是标准 JSON 格式 ### POSTMAN 环境变量不生效 **问题现象**:`{{variable}}` 无法正确替换 **解决方法**: 1. 确认环境已选择 2. 检查变量名拼写是否正确 3. 重新保存环境变量 ## 附录 ### HTTP 状态码说明 | 状态码 | 名称 | 描述 | |--------|------|------| | 200 | OK | 请求成功 | | 201 | Created | 资源创建成功 | | 204 | No Content | 请求成功,无返回内容 | | 400 | Bad Request | 请求格式错误 | | 401 | Unauthorized | 未授权 | | 403 | Forbidden | 禁止访问 | | 404 | Not Found | 资源不存在 | | 405 | Method Not Allowed | 方法不支持 | | 500 | Internal Server Error | 服务器内部错误 | | 503 | Service Unavailable | 服务不可用 | ### Redfish 常用端点 | 端点 | 描述 | |-----|------| | /redfish/v1/ | 服务根 | | /redfish/v1/Systems | 系统集合 | | /redfish/v1/Chassis | 机箱集合 | | /redfish/v1/Managers | 管理器集合 | | /redfish/v1/AccountService | 账户服务 | | /redfish/v1/SessionService | 会话服务 | | /redfish/v1/EventService | 事件服务 | ### 参考资料 - Redfish 规范: - POSTMAN 文档: - curl 文档: - openUBMC 官网: --- # Maintenance CLI Tool (mdbctl) > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/maintenance_cli_tool.html > Language: zh # 高级命令参考 # 前言 ## 概述 本文主要描述高级用户、开发及生产人员使用的命令参数说明。 ## 说明 本资料中涉及的命令,是高级用户、研发人员或生产人员使用的,应避免非专业人员执行此资料中的命令,否则由使用人承担相关责任。 # 1 mdbctl 调试命令 调测命令由维护人员在现场使用mdbctl进行问题定位时使用,该调试命令只允许具有调试诊断权限的用户执行。 ## 1.1 进入调试界面 **命令功能** 进入调试命令界面。 **命令格式** `mdbctl` **参数说明** 无 **使用实例** ```shell #进入调试模式界面。 ********************************************************************** Debug Shell Copyright(C) 2023 ********************************************************************** % ``` ## 1.2 帮助命令 **命令功能** 获取帮助信息。 **命令格式** `help` **参数说明** 无 **使用实例** ```shell # 已进入调试模式界面。 % help Usage: help Get all command help information. Usage: bye Quit micro component command line interface. Usage: lsmc List all micro component names. Usage: lsclass [module name] List all class name of this board or specified module. Usage: lsobj List all objects of specified class. Usage: lsprop [interface name] List all props of specified object. Usage: getprop Get property value of specified object. Usage: attach Attach certain module to debug. % ``` ```shell # 已进入调试模式界面且连接模块。 % help Usage: help Get all command help information. Usage: bye Quit micro component command line interface. Usage: lsmc List all micro component names. Usage: Isclass [module name] List all class name of this board or specified module. Usage: lsobj List all objects of specified class. Usage: lsprop [interface name] List all props of specified object. Usage: getprop Get property value of specified object. Usage: attach Attach certain module to debug. Usage: lscmd List all debug commands of attached module. Usage: dloglevel [level] [effective hours] Query or set debug log output level [debug, info, notice, warning, error]. effective hours: [1-24]. Usage: dlogtype [type] Query or set debug log output type [file, local]. % ``` ## 1.3 退出命令 **命令功能** 退出调试界面。 **命令格式** `bye` **参数说明** 无 **使用实例** ```shell # 已进入调试模式界面。 % bye Byebye. See you next time. ``` ## 1.4列举模块命令 **命令功能** 列举当前的功能模块。 **命令格式** `lsmc` **参数说明** 无 **使用实例** ```shell #已进入调试模式界面。 % lsmc aiengine bios bmc_health bmc_network bmc_soc bmc_time bmc_upgrade chassis compute cooling ddns event event_policy fault_diagnosis file_transfer firmware_mgmt fructrl frudata general_hardware host_agent hwdiscovery hwproxy iam ipmi_core key_mgmt license manufacture mctpd metric_analyzer network_adapter nsm oms pcie_device persistence power_mgmt power_strategy product_mgmt redfish remote_console rmcpd sensor soctrl ssdp storage thermal_mgmt trust usb_entry web_backend % ``` ## 1.5 连接模块命令 **命令功能** 连接到指定模块,方便进行后续操作。 **命令格式** `attach ` **参数说明**
参数参数说明
module name当前运行的功能模块名称,可以使用lsmc命令获取模块名。
**使用实例** ```shell #已进入调试模式界面。 % attach hwdiscovery Success. % ``` ## 1.6 列举类命令 **命令功能** 列举当前所有的类,或指定模块的类。 **命令格式** `lsclass [module name]` **参数说明**
参数参数说明
module name当前运行的功能模块名称,可以使用lsmc命令获取模块名。可选参数。
**使用实例** ```shell #已进入调试模式界面。 % lsclass Accessor AccountService Authentication Authorization BMC Bios BoardNICCard BoardRAS BootError BusinessConnector CPU CPUMetrics CPURAS CertificateAuthentication CertificateLocation CertificateService Chassis Chip Component ComputerSystem Connector CoolingArea CoolingFan CoolingRequirement Cpld CpuBoard DFT DataAcquisitionService Dft12V0Vlot Dft3V3Vlot Dft5V0Vlot DftBmcCard DftButtonCell DftCD DftCardPresence DftChassisCover DftCpld DftDdr3 DftEeprom DftEepromWp DftEth DftFlash DftIOTest DftIpmb DftTAG DftKeyBoard DftLedIntelligence DftLedTube DftLedTubeIntelligence DftLm75 DftLpc DftNCSI DftNandFlash DftNewVideo DftPmu DftPowerButton DftPowerSupply DftPhysicalLed DftSPI DftUidButton DftUSB DiscreteEvent DiscreteSensor Drive Eeprom Entity Event Events ExpBoard FDMDomain FDMService FanFanBoard FanType FaultPrediction FirmwareInventory Fru FruCtrl FruData HddBackplane Hisport I2c I2cMux IpmiCore Kerberos Key KeyService Keys LDAP Led LicenseService Lm75 ManagerAccounts ManagerVersion Memory MemoryChannel MemoryMetrics MemoryRAS Mock NCSICapabilities NandFlash NandFlashMock NetworkAdapter NetworkPort ObjectGroup OnePower PCIeDevice Pca9545 PCIeAddrInfo Pmu RMCPCipherSuites Redfish RemoteGroups RestrictedPrivileges SDRDevice SOC SOL SP Scanner SecureBootOptions Sender SerialManagement Sessions Smc Sms Smtp Snmp StorageConfig SystemLockDown Temperature ThresholdSensor Time Tracelpmi UartData Ums UpdateService UsbLocalOMService VrdMgmt Watchdog2 % lssclass hwproxy Accessor Chip Cpld DftLm75 Eeprom Hisport I2c I2cMux Lm75 Mock Pca9545 Scanner Smc % lssclass hwdiscovery Connector ObjectGroup % ``` ## 1.7 列举类的所有对象命令 **命令功能** 列举类的所有对象。 **命令格式** `lsobj ` **参数说明**
参数参数说明
class name类名称。
**使用实例** ```shell #已进入调试模式界面。 % lsobj Connector Connector_BCU_1_0101 Connector_CLU_1_0101 Connector_EXU_1_01 Connector_IEU_1_010101 Connector_IEU_2_010101 Connector_IEU_3_010101 Connector_LOM_1_0101 Connector_LOM_2_0101 Connector_OCP_1_0101 Connector_OCP_2_0101 Connector_PSR_1_0101 Connector_PowerSupply_1_0101 Connector_PowerSupply_2_0101 Connector_SEU_1_0101 Connector_SEU_2_0101 Connector_Sensor_01 Connector-TrustedModule_010101 % ``` ## 1.8 列举对象的所有属性命令 **命令功能** 列举对象的所有属性。 **命令格式** `lsprop [interface name]` **参数说明**
参数参数说明
object name对象名称。
interface name接口名称。可选参数。
**使用实例** ```shell #已进入调试模式界面。 % lsprop Connector_BCU_1_0101 bmc.kepler.Connector AuxId="" Bom="14100513" Buses=["I2c_1","I2c_2","I2c_8","JtagOverLocalBus_1","Hisport_0","Hisport_5","Hisport_6","Hisport_7"] ChassisId="" GroupId=16 GroupPosition="010101" Id="00000001020302024339" IdentifyMode=3 LoadStatus=0 ManagerId="1" Presence=1 SilkText="BCU" Slot=1 SystemId=1 Type="CPUBoard" bmc.kepler.Object.Properties ClassName="Connector" ObjectIdentifier=[1,"1","","0101"] ObjectName="Connector_BCU_1_0101" % lsprop Connector_BCU_1_0101 bmc.kepler.Connector bmc.kepler.Connector AuxId="" Bom="14100513" Buses=["I2c_1","I2c_2","I2c_8","JtagOverLocalBus_1","Hisport_0","Hisport_5","Hisport_6","Hisport_7"] ChassisId="" GroupId=16 GroupPosition="010101" Id="00000001020302024339" IdentifyMode=3 LoadStatus=0 ManagerId="1" Presence=1 SilkText="BCU" Slot=1 SystemId=1 Type="CPUBoard" % ``` ## 1.9 获取属性值命令 **命令功能** 获取指定对象的指定属性值。 **命令格式** `getprop ` **参数说明**
参数参数说明
object name对象名称。
interface name接口名称。
property name属性名称。
**使用实例** ```shell #已进入调试模式界面。 % getprop Connector_BCU_1_0101 bmc.KeplerConnector Buses ["l2c_1","l2c_2","l2c_8","JtagOverLocalBus_1","Hisport_0","Hisport_5","Hisport_6","Hisport_7"] % getprop Connector_BCU_1_0101 bmc.KeplerConnector Id "00000001020302024339" % ``` ## 1.10 列举调试方法命令 **命令功能** 列举指定连接模块的调试方法。 **命令格式** `lscmd` **参数说明** 无 **使用实例** ```shell #已进入调试模式界面且连接指定模块。 % attach maca Success % lscmd Usage: setmonitorstatus Enable or disable a specified check mechanism, including component startup status check, component running status check, and component online status check. Type s Type of the enabled check mechanism. The values can be starting (starting status check), running (running status check), and online (component online status check). Enabled b Enable or disable the check mechanism. Usage: dloglimit [DurationMins] Set the log flow control status. Enabled b The value true indicates that the log flow control function is enabled, and the value false indicates that the log flow control function is disabled. DurationMins u Set the validity period of the log flow control status. The value ranges from 1 to 720, in minutes. 10 % ``` ## 1.11 查询和设置组件的调试日志级别命令 **命令功能** 查询和设置组件的调试日志级别。 **命令格式** `dloglevel [level] [effective hours]` **参数说明**
参数参数说明取值
level日志级别。可选参数。debug, info, notice, warning, error
effective hours生效时长,单位为小时,默认为1。可选参数。1-24
**使用实例** ```shell #已进入调试模式界面且连接指定模块。 % attach hwdiscovery Success. % dloglevel "notice' % dloglevel info 2 % dloglevel "info" ``` ## 1.12 查询和设置组件的调试日志输出类型命令 **命令功能** 查询和设置组件的调试日志输出类型 **命令格式** `dlogtype [type]` **参数说明**
参数参数说明取值
type日志输出类型。可选参数file, local
取值为file时组件调试日志输出到文件
取值为local时组件调试日志输出到mdbctl终端
**使用实例** ```shell #已进入调试模式界面且连接指定模块。 % attach maca Success. % dlogtype "file" % dlogtype local Success. % dlogtype "local" ``` ## 1.13 追踪指定通道 IPMI 消息命令 **命令功能** 追踪指定通道IPMI消息 **命令格式** `traceipmi [netfn] [cmd]` **参数说明**
参数参数说明取值
operation type操作类型。start, stop
取值为start时启动ipmi命令跟踪功能
取值为stop时停止ipmi命令跟踪功能
log type日志输出类型。file
取值为file时IPMI追踪消息记录到文件
channel通道类型bt, ipmb, edma, ipmbeth
netfn网络功能码,可选参数0x00-0xff,默认值0xff
cmd命令号,可选参数0x00-0xff,默认值0xff
**使用实例** ```shell #已进入调试模式界面。 % traceipmi start file bt Success. % traceipmi stop file bt Success. ``` ## 1.14 设置组件的日志限流状态命令 **命令功能** 设置指定组件的日志限流状态 **命令格式** `dloglimit [DurationMins]` **参数说明**
参数参数说明取值
Enabled操作类型。true,false
取值为true时设置日志限流状态为开启
取值为false时设置日志限流状态为关闭
DurationMins设置日志限流状态生效时长,可选参数[1 - 720] min
取值单位为分钟,范围为1-720,默认值10
**使用实例** ```shell #已进入调试模式界面并连接目标模块。 % attach maca Success. % dlogimit false 10 % dloglimit true % ``` ## 1.15 追踪器件读写数据命令 **命令功能** 追踪指定器件的读写数据 **命令格式** `tracechip ` **参数说明**
参数参数说明取值
ObjectName跟踪器件对象名称hwproxy资源树器件对象名称,包含ads78、canbuschip、chip、cpld、cpldregister、EEPROM、jtag、lm75、pca9544、pca9545、pca9555、smc、vrd
Action操作类型取值为start时开始追踪器件读写数据
取值为stop时停止追踪器件读写数据
**使用实例** ```shell #已进入调试模式界面并连接硬件代理模块。 % attach hwproxy Success. % tracechip Lm75_1_010105 start % 2001-05-18 10:50:31.620996, Scanner_NicLm75_010105, block_read, Lm75_1_010105, addr: 144, offset: 0, read_length: 2, read_result: 24 70 % tracechip Lm75_1_010105 stop % ``` ## 1.16 设置微组件检查机制状态命令 **命令功能** 开启或关闭指定的检查机制的命令,包括组件启动状态检查、组件运行状态检查、组件在线状态检查 **命令格式** `setmonitorstatus ` **参数说明**
参数参数说明取值
Type使能的检查机制类型starting, running, online
表示使能的检查机制类型,参数选择包括:starting(启动状态检查), running(运行状态检查), online(组件在线状态检查)
Enabled开启或关闭检查机制的开关true, false
true表示开启,false表示关闭
**使用实例** ```shell #已进入调试模式界面并连接微组件管理模块。 % attach maca Success. % setmonitorstatus starting true 0 % setmonitorstatus starting false 0 % ``` ## 1.17 redfish 统计资源协作接口属性变更次数 TOPn 系列命令 ### 1.17.1 查询使能状态命令 **命令功能** 打印当前redfish统计的资源协作接口属性变更次数TOPn功能的使能状态,返回值是true(or false) **命令格式** `pcgetstatus` **参数说明** 无 **使用实例** ```shell #已进入调试模式界面并连接redfish组件模块。 % attach redfish Success % pcgetstatus false % ``` ### 1.17.2 设置使能状态命令 **命令功能** 设置当前redfish资源协作接口属性变更统计TOPn功能的使能状态 **命令格式** `pcsetstatus ` **参数说明**
参数参数说明取值
Status设置的使能状态true,false
true表示开启,false表示关闭
**使用实例** ```shell #已进入调试模式界面并连接redfish组件模块。 % attach redfish Success % pcsetstatus true % ``` ### 1.17.3 查询TOPn统计数据命令 **命令功能** 打印当前redfish统计到的资源协作接口属性变更次数TOPn的数据 **命令格式** `pcgetreport` **参数说明** 无 **使用实例** ```shell #已进入调试模式界面并连接redfish组件模块。 % attach redfish Success % pcsetstatus true % pcgetstatus true % pcgetreport { "now_period_time": "10:00 - 10:01", "now_period_top5": [ "path, interface, property, count" ], "pre_period_time": "09:58 - 09:59", "pre_period_top5": [ "path, interface, property, count" ] } % ``` ## 1.18 查询生效调速因子命令 **命令功能** 获取指定散热器件和模式生效的调速因子 **命令格式** `getactivatedpolicy ` **参数说明**
参数参数说明取值
Type散热器件类型Fan
Mode散热生效模式0,1
0表示生效因子,1表示生效算法
**使用实例** ```shell # 已进入调试模式界面并连接thermal_mgmt组件模式 % attach thermal_mgmt Success # 1. 查询风扇类型的生效因子 % getactivatedpolicy Fan 0 "Inlet_Temp" # 2. 查询风扇类型的生效算法 % getactivatedpolicy Fan 1 "MPC" ``` ## 1.19 查询电源信息命令 ### 1.19.1 查询电源风扇转速 **命令功能** 查询电源风扇转速 **命令格式** `getpsufanspeed ` **参数说明**
参数参数说明取值
ObjectName电源对象名称通过lsobj OnePower对象获取
**使用实例** ```shell #已进入调试模式界面并连接power_mgmt组件模式。 % attach power_mgmt Success % lsobj OnePower OnePower_0_010109 OnePower_0_01010B % getpsufanspeed OnePower_0_01010B 6419 % ``` ### 1.19.2 查询电源寄存器信息 **命令功能** 查询pmbus协议的电源寄存器信息 **命令格式** `getpsureg ` **参数说明**
参数参数说明取值
ObjectName电源对象名称通过lsobj OnePower对象获取
Cmd电源寄存器地址pmbus协议支持的寄存器地址
Length读取长度大于0
**使用实例** ```shell #已进入调试模式界面并连接power_mgmt组件模式。 % attach power_mgmt Success % lobj OnePower OnePower_0_010109 OnePower_0_01010B % getpsureg OnePower_0_01010B 144 2 [26,25] ``` ## 1.20 设置安全协处理器日志级别 **命令功能** 设置安全协处理器日志级别 - 说明 该命令行为取决于芯片能力 **命令格式** `setcoploglevel ` **参数说明**
参数参数说明取值
LogLevel日志级别0-紧急(emergency)
1-内核打印(common)
2-错误(error)
3-警告(warning)
4-通知(info)
5-调试(debug)
**使用实例** ```shell #已进入调试模式界面并连接soctrl组件模式 % attach soctrl Success % lscmd Usage: setcoploglevel Set the coprocessor log level. LogLevel y 0-emergency, 1-common, 2-error, 3-warning, 4-info, 5-debug % setcoploglevel 5 % ``` ## 1.21 获取运行时硬盘对象及信息命令 **命令功能** 获取运行时硬盘对象及信息 **命令格式** `getdrivedetails ` **参数说明**
参数参数说明取值
DriveName硬盘名称指定硬盘名称:获取指定硬盘实时运行数据,如“Disk0”不指定名称:“**”表示获取所有硬盘实时运行数据
**使用实例** ```shell # 已进入调试模式界面并连接storage组件模式 % attach storage Success % lscmd Usage: getdrivedetails Get the drive details. DriveName s The name of drive. % getdrivedetails * [[["ActivationLed":"1","RelativeSlot":"2","HddBackplaneStartSlot":"0","Name":"Disk2","CommandTimeoutTimes":"0","UnexpectedSenseTimes":"0","LinkFault":"false”]], [[["ActivationLed":"1","RelativeSlot":"4","HddBackplaneStartSlot":"0","Name":"Disk4","CommandTimeoutTimes":"0","UnexpectedSenseTimes":"0","LinkFault":"false”]], [[["ActivationLed":"1","RelativeSlot":"7","HddBackplaneStartSlot":"0","Name":"Disk7","CommandTimeoutTimes":"0","UnexpectedSenseTimes":"0","LinkFault":"false”]], [[["ActivationLed":"1","RelativeSlot":"0","HddBackplaneStartSlot":"0","Name":"Disk0","CommandTimeoutTimes":"0","UnexpectedSenseTimes":"0","LinkFault":"false”]], [[["ActivationLed":"1","RelativeSlot":"3","HddBackplaneStartSlot":"0","Name":"Disk3","CommandTimeoutTimes":"0","UnexpectedSenseTimes":"0","LinkFault":"false”]]] ``` ## 1.22 查询运行时 RAID 卡信息命令 **命令功能** 获取运行时RAID卡信息 **命令格式** `getctrlinfo ` **参数说明**
参数参数说明取值
ControllerIdRAID卡ID0-N:表示所查询的RAID卡ID
**使用实例** ```shell # 已进入调试模式界面并连接storage组件模式 % attach storage Success % lscmd Usage: getctrlinfo Get the running information of controller. Controllerld y The ld of controller. % getctrlinfo 0 {"DevDevice":"0","DevBus":"65","Phyaddr":"65","Eid":"0","CtrlOption3":"5888","Slotld":"3","CtrlOption2":"65 559","CtrlOption1":"34691","DevFunction":"0"} ``` ## 1.23 查询和设置资源协作对象跟踪使能命令 **命令功能** 设置与查询资源协作对象可视化跟踪相关能力 **命令格式** `trace [parameter list]` **参数说明**
参数参数说明取值
operation对资源协作对象执行的可观测跟踪使能操作["sampling"] "sampling": 设置指定资源协作对象的跟踪采样率
parameter list对资源协作对象执行可观测跟踪使能的参数sampling [object name][rate]
object name: 跟踪采样的资源协作对象,默认为查询当前已使能的资源协作对象
rate: 设置的跟踪采样率[0-1], 默认为1
**使用实例** ```shell #已进入调试模式界面 % trace sampling Object_0 Success % trace sampling Object_1 0.8 Success % trace sampling Object_0 1 Object_1 0.8 ``` ## 1.24追踪Mctp Endpoint报文命令 **命令功能** 设置与查询资源协作对象可视化跟踪相关能力 **命令格式** `tracemctp ` **参数说明**
参数参数说明取值
.ObjectName跟踪Endpoint对象名称mctpd组件资源树上的 Endpoint对象
Action操作类型取值为start时开始追踪 Endpoint收发报文数据
取值为stop时停止追踪 Endpoint收发报文数据
**使用实例** ```shell #已进入调试模式界面 % attach mctpd Success % tracemctp Endpoint_173_4 start ============= PCIe capture [SEND] ============= 7F 30 00 03 08 10 00 72 CA 0A 09 01 B4 1A 00 96 02 00 01 00 AB 50 1F 00 08 00 00 00 00 00 00 00 00 00 00 81 19 00 13 02 00 FF FF 2C 01 00 00 00 ============= PCIe capture [RECV] ============= 0A 00 00 12 00 30 00 96 B4 1A 00 03 C2 09 0A 01 02 00 01 00 AB D0 1F 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81 19 00 13 02 00 01 46 69 34 FF FE 41 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ``` ## 1.25追踪Scanner防抖数据命令 **命令功能** 设置与查询资源协作对象可视化跟踪相关能力 **命令格式** `tracedebounce ` **参数说明**
参数参数说明取值
objectname跟踪Scanner对象名称mctpd组件资源树上的Scanner对象
Action操作类型取值为start时开始追踪Scanner防抖数据
取值为stop时停止追踪Scanner防抖数据
**使用实例** ```shell # 已进入调试模式界面 % attach hwproxy Success % tracedebounce Scanner_FanBoard_Temp_0101 start % ========================= debounce policy: Midavg ========================= scanner: Scanner_FanBoard_Temp_0101, signed: true native value: 32, debounce resu ``` --- # mdbctl组件自定义命令 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/mdb_app_custom_command.html > Language: zh > **重要提示:** > > 1. 组件运行过程不能依赖和使用调试接口下的方法和属性(包括`bmc.*.Debug.*`) > 2. `bmc.*.Debug.*`类型的调试接口,必须实现构建裁剪 > 3. `bmc.*.Release.*`类型的发布接口,必须考虑功能的差异性,例如在线调试连接组件时,可以输出在线调试日志,但其他组件调用时无法输出 > 4. 调试命令和发布命令都必须上interface-sig组评审,发布命令必须补充高级命令资料 ## 命令如何添加 1. 自定义调试命令即是挂在**组件对象**下的资源树方法,`bmc.*.Debug.*`和`bmc.*.Release.*`接口下的方法被视作组件自定义调试命令,区分Debug命令与Release命令,Release版本的调试命令在Debug版本默认存在,无需重复配置 ```shell NAME TYPE SIGNATURE RESULT/VALUE FLAGS bmc.kepler.Debug.LogMock interface - - - .MockLog method a{ss}usb - - bmc.kepler.Object.Properties interface - - - ``` 2. mdb_interface定义的`bmc.*.Debug.*`和`bmc.*.Release.*`接口下(即为自定义调试命令)的方法与参数必须在model.json配置`displayDescription`字段,并用**英文**描述,`displayDescription`字段尽量保持简洁。 3. 命令接口所在路径现已支持配置动态参数路径,确保命令唯一 4. model.json的参数配置需要添加`optional`(可选参数)字段,不配置默认为`false`,配置为`true`时必须配置`default`字段,在方法调用参数缺省时使用默认值(可选参数只允许在最后,不支持跳跃配置) 5. model.json方法同级添加`cmdName`字段,**全小写**命名风格,在同一组件内不允许`cmdName`重复,命令名显示为`cmdName` 6. 命令参数不支持数组、字典等复杂数据类型 7. 需要组件方法处理操作日志打印 **mdb_interface配置示例:** ```json { "bmc.kepler.Debug.LogMock": { "properties": {}, "methods": { "MockLog": { "req": { "Count": { "baseType": "U32", "minimum": 1, "maximum": 1000, "description": "注入的日志数量" }, "Text": { "baseType": "String", "minLength": 1, "maxLength": 1024, "description": "注入的日志内容" }, "RepeatText": { "baseType": "Boolean", "description": "标志是否重复内容" } }, "rsp": { }, "description": "模拟日志注入" } } } } ``` **mds配置示例:** ```json { "LogMock": { "path": "/bmc/kepler/Debug/LogMock", "interfaces": { "bmc.kepler.Debug.LogMock": { "methods": { "MockLog": { "cmdName": "mocklog", "req": { "Count": { "minimum": 1, "maximum": 1000, "displayDescription": "Number of ingested logs." }, "Text": { "optional": true, "default": "test log", "displayDescription": "Content of ingested logs." }, "RepeatText": { "optional": true, "default": true, "displayDescription": "Indicates whether the text is duplicate." } }, "displayDescription": "Mock log update." } } } } } } ``` ## 命令如何区分目录 代码仓结构参照`/framework/maca/mds`下新增debug路径用于配置Debug方法(对象下同时配置debug接口与release接口则仍配置在默认目录,但建议评估拆分),debug方法实现部分同样也需要拆分目录,debug目录下的接口定义如不涉及接口依赖可不配置service.json。 ![alt text](../images/mdbctl_cmds/mdb_app_custom_command/image.png) ![alt text](../images/mdbctl_cmds/mdb_app_custom_command/image-1.png) **cmake配置打包debug目录:** ![alt text](../images/mdbctl_cmds/mdb_app_custom_command/image-2.png) **参考`/framework/maca/src/lualib/maca_app.lua`的`init_debug_service`方法初始化debug对象:** ![alt text](../images/mdbctl_cmds/mdb_app_custom_command/image-3.png) **挂载命令的对象需要有对象名(单例对象自动创建对象名),可以在回调方法里设置:** ![alt text](../images/mdbctl_cmds/mdb_app_custom_command/image-4.png) ## 命令如何使用 1. attach组件后通过`lscmd`命令查看当前组件支持的自定义调试命令 ```shell % attach maca Success % lscmd Usage: CommandA [param2] "Command description" param1 type "Param description" param2 type "Param description" "default value" ``` **查看的结果格式为:** - Usage: [方法名] [参数] - [方法描述] - 描述未配置时为空 - [参数] [参数类型] [参数描述] [默认值(配置可选参数)] 2. 直接使用方法名加参数的方式使用,以maca日志注入方法为例: ```shell % attach maca Success % lscmd Usage: mocklog [RepeatText] Mock log inject Count u Number of ingested logs Text s Content of ingested logs RepeatText b Indicates whether the log content is duplicate true % MockLog 10 'hello' true ``` 3. 动态参数路径下的方法如何区分 对于动态参数路径下的方法由mdbctl对方法进行合并处理,并添加ObjectName作为第一参数,即用户在使用时需额外指定执行对象。 **将配置了自定义命令的`bmc.kepler.Release.TraceChip`接口挂载至动态参数路径下,即路径下所有对象支持该方法:** ```json { "Cpld": { "package":"Cpld", "path": "/bmc/kepler/Chip/Cpld/:Id", "interfaces": [ "bmc.kepler.Release.TraceChip" ] } } ``` **使用示例:** ```shell % attach hwproxy Success -- 这里由mdbctl增加了参数用于指定对象 % lscmd Usage: tracechip Trace the read and write data of a specified component. ObjectName s Object for which the command is executed. Action s The value start indicates that the component starts to trace the read and write data. The value stop indicates that the component stops tracing the read and write data. ``` ## 注意事项 1. mdbctl ≥ 1.70.3支持添加与使用组件自定义调试命令 2. bmcgo ≥ 0.5.318支持生成displayDescription字段 3. mdbctl ≥ 1.70.6支持配置动态参数路径下的自定义命令 4. 组件codegen_policy的version ≥ 16 --- # mdbctl call命令介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/mdbctl_call.html > Language: zh ## 命令介绍 **call \ \ \ \[parameter list]** object name: 必选参数,为指定方法接口所属的对象,可以通过lsobj查询组件有哪些对象 interface name: 必选参数,为指定属性接口所属的对象,可以通过lsprop查询对象下挂了哪些接口 method name: 必选参数,调用的资源树方法名 parameter list: 可选参数,调用资源树方法的参数 可以参考traceprop介绍中的流程获取组件下的接口 ## 使用示例 ```shell -- 调用方法成功回显Success % mdbctl call LogMock_0 bmc.kepler.Debug.LogMock MockLog 0 100 "Test" false Success -- 查看日志方法调用生效 ~ # tail -f /var/log/framework.log 2025-08-07 05:17:05.671142 maca ERROR: init.lua(30): test 2025-08-07 05:17:05.671339 maca ERROR: init.lua(30): test 2025-08-07 05:17:05.671695 maca ERROR: init.lua(30): test 2025-08-07 05:17:05.671872 maca ERROR: init.lua(30): test 2025-08-07 05:17:05.672264 maca ERROR: init.lua(30): test -- 且操作会记录对应操作日志 ~ # cat /var/log/operation.log 2025-08-07 05:17:05 mdbctl,root@127.0.0.1,mdbctl,call LogMock_0 bmc.kepler.Debug.LogMock MockLog 0 5 test true successfully ``` ## 注意事项 1. mdbctl >= 0.0.3 2. 资源树方法所在对象必须配置对象名`ObjectName` 3. 无需传入资源树方法签名 --- # mdbctl dloglimit命令介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/mdbctl_dloglimit.html > Language: zh ## 命令介绍 **dloglimit \ \[DurationMins]** >Enabled: 必选参数,日志限流使能,true代表限流,false代表不限流 DurationMins: 可选参数,设置日志限流状态生效时长,范围[1-720]min,默认值为10 ## 使用示例 ```shell -- 该命令是每个组件都有的自定义命令 % attach maca Success -- lscmd能够看到对应命令的使用介绍 % lscmd Usage: dloglimit [DurationMins] 设置组件日志限流状态 Enabled b 日志限流使能,true代表限流,false代表不限流 DurationMins u 设置日志限流状态生效时长[1-720]min 10 % dloglimit false 1 % ``` ```shell -- 且操作会记录对应操作日志 ~ # cat /var/log/operation.log 2001-07-12 06:35:52 MDBCTL,@127.0.0.1,maca,Disable log limit successfully, will resume in 1 min 2001-07-12 06:36:52 MDBCTL,@127.0.0.1,maca,Resume log limit successfully ``` ## 注意事项 1. libmc4lua ≥ 1.70.36支持此组件自定义命令 2. mdbctl ≥ 1.70.3支持调用组件自定义命令 3. 组件进程重启会使日志限流状态恢复为限流 --- # mdbctl dtrace命令介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/mdbctl_dtrace.html > Language: zh ## 命令介绍 **Usage: dtrace [object_name] [enabled]** >object_name: 可选参数,代表需要使能跟踪的资源树对象名,或可以指定类名来使能类的所有对象 enabled: 可选参数,true代表使能,false代表去使能 ## 使用示例 ```shell -- 该命令是由mdbctl承载的公共命令 % help Usage: dtrace [object name] [enabled] Set trace status of specified object or query all traced objects. enabled: true/false. -- 使能对应对象 % dtrace LogMock_0 Success -- dtrace无其余参数则为查询 % dtrace LogMock_0 -- 调用该对象的资源树方法 % call LogMock_0 bmc.kepler.Debug.LogMock MockLog 0 10 test true ``` 随后即能在可视化端观测到追踪数据 ```shell -- 去使能对象 % dtrace LogMock_0 false Success ``` ## 注意事项 1. maca ≥ 1.80.3 支持查询操作 2. libmc4lua ≥ 1.80.33, mdbctl ≥ 1.70.16 支持查询与使能采样点 3. 当前使能采样点仅能关联到服务端,如需要更详细的跟踪能力需要在对象方法回调中预埋采样点 4. 若当前使能span上级存在父span则优先创建子span,否则创建父span --- # mdbctl lsprop getprop命令介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/mdbctl_lsprop_getprop.html > Language: zh ## 命令介绍 **lsprop \ \[interface name]** >object name: 必选参数,资源树上对象名,可通过lsobj查询组件的对象 interface name: 可选参数,可以筛选指定接口下的属性 **getprop \ \ \** >object name: 必选参数,资源树上对象名,可通过lsobj查询组件的对象 interface name: 可选参数,可以筛选指定接口下的属性 ## 使用示例 ### lsprop ```shell -- 列举当前对象下的接口与属性,格式为接口名下跟属性名与值 % lsprop OnePower_0_01013A bmc.kepler.Object.Properties ClassName="OnePower" ObjectIdentifier=[1,"1","","01013A"] ObjectName="OnePower_0_01013A" Private AlarmStatus=0 PhysicalInterface="pmbus" PreAlarmStatus=0 RefFrudata="$ref" RefSMCChip=[] UnsupportedProperties=[] ``` >- 接口名为Private的为私有属性,私有属性值为'$ref'的为引用对象类型 ### getprop ```shell -- 获取目标属性的属性值与配置信息,分割线下分别为属性类型及属性来源、表达式、默认值等 % getprop Drive_5_010102 bmc.kepler.Systems.Storage.Drive Presence 0 -------- details -------- type: synchronization $1: 0, [Service: bmc.kepler.hwproxy, Path: /bmc/kepler/Scanner/Scanner_Drive4PresentAccessor_010102, Interface: bmc.kepler.Scanner, Property: Status] $2: 0, [Service: bmc.kepler.hwproxy, Path: /bmc/kepler/Scanner/Scanner_Drive4PresentAccessor_010102, Interface: bmc.kepler.Scanner, Property: Value] expressions: ["expr($1 != 0 ? 255 : $2)"] ``` >- 属性类型分别为 synchronization(同步)、local reference object(本地引用对象)、remote reference object(远程引用对象)、local reference property(本地引用属性)、remote reference property(远程引用属性) >- 属性来源的格式为占位符序号 | 该来源本次计算同步的值(即该占位符参与本次属性值计算所用的值,暂时仅同步属性支持此信息) | 来源服务、路径等信息 ## 注意事项 1. libmc4lua >= 1.70.37 && mdbctl >= 1.70.7支持获取私有属性与属性详细信息 2. release版本不支持获取私有属性及属性详细信息 3. 私有属性值为'$ref'的为引用对象类型 4. 属性来源字段不存在则不显示 --- # mdbctl setprop命令介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/mdbctl_setprop.html > Language: zh # mdbctl setprop 命令介绍 ## 命令介绍 **setprop \ \ \ \ \** **参数说明:** - `operation type`:必选参数,提供set/unset/modify三种模式,用于设置属性值与解除设置,set在设置属性值时不会触发持久化和写硬件,而modify则会触发 - `object name`:必选参数,为指定属性接口所属的对象,可以通过`lsobj`查询组件有哪些对象 - `interface name`:必选参数,为指定属性所挂的接口,可以通过`lsprop`查询对象下挂了哪些接口 - `property name`:必选参数,为指定属性,可以通过`lsprop`查询对象下的属性 - `property value`:可选参数,表示待设置的属性值 可以参考traceprop介绍中的流程获取组件下的接口与属性。 ## 使用示例 ### 示例1:设置和解除属性值 ```shell # 当前属性值为54 % lsprop SOC_00 bmc.kepler.Managers.SOC Temperature=54 # 设置属性值成功回显Success % setprop set SOC_00 bmc.kepler.Managers.SOC Temperature 110 Success # 属性值为110 % lsprop SOC_00 bmc.kepler.Managers.SOC Temperature=110 # 解除override值 % setprop unset SOC_00 bmc.kepler.Managers.SOC Temperature Success # 属性值后台变更为50,解除后即为50并发送属性变更信号 % lsprop SOC_00 bmc.kepler.Managers.SOC Temperature=50 % setprop modify Dashboard_0 bmc.kepler.Dashboard.Observability.Metrics ExportIntervalSeconds 60 Success ``` ### 示例2:操作日志记录 ```shell # 操作会记录对应操作日志 ~ # cat /var/log/operation.log 2025-01-22 15:26:11 mdbctl,root@127.0.0.1,mdbctl,setprop set SOC_00 bmc.kepler.Managers.SOC Temperature 110 successfully 2025-01-22 15:26:24 mdbctl,root@127.0.0.1,mdbctl,setprop unset SOC_00 bmc.kepler.Managers.SOC Temperature successfully 2025-09-28 11:58:55 mdbctl,root@127.0.0.1,mdbctl,setprop modify Dashboard_0 bmc.kepler.Dashboard.Observability.Metrics ExportIntervalSeconds 60 successfully ``` ## 注意事项 1. **setprop设置override值不会触发持久化和写硬件** setprop设置属性变更会触发持久化流程,但持久化App添加了忽略override值的逻辑,因此override值不会被持久化。同理硬件代理覆写场景也忽略override值,不会触发写硬件。 2. **setprop以override模式设置对象属性值,Override值会常驻对外呈现** - 设置时如果与原始值不同,会触发属性变更 - 设置override值后属性的原值会保持后台业务变更逻辑,但不会触发属性变更信号,`setprop unset`解除override值时,会恢复为原值,当前值与override值不同时会触发属性变更信号 3. **(mdbctl ≥ 1.90.1新增)setprop modify模式可以触发持久化和写硬件** 功能与busctl set-property一致,且同样无法修改只读属性,只能通过set模式覆写 --- # mdbctl snapshot命令介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/mdbctl_snapshot.html > Language: zh # mdbctl snapshot 命令介绍 mdbctl提供公共命令snapshot,用于生成当前或增长内存对象的快照,帮助分析进程内存空间分布信息。快照文件存储路径分别为`/dev/shm/snapshot_组件名`和`/dev/shm/snapshotdiff_组件名`。 ## 1. 命令介绍 **snapshot \** **参数说明:** - `operation type`:必选参数,操作模式。 - `start`:生成当前内存对象的快照。 - `diff`:生成与上一次快照对比的增长内存对象的快照。 ## 2. 使用示例 ```shell % attach maca Success % help Usage: snapshot generate the snapshot of the memory object. operation type: start/diff. note: this operation may cause memory consumption. # 生成当前内存对象的快照 % snapshot start snapshot file: /dev/shm/snapshot_maca notice: this operation may cause memory consumption. # 生成与上一次生成内存对象增长对比的快照 % snapshot diff diff snapshot file: /dev/shm/snapshotdiff_maca notice: this operation may cause memory consumption. ``` ## 3. 注意事项 1. mdbctl ≥ 1.20.10支持mdbctl snapshot命令。 2. 调用该命令时可能会导致内存消耗。 --- # mdbctl traceprop命令介绍 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/mdbctl_cmds/mdbctl_traceprop.html > Language: zh ## 命令介绍 **traceprop \ \ \ \** >operation type: 必选参数,提供trace/untrace两种模式,代表开始跟踪与停止跟踪 object name: 必选参数,为指定属性接口所属的对象,可以通过lsobj查询组件有哪些对象 interface name: 必选参数,为指定属性所挂的接口,可以通过lsprop查询对象下挂了哪些接口 property name: 必选参数,为指定属性,可以通过lsprop查询对象下的属性 可以通过如下流程获取组件下的接口与属性 ```shell -- 通过lsclass直接获取所有类名 % lsclass Accessor AccountService AssetChange AssetList Authorization BMA BMC Battery Bios BiosUpgradeService BoardNICCard BoardRAS BootError BootOptions BusinessConnector CPU CPUMetrics CPURAS Certificate CertificateLocation CertificateService Chassis ChassisBMC Chip Component ComputerSystem Connector Contact Controller CoolingArea CoolingConfig CoolingFan CoolingPolicy CoolingRequirement Cpld CpuBoard DFT DataAcquisitionService Dft12V0Vlot Dft3V3Vlot Dft5V0Vlot DftBmcCard DftButtonCell DftCD DftChassisCover DftCpld DftDdr3 DftEeprom DftEepromWp DftEth DftFlash DftI2c DftIOTest DftIpmb DftJTAG DftKeyBoard DftLedIntelligence DftLedTube DftLedTubeIntelligence DftLm75 DftLpc DftNCSI DftNandFlash DftNewVideo DftPca9545 DftPca9555 DftPmu DftPowerButton DftPowerSupply DftPysicalLed DftSPI DftUidButton DftUsb DiscreteEvent DiscreteSensor Drive Eeprom EnergyMetric Entity EthGroup Event EventMetrics Events ExpBoard FDMDomain FDMService Fan FanBoard FanType FaultPrediction Firewall FirmwareActive FirmwareInventory FirmwareMatchRules Fru FruCtrl FruCtrlCapabilities FruData Gpio HddBackplane Hisport HostKeyAlgorithm I2c I2cMux InferenceAsync IpmiCore JobService Jobs Jtag JtagOverLocalBus Key KeyService Keys LanSwitch Led LedPolicy LicenseService LldpConfig Lm75 LocalAccountAuthN LogMock LogServices MacaService ManagerAccounts ManagerVersion MdbService Memory MemoryChannel MemoryMetrics MemoryRAS Mock Multihost NCSICapabilities NandFlash NandFlashCtrl NandFlashMock NetworkAdapter NetworkPort NodeLocation ObjectGroup OnePower PCIeCard PCIeDevice PCIeRASCollector Package Pca9545 Pca9555 PcieAddrInfo Pmu PowerAction PowerStrategy Product RMCPCipherSuites Redfish RestrictedPrivileges RiserCard SASPhy SOC SOL SP Scanner SecureBootOptions Sender SensorSelInfo SerialManagement SerialManagementConfig SmBios Smc Sms Smtp Snmp StorageConfig Syslog SystemFirmwareProgress SystemLockDown Temperature ThresholdSensor Time TraceIpmi TrustedSupplyChain UartData Ums UnitConfiguration UpdateMgmt UpdateService Upgrade UsbLocalOMService Watchdog2 -- lsclass [组件]获取类名 % lsclass hwdiscovery Connector ObjectGroup -- lsobj <类名>获取对象名 % lsobj Connector Connector_BCU_1_0101 Connector_CLU_1_0101 Connector_EXU_1_01 -- lsprop <对象名>获取下挂接口与属性 % lsprop Connector_BCU_1_0101 bmc.kepler.Connector AuxId="" Bom="14100513" Buses=["I2c_1","I2c_2","I2c_8","JtagOverLocalBus_1","Hisport_0","Hisport_5","Hisport_6","Hisport_7"] ChassisId="1" GroupId=14 GroupPosition="010101" Id="00000001020302024339" IdentifyMode=3 LoadStatus=0 ManagerId="1" Presence=1 SilkText="BCU" Slot=1 SystemId=1 Type="CPUBoard" bmc.kepler.Object.Properties ClassName="Connector" ObjectIdentifier=[1,"1","1","0101"] ObjectName="Connector_BCU_1_0101" ``` ## 使用示例 ```shell -- 需要traceprop必须要先attach到组件 % attach hwdiscovery Success -- 按照方法介绍使用 % traceprop trace Connector_BCU_1_0101 bmc.kepler.Connector LoadStatus Success -- 属性变更后会在mdbctl客户端有变更回显 % 2025-02-13 02:05:31.013912, :1.160, /bmc/kepler/Connector/Connector_BCU_1_0101, bmc.kepler.Connector, LoadStatus, 0, 1 Override(set) 2025-02-13 02:05:40.877220, :1.161, /bmc/kepler/Connector/Connector_BCU_1_0101, bmc.kepler.Connector, LoadStatus, 1, 0 Override(unset) --使用untrace或attach其他组件或者退出mdbctl都会使跟踪中断 % traceprop untrace Connector_BCU_1_0101 bmc.kepler.Connector LoadStatus Success ``` > 属性变更回显格式为[属性变更时间],[发起变更服务名或会话id],[对象路径],[接口名],[属性名],[变更旧值],[变更新值],[变更模式(mdbctl的setprop为Override(set))] ## 注意事项 1. mdbctl >= 1.20.12 && libmc4lua >= 1.50.32支持traceprop命令 2. libmc4lua >= 1.50.43 支持追踪由mdbctl setprop设置的属性值 3. 必须attach组件后才可以使用traceprop命令 4. 操作traceprop后,中途attach其他组件或者退出mdbctl会使trace中断 5. 最多同时traceprop 5个属性 --- # SMC、SMBUS常用命令字总结 > URL: https://openubmc.cn/docs/zh/latest/debug_tools/smc_smbus_cmds/SMC_SMBUS.html > Language: zh ## 查询厂商和版本号 ### smc(以BCU为例) busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc\_CpuBrdSMC\_0101 bmc.kepler.Chip.BlockIO Read a{ss}uu 0 0x00018500 7 ![image](../images/smc_smbus_cmds/SMC_SMBUS/smc.png) 其中7为read获取的长度,第一位为type(0为mcu、2为vrd),第三位是厂商(0是安陆,1是GD),五六七为版本号0.02.22 ### smbus(以Riser为例) - 获取版本号: mdbctl call Chip\_MCU1\_01010103 bmc.kepler.Chip.BlockIO ComboWriteRead 0 0x20 0x0e 0x0c 0x80 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x98 0x21 32 ![image](../images/smc_smbus_cmds/SMC_SMBUS/get_version.png) 这三位为版本号,其中0x98为crc校验吗,根据配置的adress不同需要重新计算(当前SDI为0x90,riser为0x98) - 获取厂商: mdbctl call Chip\_MCU1\_01010103 bmc.kepler.Chip.BlockIO ComboWriteRead 0 0x20 0x0e 0x0c 0x80 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x36 0x21 14 ![image](../images/smc_smbus_cmds/SMC_SMBUS/get_vendor.png) 最后一位,1是ST,2是GD ### PS:CPLD芯片厂商查询 查之前需要将jtag线路切到对应的值: busctl --user set-property bmc.kepler.hwproxy /bmc/kepler/Accessor/Accessor_JtagSwitch_010101 bmc.kepler.Accessor Value t _(_ 为对应值) 切到对应路线后查询对应的cpld: busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Cpld/Cpld_1_0101 bmc.kepler.Chip.JtagTarget GetChipIdcode a{ss} 0 ![image](../images/smc_smbus_cmds/SMC_SMBUS/query_cpld.png) 对应关系: ![image](../images/smc_smbus_cmds/SMC_SMBUS/correspondence.png) --- # DT用例编写指南 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/DT_code_guide.html > Language: zh # DT用例编写指南 ## 1. 背景 openUBMC的单元测试(UT)与集成测试(ST)在项目规划初期伴随业务代码就开始实施,主要为了保证业务代码的功能正确、高效开发,保证对外资源的可靠性。 ## 2. 开发流程(以IAM模块为例) 1. 整体业务功能框架搭建 2. 底层数据操作逻辑开发(UT) 3. 业务层操作汇总(UT) 4. 资源树数据管理(ST) 5. 整体业务功能测试(UT、ST) ## 3. UT数据准备与清理 **原则:**测试不依赖外部环境(包括默认配置、绝对路径等),初始化工作和清理工作需要充分完成。 **建议:** - 建立临时目录,拷贝外部依赖的文件。 - 对需要外部输入的配置统一设定参数入口,在配置文件里进行配置。 - 数据的清理可以在开始前先做一次。 ## 4. UT的Mock 对依赖skynet或者其他模块的功能,可以临时打桩实现。 **示例:**KMC功能的Mock 两种Mock方式可以参考: ```lua local kmc = require 'mc.kmc' local KmcEnc = kmc.encrypt_data local KmcDec = kmc.decrypt_data function TestIam:setUp() -- mock kmc kmc.encrypt_data = function(domain_id, cipher_alg_id, hmac_alg_id, plaintext) return plaintext end kmc.decrypt_data = function(domain_id, ciphertext) return ciphertext end end function TestIam:tearDown() kmc.encrypt_data = KmcEnc kmc.decrypt_data = KmcDec end ``` ```lua -- 自己实现一个kmc_client:hica/apps/security/src/lualib/certificate/infrastructure/kmc_client.lua function TestCertificate:setupClass() -- 其他操作 self.kmc_client = KmcClient.new(nil, true) -- mock KMC self.kmc_client.decrypt_cert_key = function(cls, encrypt_string) return encrypt_string end self.kmc_client.encrypt_cert_key = function(cls, plaintext) return plaintext end end ``` ## 5. UT的调试 测试驱动开发提效神器,F5可以直接调试,x86环境下业务功能开发必备。 ## 6. ST资源树与RPC请求 很多功能需要上资源树,UT无法和D-Bus联动,涉及资源树相关的功能需要在ST中进行测试。 **相关RPC的操作:** ```lua local function get_property(bus, prop_name) return bus:call('ibmc.app.Iam', '/bmc/kepler/SessionService', 'org.freedesktop.DBus.Properties', 'Get', 'ss', 'bmc.mdb.SessionService', prop_name):value() end local function set_property(bus, prop_name, value) return bus:call('ibmc.app.Iam', '/bmc/kepler/SessionService', 'org.freedesktop.DBus.Properties', 'Set', 'ssv', 'bmc.mdb.SessionService', prop_name, gvariant.new_uint32(value)) end ``` 因为ST启动了相关服务,底层功能不用Mock可以直接使用,方便联调测试整体功能。 ```lua function AccountCases.test_change_account_pwd(bus) assert(iam:ChangeAccountPwd(bus, 2, "Administrator", "xxx") ~= nil) local ret = iam:Authenticate(bus, "Administrator", "xxx") assert(ret.UserId == 2) assert(iam:ChangeAccountPwd(bus, 2, "Administrator", "xxx") ~= nil) end ``` ## 7. ST调试 添加打印日志,从顶层模块一直打到底层模块,可以灵活测试和调试。 > **注意**:skynet支持console,目前有VSCode插件或其他方式实现skynet服务的调试。如需要可以参考:。 ## 8. 用例耦合与解耦 1. **业务逻辑内聚**:保持业务逻辑的内聚性。 2. **单个用例的操作不要过于复杂**:建议单个用例调用的方法数量不超过5-10个。 --- # 命令说明 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/app_creation.html > Language: zh --- date: 2025/10/11 title: 组件的创建和使用 --- --- openUBMC中各个组件具有统一的代码结构,`BMC Studio`开发工具支持CLI命令`bingo new`快速创建一个符合openUBMC统一格式的组件。 # 命令说明 `BMC Studio`开发工具的各子命令都支持通过-h/--help查看命令说明: ```shell bingo new -h ``` 执行结果: ```shell 创建组件 optional arguments: -h, --help show this help message and exit -n NAME, --name NAME 指定组件名 -t TYPE, --type TYPE 指定组件类型, 可选值: application 默认: application -l LANGUAGE, --language LANGUAGE 指定组件编程语言, 可选值: lua 默认: lua ``` 指定参数传入,可以快速创建一个具有基础代码的组件仓。该代码仓已实现基本的启动服务、构建出包等功能。根据生成的组件代码仓,开发者只需关注业务代码编写即可。创建一个名为my_app的新组件示例: ```shell bingo new -n my_app ``` 执行此命令后,在终端根据提示输入对应值,便会在当前目录下快速生成一个名为my_app的组件仓。之后,开发者可以在组件仓目录下,通过`bingo build`命令构建出my_app的Conan包。执行命令如下: ```shell cd my_app git init bingo build ``` 命令执行成功后,控制台会输出`包名/版本号@用户名/通道`格式的构建产物标签,即`my_app/0.0.1@openubmc.dev/dev`。其中,包名和版本号分别由`mds/service.json`文件中的`name`属性和`version`属性定义。开发者在每次修改提交时都应该修改`version`属性值加1;并在`CHANGELOG.md`文件中记录新版本的修改信息;openUBMC中用户名的默认值是和通道相关联的,它拥有三种构建通道: 1. `dev`:表示开发者通道,开发者在本地构建时的默认通道。 2. `stable`:表示发布包。 开发者可以在构建命令中通过传入`--stage`参数来指定通道。例如,通过以下命令构建`my_app`组件的`stable`包: ``` shell bingo build --stage stable ``` 构建通道为`dev`时,用户名默认为`openubmc.dev`。构建通道为`stable`时,用户名默认为`openubmc`。当然,开发者也可以通过`--user`传参命令指定用户名,此时用户名不会根据通道发生变化。更多的组件构建命令请参考[《组件的构建与发布》](./build_process.md)。 构建完成后,开发者可以在执行`conan cache path <组件名>`查看构建产物存放的路径。 # 组件仓架构介绍 自动生成的my_app组件的文件架构格式及简要介绍如下。在此组件仓中,开发者可以在此代码仓内编写属于自己的组件特性代码。 ```shell ├── .clang-format ├── .gitignore ├── CHANGELOG.md --记录修改日志信息 ├── README.md --组件介绍文件 ├── CMakeLists.txt --cmake构建脚本,一般包含编译和打包 ├── Makefile ├── conanfile.py --conan脚本,继承自conanbase.py,可以重写conanbase的方法 ├── permissions.ini --权限配置文件 ├── config.cfg --组件启动配置文件 ├── mds │ ├── model.json --配置资源协作接口属性、方法、信号等 │ └── service.json --配置组件仓版本信息、需要依赖的接口和路径等 ├── src --源码文件夹 │ ├── lualib │ │ └── my_app_app.lua --组件实现文件 │ └── service │ └── main.lua --定义skynet服务,是组件入口服务。 ├── test │ ├── integration --集成测试文件的存放目录 │ │ ├── test_my_app.conf │ │ └── test_my_app.lua --集成测试的入口文件 │ └── unit --单元测试文件的存放目录 │ └── test.lua --单元测试的入口文件 └── user_conf --用户配置,构建系统根据rootfs目录的文件原样安装到根文件系统对应位置 └── rootfs └── etc └── systemd └── system ├── multi-user.target.wants │ └── my_app.service --Systemd进程启动配置文件 └── my_app.service ``` 在此组件架构中,不同的文件和目录分别具有不同的功能职责: - `CHANGELOG.md`和`README.md`文件分别用于记录修改日志和组件介绍,不参与组件运行。 - `CMakeLists.txt`、`conanfile.py`是组件的编译、构建脚本,与组件的业务代码无关。更详细的介绍请参考[《组件的构建与发布》](./build_process.md)。 - `Makefile`是一个可移植的构建系统文件,由`CMake`构建系统通过`CMakeLists.txt`生成。 - `permissions.ini`:权限配置文件。 - `user_conf`:用户配置目录。其中,`my_app.service`为组件启动配置文件。文件中定义了`Skynet`读取`/opt/bmc/apps/bmc_time/config.cfg`配置文件,以拉起服务。 - `config.cfg`:`Skynet`服务启动配置文件,在此文件中定义了服务入口文件为`my_app/service/main.lua`, - `mds`:定义组件的模型描述。包括组件实现的资源协作接口、组件数据的持久化描述、组件的依赖等。存放统一格式的组件模型定义源文件,不同模型定义不同的json文件。其中,`model.json`文件描述组件数据模型,配置资源协作接口上挂载的属性、方法、信号等;`service.json`文件描述组件的服务模型,配置组件仓版本信息、需要依赖的接口和路径等。`BMC Studios`工具的`CLI`命令`bingo gen`会依赖此部分模型定义和资源协作接口定义自动生成相关代码。更详细的模型文档介绍请参考[《MDS》](../../overview/architecture/mds_model/MDS.md)。 - `src`目录作为源码文件目录,组件的实现代码在`src/lualib/my_app_app.lua`文件中定义,`src/service/main.lua`文件是组件APP的入口函数,拉起了此组件的服务。开发人员可以在src目录下编写自己的业务代码。具体的介绍请参考[《组件的开发和代码编写》](./coding.md)。 - `test`目录作为开发者测试相关代码的存放目录。在openUBMC中,开发者测试用于对组件代码开发做保障。因此,开发者在业务代码开发的同时,需要完成开发者测试。开发者测试采用集成测试和单元测试进行组件接口测试和组件功能函数测试,相关代码分别存放在`test/integration`和`test/unit`目录中。具体的介绍请参考[《组件的独立测试》](./testing.md)。 openUBMC的业务组件通过模型描述文件`MDS`来配置资源协作接口、组件依赖等,与此部分模型定义相关的代码并未出现在以上的代码架构中。开发者可以使用`CLI`命令获取组件的全量代码: ``` shell cd <组件仓目录> bingo gen ``` 执行此命令,会在组件仓目录下自动生成`gen`目录。`gen`目录包含了模型描述文件所配置的资源协作接口的调用、订阅,和其他模型描述相关的代码。详细的介绍可参考[《代码自动生成》](../../overview/architecture/cpp_lua_framework/code_generation.md)。 # 组件启动流程 openUBMC通过Linux系统的服务管理工具`Systemd`进行服务和资源的管理。在`Systemd`的守护进程中,每个组件作为一个`Unit`(单位),采用`<组件名>.service`的`Unit`文件定义相应服务的描述、属性以及需要运行的命令等,并将此文件存放在组件代码仓的`user_conf/rootfs/etc/systemd/system/`路径下。 以创建的新组件`my_app`为例,它的`Unit`文件`my_app.service`中定义了`my_app`组件的默认配置信息: ```lua [Unit] Description=my_app service After=dbus.service Requires=dbus.service [Service] User=root Restart=always RestartSec=1 StartLimitInterval=0 EnvironmentFile=/dev/shm/dbus/.dbus Environment="ROOT_DIR=" Environment="PROJECT_DIR=" WorkingDirectory=/opt/bmc/apps/my_app ExecStart=/opt/bmc/skynet/skynet /opt/bmc/apps/my_app/config.cfg [Install] WantedBy=multi-user.target ``` 该文件主要分为三个配置区段: - `Unit`段:配置了该服务的描述、依赖和随系统启动的方式。即在dbus服务拉起之后,再拉起本服务。 - `Service`段:定义服务的具体管理和操作方法。即该服务默认运行在`/opt/bmc/apps/my_app`的工作目录中;通过Skynet读取`/opt/bmc/apps/my_app/config.cfg`配置文件信息启动服务。 - `Install`段:multi-user.target是systemd默认的target。在此目录下保存上级目录systemd配置的软连接,用于支持自动拉起systemd配置对应的服务。 根据新组件`my_app`的`Unit`文件定义,`my_app`服务通过启动`Skynet`被拉起。`Skynet`的启动配置文件`/opt/bmc/apps/my_app/config.cfg`默认定义如下: ``` lua include "/opt/bmc/libmc/config.cfg" config:set_root("/") config:set_start("my_app/service/main") config:include_app("my_app") config:done() ``` 该配置文件即为组件代码仓目录下的`config.cfg`文件,其本质是`Lua`脚本。openUBMC在`opt/bmc/libmc/config.cfg`中定义了基础配置模块。`Skynet`的配置文件通过导入此模块,并调用此模块中的方法,定义了各种文件运行的根目录、`Skynet`的启动脚本、以及在该`Skynet`进程中能够访问的`Lua`目录。 其中,`Skynet`的启动脚本定义为`my_app/service/main.lua`文件: ``` lua require 'skynet.manager' local skynet = require 'skynet' local logging = require 'mc.logging' local my_app_app = require 'my_app_app' local CMD = {} function CMD.exit() logging:notice('my_app service exit') end skynet.start(function() skynet.uniqueservice('sd_bus') skynet.register('my_app') local ok, err = pcall(my_app_app.new) if not ok then logging:error('my_app start failed, err: %s', err) end skynet.dispatch('lua', function(_, _, cmd, ...) local f = assert(CMD[cmd]) skynet.ret(skynet.pack(f(...))) end) end) ``` 各组件代码仓使用`src/lualib`目录存放组件的lua代码,其中`xxx_app.lua`(xxx为组件名)是整个组件的入口。在上述`Skynet`的启动脚本中,通过引入`my_app`组件的入口文件`my_app_app.lua`,将`my_app`组件注册到`Skynet`中,并创建了`my_app`对象(`my_app`类在文件`my_app_app.lua`中定义,这里定义的`my_app_app`类即为`my_app`类)。注意:类实例化时,会自动执行此类的构造函数`ctor()`,再执行此类的初始化函数`init()`。 `my_app_app.lua`文件定义如下: ```lua local class = require 'mc.class' local service = require 'my_app.service' local my_app = class(service) function my_app:ctor() end function my_app:init() self.super.init(self) end return my_app ``` `my_app`类继承了该组件的`my_app.service`类。`my_app.service`类是根据`MDS`模型定义文件`model.json`、`service.json`,和资源协作接口组件仓`mdb_interface`的代码自动生成的类,是整个服务的入口,定义了组件初始化和服务端资源协作接口方法注册、对象创建等。 # 定制组件启动 ## 定制组件配置 除了通用组件的启动,还存在定制组件场景,和通用场景配置存在一定差异,以定制组件`custom_app`配置为例,需要在组件代码仓中进行配置,`custom_app.service`配置如下: ```lua [Unit] Description=custom_app service After=framework.service Requires=dbus.service framework.service [Service] StandardOutput=tty TTYPath=/dev/ttyS0 User=root Restart=always RestartSec=1 StartLimitInterval=0 EnvironmentFile=/dev/shm/dbus/.dbus Environment="ROOT_DIR=" Environment="PROJECT_DIR=" WorkingDirectory=/opt/bmc/extend/custom_app/apps/custom_app ExecStartPre=/bin/bash -c "uptime=`/bin/cat /proc/uptime |awk -F '.' '{print $1}'`; if [ $uptime -lt 100 ]; then /bin/sleep 30; fi" ExecStart=/opt/bmc/skynet/skynet /opt/bmc/extend/custom_app/apps/custom_app/config.cfg ExecStartPost=/bin/bash -c 'echo 0x21 > /proc/$MAINPID/coredump_filter' KillMode=process MemoryHigh=400M MemoryMax=512M LimitCORE=100000000 LimitSTACK=100000000 [Install] ``` 根据定制组件`custom_app`的`Unit`文件定义,`custom_app`服务通过启动`Skynet`被拉起。`Skynet`的启动配置文件`/opt/bmc/extend/custom_app/apps/custom_app/config.cfg`默认定义如下: ```lua include "/opt/bmc/libmc/config.cfg" app_root = "/opt/bmc/extend/custom_app/apps/" config:set_root("/") config:set_start("custom_app/service/main") config:include_app("persistence") config:include_app("maca") config:include_app("custom_app") config:done() MODULE_NAME = "custom_app" -- 服务名 ``` 与通用组件类似,定制组件也需要配置启动脚本,`custom_app/service/main.lua`文件示例: ``` lua require 'skynet.manager' local skynet = require 'skynet' local logging = require 'mc.logging' local custom_app = require 'custom_app' local CMD = {} function CMD.exit() logging:notice('custom_app service exit') end skynet.start(function() skynet.uniqueservice('sd_bus') skynet.register('custom_app') local ok, err = pcall(custom_app.new) if not ok then logging:error('custom_app start failed, err: %s', err) end skynet.dispatch('lua', function(_, _, cmd, ...) local f = assert(CMD[cmd]) skynet.ret(skynet.pack(f(...))) end) end) ``` `custom_app.lua`文件定义如下: ```lua local class = require 'mc.class' local service = require 'custom_app.service' local custom_app = class(service) function custom_app:ctor() end function custom_app:init() self.super.init(self) end return custom_app ``` 组件仓代码配置完成后,还需配置manifest,保证整包构建时可以将定制组件打包,在manifest `build/product/BMC/openUBMC/manifest.yml` 中添加定制组件依赖项 ```yml dependencies: - conan: custom_app ``` 在`build/subsys/rc`和`build/subsys/stable`中配置组件版本即可 ```yml dependencies: - conan: "custom_app/1.1.0@openubmc/stable" ``` 定制组件其他构建方式同通用组件,参考[《组件的构建与发布》](./build_process.md)。 ## 定制组件使用 定制组件与通用组件不同,打包构建完成之后,若要使用定制组件,需要进行定制才能使用对应服务 修改`maca`组件资源协作接口`Customer`属性为定制组件名,设置完成后重启bmc即可使用 ```shell busctl --user introspect bmc.kepler.maca /bmc/kepler/Managers/1/Package bmc.kepler.Managers.Package ``` ```shell NAME TYPE SIGNATURE RESULT/VALUE FLAGS bmc.kepler.Managers.Package interface - - - .Customer property s "" - .Provider property s "" const .Version property s "" const ``` --- # 组件启动配置 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/app_startup.html > Language: zh openUBMC采用了先进的微组件开发架构,将BMC管理的资源抽象成资源对象,组件通过资源接口标准相互通信,启动过程采用层级内并行拉起,可快速拉起openUBMC整套服务。 # openUBMC启动框架 openUBMC的启动框架采用***Systemd**+**Skynet**实现。其中服务的启动借助Systemd完成。Systemd作为一个Linux系统的初始化系统和系统管理器,负责启动系统中的各种服务和进程,并管理它们的生命周期。通过Systemd,openUBMC能够轻松地监控服务状态、控制服务的启动和停止,以及以进程为单位管理子服务的日志记录和用户管理。 除此之外,openUBMC采用了Skynet作为底层运行框架,Skynet是使用C+Lua实现的轻量级服务器框架,能够将数据包从一个服务发送出去,使同一进程内的服务接收并触发对应的回调函数进行处理。 # openUBMC的服务启动特点 - **并行启动**:传统的初始化系统采用串行启动方式,即按照固定的顺序逐个启动服务。而systemd采用并行启动方式,可以同时启动多个服务,大大提高了系统启动速度。 - **依赖管理**:systemd使用了一种基于依赖关系的服务启动方式。通过定义服务之间的依赖关系,systemd可以确保服务在正确的顺序下启动,并自动处理服务之间的依赖冲突。 - **子服务拉起**:采用Skynet完成单个进程服务内的子服务拉起。服务与服务之间环境解耦,减少服务之间的冲突。 - **灵活配置**: openUBMC采用Systemd执行Skynet,此过程也可以自定义Systemd执行非Skynet命令以启动定制化服务。 - **独立重启**:组件服务出现异常时,若无其他依赖项,无需执行openUBMC全量重启,只需重启单服务即可。 # openUBMC 启动流程 ## Systemd拉起服务 openUBMC的启动服务使用Systemd并行拉起服务(采用执行Skynet+配置文件方式拉起),整个流程中通过定义启动顺序和依赖项完成服务拉起。以bmc_core服务的拉起为例(所有的Systemd配置都在hica仓中): ```lua [Unit] Description=bmc_core service After=framework.service Requires=dbus.service framework.service [Service] StandardOutput=tty TTYPath=/dev/ttyS0 User=root Restart=always RestartSec=2 StartLimitInterval=0 EnvironmentFile=/dev/shm/dbus/.dbus Environment="ROOT_DIR=" Environment="PROJECT_DIR=" WorkingDirectory=/opt/bmc/apps/hica ExecStartPre=/bin/bash -c "uptime=`/bin/cat /proc/uptime |awk -F '.' '{print $1}'`; if [ $uptime -lt 100 ]; then /bin/sleep 30; fi" ExecStart=bash -c 'exec -a bmc_core /opt/bmc/skynet/skynet /opt/bmc/apps/hica/subsys/bmc_core/config.cfg' ExecStartPost=/bin/bash -c 'echo 0x21 > /proc/$MAINPID/coredump_filter' KillMode=process MemoryHigh=1000M MemoryMax=1024M LimitCORE=100000000 LimitSTACK=100000000 [Install] WantedBy=multi-user.target ``` 以上配置为Systemd的配置,具体配置请参考[Systemd](https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html)。 `Unit`:服务单元描述
`Unit.Description`:服务进程描述
`Unit.After`:服务拉起时序,在指定服务拉起后才能拉起
`Unit.Requires`:服务拉起时序,当依赖项重启时,本服务也会被重启
`Service`: 服务环境配置与约束
`Service.User`: 服务启动账户声明
`Service.Restart`: 服务重启模式
`Service.RestartSec`: 服务重启时延,单位秒
`Service.StartLimitInterval`: 无限次重启设置
`Service.Environmentxxx`: 环境变量配置
`Service.WorkingDirectory`: 服务工作路径(最终在服务器中的位置)
`Service.ExecStartPre`: 服务拉起预处理,通过抓取uptime中的信息进行时延启动
`Service.ExecStart`: 服务拉起命令,通过bash运行Skynet及其配置文件完成服务的拉起
`Service.ExecStartPost`: 服务拉起后处理
`Service.KillMode`: 设置在该单元服务停止时,杀死进程的方法
`Service.MemoryHigh`: 内存使用限制,如果进程的内存超过该限制,进程将会被降低运行时间,并快速回收其占用的内存
`Service.MemoryMax`: 内存最大使用限制,如果进程的内存超过该限制,则会触发out of memeory将其kill掉
`Service.LimitCORE`: 用于设置服务进程可创建的核心转储(core dump)的最大大小
`Service.LimitSTACK`:设置服务进程的栈大小限制
`Install`: 定义服务安装位置
`Install.WantBy`: 定义服务启动的拉起目标
在启动配置中,明确了服务启动的顺序、依赖服务、服务用户权限、服务重启模式、以及服务启动前置条件和**服务执行命令**。 ## Skynet拉起子服务 在上述描述中,我们知道Systemd会拉起一个个的进程服务,但本质上服务的拉起还是执行特定配置文件条件下的Skynet服务。在配置文件中定义了Skynet的所需的执行**入口**、执行**环境**、拉起**子服务**的定义。bmc_core配置文件如下所示: ```lua include "/opt/bmc/libmc/config.cfg" config:set_root("/") config:set_start("hica/subsys/bmc_core/service/main") config:include_app("firmware_mgmt") config:include_app("bmc_upgrade") ... config:include_app("ipmi_core") config:done() MODULE_NAME = "bmc_core" -- 服务名 thread = 6 -- 线程配置 ... -- 环境配置 OPERATE_LOG_PATH = '/var/log/operate_log' ``` `include`:基础配置文件的引入
`config:set_root`: 设置root路径
`config:set_start`: 服务启动程序入口
`config:include_app`: 服务启动包含组件的路径申明
`config:done()`: 结束config配置申明
`MODULE_NAME`:启动模块名
`thread`: 启动线程数
在本配置文件中完成了服务的入口的定义,在此配置下,进入到`hica/subsys/bmc_core/service/main`执行Skynet的`fork`完成子服务的拉起。 ```lua -- hica/subsys/hardware/service/main local skynet = require 'skynet' local launch_control = require 'mc.launch_control' skynet.start(function() local module_name = skynet.getenv('MODULE_NAME') ... skynet.uniqueservice('sd_bus') -- sd_bus服务拉起 launch_control.launch_components('bmc_core') -- bmc_core子服务拉起 end) ``` # 组件状态查询命令 在组件运行过程中,可以通过如下命令进行组件状态的查询: ```shell top -cbn 1 # 查看当前启动服务、启动命令、cpu利用率、内存占用率等等 ``` ```shell systemctl status # 查看openUBMC的服务启动进程与子进程树状关系 ``` 更多系统级信息可以在一键收集日志的`dump_info/RTOSDump/sysinfo`中的日志文件查看。 # 定制组件启动 定制组件启动请参考[《组件的创建和使用》](./app_creation.md) # More 更多配置请参考组件实现[《hica》](../component_interface_spec/hica.md) --- # 组件的构建与发布 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/build_process.html > Language: zh openUBMC采用`Conan`包管理器与`CMake`构建系统集成的方式,实现组件的独立构建和发布。`Conan`是一个`C`/`C++`构建框架,由命令、属性和方法构成,主要负责封装并对外提供一致的接口,并基于`Conan`仓库完成组件交付。`CMake`定义了如何从源代码生成可执行文件或库,主要任务是负责项目的构建过程。关于`CMake`的详细介绍请参考[Cmake官方文档](https://cmake.org/documentation/);`Conan`的详细介绍请参考[Conan官方文档](https://docs.conan.io/en/1.6/introduction.html)。 openUBMC组件构建由`CMake`脚本`cmakelists.txt`和`Conan`脚本`conaninfo.py`、`conanfile.py`以及`conanbase.py`组成: 1. `cmakelists.txt`:`CMake`构建配置文件,用于定义项目的构建规则、依赖关系、编译选项等,简化项目的编译和构建过程。 2. `conaninfo.py`:定义了`Conan`基本信息,包括包名,版本号和git仓。 3. `conanbase.py`:定义了统一的`Conan`构建脚本。 4. `conanfile.py`:`Conan`脚本,继承自`conanbase.py`,可以重写`conanbase`的方法。 # CMake基本使用 `CMake`是一个开源的跨平台自动化建构系统,用来管理软件构建的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个函数库。 `CMake`的所有语句都写在一个`CMakeLists.txt`的文件中。`CMakeLists.txt`文件确定后,直接使用Cmake命令运行`CMakeLists.txt`所在的目录,CMake之后就会自动生成makefile文件,然后再直接make就可以编译出构建结果。 更简单的解释就是`CMake`是为了生成`Makefile`而存在,开发者不需要自己去写`Makefile`,只需要写简单的`CMakeLists.txt`即可。开发者可以在`CMakeLists.txt`中添加引用所需的`C`/`C++`库。 这里,以组件`new_app`的`CMakeLists.txt`为例,简单介绍openUBMC中用到的`CMake`指令: ```cmake -- cmake最低版本需求 cmake_minimum_required(VERSION 3.14) -- 设置项目名称,后面可添加支持的语言,默认是C和C++ project(new_app) -- 查找PkgConfig模块,通过PkgConfig模块找到你想要找到的第三方库 find_package(PkgConfig REQUIRED) -- 用于查找PkgConfig格式的库信息 pkg_search_module(GLIB REQUIRED glib-2.0) ... -- 设置变量的值 set(TARGET_LIB ${PROJECT_NAME}) ... -- 指定安装时运行规则 install(DIRECTORY src/lualib DESTINATION ${APP_INSTALL_DIR} OPTIONAL) ... ``` 若为定制组件,则在通用组件配置的基础上,新增定制组件构建项 ```cmake ## customized resource deployment options set(CUSTOMER new_app) set(CUSTOM_INSTALL_DIR opt/bmc/extend/${CUSTOMER}) -- 定制仓所需的sr等文件/目录 install(DIRECTORY sr DESTINATION ${CUSTOM_INSTALL_DIR} OPTIONAL) ... message(STATUS "new_app customized resource deployment is completed.") ``` # Conan基本介绍 `Conan`是一个开源的`C/C++`包管理器,用于下载、管理和构建项目所需的依赖库。简单来说,`Conan`可以作为包的使用者和包的创建者,它使用`conanfile.py`文件自动化实现构建出包。在openUBMC中,`Conan`与`CMake`构建工具集成实现项目的编译和构建。 `conanfile.py`文件需定义一个继承自`ConanFile`的类。这个类包括两个部分:属性和方法。属性用于设置一些只读信息而方法用于自动化打包的逻辑。在编写完`conanfile.py`文件之后,执行`Conan`工具的`conan create`命令会默认按照以下顺序自动执行conanfile类的方法: ```python 1. export() 2. export_sources() 3. config_options() 4. configure() 5. layout() 6. requirements() 7. package_id() 8. validate() 9. validate_build() 10. build_requirements() 11. build_id() 12. system_requirements() 13. source() 14. generate() 15. imports() 16. build() 17. package() 18. package_info() ``` 这里简单介绍`conanbase`中定义的`export`、`generate`、`build`和`package`等方法。各方法的函数体功能简要介绍如下 ```python import os import stat import urllib3 from conans import ConanFile, CMake from bingo.component.gen import GenComp urllib3.disable_warnings() class ConanBase(ConanFile): name = "new_app" #定义包名 version = "0.0.1" url = "https://www.huawei.com" settings = "os", "compiler", "build_type", "arch" # 定义不同二进制包的配置。对操作系统、编译器、构建类型或架构定义的任何修改都将生成不同的二进制包。 generators = "cmake" language = "lua" _cmake = None _codegen_version = 14 scm = { "type": "git", "url": "", "revision": "auto" } options = { # 包特定的配置,可以在default_options中定义默认值 "asan": [True, False], "gcov": [True, False], "manufacture": [True, False], } default_options = { "asan": False, "gcov": False, "manufacture": False, } def generate(self): # 执行将创建一个映射Conan和CMake语法的conan_toolchain.cmake文件 ... # 构建时,此方法会自动生成export目录 def export(self): # 此方法定义拷贝文件到export目录 ... def requirements(self): # 引用组件的依赖包 ... # 构建时,此方法会自动生成build目录 def build(self): # 主要调用了cmake下的build方法,相当于执行了cmake build命令,完成从预处理到链接的全部过程 ... cmake = self._configure_cmake() cmake.build() # 构建时,此方法会自动生成package目录 def package(self): # 执行了cmake install命令,根据cmakelists.txt文件当中的install命令将编译生成后的文件移动到指定位置 cmake = self._configure_cmake() cmake.install() ... ``` openUBMC的工程工具`bingo`在构建命令`bingo build`中集成了自动生成`conanbase.py`的功能。此文件定义了继承自`ConanFile`的类`conanbase`,并在此类中已实现基本的构建方法。因此,在各组件的conanfile.py文件中,只需定义继承自conanbase的类即可。若开发者需要自定义构建出包文件,可在`conanfile.py`文件定义的类中重写相关方法。 `conanfile.py`文件的`settings`字段定义了不同二进制包的配置。在此示例中,对操作系统、编译器、构建类型或架构定义的任何修改都将生成不同的二进制包。这些配置信息的值都统一存放于`profile`文件中。在执行构建时,`Conan`工具会根据设置的`–profile`参数获取配置文件中的所有信息,并应用于要构建或安装的软件包。如果没有指定该参数,相当于使用`–profile=default`进行调用。 在组件目录下执行命令构建包时,会生成以`<包名>/<版本>@<用户>/<渠道>`格式命名的`Conan`包。 可通过`conan cache path <组件名>`获取`Conan`生成的包所存在的具体目录,构建生成的每一个`Conan`包都会包含五个重要文件夹,每个文件夹都在`confile`类中有对应同名的方法。 - `e`: 用于存储包的文件夹,`export`方法的默认目标文件夹。 - `es`: 在`conanfile.py`文件定义的类中,使用`exports_sources`方法`copy`的文件默认存放于此文件夹中。 - `s`: 存储源码文件,`source`方法的默认目标文件夹。 - `b`: 完成实际源代码编译的文件夹,`build`方法的默认目标文件夹。 - `p`: 最终构建生成的包所在的文件夹,每个不同的二进制配置将有一个子文件夹。`package`方法的默认目标文件夹。 # 构建、发布 openUBMC的工程工具实现了`CMake`和`Conan`工具的相关文件自动生成。同时,支持CLI命令一键完成组件的构建,运行`bingo build`命令所执行的整个构建流程可以描述为: 1. 主动生成`conanbase.py`文件。组件的`conanfile.py`文件继承自`conanbase.py`定义的类`conanbase`。 2. 根据命令参数获取交叉编译所需的配置信息。 3. 清除组件锁文件,对于组件在`service.json`文件中未指明特定版本的依赖,使用最新版本的依赖包。 4. 执行`conan create`命令,依据`conanfile.py`文件实现构组件定制化构建出包。 `bingo build`命令的相关参数如下: ```shell Build conan optional arguments: -h, --help show this help message and exit -bt BUILD_TYPE, --build_type BUILD_TYPE 构建类型,可选:dt,debug,release 默认:debug --stage STAGE 组件包发布阶段, 可选: dev(developer), pre, rc, stable 默认:dev -r REMOTE, --remote REMOTE conan仓别名,请检查conan remote list查看已配置的conan仓 默认: openUBMC_dev -nc, --no_cache 不使用~/.conan/data目录下的缓存包(构建前删除缓存) -o OPTIONS, --options OPTIONS Define options values (host machine), e.g.: -o Pkg:with_qt=true --user USER 指定conan包的user字段,尝试从/etc/bingo.conf文件读取conan.user字段,否则由程序管理 -as, --asan Enable address sanitizer ``` `bingo build`命令集成了`Conan`和`CMake`工具的使用,实现组件自动化编译出包。 开发者进行个人开发时,使用此命令生成的组件`Conan`包,将会发布并存放于本地的`root/.conan2/p`目录下。 --- # 资源协作接口查看 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/coding.html > Language: zh --- date: 2025/10/11 title: 组件的开发和代码编写 --- --- 在阅读本章节之前,您可以通过[《新增一个组件》](../quick_start/create_an_app.md)快速了解如何实现新增组件,以及在新组件中扩展相关接口和硬件适配等。 openUBMC各个组件对外的接口统一由资源协作接口定义。组件是全量功能提供者,来实现资源协作接口。资源协作接口采用`D-Bus`总线协议实现。各组件可以通过资源协作接口新增、查看或调用各服务提供的可用接口,而无需关注接口在其他组件中的内部实现。在阅读本篇介绍之前,请先了解[D-Bus总线协议](https://www.freedesktop.org/wiki/Software/dbus/)。 除了统一管理各组件对外的接口。openUBMC通过引入错误引擎框架,也建立了一套通用的错误处理机制,将各组件的错误定义统一管理。利用错误引擎框架,各组件只需自动动态将错误信息注册到错误引擎,后续由错误引擎框架接管各组件的错误处理流程。 openUBMC将资源协作接口和错误引擎统一由`mdb_interface`组件仓管理。开发者可以通过依赖`mdb_interface`组件仓,使用资源协作接口和错误引擎。也可以通过`mdb_interface`组件仓将自定义的错误机制添加到错误引擎中,或将自己所开发组件的对外接口添加到资源协作接口中,暴露给其他组件使用。开发者可参考[《mdb_interface》](https://gitcode.com/openUBMC/mdb_interface)快速了解`mdb_interface`组件仓。 下面简单介绍组件开发过程中,如何利用`mdb_interface`组件仓实现查看、新增和调用资源协作接口。以及组件开发过程中,错误引擎的使用。 # 资源协作接口查看 与`D-Bus`总线进行交互的命令行工具`busctl`,提供了许多管理和控制`D-Bus`总线的功能。使用`busctl`命令,可以查看和控制`D-Bus`总线上的所有对象,接口和方法。因此,开发者可以在支持openUBMC的环境中,使用`busctl`命令查看资源协作接口信息。 > [!NOTE] > 若环境中使用的是`build_type`为`release`类型的制品包,则不支持`busctl`命令,需`build_type`指定为`debug`类型构建的制品包才支持环境使用`busctl`命令。 常用`busctl`命令如下: - 查看`D-Bus`用户总线上的所有服务信息 ```shell busctl --user tree ``` - 查看`D-Bus`用户总线上指定服务的对象 ```shell busctl --user tree ``` - 查看`D-Bus`用户总线上指定对象的接口 ```shell busctl --user introspect ``` - 监视`D-Bus`用户总线上的消息传递 ```shell busctl --user monitor [service] [object] ``` - 查看`D-Bus`用户总线上指定对象的属性 ```shell busctl --user get-property ``` - 设置`D-Bus`用户总线上指定对象的属性 ```shell busctl --user set-property ``` - 使用`D-Bus`用户总线进行方法调用 ```shell busctl --user call [SIGNATURE [ARGUMENT...]] ``` 这里以`chassis`服务的`/bmc/kepler/chassis/MicroComponent`接口为例,使用以下命令查看该接口上挂载的所有属性和方法等。 ```shell busctl --user introspect bmc.kepler.chassis /bmc/kepler/chassis/MicroComponent ``` 命令执行成功,会返回以下信息(由于篇幅限制,这里只展示部分返回信息): ```shell NAME TYPE SIGNATURE RESULT/VALUE FLAGS bmc.kepler.MicroComponent interface - - - .HealthCheck method a{ss} i - .Author property s "openUBMC" const .Description property s "chassis management component" const .License property s "Mulan PSL v2" const .Name property s "chassis" const .Pid property i 2543 const .Status property s "InitCompleted" - .Version property s "1.60.16" const bmc.kepler.MicroComponent.ConfigManage interface - - - .Backup method a{ss}s a(ss) - .Export method a{ss}s s - .GetTrustedConfig method a{ss} s - .Import method a{ss}ss - - .Recover method a{ss}a{sb} - - .Verify method a{ss}s s - ``` 如上述返回信息所示,表头信息NAME表示此列为接口名、属性或方法名;表头信息`TYPE`表示数据类型;表头信息`SIGNATURE`表示属性的数据类型或方法的入参数据类型,`SIGNATURE`类型定义可参考[D-Bus Specification官方文档](https://www.freedesktop.org/software/systemd/man/latest/sd_bus_message_read_basic.html);表头信息`RESULT/VALUE`表示属性值或方法的返回值;表头信息`FLAGS`表示是否可读写。 # 资源协作接口RPC方法说明 开发者在阅读组件代码时,会发现几乎每个组件都在 `register_rpc_methods()` 中注册了大量形如 `ImplXxx` 的方法。本节统一说明这些RPC方法是什么、为什么这么多、参数如何理解以及怎么调用,帮助快速读懂组件代码。 ## RPC方法是什么 这里的“RPC方法”,本质上就是挂载在**资源协作接口**(`D-Bus`接口)上的方法,是组件对外暴露能力、供其他组件远程调用的标准通道。组件之间不直接调用彼此的内部函数,而是统一通过资源协作接口上的RPC方法进行协作。北向的 Redfish/IPMI 等请求,通常也是最终落到某个组件的RPC方法上执行。 ## 为什么每个组件注册了这么多 RPC方法的“定义”和“实现”是分离的: - **定义**:在 `mdb_interface` 组件仓中统一定义接口及其挂载的方法(参见本文「新增资源协作接口」一节)。 - **生成**:组件在 `mds/model.json` 中引用这些接口后,执行 `bingo gen`,框架会**为该组件每个对象、每个接口上的每个方法各生成一个 `ImplXxx(cb)` 桩函数**(位于自动生成的基类 `service.lua` 中)。 - **实现**:开发者在 `register_rpc_methods()` 中调用这些 `ImplXxx`,传入回调来填充具体实现。**未被填充实现的方法,被调用时将无人应答。** 因此,一个组件挂载的接口方法越多,需要注册的 `ImplXxx` 就越多——这正是“每个组件注册了一大堆RPC函数”的原因,它们与接口定义是一一对应的。 `ImplXxx` 的命名规则为:`Impl` + **模型类名** + **接口短名** + **方法名**(接口短名取接口全名的最后一段)。例如: - `ImplMyMDSModelCommunityGetRepoURL` = `Impl` + 模型类 `MyMDSModel` + 接口 `bmc.demo.OpenUBMC.Community` 的短名 `Community` + 方法 `GetRepoURL`。 - `ImplNPUMetricGetData`(`compute` 组件)= `Impl` + 模型类 `NPU` + 接口短名 `Metric` + 方法 `GetData`。 ## 回调函数的参数 注册RPC方法时传入的回调,统一为 `function(obj, ctx, ...)` 形式: | 参数 | 含义 | | --- | --- | | `obj` | 被调用方法所属的 mds 对象实例。可通过 `obj.service`、`obj.path`、`obj.interface` 获取其定位信息,并访问对象的属性。| | `ctx` | 调用上下文,承载调用发起方的身份信息(如北向接口 `Interface`、用户名 `UserName`、客户端地址 `ClientAddr`),用于权限校验与审计。| | `...` | 方法的入参,顺序与 `mdb_interface` 接口定义中 `req` 字段的定义一致(即 `busctl introspect` 中看到的 `SIGNATURE`)。| > [!TIP] > 当RPC方法内部需要继续调用其他组件的RPC时,应把收到的 `ctx` **原样透传**下去(如 `self.bus:pcall(obj.service, obj.path, obj.interface, "GetRepoURL", "a{ss}u", ctx, 1)`),以保证调用方身份在整条调用链上不丢失。只有当你是调用链的发起方(例如组件初始化、定时任务)且没有现成上下文时,才用 `context.new(interface, username, client_addr)` 或空的 `context.new()` 新建一个。 ## 如何调用RPC方法 - **命令行调试**:使用 `busctl --user call [SIGNATURE [ARGUMENT...]]`,详见本文「资源协作接口查看」一节。 - **在组件代码中调用**:通过 `self.bus:pcall(service, path, interface, method, signature, ctx, args...)` 直接发起调用,返回 `(err, result...)`;也可使用 `bingo gen` 生成的 `client.lua` 中的封装函数先获取接口对象再调用。详见本文「调用资源协作接口RPC接口」一节。 ## 真实示例 以 `compute` 组件为例,其注册的部分RPC方法如下: ```lua function compute_app:register_pmu_methods() self:ImplPmuPmuGetPcieVidDid(function(obj, ctx, ...) return self:GetPcieVidDid(...) -- 只读查询,未使用 ctx end) self:ImplPmuPmuReset(function(obj, ctx, ...) return self:Reset(ctx, ...) -- 涉及权限/审计,透传 ctx end) end ``` 可以看到,注册回调通常只是“接住”请求并转交给组件内部的业务函数;是否使用、透传 `ctx`,取决于该方法是否涉及权限或是否需要继续向下调用。 如需进一步了解模型定义与代码自动生成机制,请参考[《MDS》](../../overview/architecture/mds_model/MDS.md)和[《代码自动生成》](../../overview/architecture/cpp_lua_framework/code_generation.md)。 # 新增资源协作接口 >**注意:**
在openUBMC中,开发者如需新增`D-Bus`的接口资源,需要明确新增的属性信息,例如接口所在的服务、对象、以及接口名称、接口下所挂载的方法、属性等,并交由开源SIG组织的评审会议进行评审。评审通过后,可在`mdb_interface`组件仓中进行资源协作接口配置,并在组件代码仓中实现相应的功能。 openUBMC采用数据模型的方式定义资源协作接口。此数据模型在`mdb_interface`组件中统一定义资源协作接口及其挂载的公共属性和RPC方法等。组件通过模型定义接口、具体实现接口方法,再由自动生成代码注册资源协作接口上所挂载的RPC方法。由于openUBMC不支持用户对`mdb_interface`组件仓中的接口定义随意更改,`mdb_interface`组件仓提供了一个额外的资源协作接口的定义,用于社区演示和开发人员调试学习。在本章节中,将根据此接口定义介绍openUBMC新增一个资源协作接口的代码实现流程。 ## 步骤一:新增资源协作接口定义 通过开源SIG组织评审后,开发人员根据评审结果可在`mdb_interface`组件仓中新增资源协作接口数据模型的定义。对象和接口的定义分别存放在`json/path/`和`json/intf/`路径下。其中,在`json/path/`目录下定义对象以及该对象下所挂载的接口,而接口的具体定义(即接口上所挂载的方法、属性等信息)存放在`json/intf/`目录下。 为支持本文档的示例演示,openUBMC在资源协作接口定义的组件仓`mdb_interface`中已经添加了`/bmc/demo/MyMDSModel`对象定义和在该对象下挂在的`bmc.demo.OpenUBMC.Community`接口定义。此部分的代码定义如下: 1. 新增对象定义:开发者需要在`mdb_interface`组件代码仓的`json/path/`路径下添加对象定义文件,如新增`/bmc/demo/MyMDSModel/`对象定义文件`json/path/mdb/bmc/demo/MyMDSModel/MyMDSModel.json`(此文件路径和对象定义中的`path`属性对应,将path属性表示的路径中删除参数变量的层级即为该文件在`json/path/mdb`目录下存放的路径,且创建的文件名与类名一致)。对象定义代码如下: ```json { "MyMDSModel":{ "path":"/bmc/demo/MyMDSModel/", "interfaces": [ "bmc.demo.OpenUBMC.Community" ] } } ``` 若在`mdb_interface`组件中已经存在此对象定义,开发者只需在该对象定义的`interfaces`属性中添加需要新增的接口即可。 2. 在`mdb_interface`代码仓的`json/intf/`路径下新建`bmc.demo.OpenUBMC.Community`接口的定义文件`intf/mdb/bmc/demo/OpenUBMC/Community.json`文件(此文件路径与接口定义对应,将`interfaces`属性表示的值转换为路径表示,即为该文件在`json/intf/mdb`目录下存放的路径,最后一层为文件名),并添加接口定义信息: ```json { "bmc.demo.OpenUBMC.Community": { "properties": { "WelcomeMessage": { "baseType": "String", "description": "OpenUBMC欢迎消息" } }, "methods": { "GetRepoURL": { "description": "获取OpenUBMC代码仓的URL", "req": { "SecretNumber": { "baseType": "U32", "description": "OpenUBMC的神秘代码" } } , "rsp": { "OutData": { "baseType": "String", "description": "OpenUBMC的URL" } } } } } } ``` 3. 完成以上步骤后,开发者修改`service.json`中定义的版本号(即将三段式版本号的最后一段值加1),并在`CHANGELOG.md`中添加修改日志,便可在`mdb_interface`代码仓路径下通过以下命令构建出包: ``` shell bingo build ``` 构建成功后便实现了在资源协作接口定义中新增`/bmc/demo/MyMDSModel/`对象定义、并在该对象定义上挂载`bmc.demo.OpenUBMC.Community`接口定义,此接口定义上挂载`WelcomeMessage`属性和`GetRepoURL`方法的定义。 ## 步骤二:自动生成代码 openUBMC采用的模型定义文件简化了开发任务,只需要在组件中的模型描述文件中依赖与组件所需实现的接口定义,便可通过代码自动生成相关代码的实现。模型描述文件的详细代码编写可参考[《MDS》](../../overview/architecture/mds_model/MDS.md)。这里以`my_app`组件为例,实现`bmc.demo.OpenUBMC.Community`接口: 1. 首先,需要在`my_app`组件的`mds/service.json`文件中引用`mdb_interface`组件依赖: ```json { ... "dependencies": { ... "build": [ ... { "conan": "mdb_interface/[>=0.0.1]" } ] } } ``` 2. 在`my_app`组件的`mds/model.json`文件中定义该接口。注意接口定义路径和属性、方法类型等与`mdb_interface`组件仓中的接口定义相同。其中,`MyMDSModel`为业务模型定义的类名,与`path`属性对应的文件名保持一致。`interfaces`表示该类支持的资源协作接口的接口集合。接口定义下的`properties`属性表示需要挂到资源协作接口下的属性的集合。`MyMDSModel`属性下的`properties`表示此类的私有属性,无需挂到资源协作接口下,且不能与挂到资源协作接口下的属性和属性别名重名。 ```json { "MyMDSModel": { "path": "/bmc/demo/MyMDSModel/${id}", "interfaces": { "bmc.demo.OpenUBMC.Community": { "properties":{ "WelcomeMessage": {} } } }, "properties": { "SecretNumber": { "baseType": "U32" } } } } ``` 3. 以上已经完成`my_app`组件的类定义数据模型。根据`BMC Studio CLI`提供的命令便可以根据上述数据模型定义文件自动生成相关代码。 ```shell cd bingo gen ``` 命令执行成功,会在`my_app`组件目录下生成`gen`文件夹,此文件夹下包含了多个自动生成的代码文件。自动生成代码实现了对象注册的回调函数、服务的初始化、接口和属性监听的订阅函数等。关于自动生成的代码文件介绍可参考[代码自动生成](../../overview/architecture/cpp_lua_framework/code_generation.md)。 ## 步骤三:组件实现 自动生成的代码文件`my_app/service.lua`为组件的基类,开发者可以通过引入此基类,在源码文件中注册并实现接口。示例: ```lua local class = require 'mc.class' -- Lua开发框架提供的增强类型系统 local service = require 'my_app.service' -- 自动生成代码生成的组件基类 local log = require 'mc.logging' local object_manage = require 'mc.mdb.object_manage' local app = class(service) -- 创建一个组件类型 function app:ctor() -- 组件的构造函数 end function app:init() -- 组件的初始化函数 app.super.init(self) -- 先调用基类的初始化函数 self.my_mds_model = self:CreateMyMDSModel(1, function(object) -- 创建一个mds对象实例 object.ObjectName = "MyMDSModel_1" -- 在回调函数中进行对象的属性赋值 object.WelcomeMessage = "Hello OpenUBMC!" object.SecretNumber = 330 end) log:notice("SecretNumber") log:notice(self.my_mds_model.SecretNumber) self:register_rpc_methods() end function app:register_rpc_methods() --通过基类中的回调函数实现接口上挂载的RPC方法 self:ImplMyMDSModelCommunityGetRepoURL(function(obj, ctx, ...) log:notice("welcome to the method") return 'https://gitcode.com' end) end return app ``` 在openUBMC中,Lua开发框架定义了类实例化时,会自动执行此类的构造函数`ctor()`,再执行此类的初始化函数`init()`。 > [!NOTE] > 关于 `register_rpc_methods` 与 `ImplXxx` 回调的含义、命名规则、`obj`/`ctx` 参数说明,以及为什么每个组件都注册了大量RPC方法,请参考本文「资源协作接口RPC方法说明」一节。 ## 步骤四:组件构建 完成以上步骤,新增RPC方法的代码已经全部完成。开发者修改`my_app`代码仓中`service.json`文件中定义的版本号(将三段式版本号的最后一段值加1,即`my_app`组件版本号从0.0.1修改为0.0.2),并在`CHANGELOG.md`中记录修改日志,便可在`my_app`代码仓的路径下执行以下命令构建出`my_app`的组件包: ``` shell bingo build ``` 构建成功,控制台会输出组件包名`my_app/0.0.2@openubmc.dev/dev`。 ## 步骤五:产品构建 获取组件的Conan包后,开发者在openUBMC的制品仓`manifest`中添加此组件,便可构建出openUBMC的制品包。 这里开发者需要先拉取`manifest`组件仓。根据环境机型在对应的`manifest.yml`文件中添加组件包依赖。例如,这里选择`TaiShan200_2280v2`机型的环境。则应该在`manifest`组件仓的`build/product/BMC/openUBMC/manifest.yml`文件中添加`my_app`依赖: ```yml dependencies: - conan: "my_app/0.0.2@openubmc.dev/dev" ... ``` 执行完以上步骤,在`manifest`组件仓目录下执行以下命令构建`TaiShan200_2280v2`机型的openUBMC制品包: ``` shell bingo build ``` 命令执行成功,便可在`manifest`组件仓的`output`目录下生成制品包`rootfs_TaiShan200_2280v2.hpm`。之后,开发者便可使用此制品包更新openUBMC环境,并进行验证。 示例: 1. 在支持openUBMC的环境中升级此制品包后,可执行以下命令查看`/bmc/demo/MyMDSModel`对象上挂载的所有接口: ```shell busctl --user introspect bmc.kepler.my_app /bmc/demo/MyMDSModel/1 ``` 2. 在支持openUBMC的环境中升级此制品包后,可执行以下命令调用`bmc.demo.OpenUBMC.Community`接口的`GetRepoURL`方法: ``` shell busctl --user call bmc.kepler.my_app /bmc/demo/MyMDSModel/1 bmc.demo.OpenUBMC.Community GetRepoURL a{ss}u 0 1 ``` >**注意:**
为了提升效率,openUBMC支持组件根据组件的依赖关系有序拉起,且根据不同子系统并行被拉起。但根据以上的代码实现,`my_app`组件将会在环境中单独被拉起。若`my_app`和其他组件被拉起的顺序有要求时,可以修改`hica`组件仓,并在制品仓中修改制品中依赖的`hica`版本,将`my_app`组件放入子系统进程中启动。之后在`manifest`仓中构建出包便支持组件并行有序被拉起。关于`hica`组件的修改请参考[《hica》](../component_interface_spec/hica.md)。 # 调用资源协作接口RPC接口 在开发组件的业务代码时,不可避免的需要调用其他组件的RPC方法。下面简要介绍如何在另一个新增组件`new_app`中调用资源协作接口上挂载的`bmc.demo.OpenUBMC.Community`接口的`GetRepoURL`方法: ## 步骤一:引用接口 首先在`new_app`组件的`service.json`文件的`required`属性值中添加依赖的接口。这里,`path`值为“*”,表示会在资源协作接口上全局搜索此接口。当然,开发者也可以通过定义`path`属性,引用特定路径下的接口。 ``` json "required": [ { "path": "*", "interface": "bmc.demo.OpenUBMC.Community" } ] ``` ## 步骤二:代码自动生成 执行`bingo gen`命令后,在`/gen`路径下自动生成代码。关于自动生成代码的详细介绍请参考[《代码自动生成》](../../overview/architecture/cpp_lua_framework/code_generation.md)。其中,`gen/new_app/client.lua`是依据`service.json`以及`mdb_interface`接口定义文件自动生成的代码文件。根据`service.json`文件`required`部分定义的接口依赖生成客户端资源协作接口的接口方法调用、对象获取和信号订阅等函数。例如此文件中定义了获取`bmc.demo.OpenUBMC.Community`接口对象的方法: ```lua function new_app_client:GetCommunityObjects() return get_non_virtual_interface_objects(self:get_bus(), 'bmc.demo.OpenUBMC.Community', true) end ``` ## 步骤三:代码开发 通过以上自动生成代码,开发者在编写业务代码时,可以使用`client`中相应的函数获取接口对象,并通过接口对象调用此对象下挂载的RPC方法。这里以`new_app`组件业务代码的入口文件`/src/lualib/new_app_app.lua`为示例,编写以下代码实现: ```lua local class = require 'mc.class' local service = require 'new_app.service' local new_app_client = require 'new_app.client' local log = require 'mc.logging' local context = require 'mc.context' local new_app = class(service) function new_app:ctor() end function new_app:init() self.super.init(self) -- 获取接口对象 local objs = new_app_client:GetCommunityObjects() -- 调用接口对象下挂载的GetRepoURL()方法 local err , repoURL = self.bus:pcall("bmc.kepler.my_app","/bmc/demo/MyMDSModel/1", "bmc.demo.OpenUBMC.Community","GetRepoURL", "a{ss}u", context.new(), 1) log:notice(repoURL) end return new_app ``` 以上已经实现在组件中如何调用资源协作接口上的接口和调用资源协作接口RPC方法。 # 错误引擎 在openUBMC中,组件对外的错误由`mdb_interface`组件统一管理。错误定义的json文件存放在`mdb_interface`代码仓的`message`目录下。message目录结构如下: ```shell . ├── base.json -- Redfish标准错误 └── custom.json -- openUBMC自定义错误 ``` 开发者可以按需在`message`目录下,新增错误定义的目录和文件。 ## 步骤一:代码自动生成 开发者在使用错误引擎前,首先要确认在组件中引入了`mdb_interface`依赖。即在`service.json`文件中添加`build`依赖。然后,在本地组件仓路径下构建后可在`temp/opt/bmc/lualib/messsages`目录下获取到部署态的代码。`temp/opt/bmc/lualib/messsages`目录结构如下: ```shell . ├── base.lua ├── custom.lua └── init.lua ``` 其中部分代码样例如下: ```lua M.PropertyValueTypeErrorMessage = { Original = { Description = [=[Indicates that a property was given the wrong valu]=] .. [=[e type, such as when a number is supplied for a pr]=] .. [=[operty that requires a string.]=], Message = [=[The value %1 for the property %2 is of a different]=] .. [=[ type than the property can accept.]=], Severity = [=[Warning]=], NumberOfArgs = 2, ParamTypes = {[=[string]=], [=[string]=]}, Resolution = [=[Correct the value for the property in the request ]=] .. [=[body and resubmit the request if the operation fai]=] .. [=[led.]=], HttpStatusCode = 400, IpmiCompletionCode = [=[0xFF]=], SnmpStatusCode = 7, TraceDepth = 0 }, Name = 'PropertyValueTypeError', Format = [=[The value %s for the property %s is of a different]=] .. [=[ type than the property can accept.]=], BacktraceLevel = 0, Severity = log.WARN, HttpResponse = 400, IpmiResponse = 0xFF, RegistryPrefix = 'Base' } ---@return Error function M.PropertyValueTypeError(val1, val2) return create_error(M.PropertyValueTypeErrorMessage, val1, val2) end ``` 该样例中定义了类型错误函数。开发者在代码编写时,可直接调用此方法对错误信息抛出异常。 ## 步骤二:错误引擎的应用 以上述样例中抛出属性类型不一致错误的`M.PropertyValueTypeError`函数为例。使用错误引擎对上述添加的`bmc.demo.OpenUBMC.Community`接口的`GetRepoURL`方法的入参参数类型进行检查。由于资源协作接口中定义的`GetRepoURL`方法的入参为无符号整型,当传入参数类型为非整型时,应该抛出参数类型不一致错误。这里在此接口的实现组件`my_app`中,添加此错误引擎的使用。 在`my_app`组件的业务代码入口文件`/src/lualib/new_app_app.lua`中编写RPC方法的实现,并在实现代码中添加错误引擎。代码示例如下: ```lua local base_messages = require 'messages.base' function my_app:MyMDSModelCommunityGetRepoURL(attribute, value) if type(value) ~= 'number' then error(base_messages.PropertyValueTypeError(value, 'Attributes/' .. attribute.AttributeName)) end return 'https://gitcode.com' end ``` 与北向接口直接对接的方法中,接收到其他组件抛出的错误,可在中间层报错,将错误转换后再抛出错误异常。例如,在`new_app`组件中修改调用`GetRepoURL`方法的函数体。代码示例如下: ``` lua local base_messages = require 'messages.base' function new_app:MyMDSModelCommunityGetRepoURL(obj, ctx, attribute, value) local err , repoURL = self.bus:pcall(obj.service,obj.path, obj.interface,"GetRepoURL", "a{ss}u", ctx, 1) if err then if err.name == base_messages.PropertyValueTypeError.Name then error(base_messages.PropertyValueTypeError(value, 'Attributes/' .. attribute.AttributeName)) end end end ``` --- # 灵活扩展规则开发指南 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/flexible_extension_rule_development_guide.html > Language: zh 本文档主要介绍如何灵活扩展模型检查规则。 # 概述 为便于用户维护自己的模型检查规则,BMC Studio 支持用户自定义模型检查规则,工具将自动调用规则的代码完成模型检查。 # 规则定义 为模型检查定义规则,具体的操作方法如下: 1. 在`~/bmc_studio/var/plugins/rule_definition`路径下,打开`grammar_check.json`文件。 2. 修改`grammar_check.json`文件进行自定义检查规则。以下为定义规则的样例,请结合实际情况进行配置: ```json { "oem_rule_csr_001": { "name": "CSR 扩展规则查询样例", "category": "CSR", "description": "CSR 自定义语法中 expr 的配置写法为 expr(...),其中 expr()为固定语法,...为计算表达式,计算表达式中左右括号个数必须匹配,三元运算符参数个数匹配。", "errorListTemplate": [ "表达式(1%)的左右括号个数不匹配。" ], "errorInfluence": "CSR 扩展规则样例", "repairSugTemplate": [ "确保表达式中左右括号个数匹配。" ], "alarmLevel": "严重", "ciEnabled": false } } ``` - **oem_rule_csr_001**:规则编号,满足`oem_rule_{type}_{index}`,其中`{type}`为模型类型,取值包括`csr`、`ipmi`、`mds`、`intf_mapping`、`resource`、`custom_type`,`{index}`为`1~999`的序号,全局唯一。查看全量规则定义可以查看`/usr/share/bmc_studio/server/data`文件夹的complex_rules.json和base_rules.json,查看现有的规则定义,建议index从200开始,与基础规则,组件业务规则区分开 - **name**:规则名称,长度为小于128的非空字符串,全局唯一。 - **category**:模型分类,包括 CSR、IPMI、MDS、接口映射、资源协作接口、自定义类型。 - **description**:规则描述,长度小于1024的非空字符串。 - **errorListTemplate**:错误提示,长度小于1024的非空字符串。 - **errorInfluence**:错误影响,长度小于1024的非空字符串。 - **repairSugTemplate**:修复建议,长度小于1024的非空字符串。 - **alarmLevel**:错误级别,“提示”,“一般”,“严重”。 # 规则实现 规则定义完成后,须配置一个`.py`文件,用于实现规则。操作方法如下: 1. 在`~/bmc_studio/var/plugins/src`路径下创建`.py`文件。要求`.py`文件的名称与规则定义中的规则编号保持一致,例如,规则编号为:oem_rule_csr_001,则.py文件命名为:`oem_rule_csr_001.py`。 2. 在`oem_rule_csr_001.py`文件内配置相关规则,以下为定制规则的样例,请结合实际情况进行配置: > [!NOTE]说明:
> - BMC Studio 提供框架代码,位于`/usr/share/bmc_studio/server/tools/plugins/util`,其中包括"GrammarRule"类和"GrammarIssue"类,用户可基于这两个类实现自己的定制规则。
> - 规则逻辑定义在类中,要求继承 GrammarRule 并实现 validate 函数。
> - BMC Studio 会自动创建`__init__.py`文件。 ```python import re import importlib GrammarIssue = getattr(importlib.import_module("issue"), "GrammarIssue") GrammarRule = getattr(importlib.import_module("grammar_rule"), "GrammarRule") BASE_ERROR_TEMPLATE = "CSR 文件(1%)中的(2%)对象存在如下问题:" BASE_SUGGESTION_TEMPLATE = "对 CSR 文件(1%)中的(2%)进行如下修改:" # 规则实现类应当继承 GrammarRule 基类 class GrammarRuleCsrExample(GrammarRule): def __init__(self, config: dict): # init 时第一个参数应与规则定时时的编号一致 super().__init__("oem_rule_csr_001", config) # 框架调用入口,用户必须将检查逻辑实现在 validate 函数中 # value: dict 待检查文件的全部内容 # model: str模型分类,创建 GrammarIssue 类时使用 # file_path: str 待检查文件路径 # file_type: str 文件类型 # require_data: dict 模型的依赖数据,包括 MDB 模型数据,资源协作接口数据等 def validate(self, value: dict, model: str, file_path: str, file_type: str, require_data: dict): issues = [] for object_key, object_val in value['Object'].item(): # 创建 GrammarIssue 对象 issue = GrammarIssue(self.rule_id, config=self.config, model=model,file_path=file_path, file_type=file_type)\ .err(BASE_ERROR_TEMPLATE, [file_path, object_key])\ .suggest(BASE_SUGGESTION_TEMPLATE, [file_path, object_key]) # 核心检查逻辑,用户根据自身需求编写此处代码 for _, prop_val in object_val.items(): if not isinstance(prop_val, str): continue if not self.checkExpr(prop_val): print(prop_val) # 如果检查到错误,通过 err suggest 函数调用来加入检查结果 issue = issue.err(self.error_list_template[0], [prop_val]).suggest(self.repair_sug_template[0]) # 如果调用过 err suggest 函数,框架会自动将 need_append 设置为 ture if issue.need_append: # 调用 issue.format_issue 函数标准化报错信息,加入 issues 即可 issue.append(issue.format_issue(error_obj=object_key)) return issues def checkExpr(self, expr: str): brackets = re.findall(r'[()]', expr) #使用栈来检查括号是否匹配 stack = [] for bracket in brackets: if bracket == '(': stack.append(bracket) elif bracket == ')': if not stack or stack[-1] != '(': return False stack.pop() return not stack ``` # 规则生效 重启 BMC Studio,在模型检查界面,勾选对应检查规则即可。 --- # 如何管理组件的特性 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/manage_app_feature.html > Language: zh 组件的可裁剪特性可以使用宏隔离、条件打包、条件编译等描述实现,在构建侧需要使用options管理特性,本文指导开发者正确管理可裁剪的特性 ## 组件包如何管理options conan包使用Options对外呈现特性,openubmc为方便特性管理,使用mds/service.json文件的options向构建工具申明当前组件自定义的特性,每一项配置由`description`、`option`、`default`三部分组成,具体定义与conan特性控制相同,具体细节参考文档 [Conan options](https://docs.conan.io/2/reference/conanfile/attributes.html#options) 下面是一个只支持开和关特性的示例,该示例演示了一个叫`enable_firmware`的特性,该特性支持`True`和`False`两个配置,默认配置为`False` ```python "options": { "enable_firmware": { "description": "这是一个测试AAPA", "option": [true, false], "default": false } }, ``` ## 构建工具如何使用options 构建工具读取service.json后会使用模板引擎生成conanbase.py,该文件可以被conan理解,其中关键的信息有特性申明、cmake传递、cmake使用 ### 特性申明 模块引擎会将service.json定义的特性转换成python变量。 如下为生成的conanbase.py示例: ```python options = { "asan": [True, False], "gcov": [True, False], "manufacture": [True, False], "enable_firmware": [True,False], } default_options = { "asan": False, "gcov": False, "manufacture": False, "enable_firmware": False, } ``` - 注:asan、gcov、manufacture为开发者测试和装备预先定义的特性,开发者不用申明。 ### cmake传递 openubmc的组件自定义构建过程普遍使用CMakeLists.txt构建脚本,因此构建工具会向cmake传递特性状态,具体方式是在conanbase.py的_configure_cmake方法中定义cmake变量。 下面的示例为conanbase.py生成的代码,传递给cmake的变量固定以特性名转大写后加上`CONAN_DEFS_`前缀,如示例所示的`CONAN_DEFS_ENABLE_FIRMWARE`: ```python def _configure_cmake(self): # 其它代码 self._cmake.definitions["CONAN_DEFS_ENABLE_FIRMWARE"] = self.options.enable_firmware # 其它代码 ``` ### cmake使用 cmake如何使用不在本文讲解,请参考官方指导。 下面是一种使用方式示例,演示了打开`CONAN_DEFS_ENABLE_FIRMWARE`特性时包含`firmware_mgmt`目录的构建脚本: ```CMakeList if (CONAN_DEFS_ENABLE_FIRMWARE) add_subdirectory("firmware_mgmt") endif() ``` 也可以按特性状态定义宏,如示例: ```CMakeList if (CONAN_DEFS_ENABLE_FIRMWARE) add_definitions("-DFIRMWARE_ENABLE") endif() ``` 或者控制文件打包,如示例: ```CMakeList if (CONAN_DEFS_ENABLE_FIRMWARE) install(DIRECTORY firmware_mgmt/gen/interface/client/ DESTINATION include/client FILES_MATCHING PATTERN "*.h") endif() ``` ## 依赖管理 特性使能后可能引入新的依赖,当前service.json还不具备此项管理能力,需要组件owner自定义依赖管理,具体方法是在组件的`conanfile.py`实现`requirements`方法,因为`conanbase.py`提供了`requirements`基础实现,所以组件开发者一般是继承父方法再重写。 `conanfile.py`新增依赖示例,该示例演示了如果使能了enable_firmware特性后需要添加huawei_secure_c/1.0.0@openubmc.release/stable依赖: ```python def requirements(self): super(ConanBase, self).build() if self.options.enable_firmware: self.requires("huawei_secure_c/1.0.0@openubmc.release/stable") ``` --- # 微组件管理介绍 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/micro_component_management.html > Language: zh 微组件管理功能由MACA(micro & agile component architecture)组件提供,本文将介绍组件状态检查、系统重启机制等微组件管理功能以及相关的阈值配置,帮助开发者分析和定位组件、BMC重启问题 # 1 组件状态检查 ## 1.1 启动状态检查 ### 1.1.1 检查范围 service.json中配置了type和deployConfig字段的组件 type字段:用于表示组件类型,常驻进程组件需要配置type为application deployConfig字段:用于表示拉起组件的systemd配置文件,组件按照子系统维度拉起,如framework.service拉起hwdiscovery ### 1.1.2 检查原理 每个组件的默认启动状态会被置为starting,框架对公共接口 bmc.kepler.MicroComponent 上树时,会把该接口下的Status属性置为Starting 在组件初始化完成后,会把启动状态置为 InitCompleted 如果在一个组件的六次启动状态检测中,组件的启动状态始终为starting,就会被认为组件启动失败 ### 1.1.3 检查机制 - MACA 在启动1分钟后会进行两轮启动状态检查,每轮检查时间为2分钟 - 第一轮检查时,每个组件最多检查8次,每次间隔15秒,八次都失败后,重启检查失败组件所在的子系统进程,将组件服务重新拉起 - 重拉子系统进程后会进行第二轮检查,如果第二轮检查再次失败,则重启BMC。由于启动状态检查成功之后才会通知m3,升级BMC后连续启动检查失败2次后切换分区,连续10次检查失败后不再复位BMC - 升级之后,启动状态检查失败,导致连续重启BMC 2次,会触发切分区机制;非升级场景(如修改代码调试导致重启后启动状态检查失败),连续重启BMC 3次,会触发切分区机制;无论哪种场景,切分区都只会切一次 ### 1.1.4 阈值配置 在manifest仓的mc_control.json中,可以实现对启动状态检查各参数阈值的配置 ```json "startup_check": { "enabled": true, "timeout_mins": 2, "recovery_condition": { "abnormal_threshold": 2 }, "recovery_policy": { "action": "restart_system", "threshold": 10 } } ``` 参数说明如下 enabled:启动状态检查开关,可配置为true或false,默认为true timeout_mins:每轮检查的超时时间阈值,单位为分钟,默认为2 abnormal_threshold:最大检查轮数,默认为2 threshold:检查失败后BMC重启次数上限,默认为10 ## 1.2 健康状态检查 ### 1.2.1 检查机制 - 当组件启动后,会在资源树上注册健康状态检查的方法(框架提供的微组件框架自带接口和方法) - MACA收集到所有组件列表后,需要周期性调用该方法检测组件的健康状态,如果健康状态异常达到阈值(检测周期1分钟,连续3次,框架主程序需要杀掉对应的组件所在的进程,由systemd重新拉起) ### 1.2.2 阈值配置 在manifest仓的mc_control.json中,可以实现对健康状态检查各参数阈值的配置 ```json "health_check": { "enabled": true, "interval_mins": 1, "recovery_condition": { "abnormal_threshold": 3 }, "recovery_policy": { "action": "restart_process", } } ``` 参数说明如下 enabled:健康状态检查开关,可配置为true或false,默认为true interval_mins:检测周期,单位为分钟,默认为1 abnormal_threshold:健康状态异常阈值,默认为3 ## 1.3 组件在线状态检查 组件运行阶段出现异常导致组件(组件所在进程)连续重启,通过组件健康状态检查无法对齐采取自愈措施时,需要新增检查机制,进行干预。例如,某组件执行到特定业务时出现异常,导致进程反复coredump,由于组件能正常启动,且在健康状态检查的周期内,MACA能收到健康状态OK的返回消息 ### 1.3.1 检查机制 - 组件在10分钟内连续掉线5次,则复位BMC - 组件下线总次数:所有组件累计下线2000次后复位BMC - 默认最多复位3次,超过3次不再复位,只记录组件掉线次数 ### 1.3.2 阈值配置 在manifest仓的mc_control.json中,可以实现对组件在线状态检查各参数阈值的配置 ```json "online_check": { "enabled": true, "recovery_condition": { "time_window_mins": 10, "abnormal_threshold": 5 }, "recovery_policy": { "action": "restart_system", "threshold": 3 } } ``` 参数说明如下 enabled:组件在线状态检查开关,可配置为true或false,默认为true time_window_mins:检测时间范围,单位为分钟,默认为10 abnormal_threshold:连续掉线次数阈值,默认为5 threshold:复位次数阈值,默认为3 # 2 复位管理 MACA提供了BMC平滑重启、强制重启机制 ## 2.1 平滑重启 ### 2.1.1 看门狗概念 **看门狗(watchdog)**:watchdog可以理解为一个定时器,一种硬件设备,定时器超时会触发某种动作,如重启系统。每秒给watchdog发送一个“保持活动”的信号,表示BMC正常运行。在Linux内核中,可以通过ioctl命令来控制watchdog定时器的行为。 平滑重启会在完成准备以及清理阶段后,停止看门狗喂狗,复位BMC ### 2.1.2 复位流程 当前平滑复位流程共有Prepare、Process、Action、Cancel四种阶段,libmc4lua在mc.mdb.micro_component.reboot库提供on_prepare、on_process、on_action、on_cancel方法供业务注册自定义处理,各阶段的说明如下 | 阶段 | 说明 | 超时限制 | 组件操作约束 | 执行条件 | 执行成功的后置处理 | 执行失败的后置处理 | 注意事项 | | -- | -- | -- | -- | -- | -- | -- | -- | | Prepare | 复位前准备阶段 | 10s | 组件进行复位前准备操作,要求操作耗时短、可恢复,例如检测是否可以进行复位、数据落盘 | 组件正常运行,且未执行复位处理 | 进入Process | 进入Cancel阶段 | 所有组件Prepare成功后,BMC必定会完成复位操作 | | Process | 复位前处理阶段 | 默认120s,支持可配置,上限为600s,下限为120s | 组件进行复位前处理操作,支持耗时较长、不可回滚、依赖其它组件的处理操作,例如CPLD生效。该阶段操作不能影响组件业务功能的正常运行 | 所有组件复位前准备完成,且组件正常运行 | 进入Action阶段 | 进入Action阶段 | 返回结果不影响后续操作和BMC复位 | | Action | 复位执行阶段 | 60s | 组件进行复位执行操作,支持耗时适中、不可回滚、不依赖其它组件的操作,例如资源回收、停止服务、数据落盘 | 组件正常运行 | 执行重启 | 执行重启 | 1. 返回结果不影响BMC复位
2. 执行完成后,组件业务可能停止工作 | | Cancel | 复位取消阶段 | 无 | 组件进行复位取消操作,恢复Prepare阶段的操作,并取消重启 | 组件正常运行 | 取消复位 | 取消复位 | 无 | **注意事项**:各复位操作接口的使用需要符合上述约束,错误实现复位时操作或不实现复位时操作可能引发业务错误。尤其注意到进入Action阶段后,当前组件依赖的其它组件可能已停止正常工作,此时组件应该停止关键业务的执行,避免引发误告警等问题 ## 2.2 强制重启 直接停止喂狗,复位BMC。MACA在组件启动状态检查失败、触发组件连续掉线机制重启时,会执行强制重启 --- # 组件的独立测试 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/testing.html > Language: zh --- 开发者在进行业务代码开发时,需要关注自己开发的功能是否正常运作。尽管这些功能可能只是整个系统中的一小部分,但它们仍然需要经过单元测试(UT)、集成测试(IT)以及一定程度的真实环境测试。这些测试的目的不仅是验证新开发的单元功能是否正确,还要确保这些新功能在集成过程中与周围接口的正确性,并且没有破坏其他功能。 开发者在进行开发者测试代码编写时,要以提高产品业务代码的可测试性,提升DT用例设计、DT用例实现与执行质量;优化DT工程编译、运行、调试加载时间和降低DT工程维护成本,从而提升DT效率,降低DT成本,提升开发生产率为目标。 对于openUBMC的各个组件来说,它们在开发阶段就具备了独立测试的能力。开发者进行的测试可以显著减少版本集成后的缺陷,并减少后期定位缺陷的成本。开发者编写的测试代码与业务代码具有同等的重要性。 当前openUBMC DT测试框架主要涵盖的场景包括单元测试和集成测试: 1. 单元测试主要关注组件内函数可靠性,主要测试对象为组件内部各个子模块之间互相调用的函数。 2. 集成测试主要关注本组件与其他组件的接口可靠性,不关注内部函数。 openUBMC的开发工具`BMC Studio`提供了开发者测试的CLI命令`bingo test`此命令的相关参数如下: ```shell Test component optional arguments: -h, --help show this help message and exit -bt BUILD_TYPE, --build_type BUILD_TYPE 构建类型,可选:dt,debug,release 默认:debug --stage STAGE 组件包发布阶段, 可选: dev(developer), pre, rc, stable 默认:dev -r REMOTE, --remote REMOTE conan仓别名,请检查conan remote list查看已配置的conan仓 默认: openUBMC_dev -s, --from_source Build from source, include dependency component -nc, --no_cache 不使用~/.conan/data目录下的缓存包(构建前删除缓存) --user USER 指定conan包的user字段,尝试从/etc/bingo.conf文件读取conan.user字段,否则由 程序管理 -as, --asan Enable address sanitizer -ut, --unit_test Enable unit test -it, --integration_test Enable integration test -f TEST_FILTER, --test_filter TEST_FILTER Run unit test with a filter -a APP, --app APP App in hica -wb, --without_build 测试时不重新构建 ``` 其中,`bingo test -ut`和`bingo test -it`分别单元测试和集成测试的运行命令,也是开发人员最常用的测试命令。 # 单元测试 单元测试(UT)又称为模块测试,是针对程序模块来进行正确性检验的测试工作。开发者需要为自己所要编写的代码和自动生成的代码编写测试用例,确保代码逻辑的正确性。 ## 测试框架 openUBMC采用`LuaUnit`开源软件作为单元测试的基础测试框架。它提供了用例管理、调度和断言等功能,是一个功能全面、易于使用的单元测试框架。该框架会分析引用的文件中,所有以`Test`为开头的类,并依次调用以`test_*`命名的测试函数。目前,openUBMC已将`luaunit`转移至开发工具,在构建过程中会自动写入开发者测试依赖中,不需要开发人员自行配置。开发人员只需要在测试代码中导入`LuaUnit`,编写相关测试代码即可: ```lua luaunit = require('luaunit') ``` `LuaUnit`提供了`assertXX()`系列断言函数,比如`assertNotNil()`, `assertEquals()`等,可以提供更丰富的提示信息等。因此,在openUBMC中,不直接使用`assert()`函数。下面简要介绍常用的几种断言函数: **相等性断言:** ```lua -- 相等性断言。如果断言失败,将会打印extra_msg。对于table类型参数会进行更深层次的比较(元素个数、键、值比较) assertEquals(actual, expected[, extra_msg]) -- 不等性断言。 assertNotEquals(actual, expected[, extra_msg]) ``` **值断言:** ```lua -- 应用lua的规则,除了false和nil以外的值都认为是true,可以通过断言。 assertEvalToTrue(value[, extra_msg]) -- 只有false和nil才能通过断言,其他值均不能通过断言。 assertEvalToFalse(value[, extra_msg]) -- 只有true才能通过断言 assertTrue(value[, extra_msg]) -- 只有false才能通过断言 assertFalse(value[, extra_msg]) -- 只有nil才能通过断言 assertNil(value[, extra_msg]) -- 非nil的值都可以通过断言 assertNotNil(value[, extra_msg]) -- 只有actual和expected指向同一个对象才能通过断言,对于基本类型string、numbers、boolean、nil,等效于assertEquals assertIs(actual, expected[, extra_msg]) -- actual和expected指向不同对象才能通过断言 assertNotIs(actual, expected[, extra_msg]) ``` **类型断言:** ```lua -- 变量类型是number才可通过断言 assertIsNumber(value[, extra_msg]) -- 类型为string才可通过断言 assertIsString(value[, extra_msg]) -- 类型为table才可通过断言 assertIsTable(value[, extra_msg]) -- 类型为boolean才可通过断言 assertIsBoolean(value[, extra_msg]) -- 类型为nil才可通过断言 assertIsNil(value[, extra_msg]) -- 类型为function才可通过断言 assertIsFunction(value[, extra_msg]) -- 类型为userdata才可通过断言 assertIsUserdata(value[, extra_msg]) -- 类型为协程才可通过断言 assertIsCoroutine(value[, extra_msg]) -- 类型为线程才可通过断言 assertIsThread(value[, extra_msg]) ``` ## 单元测试范围 单元测试专注于验证软件中最小的可测试部分——功能单元的正确性。其核心目标是对功能单元的外部接口进行测试,以确保这些接口的稳定性和可靠性。由于功能单元内部调用的函数可能会因为各种原因(如代码重构或功能优化)而发生变化,因此这些内部函数不需要直接进行单元测试。 在Lua模块中,单元测试的对象是那些可供组件内其他Lua模块访问的函数。这些函数通常是通过模块的`return`语句返回的,或者是定义在返回的`table`内的函数。如果一个函数是局部的(`local`),并且没有通过`return`语句导出,那么这个局部函数通常不需要单独进行单元测试。这类函数的测试通常通过其他对外暴露的函数来间接完成。然而,如果某个局部函数通过`return`语句被导出,那么它也需要被纳入单元测试的范围。 ## 测试代码编写 UT是针对接口层面的测试用例,其测试代码位于组件仓的`test/unit`目录下。开发人员在编写单元测试代码时,需根据测试模块在`test/unit`目录下定义对应的测试用例文件。测试用例文件编写规则如下: - 根据测试功能定义对应的测试文件:测试文件名需以`test`开头,后面跟上该文件具体测试功能。如`test_operation.lua` - 在测试文件中需要定义一个全局表对象,用来承载具体的测试函数,测试函数名同样需要以`test`开头。示例如下: **被测文件`operation.lua`:** 作为源码文件,存放在`src/lualib`目录下 ```lua -- 该文件为业务功能实现文件,实现了运算方法 local calculator = {} function calculator:multiply(v1, v2) return v1 * v2 end function calculator:divide(v1, v2) if v2 == 0 then error("Division by zero") end return v1 / v2 end return calculator ``` **对应测试用例文件`test_operation.lua`:** 作为UT文件,存放在`test/unit`目录下 ```lua -- 导入被测模块 local calculator = require 'operation' -- 导入LuaUnit框架 local lu = require 'luaunit' -- 编写测试用例 test_calculator = {} -- 测试 function test_calculator:test_multiply() local re = calculator:multiply(0, 1) lu.assertEquals(re, 1) end function test_calculator:test_divide() local re = calculator:divide(0, 1) lu.assertEquals(re, 0) re = calculator:divide(1, 1) lu.assertEquals(re, 1) local ok = pcall(calculator.divide, 1, 0) lu.assertEquals(ok, false) end ``` openUBMC中,组件的单元测试是直接执行lua脚本,入口文件为`test/unit`目录下的`test.lua`。该文件的主要动作包含:加载配置文件、导入依赖库、导入所有测试模块(编写好的测试用例文件或目录)、通过luaunit启动测试。`test.lua`中的大部分代码是固定的,无需修改。一般情况下,只需要使用`require`将测试模块导入: ```lua require 'test_operation' ``` 完整的`test.lua`文件示例如下: ```lua loadfile(os.getenv('CONFIG_FILE'), 't', {package = package, os = os})() local lu = require('luaunit') local utils = require 'utils.core' local logging = require 'mc.logging' local current_file_dir = debug.getinfo(1).source:match('@?(.*)/') utils.chdir(current_file_dir) logging:setPrint(nil) logging:setLevel(logging.INFO) -- 导入测试模块 require 'test_operation' -- 启动LuaUnit os.exit(lu.LuaUnit.run()) ``` 在单元测试的入口文件`test.lua`中导入测试模块之后,在组件仓路径下执行单元测试命令: ```shell bingo test -ut ``` 执行此命令会自动执行单元测试入口文件`test.lua`。根据`test.lua`文件,`LuaUnit`框架会扫描导入的测试模块中所有的`test`或`Test`开头的变量(函数或表)来运行。 由于单元测试只关注功能测试,通过直接执行Lua脚本执行测试方法。对于需要调用外部组件接口的函数方法,单元测试无法调用到外部组件接口。面对此种情况,开发者可以通过`mock`打桩的方式模拟接口调用。 简单来说,单元测试的实现流程如下: 1. 确定测试范围:明确待测`lua`模块对外可访问的函数。 2. 对于新模块,在`test/unit`目录下创建`test_xxx.lua`文件(xxx即为业务代码文件的名称),编写相应开发者测试代码: 单元测试文件的编写格式如下: 1)导入被测模块。 2)创建测试`table`(同一类的用例需要通过一个`table`整合在一起,组成一个测试套,即一组相似的测试用例)。 3)编写测试函数主体,请注意测试用例应包含正常业务流,并考虑关键异常逻辑、边界值等场景。测试覆盖率应尽可能完整。 3. 在单元测试入口脚本`test.lua`中加载测试文件,例如: ```lua require 'test_operation' ``` 4. 在组件路径下运行测试命令执行组件的单元测试。 ```shell bingo test -ut ``` ## 测试覆盖率 openUBMC的工程工具`bingo`提供了单元测试覆盖率统计。覆盖率统计框架`luacov`自动统计单元测试用例的覆盖率。此框架和`luaunit`开发框架一样,也已转移至开发工具,不需要开发人员自行配置。 开发者在编写完单元测试和业务代码后,可在组件目录下执行以下命令统计测试覆盖率: ```shell bingo test -ut -cov ``` 此命令会自动检测UT代码覆盖率,并在`temp/coverage`路径下生成覆盖率可视化文件`luacov.report.html`。同时,开发者也可以通过控制台查看代码覆盖率统计结果。统计结果示例如下: ```shell 行覆盖率: 18.7%, 命中: 346 行, 未命中: 1509 行 覆盖率报告 luacov.report.html 保存到 /new_app/temp/coverage Dt 报告结果输出到 /new_app/temp/coverage/dt_result.json 增量总覆盖:100.0%, c代码覆盖: 100.0%, lua代码覆盖: 100.0% 增量覆盖率报告保存到 dt_result.json ================================ 构建菜单 ================================ 单元测试(ut): True 集成测试(it): False 覆盖率: True 地址消毒: False ============================================================================ ``` 组件的覆盖率统计范围包括组件代码根目录`src`下的所有Lua代码的覆盖率。 开发者在进行单元测试代码编写时,应尽可能提高测试用例的覆盖率,并充分考虑测试用例的边界值。 # 集成测试 单元测试是对组件内功能函数的测试,而集成测试主要关注本组件与其他组件的接口可靠性。集成测试通过`D-Bus`对外提供的接口需要开展集成测试,确保组件对外接口稳定。以组件`my_app`为例,在集成测试中,配置文件`test/integration/test_my_app.conf`(此配置文件名格式为以`test_`为头,后面跟组件名)通常用于定义Skynet的环境变量、引用集成测试所依赖的组件。而以`test/integration/test_my_app.lua`(此文件名格式为以`test_`为头,后面跟组件名)作为集成测试的入口运行文件。开发人员可在此文件中编写集成测试代码或引用集成测试文件。 `test_new_app.config`文件作为组件集成测试的入口配置文件,集成测试命令`bingo test -it`通过该配置文件的定义执行集成测试。`test_new_app.config`简要介绍如下: ```lua -- 引入/root/BMC/new_app/temp/opt/bmc/libmc/config.cfg文件 include("$CONFIG_FILE") -- 初始化集成测试目录 config:init_integration_test_dirs() -- 定义集成测试的入口文件 config:set_start("test_new_app") -- 定义集成测试相关的组件,注意此组件必须在service.json中定义test依赖 config:include_app('new_app') config:done() -- 定义SkyNet的变量,这些变量可在集成测试的lua文件中使用 TEST_DATA_DIR = 'test/integration/.test_temp_data/' test_apps_root = 'test/integration/apps/' ``` 在`test_new_app.config`配置文件中,`config:set_start("test_new_app")`定义了集成测试的入口文件为`test_new_app.lua`文件。`test_new_app.lua`简要介绍如下: ```lua -- 引用集成测试所需的服务 local skynet = require 'skynet' require 'skynet.manager' local log = require 'mc.logging' local utils = require 'mc.utils' local test_common = require 'test_common.utils' -- 集成测试准备阶段,创建临时目录用于存放集成测试过程中需要的文件 local function prepare_test_data() local test_data_dir = skynet.getenv('TEST_DATA_DIR') -- 变量test_data_dir在test_xxx.config中已定义 os.execute('mkdir -p ' .. test_data_dir) os.execute('mkdir -p ' .. '/tmp/test_dump') end -- 清除测试数据,避免临时目录存在数据影响集成测试的执行 local function clear_test_data(exit_test) log:info('clear test data') local test_data_dir = skynet.getenv('TEST_DATA_DIR') if not exit_test then return utils.remove_file(test_data_dir) end skynet.timeout(0, function() skynet.sleep(20) skynet.abort() utils.remove_file(test_data_dir) utils.remove_file('/tmp/test_dump') end) end -- 集成测试的业务测试代码,开发人员可在此部分编写相关业务测试代码 local function test_new_app() log:info('================ test start ================') -- todo log:info('================ test complete ================') end -- 集成测试的入口函数 skynet.start(function() clear_test_data(false) prepare_test_data() test_common.dbus_launch() skynet.uniqueservice('main') skynet.fork(function() local ok, err = pcall(test_new_app) clear_test_data(true) if not ok then error(err) end end) end) ``` 简单来说,集成测试的实现流程如下: 1. 确定测试范围:明确组件对外`rpc`接口。 2. 对于新模块,集成测试可能存在多种场景,每种场景的配置文件和测试脚本均不同,此时可在`test/integration`目录下创建不同的子目录,来管理不同的集成测试场景。 3. 在`service.json`文件中定义集成测试需要依赖的组件。 4. 在集成测试配置文件`test_xxx.conf`和集成测试skynet启动函数所在脚本文件`test_xxx.lua`编写相应代码,调用测试函数。 5. 运行测试命令执行组件的集成测试 ```shell bingo test -it ``` --- # 组件热复位介绍 > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_dev_basics/warm_reset.html > Language: zh ## 背景介绍 热复位是一种轻量级复位机制,其核心目的是清理设备及其通信接口的内部状态。其关键特性有以下几点:保留配置参数,即不重置中断使能、阈值、地址等预设配置;重置通信状态,即清除通信接口的临时状态数据,如序列号、会话状态等;不会触发自检。 ## 实现简介 实现方式:maca 调用新增资源树方法 WarmReset,通过 WarmReset 向所有其他组件发送消息,由各组件注册热复位回调函数,自己决定热复位的具体操作。组件完成热复位后,将结果返回给maca。maca输出完成热复位的日志,列出热复位异常的组件 ## 热复位命令 ```shell busctl --user call bmc.kepler.maca /bmc/kepler/MacaService bmc.kepler.SystemControl WarmReset a{ss} 0 ``` 或 ```shell mdbctl call MacaService_0 bmc.kepler.SystemControl WarmReset 0 ``` ## 相关日志 调用热复位接口后,组件执行热复位操作。观察到框架日志下有 “WarmReset begin”、“warm reseting ... prepare successfully”、“warm reseting ... closed successfully”、“WarmReset successfully” 格式的日志输出。运行日志下有“Warm reset start”以及“Warm reset Successfully”的日志输出,以下是部分日志的示例 ![image](../images/component_dev_basics/create_component/warm_reset/framework_log.png) ![image](../images/component_dev_basics/create_component/warm_reset/running_log.png) --- # account > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_interface_spec/account.html > Language: zh # account ## 版本信息 | 项目 | 内容 | | :------- | :--------------------------- | | 组件版本 | 1.120.42 | | 首发版本 | 1.70.19 | | 文档作者 | dowantgo | | 最后更新 | 2026-08-25 | ## 1. 组件概述 ### 1.1 组件简介 account 是 openUBMC 的用户与用户服务管理核心组件,负责 BMC 上所有用户及用户相关服务的管理。提供用户查询、创建、删除、用户密码策略配置、用户类型管理等功能。 在系统中,account 组件通过资源协作接口对外暴露用户、角色、登录规则、SNMP 团体名、密码策略等对象,提供本地认证、VNC 认证、RMCP 认证等RPC服务。 组件整体采用领域驱动设计(DDD)架构,分为四层: 1. 接口层(interface):作为组件级的对外统一出口,处理北向映射器、IPMI 通道下发的属性/方法变化,统一记录操作日志。 2. 服务层(service):完成多个领域对象与外部服务之间协调性、组合性的交互逻辑,作为各业务模块的出口。 3. 领域层(domain):提供相关实体类定义,承载核心业务逻辑,包括管理与备份用户、管理登录规则、管理权限角色等。 4. 基础设施层(infrastructure):提供供其他层调用的底层功能与公用处理方法的封装。 ### 1.2 解决什么问题 account 组件为 BMC 的安全访问控制提供了统一的用户管理底座: - 统一管理所有“用户”:IPMI 用户、本地用户、定制(OEM)用户,以及被视为用户管理的 SNMP 团体名、VNC 密码、SNMPv3 trap 用户、框内通信用户,权限与策略一致生效。 - 提供整套密码安全体系:密码复杂度检查、弱口令字典、历史密码检查、密码有效期/最短使用期、用户名密码前缀比对、首次登录强制改密。 - 提供登录访问控制:用户与权限关联、三条登录规则(IP/MAC/时间)、角色权限九大权限及自定义角色,登录接口管理 ### 1.3 核心功能 - 核心功能一:**用户生命周期管理** —— 新建、查询、修改、删除本地用户(ID 2~17)与 OEM 用户(内部 ID 101~115),含用户名、密码、登录接口、角色权限、首次登录策略、用户使能/禁用、手动锁定/解锁等属性管理。 - 核心功能二:**密码策略与安全服务** —— 密码复杂度检查、弱口令字典导入导出与检查、历史密码检查、密码最大/最短有效期、用户名密码前缀比对、首次登录强制改密策略。 - 核心功能三:**登录访问控制** —— 登录接口(Web/SNMP/IPMI/SSH/SFTP/Local/Redfish)管理、三条登录规则(IP 规则、MAC 规则、时间规则)、紧急登录用户(不受登录规则/接口/有效期限制)、角色权限九大权限管理及自定义角色。 - 核心功能四:**特殊账户管理** —— VNC 密码、SNMP 团体名(ro/rw,支持长团体名)、SNMPv3 用户鉴权/加密算法与密码、SSH 公钥导入删除、SNMP trapv3 用户、框内通信账户管理。 ### 1.4 关键术语表 | 术语 | 解释 | | :----------- | :------------------------------------- | | 本地用户 | 由 BMC 自身维护、存储在 BMC 数据库中的用户,ID 2~17,密码存储于 Linux shadow 文件 | | OEM 用户 | 定制用户,内部 ID 101~115,满足定制场景使用 | | 紧急登录用户 | 不受登录规则、登录接口、密码有效期限制的管理员用户,避免所有用户被限制后无法登陆 | | 登录规则 | 从 IP / MAC / 时间三个维度限制用户可登录的规则) | | 弱口令字典 | 预先导入的弱密码清单,密码命中字典(字典使能时)不允许被设置 | ### 1.5 外部交互边界图 ```mermaid flowchart TB subgraph 上层访问通道 A1[Web / Redfish 接口] A2[CLI / SSH / SFTP] A3[SNMP 接口] A4[IPMI 通道
LAN / BT / EDMA / IPMB-SM] end subgraph account组件 B1[用户与用户服务
本地用户 / OEM 用户] B2[密码安全服务
复杂度 / 弱口令 / 历史密码 / 有效期] B3[登录访问控制
接口掩码 / 登录规则 / 角色权限] B4[特殊账户
VNC / SNMP 团体名 / trap用户 / 框内通信] B5[认证服务
LocalAuthenticate / VncAuthenticate / RMCP] B6[扩展运维
定制化 / 导入导出 / 备份还原 / 日志收集] end subgraph 平台与第三方服务 C1[om / skynet 平台进程] C2[session 组件
认证后创建会话] C3[Web后端 / 北向映射器] C4[Linux 用户文件
passwd / shadow / group / ipmi] end A1 -->|鉴权 / 用户管理| B1 A1 -->|安全配置| B2 A2 -->|SSH公钥 / 登录规则| B1 A3 -->|SNMPv3用户 / 团体名| B4 A4 -->|Set/Get User Access 等| B1 C3 -->|业务侧IPMI命令| B3 B5 -->|认证结果| C2 B2 -->|锁定 / 解锁| C4 B1 -->|用户落库 / 文件同步| C4 B6 -->|定制 / 导入导出| C1 ``` ## 2. API 使用说明与示例 > **调用约定与安全提示**:文中 `a{ss}` 为调用上下文字典,示例中的 > `Interface`、`UserName`、`ClientAddr`、`Privilege` 应替换为实际调用环境 > 可用的上下文;`<账号ID>`、`<用户名>` 等尖括号内容均为占位符。`busctl` > 输出开头的 `y`、`u`、`b`、`s`、`ss` 等是 D-Bus 类型标记,属于成功响应 > 的一部分。涉及账号删除、改密、锁定、策略、SNMP 团体名或公钥的示例会改变 > 设备状态,验证前应记录原值并在结束后恢复;密码、私钥和 SNMP Ku 等敏感值 > 不应写入文档、工单或普通日志。 ### 2.1 用户集合对象(ManagerAccounts) 提供新建用户、按用户名查ID、设置用户可修改属性与锁定用户等能力。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .New method a{ss}ysayiaii y - .NewOEMAccount method a{ss}yssa{ss} y - .GetIdByUserName method a{ss}s y - .GetUidGidByUserName method a{ss}s uu - .SetAccountWritable method a{ss}ya{sb} - - .GetAccountWritable method a{ss}y a{sb} - .SetAccountLockState method a{ss}yb - - ``` #### 功能说明 通过该对象完成用户集合级的管理操作:新建本地用户(`New`)、新建 OEM 用户(`NewOEMAccount`)、按用户名查询用户 ID(`GetIdByUserName`)与 UID/GID(`GetUidGidByUserName`)、设置/查询用户属性的可修改性(`Set/GetAccountWritable`,用于制造定制化)、设置用户手动锁定状态(`SetAccountLockState`)。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.AccountService.ManagerAccounts | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | New | ysayiaii | y | 新建用户 | 入参:
y: 用户 ID,0(由系统从未占用的2~17中选择)或2~17
s: 用户名,1~32 字符;创建时还受当前账号类型的 `NamePattern` 策略及其他业务校验限制
ay: 密码字节数组,接口最大长度为 512 字节;实际密码要求还受当前密码策略限制
i: 角色ID:0 或2~20,枚举值见下方表格
ai: 登录接口数组,登录接口枚举值见下方表格
i: 首次登录策略:1-提示修改密码;2-强制修改密码
出参:
y: 新建用户 ID | | NewOEMAccount | yssa{ss} | y | 新建 OEM 用户 | y: 用户ID,101~115
s: 用户名,1~32 字符;创建时还受当前账号类型的 `NamePattern` 策略及其他业务校验限制
s: 密码,1~1024 字符;实际密码要求还受当前密码策略限制
a{ss}: 额外信息:operation(操作类型,取值:New-新建或Verify-校验)、role_id(角色ID,枚举值见下方表格)、interface(登录接口集合,枚举值见下方表格)、first_login_policy(首次登录策略:1-提示修改密码;2-强制修改密码)、is_pwd_encrypted(是否为密文密码,取值:2-是,其他-否)
出参:
y: 新建用户 ID | | GetIdByUserName | s | y | 通过用户名获取用户 ID | s: 用户名,1~32 字符(`` 会被映射为 `root`)
出参:
y: 用户 ID,0~255 | | GetUidGidByUserName | s | uu | 通过用户名查找用户 UID/GID | s: 用户名,1~32 字符
出参:
u: UID(非负整数),u: GID(非负整数) | | SetAccountWritable | ya{sb} | - | 设置用户某属性是否可修改 | y: 用户 ID,2~115
a{sb}: 属性可修改性字典(`*Writable` 属性名→是否可修改),例如 `UserNameWritable`→false | | GetAccountWritable | y | a{sb} | 获取用户属性可修改性 | y: 用户 ID,2~115
出参:
a{sb}: 属性可修改性字典,例如 `UserNameWritable`→true/false | | SetAccountLockState | yb | - | 设置用户锁定状态 | y: 用户 ID,2~115
b: 锁定状态(true 锁定 / false 解锁) | 角色类型: | 类型 | 枚举值 | 描述 | |------|--------| --- | | NoAccess | 0 | 无权限 | | CommonUser | 2 | 普通用户 | | Operator | 3 | 操作员 | | Administrator | 4 | 管理员 | | CustomRole1~4 | 5~8 | 自定义用户1~4 | | CustomRole5~16 | 9~20 | 自定义用户5~16 (定制开启) | 登录接口类型: | 类型 | 枚举值 | 描述 | |------|--------| --- | | Web | 1 | 使用浏览器登录BMC Web界面 | | SNMP | 2 | 使用符合SNMP协议的终端工具登录BMC | | IPMI | 4 | 使用符合IPMI协议的终端工具登录BMC | | SSH | 8 | 使用符合SSH协议的终端工具登录BMC命令行 | | SFTP | 16 | 使用符合SFTP协议的终端工具登录BMC文件系统 | | Local | 64 | 通过服务器的串口登录BMC命令行 | | Redfish | 128 | 使用符合Redfish协议的工具登录BMC | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | kepler.account.UserFull | 新建用户失败 | 用户数量已达上限 | 删除无用用户后再新建 | | kepler.account.InvalidAccountId | 新建/操作失败 | 用户 ID 非法(如指定为 1) | 使用合法用户 ID | | kepler.account.UserNameInvalid | 新建用户失败 | 用户名不符合命名规则 | 按 `AccountPolicy.NamePattern` 规则命名 | | ResourceAlreadyExists | 新建用户失败 | 用户名已存在 | 更换用户名 | | PropertyValueOutOfRange | 新建OEM用户失败 | 用户ID超出范围 | 使用范围内的OEM用户ID | | y | 新建用户成功返回用户 ID | NA | NA | #### 应用场景 - Web/CLI/Redfish 接口新建本地用户、配置角色与登录接口 - 制造定制化批量下发 OEM 用户 - 按用户名查询用户 ID 以定位后续操作方法 - 用户找回、登录失败锁定后的解锁操作(SetAccountLockState) #### 限制条件 - `New` 中 AccountId 取值范围 0~17,0 表示由系统自动选择,1 为内置管理员不允许指定 - `New` 密码为 `ay` 字节数组,不会在总线上明文透传;`NewOEMAccount` 密码为字符串(1~1024 字符) - `SetAccountWritable`/`GetAccountWritable` 中属性可修改性为字符串键字典;键名使用 `*Writable` 形式,例如 `UserNameWritable`。修改前应先读取并记录原值,验证后恢复原值 - 通过 SNMP 接口调用 `New` 时,组件内部走 `account_service_snmp` 分支,仅设置用户名 #### 调试示例 ##### 命令行调试 ```bash # 新建本地用户(不指定用户 ID,角色=管理员(4),1个登录接口=Web(1),强制首次改密(2)) busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ New a{ss}ysayiaii 3 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 \ 0 <用户名> <密码长度> <字节数组形式的密码> 4 1 1 2 响应示例: 成功:y <系统自动分配的账号 ID> 失败:Call failed: {"registry_prefix":"<注册表前缀>","name":"ResourceAlreadyExists","format":"The requested resource already exists."} 适用版本 1.70.19 及以上 # 新建oem用户(指定用户 ID(102),角色=管理员(4),登录接口 9=Web(1)+SSH(8),强制首次改密(2)) busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ NewOEMAccount a{ss}yssa{ss} 3 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 \ 102 <用户名> <密码> 4 operation New role_id 4 interface 9 first_login_policy 2 响应示例: 成功:y 102 失败:Call failed: {"name":"PropertyValueOutOfRange","params":["162","AccountId"],"args_with_index":["%1:162","%1"],"registry_prefix":"<注册表前缀>","format":"The value '%s' for the property %s is not in the supported range of acceptable values."} 适用版本 1.70.19 及以上 # 按用户名查询用户 ID busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ GetIdByUserName a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 user01 响应示例: 成功:y <该用户名对应的账号 ID> 失败:Call failed: {“registry_prefix”:“<注册表前缀>”,“format”:“UserName not exist.”,“name”:“UserNameNotExist”} 适用版本 1.70.19 及以上 # 按用户名查询 UID/GID(用户名必须是当前环境中已存在的测试账号) busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ GetUidGidByUserName a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <测试用户名> 响应示例: 成功:uu 适用版本 1.70.19 及以上 # 查询指定账号的属性可修改性;先记录 UserNameWritable 的原值 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ GetAccountWritable a{ss}y 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <账号ID> 响应示例: 成功:`a{sb} <属性数量> "UserNameWritable" ...` 适用版本 1.70.19 及以上 # 设置指定账号的用户名可修改性为 false;验证后必须恢复为上一步读取的原值 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ SetAccountWritable a{ss}ya{sb} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <账号ID> 1 UserNameWritable false 响应示例: `SetAccountWritable` 成功:无输出。 随后再次调用 `GetAccountWritable`,预期: `a{sb} <属性数量> "UserNameWritable" false ...` # 恢复 UserNameWritable 原值(将 <原值> 替换为查询时记录的 true 或 false) busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ SetAccountWritable a{ss}ya{sb} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <账号ID> 1 UserNameWritable <原值> # 预期响应:无输出。恢复后再次调用 GetAccountWritable, # UserNameWritable 应回到 <原值>。 适用版本 1.70.19 及以上 # 锁定指定账号(先通过 get-property 记录 Locked 原值;验证后用原值恢复) busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount Locked # 预期响应:b <原Locked值> busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ SetAccountLockState a{ss}yb 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <账号ID> true # 预期响应:无输出。 # 再次查询 Locked,确认输出为 b true;最后调用 SetAccountLockState 并传入原值恢复 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount Locked # 预期响应:b true # 恢复 Locked 原值(将 <原Locked值> 替换为首次查询时记录的 true 或 false) busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts bmc.kepler.AccountService.ManagerAccounts \ SetAccountLockState a{ss}yb 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <账号ID> <原Locked值> 响应示例: 成功:无 适用版本 1.70.19 及以上 ``` > 调试安全提示:上述方法可操作任意有权限的目标账号。验证接口时建议使用可删除的测试账号;对真实业务账号操作前应记录原值,并在验证后恢复配置。 ### 2.2 用户对象(ManagerAccount) 用户对象位于 `/bmc/kepler/AccountService/Accounts/:Id`,提供对单个用户的操作(删用户、改密码、导入/删除 SSH 公钥、记录上次登录、校验密码)。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .Delete method a{ss} - - .ChangePwd method a{ss}ay - - .ChangeSnmpPwd method a{ss}ay - - .ImportSSHPublicKey method a{ss}ss u - .DeleteSSHPublicKey method a{ss} - - .SetLastLogin method a{ss}ss y - .VerifyPassword method a{ss}s - - ``` #### 功能说明 针对单个用户提供完整的管理能力:删除用户、修改用户密码/SNMP 加密密码(`ChangePwd`/`ChangeSnmpPwd`,密码以 `ay` 字节数组传入,不做回显)、导入/删除 SSH 公钥(`ImportSSHPublicKey` 支持 URI 远程上传与文本两种方式)、记录用户上次登录 IP 与接口(`SetLastLogin`,供第三方认证使用)、校验密码正确性(`VerifyPassword`)。对象还通过属性暴露该用户的状态(Enabled/Locked/RoleId/Privileges/LoginInterface 等)。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.AccountService.ManagerAccount | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | Delete | - | - | 删除账户 | 无(对象路径中的 Id 即待删除用户 ID) | | ChangePwd | ay | - | 修改账户密码 | ay: 待设置密码字节数组,1~512 字节(需满足密码复杂度/弱口令/历史密码策略) | | ChangeSnmpPwd | ay | - | 修改本地用户 SNMP 加密密码 | ay: 待设置密码字节数组,1~512 字节 | | ImportSSHPublicKey | ss | u | 导入 SSH 公钥 | s: 类型,`URI` 或 `Text`
s: 内容,`URI` 为远程/本地路径;`Text` 为公钥文本
出参:
u: 任务 ID(远程上传时有效,否则为 0) | | DeleteSSHPublicKey | - | - | 删除 SSH 公钥 | 无 | | SetLastLogin | ss | y | 记录用户上次登录信息(第三方认证调用) | s: 上次登录 IP
s: 上次登录接口
出参:
y: 处理结果(0 成功) | | VerifyPassword | s | - | 校验用户密码 | s: 需要校验的密码字符串,最长 512 字符 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | kepler.account.PasswordComplexityCheckFail | 修改密码失败 | 新密码不满足复杂度要求 | 使用满足复杂度要求的密码 | | kepler.account.InvalidPasswordSameWithHistory | 修改密码失败 | 新密码与历史密码相同 | 更换新密码 | | kepler.account.PasswordNeedReset | 修改密码失败 | 用户首次登录需强制改密 | 先完成强制改密 | | kepler.account.IncorrectPublicKeyFormat | 导入公钥失败 | 公钥格式不正确 | 使用正确的 SSH 公钥文件 | | - | 操作成功 | NA | NA | #### 应用场景 - Web 端修改用户密码、删除用户、管理 SSH 公钥 - CDN/第三方认证登录后回写用户上次登录 IP 与接口 - Web 前端登录时校验密码(VerifyPassword) #### 限制条件 - `ChangePwd`/`ChangeSnmpPwd` 的密码为 `ay` 字节数组,总线上不出现明文 - 修改密码会触发密码复杂度、弱口令字典、历史密码、用户名密码前缀比对等全量策略校验 - 删除用户时,若用户为`内置用户`(如管理员、trapv3 用户、OEM 存储的底层用户等)会根据 `AccountPolicy.Deletable` 与删除保护规则失败 - `ImportSSHPublicKey` 的 `URI` 参数支持远程地址或本地绝对 `.pub` 文件路径;本地文件应置于 `/tmp` 目录。`Text` 参数必须是完整的 OpenSSH 公钥文本(例如以 `ssh-rsa` 开头的单行公钥),不能使用截断示例或私钥内容 #### 调试示例 ##### 命令行调试 ```bash # 参数说明:<账号ID> 为待操作的目标账号 ID;<当前密码> 与 <新密码> 替换为该账号的实际密码。 # 1. VerifyPassword:校验指定账号的当前密码。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ VerifyPassword a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <当前密码> # 预期响应:无输出。 # 2. SetLastLogin:记录最后登录 IP 与接口。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ SetLastLogin a{ss}ss 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 127.0.0.1 Web # 预期响应:y 0 # 3. ChangePwd:设置新密码 Xyz@2026AB;ay 长度为 10。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ ChangePwd a{ss}ay 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 10 88 121 122 64 50 48 50 54 65 66 # 预期响应:无输出。 # 3.1 VerifyPassword:用新密码回读确认 ChangePwd 生效。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ VerifyPassword a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 Xyz@2026AB # 预期响应:无输出。 # 4. ChangeSnmpPwd:设置 SNMP 密码 Snmp@2026AB;ay 长度为 11。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ ChangeSnmpPwd a{ss}ay 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 11 83 110 109 112 64 50 48 50 54 65 66 # 预期响应:无输出。 # 5. ImportSSHPublicKey:将完整 OpenSSH 测试公钥预先传至远程 /tmp/account_it_pem_key.pub,再按 URI 导入。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ ImportSSHPublicKey a{ss}ss 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 URI /tmp/account_it_pem_key.pub # 预期响应:u 0 # 5.1 读取摘要,确认导入结果非空。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ SshPublicKeyHash # 预期响应:s "<非空公钥摘要>" # 6. DeleteSSHPublicKey:删除刚导入的公钥。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ DeleteSSHPublicKey a{ss} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 # 预期响应:无输出。 # 6.1 再读摘要,确认输出为空字符串。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ SshPublicKeyHash # 预期响应:s "" # 7. Delete:删除指定账号。验证时可在测试结束后删除测试账号。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount \ Delete a{ss} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 # 预期响应:无输出。 ``` 适用版本 1.70.19 及以上 > 调试安全提示:改密、导入/删除公钥和删除账号均会改变目标账号。验证时建议创建可删除的测试账号;生产操作应使用实际目标账号 ID,并遵循相应变更流程。 ### 2.3 用户 SNMP 接口(ManagerAccount.SnmpUser) 该接口挂载在账号对象 `/bmc/kepler/AccountService/Accounts/:Id` 上,接口名为 `bmc.kepler.AccountService.ManagerAccount.SnmpUser`;它不是 `/SnmpUser` 子路径。该接口提供 SNMPv3 用户的鉴权/加密算法与密钥管理。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .SetAuthenticationProtocol method a{ss}yss - - .SetEncryptionProtocol method a{ss}y - - .GetSnmpKeys method a{ss} ss - ``` #### 功能说明 配置本地用户的 SNMPv3 鉴权算法与鉴权密码、加密算法与加密密码(`SetAuthenticationProtocol` 一次设置算法+两个密码,`SetEncryptionProtocol` 单独设置加密算法),并支持获取用户当前鉴权 key 与加密 key(`GetSnmpKeys`,返回 Ku)。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.AccountService.ManagerAccount.SnmpUser | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | SetAuthenticationProtocol | yss | - | 设置 SNMP 鉴权算法、鉴权密码和加密密码 | y: 鉴权算法:0 None / 1 MD5 / 2 SHA96 / 3 SHA224 / 4 SHA256 / 5 SHA384 / 6 SHA512
s: 鉴权密码,1~512 字符
s: 加密密码,1~512 字符 | | SetEncryptionProtocol | y | - | 设置 SNMP 加密算法 | y: 加密算法:0 None / 1 DES / 2 AES128 / 3 AES256 | | GetSnmpKeys | - | ss | 获取鉴权 key 和加密 key(Ku) | 出参:
s: 鉴权密码 Ku
s: 加密密码 Ku | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | kepler.account.PasswordComplexityCheckFail | 设置鉴权/加密密码失败 | 密码不满足 SNMP 密码策略 | 使用满足策略的密码 | | kepler.account.EncryptFail | 获取密钥失败 | 密钥加密解密异常 | 检查环境数据库/密钥是否损坏 | | - | 操作成功 | NA | NA | #### 应用场景 - Web 端配置用户 SNMPv3 鉴权/加密算法与密码 - SNMP 下发前校验用户算法与密码是否与脚本一致(避免 "Authentication failure") #### 限制条件 - 密码长度 1~512 字符,受 SNMP 密码策略(`SnmpCommunityPasswordRulePolicy`)约束 - 算法枚举为平台定义的 SNMP 算法值,需与 `SNMPAuthenticationProtocols`/`SNMPEncryptionProtocols` 定义一致 - 用户未设置密码时 SNMP 下发会失败,需先设置鉴权密码 - `GetSnmpKeys` 会返回实际 Ku 密钥材料;仅应在受控调试环境使用,输出不得写入文档、工单或普通日志 #### 调试示例 ##### 命令行调试 ```bash # 参数说明:<账号ID> 为待操作的目标账号 ID;SnmpUser 是接口名,路径始终为 /Accounts/<账号ID>。 # 1. SetAuthenticationProtocol:设置 SHA256(4)、鉴权密码 Auth@2026AB、加密密码 Encry@2026AB。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount.SnmpUser \ SetAuthenticationProtocol a{ss}yss 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 4 Auth@2026AB Encry@2026AB # 预期响应:无输出。 # 1.1 回读鉴权算法。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount.SnmpUser \ AuthenticationProtocol # 预期响应:y 4(SHA256) # 2. SetEncryptionProtocol:设置 AES256(3)。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount.SnmpUser \ SetEncryptionProtocol a{ss}y 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 3 # 预期响应:无输出。 # 2.1 回读加密算法。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount.SnmpUser \ EncryptionProtocol # 预期响应:y 3(AES256) # 3. GetSnmpKeys:返回两个非空 Ku 字符串。实际返回值属于敏感信息,不得复制到文档或普通日志。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<账号ID> bmc.kepler.AccountService.ManagerAccount.SnmpUser \ GetSnmpKeys a{ss} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 # 预期响应:ss "<脱敏鉴权Ku>" "<脱敏加密Ku>" ``` 适用版本 1.70.19 及以上 > 调试安全提示:上述方法会修改指定账号的 SNMP 配置。验证时建议使用可删除的测试账号;生产操作应使用实际目标账号 ID,并遵循相应变更流程。 ### 2.4 全局配置对象(AccountService) 全局配置对象位于 `/bmc/kepler/AccountService`,负责安全策略等全局属性的修改(属性直接通过 `Set` 修改),以及弱口令字典的导入导出、Web 公钥获取、用户恢复还原点操作。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .ImportWeakPasswordDictionary method a{ss}s u - .ExportWeakPasswordDictionary method a{ss}s u - .GetRequestedPublicKey method a{ss}y s - .RecoverAccount method a{ss}yy - - ``` #### 功能说明 该对象承载所有全局安全策略属性(详见下表)与四个方法:导入/导出弱口令字典(`Import/ExportWeakPasswordDictionary`,支持本地路径与远程 `URI` 上传,返回任务 ID)、获取 Web 前端登录加密公钥(`GetRequestedPublicKey`)、根据用户 ID 恢复到还原点(`RecoverAccount`)。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.AccountService | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 属性参数说明 | 属性名 | 类型 | 默认值 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | AccountLockoutCounterResetAfter | S32 | 0 | 账号锁定失败计数重置时间配置 | 当前接口未声明数值范围 | | AccountLockoutCounterResetEnabled | Boolean | false | 账号锁定失败计数重置使能 | true/false | | AuthFailureLoggingThreshold | S32 | 0 | 认证失败日志阈值配置 | 当前接口未声明数值范围 | | ServiceEnabled | Boolean | true | 账号服务使能状态 | true/false | | MinPasswordLength | S32 | 8 | 密码最短长度 | 单位:字符 | | MaxPasswordLength | S32 | 20 | 密码最长长度(只读) | 单位:字符 | | PasswordComplexityEnable | Boolean | true | 密码复杂度检查开关 | true/false | | InitialPasswordPromptEnable | Boolean | true | 首次登录修改密码提示 | true/false | | InitialAccountPrivilegeRestrictEnabled | Boolean | false | 初始账户权限限制开关 | true/false | | MinPasswordValidDays | U32 | 0 | 密码最短有效期 | 单位:天,与 MaxPasswordValidDays 差值不大于 10 | | MaxPasswordValidDays | U32 | 0 | 密码最长有效期 | 单位:天,0 表示不限制 | | EmergencyLoginAccountId | U8 | 0 | 逃生用户 | 0~17 | | SNMPv3TrapAccountId | U8 | 2 | SNMPv3Trap 用户 | 用户 ID | | InactiveDaysThreshold | U32 | 0 | 用户不活跃阈值 | 单位:天 | | WeakPasswordDictionaryEnabled | Boolean | true | 弱口令字典使能开关 | true/false | | HistoryPasswordCount | U8 | 5 | 检查历史密码数 | 0~MaxHistoryPasswordCount | | MaxHistoryPasswordCount | U8 | 5 | 历史密码设置的最大范围 | 单位:条 | | InitialPasswordNeedModify | Boolean | true | 初始密码需要强制修改 | true/false | | HostUserManagementEnabled | Boolean | true | 业务侧用户管理使能 | true/false | | OSAdministratorPrivilegeEnabled | Boolean | true | 业务侧管理员权限使能 | true/false | | SNMPv3TrapAccountLimitPolicy | U8 | 2 | trap 用户修改策略 | 0 Modifiable / 1 NameModifiable / 2 NotModifiable | | UserNamePasswordPrefixCompareEnabled | Boolean | false | 密码与用户名前 n 字节比较使能 | true/false | | UserNamePasswordPrefixCompareLength | U8 | 4 | 密码与用户名前 n 字节比较长度 | 单位:字节 | | SNMPv3TrapAccountChangePolicy | U8 | 0 | snmpv3trap 用户修改策略 | 0 保持原有 / 1 可重命名删除 | | RequireChangePasswordAction | Boolean | false | 是否要求仅可通过 ChangePwd 修改密码 | true/false | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | ImportWeakPasswordDictionary | s | u | 导入弱口令字典 | s: 本地文件使用 `/tmp/<文件名>`;也可传入远程 URL
文件大小不超过 1MB,行数不超过 1000 行,单行长度不超过密码最大长度
出参:
u: 本地导入返回 0,远程导入返回任务 ID | | ExportWeakPasswordDictionary | s | u | 导出弱口令字典 | s: 本地导出文件使用 `/tmp/<文件名>`,长度不超过 256 字符;也可传入远程 URL
出参:
u: 本地导出返回 0,远程导出返回任务 ID | | GetRequestedPublicKey | y | s | 获取 Web 登录加密公钥 | y: 公钥用途,当前支持 web 前端加密公钥:1
出参:
s: 公钥字符串 | | RecoverAccount | yy | - | 根据用户传入 ID 恢复还原点用户信息 | y: 用户 ID,2~17
y: 恢复策略,0:强制恢复(当前支持的策略) | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | kepler.account.WeakPWDDictImportFailed | 导入弱口令字典失败 | 文件为空、大小/行数超限或内容不合法 | 检查字典文件格式与限制 | | kepler.account.InvalidPath | 导入/导出失败 | 本地路径不在 `/tmp` 或路径格式不合法 | 使用 `/tmp/<文件名>` | | kepler.account.OperationInProcess | 导入/导出失败 | 字典导入/导出操作进行中 | 等待上一次操作完成 | | kepler.account.ValueOutOfRange | 属性设置失败 | 属性值超出取值范围 | 使用合法取值 | | kepler.account.PasswordForbidSetComplexityCheck | 设置失败 | 密码复杂度检查被锁定 | 见 FAQ Q1 | #### 应用场景 - Web/CLI 修改全局安全策略(密码复杂度、有效期、历史密码数、逃生用户、trap 用户等) - 制造定制化/恢复出厂时导入导出弱口令字典 - Web 前端登录获取加密公钥 - 用户数据备份还原点恢复 #### 限制条件 - 弱口令字典本地导入/导出路径使用 `/tmp/<文件名>`,文件最大 1MB、最多 1000 行,行内不允许存在不可见 ASCII 字符 - 弱口令字典的导入/导出使用 IN_PROCESS 状态锁,同一时间只允许一个导入/导出操作 - 密码复杂度检查(PasswordComplexityIsLock)被 IPMI 置位后,非制造模式下不可关闭(`PasswordForbidSetComplexityCheck`),详见 FAQ Q1 - `Set` 属性修改全局策略时,属性间存在联动约束(如 `MaxPasswordValidDays` 与 `MinPasswordValidDays` 差值不大于 10) - `RecoverAccount` 依赖设备中已存在的持久账号备份,且会覆盖目标账号数据;当前未在普通调试环境验证成功恢复场景,不能对业务账号直接执行 #### 调试示例 ##### 命令行调试 ```bash # 1. ExportWeakPasswordDictionary:先导出当前字典作为备份。 # 后续导入临时字典后,必须用该备份恢复。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService bmc.kepler.AccountService \ ExportWeakPasswordDictionary a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 /tmp/account_weakpwd_backup # 预期响应:u 0 # 预期失败响应(路径不在 /tmp): # Call failed: {"format":"The value %s of the property %s does not contain the file name or does not exist in the tmp directory.","name":"InvalidPath","params":["******","Export Path"],"registry_prefix":"<注册表前缀>"} # 前置:创建一份临时弱口令字典文件;该步骤不调用 AccountService 方法。 printf 'DocWeak2026\n' > /tmp/account_weakpwd_test # 2. ImportWeakPasswordDictionary:导入临时字典。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService bmc.kepler.AccountService \ ImportWeakPasswordDictionary a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 /tmp/account_weakpwd_test # 预期响应:u 0 # 预期失败响应(路径不在 /tmp): # Call failed: {"format":"The value %s of the property %s does not contain the file name or does not exist in the tmp directory.","name":"InvalidPath","params":["******","Import Path"],"registry_prefix":"<注册表前缀>"} # 清理:重新导入第 1 步备份,恢复测试前的弱口令字典。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService bmc.kepler.AccountService \ ImportWeakPasswordDictionary a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 /tmp/account_weakpwd_backup # 预期响应:u 0 # 3. GetRequestedPublicKey:获取 Web 登录加密公钥,用途值为 1。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService bmc.kepler.AccountService \ GetRequestedPublicKey a{ss}y 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 1 # 预期响应:s "<公钥字符串>" # 环境未配置该用途密钥时,允许响应:s "" # 预期失败响应(用途值为 0): # Call failed: {"format":"The value %s for the property %s is of a different type than the property can accept.","name":"PropertyValueTypeError","params":[0,"PublicKeyUsageType"],"registry_prefix":"<注册表前缀>"} # 查询全局策略属性示例:用户名密码前缀比对使能状态。 busctl --user get-property bmc.kepler.account /bmc/kepler/AccountService bmc.kepler.AccountService \ UserNamePasswordPrefixCompareEnabled # 预期响应:b true 或 b false(取决于设备当前配置)。 ``` 适用版本 1.70.19 及以上 ### 2.5 角色对象与角色集合(Role / Roles) 角色对象位于 `/bmc/kepler/AccountService/Roles/:Id`,角色集合位于 `/bmc/kepler/AccountService/Roles`,提供九大权限的管理与自定义角色的新增删除。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .New method a{ss}yasas - - .SetRolePrivilege method a{ss}yb - - .Delete method a{ss} - - ``` #### 功能说明 角色集合对象(`bmc.kepler.AccountService.Roles`)提供 `New` 新增自定义角色;角色对象(`bmc.kepler.AccountService.Role`)提供 `SetRolePrivilege` 设置角色九大权限、`Delete` 删除角色。角色对象的 `Name`/`RolePrivilege` 属性为只读,展示角色名称与权限列表。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.AccountService.Roles / bmc.kepler.AccountService.Role | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | New(Roles) | yasas | - | 新增扩展自定义角色 | y: 角色 ID,仅支持 CustomRole5~16(9~20)
as: 标准权限列表,仅接受 ReadOnly、UserMgmt、ConfigureSelf、BasicSetting
as: OEM 权限列表,仅接受 PowerMgmt、SecurityMgmt、KVMMgmt、VMMMgmt、DiagnoseMgmt | | SetRolePrivilege | yb | - | 设置角色权限 | y: 权限类型(PrivilegeType):0 UserMgmt / 1 BasicSetting / 2 KVMMgmt / 3 VMMMgmt / 4 SecurityMgmt / 5 PowerMgmt / 6 DiagnoseMgmt / 7 ReadOnly / 8 ConfigureSelf
b: 是否开启该权限。UserMgmt、ReadOnly、ConfigureSelf 不允许修改 | | Delete | - | - | 删除扩展自定义角色 | 无;仅支持删除 CustomRole5~16(9~20) | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | PropertyValueNotInList | 新增或删除角色失败 | RoleId 不在支持范围,或设置了无效权限类型 | 使用支持的 RoleId、PrivilegeType | | ResourceAlreadyExists | 新增角色失败 | 指定的扩展自定义角色已存在 | 选择尚未创建的角色 ID | | PropertyMissing | 新增角色失败 | 标准权限未同时包含 ReadOnly、ConfigureSelf | 在标准权限列表中同时传入二者 | | InsufficientPrivilege | 修改角色权限失败 | 尝试修改 UserMgmt、ReadOnly 或 ConfigureSelf | 仅修改允许调整的权限类型 | | ActionNotSupported | 新增或删除角色失败 | ExtendedCustomRoleEnabled 未开启 | 先开启扩展自定义角色功能 | | - | 操作成功 | NA | NA | #### 应用场景 - 新建扩展自定义角色(CustomRole5~16)并配置其权限 - 为用户分配角色实现最小权限管理 - 角色权限调整(如临时关闭某用户组的部分权限) #### 限制条件 - `New` 与 `Delete` 仅支持 CustomRole5~16(ID 9~20);CustomRole1~4 与内置角色不能通过这两个方法新增或删除 - 调试前需开启 `ExtendedCustomRoleEnabled`;结束后应恢复其原始值 - UserMgmt、ReadOnly、ConfigureSelf 是不可修改的权限类型 - `Name`/`RolePrivilege` 为只读属性,角色名称不可修改 #### 调试示例 ##### 命令行调试 ```bash # 前置:记录并开启扩展自定义角色功能;完成调试后,将该属性恢复为记录的原始值。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Roles bmc.kepler.AccountService.Roles \ ExtendedCustomRoleEnabled # 预期响应:b true 或 b false(记录该值)。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Roles bmc.kepler.AccountService.Roles \ ExtendedCustomRoleEnabled b true # 预期响应:成功时无输出。 # 新增临时扩展自定义角色 CustomRole5(示例角色 ID 为 9)。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Roles bmc.kepler.AccountService.Roles \ New a{ss}yasas 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <角色ID> 2 ReadOnly ConfigureSelf 0 # 预期响应:成功时无输出。 # 构造失败:RoleId=5 不在 New 支持的 9~20 范围内。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Roles bmc.kepler.AccountService.Roles \ New a{ss}yasas 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 5 2 ReadOnly ConfigureSelf 0 # 预期失败响应: # Call failed: {"format":"The value %s for the property %s is not in the list of acceptable values.","name":"PropertyValueNotInList","params":[5,"RoleId"],"registry_prefix":"<注册表前缀>"} # 回读角色名称;若上一步使用角色 ID 9,预期为 CustomRole5。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Roles/<角色ID> bmc.kepler.AccountService.Role \ Name # 预期响应:s "CustomRole" # 设置该角色的 BasicSetting 权限为开启(PrivilegeType=1)。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Roles/<角色ID> bmc.kepler.AccountService.Role \ SetRolePrivilege a{ss}yb 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 1 true # 预期响应:成功时无输出。 # 构造失败:ReadOnly(PrivilegeType=7)为不可修改权限。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Roles/<角色ID> bmc.kepler.AccountService.Role \ SetRolePrivilege a{ss}yb 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 7 false # 预期失败响应: # Call failed: {"format":"There are insufficient privileges for the account or credentials associated with the current session to perform the requested operation.","name":"InsufficientPrivilege","registry_prefix":"<注册表前缀>"} # 回读权限列表,确认其中包含 BasicSetting、ReadOnly、ConfigureSelf;字符串顺序不保证固定。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Roles/<角色ID> bmc.kepler.AccountService.Role \ RolePrivilege # 预期响应:as <数量> ... "BasicSetting" ... "ReadOnly" ... "ConfigureSelf" ... # 删除临时扩展自定义角色。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Roles/<角色ID> bmc.kepler.AccountService.Role \ Delete a{ss} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 # 预期响应:成功时无输出。 # 构造失败:内置 Administrator 角色 ID=4 不在 Delete 支持的 9~20 范围内。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Roles/4 bmc.kepler.AccountService.Role \ Delete a{ss} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 # 预期失败响应: # Call failed: {"format":"The value %s for the property %s is not in the list of acceptable values.","name":"PropertyValueNotInList","params":[4,"RoleId"],"registry_prefix":"<注册表前缀>"} # 清理:将 ExtendedCustomRoleEnabled 恢复为前置步骤记录的 true 或 false。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Roles bmc.kepler.AccountService.Roles \ ExtendedCustomRoleEnabled b <记录的原始值> # 预期响应:成功时无输出。 ``` 适用版本 1.70.19 及以上 ### 2.6 登录规则对象(Rule) 登录规则对象位于 `/bmc/kepler/AccountService/Rules/:RuleId`(规则 ID 1~3),提供 IP/MAC/时间三个维度的登录限制(仅属性,无方法)。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS Enabled property b - - .IpRule property s - - .MacRule property s - - .TimeRule property s - - ``` #### 功能说明 每条登录规则包含使能状态 `Enabled`、源 IP 规则 `IpRule`、源 MAC 规则 `MacRule`、时间规则 `TimeRule` 四个可读写属性。用户可通过用户对象的 `LoginRuleIds` 属性绑定规则;规则生效时会参与登录准入校验。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.AccountService.Rule | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 属性参数说明 | 属性名 | 类型 | 默认值 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | Enabled | Boolean | false | 登录规则使能状态 | true/false | | IpRule | String | 空字符串 | IP 登录规则 | IPv4/IPv6 地址,或带掩码的地址;IPv4 掩码范围 1~32,IPv6 掩码范围 1~128 | | MacRule | String | 空字符串 | MAC 地址登录规则 | `XX:XX:XX:XX:XX:XX` 或三段前缀 `XX:XX:XX`,每段为两位十六进制数 | | TimeRule | String | 空字符串 | 时间登录规则 | `HH:MM/HH:MM`、`YYYY-MM-DD/YYYY-MM-DD` 或 `YYYY-MM-DD HH:MM/YYYY-MM-DD HH:MM` | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | PropertyValueFormatError | 设置规则失败 | IP、MAC 或时间规则表达式非法 | 使用合法格式;错误参数会标识 IP、MAC 或 StartTime/EndTime | | org.freedesktop.DBus.Error.UnknownProperty | 查询或设置失败 | 属性名称不存在或拼写错误 | 使用 Enabled、IpRule、MacRule、TimeRule 中的准确名称 | | - | 操作成功 | NA | NA | #### 应用场景 - 限制某类用户仅在办公网段、特定时间段内允许登录 - 绑定规则到用户实现细粒度登录准入 #### 限制条件 - Rule 是纯属性对象,没有业务方法;属性写入需要 SecurityMgmt 权限 - 固定提供规则 ID 1~3;调试时应记录并恢复被修改规则的原始值 - 启用带限制条件的规则可能影响后续登录;建议先保持 Enabled=false 完成格式验证 #### 调试示例 ##### 命令行调试 ```bash # 以下以规则 3 为例。开始前先读取四个属性并记录原值;不要假定其他环境的规则为空或关闭。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ Enabled # 预期响应:b true 或 b false busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ IpRule # 预期响应:s "<当前IP规则>" busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ MacRule # 预期响应:s "<当前MAC规则>" busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ TimeRule # 预期响应:s "<当前时间规则>" # 设置并回读 IP 规则;保持 Enabled=false,不会启用登录限制。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ IpRule s "192.0.2.0/24" busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ IpRule # 预期响应:s "192.0.2.0/24" # 构造失败:IPv4 掩码 33 超出支持范围。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ IpRule s "192.0.2.0/33" # 预期失败响应:Call failed: {..."name":"PropertyValueFormatError","params":["192.0.2.0/33","IP"],"registry_prefix":"<注册表前缀>"...} # 设置并回读 MAC 规则。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ MacRule s "02:00:00:00:00:01" busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ MacRule # 预期响应:s "02:00:00:00:00:01" # 设置并回读全天时间规则。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ TimeRule s "00:00/23:59" busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ TimeRule # 预期响应:s "00:00/23:59" # 清理:将三个规则属性替换为前置步骤记录的原始值;Enabled 在本示例中未修改。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ IpRule s "<记录的原始IpRule>" busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ MacRule s "<记录的原始MacRule>" busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/Rules/3 bmc.kepler.AccountService.Rule \ TimeRule s "<记录的原始TimeRule>" # 预期响应:各命令成功时无输出。 ``` 适用版本 1.70.19 及以上 ### 2.7 SNMP 团体名对象(SnmpCommunity) SNMP 团体名对象位于 `/bmc/kepler/Managers/1/SnmpService/SnmpCommunity`,提供 SNMP 团体名与团体登录规则的管理。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .SetRwCommunity method a{ss}s - - .SetRoCommunity method a{ss}s - - .GetSnmpCommunity method a{ss} ss - .SetSnmpCommunityLoginRule method a{ss}as - - ``` #### 功能说明 设置/获取 SNMP 读写团体名(`SetRwCommunity`/`SetRoCommunity`/`GetSnmpCommunity`)。模型中还声明了 `SetSnmpCommunityLoginRule`,但当前服务未注册其回调,运行时调用会返回“method SetSnmpCommunityLoginRule not implemented”。团体名支持普通与长团体名(由 `LongCommunityEnabled` 控制)。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Managers.SnmpService.SnmpCommunity | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | SetRwCommunity | s | - | 设置 rw SNMP 团体名 | s: rw 团体名字符串(空字符串表示删除) | | SetRoCommunity | s | - | 设置 ro SNMP 团体名 | s: ro 团体名字符串(空字符串表示删除) | | GetSnmpCommunity | - | ss | 获取 snmp 团体名 | 出参:
s: rw 团体名
s: ro 团体名 | | SetSnmpCommunityLoginRule | as | - | 设置 SNMP 团体名登录规则 | as: 登录规则 ID 字符串列表。当前版本仅在模型中声明,服务端未实现,调用会失败 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | kepler.account.InvalidCommunityStringLength | 设置团体名失败 | 团体名长度超出范围 | 使用合法长度的团体名 | | kepler.account.CommunityStringContainSpace | 设置团体名失败 | 团体名含空格 | 移除空格 | | SameROCommunityName | 设置 ro 团体名失败 | ro 团体名与当前 rw 团体名相同 | 使用不同的 ro、rw 团体名 | | SameRWCommunityName | 设置 rw 团体名失败 | rw 团体名与当前 ro 团体名相同 | 使用不同的 ro、rw 团体名 | | BMC.Error.Unknow | 设置团体名登录规则失败 | 当前服务未注册 SetSnmpCommunityLoginRule 回调 | 当前版本不可使用该接口;需服务端补充实现后再调用 | | - | 操作成功 | NA | NA | #### 应用场景 - 配置 SNMP 读写团体名(ro/rw) - 在 SNMP 客户端与设备侧保持团体名一致 #### 限制条件 - ro 与 rw 团体名不能相同;空字符串表示删除对应团体名 - 团体名不允许包含空格,长度受 SNMP 配置约束 - 调试前必须读取并记录原始团体名;团体名属于敏感凭据,日志和文档中应脱敏 - `SetSnmpCommunityLoginRule` 在当前服务中未实现,不能作为可用 API 示例 #### 调试示例 ##### 命令行调试 ```bash # 先读取并记录当前 rw、ro 团体名;返回值包含敏感凭据,请勿写入日志或文档。 busctl --user call bmc.kepler.account \ /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity \ GetSnmpCommunity a{ss} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 # 预期响应:ss "<当前rw团体名>" "<当前ro团体名>" # 设置临时 rw、ro 团体名;两者必须不同。 busctl --user call bmc.kepler.account \ /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity \ SetRwCommunity a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <临时rw团体名> # 预期响应:成功时无输出。 busctl --user call bmc.kepler.account \ /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity \ SetRoCommunity a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <临时ro团体名> # 预期响应:成功时无输出。 # 回读确认;返回顺序为 rw、ro。 busctl --user call bmc.kepler.account \ /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity \ GetSnmpCommunity a{ss} 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 # 预期响应:ss "<临时rw团体名>" "<临时ro团体名>" # 构造失败:将 ro 设置为与 rw 相同的团体名。 busctl --user call bmc.kepler.account \ /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity \ SetRoCommunity a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 <临时rw团体名> # 预期失败响应:Call failed: {"format":"The property ReadOnlyCommunity is the same as another community name.","name":"SameROCommunityName","registry_prefix":"<注册表前缀>"} # SetSnmpCommunityLoginRule 在模型中声明但当前服务未实现;以空数组调用不会修改配置。 busctl --user call bmc.kepler.account \ /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity \ SetSnmpCommunityLoginRule a{ss}as 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 0 # 预期失败响应:Call failed: {"format":"... method SetSnmpCommunityLoginRule not implemented","name":"BMC.Error.Unknow"} # 清理:将 rw、ro 团体名恢复为前置步骤记录的原始值。 busctl --user call bmc.kepler.account \ /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity \ SetRwCommunity a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 "<记录的原始rw团体名>" busctl --user call bmc.kepler.account \ /bmc/kepler/Managers/1/SnmpService/SnmpCommunity bmc.kepler.Managers.SnmpService.SnmpCommunity \ SetRoCommunity a{ss}s 4 Interface CLI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 "<记录的原始ro团体名>" # 预期响应:各命令成功时无输出。 ``` 适用版本 1.70.19 及以上 ### 2.8 本地认证对象(LocalAccountAuthN) 本地认证对象位于 `/bmc/kepler/AccountService/LocalAccountAuthN`,供 session 等组件进行本地用户、VNC 用户与 RMCP(IPMI)认证。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .LocalAuthenticate method a{ss}saya{sb} a{ss} - .VncAuthenticate method a{ss}ss a{ss} - .GenRmcp20Code method a{ss}ysuuayayayys ayayay - .GenRmcp15Code method a{ss}yayyuu ay - ``` #### 功能说明 提供本地用户认证(`LocalAuthenticate`,通过 `Config` 字典可切换到 TestPassword/IpmiLocalAuth/RecordOnly 模式)、VNC 认证(`VncAuthenticate`,密文+挑战码)、IPMI 2.0(`GenRmcp20Code`)与 IPMI 1.5(`GenRmcp15Code`)的认证码生成。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.AccountService.LocalAccountAuthN | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | LocalAuthenticate | saya{sb} | a{ss} | 本地用户认证 | s: 用户名,1~32 字符
ay: 密码字节数组
a{sb}: 扩展配置字典(IsAuthPassword / TestPassword / IpmiLocalAuth / RecordOnly / RecordLoginInfo / UpdateActiveTime 等开关)
出参:
a{ss}: 账户信息 | | VncAuthenticate | ss | a{ss} | VNC 用户认证 | s: 密文
s: 挑战码
出参:
a{ss}: 账户信息 | | GenRmcp20Code | ysuuayayayys | ayayay | IPMI 2.0 认证码生成 | y: 加密算法
s: 用户名,1~32 字符
u: 控制台端会话 ID
u: 服务端系统身份 ID
ay: 控制随机数(16 字节)
ay: BMC 随机数(16 字节)
ay: 服务端设备身份 ID(16 字节)
y: 角色权限
s: IP 地址
出参:
ay: RAKP2 认证码
ay: SIK
ay: RAKP3 认证码 | | GenRmcp15Code | yayyuu | ay | IPMI 1.5 版本用户认证 | y: 加密算法
ay: 有效负载,1~255 字节
y: 用户 ID
u: 会话 ID
u: RMCP 会话的序列号
出参:
ay: 认证码 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | AuthorizationFailed | 认证失败 | 用户不存在、密码错误、账号被禁用、接口未开放或登录规则不通过 | 检查账号、密码和接口配置 | | UserLocked | 认证失败 | 用户被手动锁定 | 解锁用户后重试 | | NoAccess | 本地认证失败 | 角色为 NoAccess | 调整用户角色 | | AuthorizationUserRestricted | VNC 认证失败 | 命中登录规则限制 | 检查 VNC 用户的登录规则 | | - | 认证成功返回账户信息 | NA | NA | #### 应用场景 - session 组件创建本地用户会话时调用 `LocalAuthenticate` - VNC 认证(远程窗口) - IPMI LAN 会话建立时的 RMCP2.0/RMCP1.5 认证码生成 #### 限制条件 - `LocalAuthenticate` 的 Config 类型为 `a{sb}`,不是 `a{ss}`;可通过 RecordLoginInfo、UpdateActiveTime 关闭测试产生的登录记录 - GenRmcp20Code、GenRmcp15Code 均要求目标账号开启 IPMI 登录接口;二者会记录该账号的 IPMI 登录信息 - VNC 认证失败会计入 VNC 账号的 PAM 失败次数,可能导致账号锁定;没有真实 VNC 密码和匹配挑战码时,不应构造失败请求 - 建议使用临时 Web+IPMI 账号验证前三个方法,完成后删除该账号 #### 调试示例 ##### 命令行调试 ```bash # 前置:创建一个临时 Web+IPMI 账号。以下示例中用户名为 itauth20260825、账号 ID 为 <临时账号ID>。 # LocalAuthenticate:使用正确密码认证,关闭登录记录和活跃时间更新。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/LocalAccountAuthN bmc.kepler.AccountService.LocalAccountAuthN \ LocalAuthenticate a{ss}saya{sb} 4 Interface Web UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 itauth20260825 11 65 117 116 104 64 50 48 50 54 88 89 3 IsAuthPassword true RecordLoginInfo false UpdateActiveTime false # 预期响应:a{ss} <数量>,其中包含 "Id" "<临时账号ID>" 与 "UserName" "itauth20260825"。 # 构造失败:以错误密码认证临时账号。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/LocalAccountAuthN bmc.kepler.AccountService.LocalAccountAuthN \ LocalAuthenticate a{ss}saya{sb} 4 Interface Web UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 itauth20260825 10 66 97 100 64 50 48 50 54 88 89 3 IsAuthPassword true RecordLoginInfo false UpdateActiveTime false # 预期失败响应:Call failed: {"format":"Authorization failed because the user name or password is incorrect, or your account is locked.","name":"AuthorizationFailed","registry_prefix":"<注册表前缀>"} # GenRmcp20Code:使用 HmacSha1(1) 和三个固定 16 字节输入生成 RAKP2、SIK、RAKP3。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/LocalAccountAuthN bmc.kepler.AccountService.LocalAccountAuthN \ GenRmcp20Code a{ss}ysuuayayayys 4 Interface IPMI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 1 itauth20260825 1 1 16 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 16 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 16 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 4 127.0.0.1 # 预期响应:ay 20 ay 20 ay 20 。 # 构造失败:使用不存在的用户名生成 RMCP 2.0 认证码。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/LocalAccountAuthN bmc.kepler.AccountService.LocalAccountAuthN \ GenRmcp20Code a{ss}ysuuayayayys 4 Interface IPMI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 1 itauth_not_exist 1 1 16 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 16 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 16 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 4 127.0.0.1 # 预期失败响应:Call failed: {"format":"Authorization failed because the user name or password is incorrect, or your account is locked.","name":"AuthorizationFailed","registry_prefix":"<注册表前缀>"} # GenRmcp15Code:使用 HmacMd5(2) 和临时账号 ID 生成认证码。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/LocalAccountAuthN bmc.kepler.AccountService.LocalAccountAuthN \ GenRmcp15Code a{ss}yayyuu 4 Interface IPMI UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 2 4 1 2 3 4 <临时账号ID> 1 1 # 预期响应:ay 16 <认证码字节>。 # VncAuthenticate:不提供通用伪造调用。该方法必须使用真实 VNC 密码生成的密文和匹配挑战码;错误调用会累计 VNC 账号失败次数。 # 清理:删除临时账号,清除本轮 RMCP 登录记录与认证失败次数。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/<临时账号ID> bmc.kepler.AccountService.ManagerAccount \ Delete a{ss} 4 Interface Web UserName <当前登录管理员> ClientAddr 127.0.0.1 Privilege 16 # 预期响应:成功时无输出。 ``` 适用版本 1.70.19 及以上 ### 2.9 密码策略对象与账户策略对象(PasswordPolicy / AccountPolicy) 密码策略对象位于 `/bmc/kepler/AccountService/PasswordPolicys/:AccountType`,账户策略对象位于 `/bmc/kepler/AccountService/AccountPolicies/:AccountType`,提供按账户类型(Local/OEM/SNMPCommunity/VNC 等)的密码与账户策略。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS Policy property u - - .Pattern property s - - .MaxPasswordLength property u - - .AccountType property s - - ``` #### 功能说明 `PasswordPolicy` 按账户类型配置密码校验策略(`Policy` 位图:bit0 默认开关、bit1 指定开关)、密码正则 `Pattern`、最大密码长度 `MaxPasswordLength`;`AccountPolicy` 按账户类型配置用户名正则 `NamePattern`、允许的登录接口集合 `AllowedLoginInterfaces`、前端是否呈现 `Visible`、是否可删除 `Deletable`/`OnlineDeletable`。策略与 IPMI 0x30/0x93 的 Set/Get PasswordRulePolicy(0x77/0x76-07)与 Set/Get PasswordPattern(0x77/0x76-08)对应。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.AccountService.PasswordPolicy / bmc.kepler.AccountService.AccountPolicy | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 属性参数说明 | 属性名 | 类型 | 默认值 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | Policy(PasswordPolicy) | U8 | - | 密码校验策略 | 以 bit 位区分,bit0 默认开关,bit1 指定开关,取值不可为 0 | | Pattern(PasswordPolicy) | String | - | 密码校验正则表达式 | 0~255 字符 | | MaxPasswordLength(PasswordPolicy) | U32 | - | 本账户类型可支持的密码最大长度 | 1~512 | | AccountType(PasswordPolicy) | String | - | 账户类型(只读) | Local / OEM / SNMPCommunity / VNC 等 | | NamePattern(AccountPolicy) | String | "" | 用户名正则规则 | 0~255 字符,如 `^[a-zA-Z_][a-zA-Z0-9_]{0,15}$` | | AllowedLoginInterfaces(AccountPolicy) | String[] | 7 接口 | 允许本地用户开启的登录接口 | Web/SNMP/IPMI/SSH/SFTP/Local/Redfish | | Visible(AccountPolicy) | Boolean | false | 标识某类型用户前端是否呈现 | true/false | | Deletable(AccountPolicy) | Boolean | false | 标识某类型用户是否可删除 | true/false | | OnlineDeletable(AccountPolicy) | Boolean | true | 标识在线用户是否可删除 | true/false | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | kepler.account.ValueOutOfRange | 设置策略失败 | 策略值/正则非法 | 使用合法取值 | | kepler.account.PasswordPatternInvalid | 设置失败 | 正则表达式非法 | 检查正则语法 | | - | 操作成功 | NA | NA | #### 应用场景 - 按账户类型差异化配置密码复杂度与用户名规则 - IPMI 侧同步设置密码规则(SetPasswordRulePolicy) #### 限制条件 - 策略按 `AccountType` 区分,不同账户类型独立配置 - 该对象仅属性,通过 `Set` 操作生效,设置成功会打印对应操作日志(`PasswordPolicy`/`PasswordPattern`/`MaxPasswordLength`/`NamePatternChange` 等) #### 调试示例 ##### 命令行调试 ```bash # PasswordPolicy:读取 Local 账户类型的最大密码长度;u 表示无符号整数。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/PasswordPolicys/Local bmc.kepler.AccountService.PasswordPolicy \ MaxPasswordLength # 预期响应:u <当前最大密码长度>,默认通常为 u 20。 # AccountPolicy:读取并记录 Visible 原始值;b 表示 Boolean。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/AccountPolicies/Local bmc.kepler.AccountService.AccountPolicy \ Visible # 预期响应:b true 或 b false。请记录 true/false,恢复时使用该原始值。 # 将 Visible 设为 true,演示布尔属性写入。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/AccountPolicies/Local bmc.kepler.AccountService.AccountPolicy \ Visible b true # 预期响应:成功时无输出。 # 回读确认写入生效。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/AccountPolicies/Local bmc.kepler.AccountService.AccountPolicy \ Visible # 预期响应:b true。 # 清理:将 true 替换为前一步记录的原始值;例如原始值为 false 时执行以下命令。 busctl --user set-property bmc.kepler.account \ /bmc/kepler/AccountService/AccountPolicies/Local bmc.kepler.AccountService.AccountPolicy \ Visible b false # 预期响应:成功时无输出。 # 最终回读,确认 Visible 已恢复为记录的原始值。 busctl --user get-property bmc.kepler.account \ /bmc/kepler/AccountService/AccountPolicies/Local bmc.kepler.AccountService.AccountPolicy \ Visible # 预期响应:b <记录的原始值>。 ``` 适用版本 1.70.19 及以上 ### 2.10 IPMI 命令 account 组件向 IPMI 通道注册用户管理命令,供带内(OS/管理软件)对用户进行管理。 #### 功能说明 account 组件提供基于 IPMI 的用户及账号安全策略查询和用户维护能力,用于获取设备当前配置、维护指定用户,包括: - 用户访问权限、用户名和登录接口等用户基础信息; - 密码复杂度检查、用户名密码前缀比对、密码校验策略和密码正则等密码安全策略; - SNMP 配置、弱口令字典使能、首次登录改密、历史密码检查、逃生用户和初始密码提示等账号策略配置。 - 指定用户的用户名、通道访问权限和登录接口设置,以及用户密码设置、启用和禁用。 查询命令不修改用户信息或安全策略,可用于带内管理软件获取当前配置,也可用于设备维护和问题定位时核对账号状态。写操作会修改指定用户;本文示例使用临时账号,避免影响设备中的业务账号。 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | IPMI(netfn 0x06 / 0x30) | | 首发版本 | 1.70.19 | | 废弃状态 | 正常可用 | ##### 参数说明 常用命令示例,全量命令请参考[IPMI 标准命令索引集合](../../interface/interface_custom/ipmi_custom/ipmi_spec/standard.md)。 | IPMI 命令 | netfn / cmd | 说明 | 权限 | | :---- | :---- | :---- | :---- | | Get User Access | 0x06 / 0x44 | 获取用户通道权限 | UserMgmt | | Set User Access | 0x06 / 0x43 | 设置指定用户的通道访问权限 | UserMgmt | | Get User Name | 0x06 / 0x46 | 获取用户名 | UserMgmt | | Set User Name | 0x06 / 0x45 | 设置指定用户的用户名 | UserMgmt | | Get User Password Complexity | 0x30 / 0x93(Sel 0x21) | 获取密码复杂度检查开关 | ReadOnly | | Get SNMP Configuration | 0x30 / 0x93(Sel 0x75) | 获取 SNMP 配置 | UserMgmt | | Get Account Interface | 0x30 / 0x93(Sel 0x79) | 获取用户登录接口 | UserMgmt | | Set User Interface | 0x30 / 0x93(Sel 0x68) | 设置指定用户的登录接口 | UserMgmt | | Set Account Password | 0x06 / 0x47(操作 0x02) | 设置指定用户的密码 | ConfigureSelf | | Disable Account | 0x06 / 0x47(操作 0x00) | 禁用指定用户 | ConfigureSelf | | Enable Account | 0x06 / 0x47(操作 0x01) | 启用指定用户 | ConfigureSelf | | Get User Password Compare Info | 0x30 / 0x93(Sel 0x5B-30) | 获取用户名密码前缀比对配置 | ReadOnly | | Get WeakPwdDictionaryEnabled | 0x30 / 0x93(Sel 0x76-01) | 查询弱口令字典使能状态 | UserMgmt | | Get FirstLoginModifyPolicy | 0x30 / 0x93(Sel 0x76-02) | 查询首次登录改密策略 | UserMgmt | | Get HistoryPwdCheckCount | 0x30 / 0x93(Sel 0x76-03) | 查询历史密码检查数 | UserMgmt | | Get EmergencyLoginAccount | 0x30 / 0x93(Sel 0x76-05) | 查询逃生用户配置 | UserMgmt | | Get InitialPasswordPromptEnable | 0x30 / 0x93(Sel 0x76-06) | 查询初始密码提示开关 | UserMgmt | | Get PasswordRulePolicy | 0x30 / 0x93(Sel 0x76-07) | 查询密码校验策略 | SecurityMgmt | | Get PasswordPattern | 0x30 / 0x93(Sel 0x76-08) | 查询密码正则配置 | SecurityMgmt | #### 调试示例 以下示例命令将 `` 及各命令注明的 IPMI 用户名、密码替换为目标环境的实际值;用户 ID、通道号及响应数据会随设备配置而变化。`ipmitool raw` 成功时仅输出响应数据,不额外显示 Completion Code `0x00`。 ```bash # 1. Get User Access:查询通道 1 上用户 ID 2 的访问权限。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x44 0x01 0x02 ``` 响应示例:`11 46 01 34` ```bash # 2. Get User Name:查询用户 ID 2 的用户名。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x46 0x02 ``` 响应示例:`41 64 6d 69 6e 69 73 74 72 61 74 6f 72 00 00 00` ```bash # 3. Get User Password Complexity:查询密码复杂度检查开关。 ipmitool -H -I lanplus \ -U -P '<对应用户密码>' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x21 ``` 响应示例:`db 07 00 01` ```bash # 4. Get SNMP Configuration:查询 SNMP 配置。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x75 0x01 0x02 0x00 ``` 响应示例:`db 07 00 01 01` ```bash # 5. Get Account Interface:查询用户 ID 2 的登录接口。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x79 0x02 ``` 响应示例:`db 07 00 df` ```bash # 6. Get User Password Compare Info:查询用户名密码前缀比对配置。 ipmitool -H -I lanplus \ -U -P '<对应用户密码>' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x5b 0x30 0x00 ``` 响应示例:`db 07 00 00 04` ```bash # 7. Get WeakPwdDictionaryEnabled:查询弱口令字典使能状态。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x76 0x01 0x02 ``` 响应示例:`db 07 00 01 01` ```bash # 8. Get FirstLoginModifyPolicy:查询首次登录改密策略。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x76 0x02 0x02 ``` 响应示例:`db 07 00 01 00` ```bash # 9. Get HistoryPwdCheckCount:查询历史密码检查数。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x76 0x03 0x02 ``` 响应示例:`db 07 00 01 05` ```bash # 10. Get EmergencyLoginAccount:查询逃生用户配置。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x76 0x05 0x02 ``` 响应示例:`db 07 00 01 02` ```bash # 11. Get InitialPasswordPromptEnable:查询初始密码提示开关。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x76 0x06 0x02 ``` 响应示例:`db 07 00 01 01` ```bash # 12. Get PasswordRulePolicy:查询密码校验策略。 ipmitool -H -I lanplus \ -U -P '<对应用户密码>' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x76 0x07 0x00 ``` 响应示例:`db 07 00 01 01` ```bash # 13. Get PasswordPattern:查询密码正则配置。 ipmitool -H -I lanplus \ -U -P '<对应用户密码>' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x76 0x08 0x00 ``` 响应示例:`db 07 00 00` ##### 用户维护写操作前置 下列写操作以临时账号为对象,避免修改实际业务账号。先通过 D-Bus 创建临时账号;`New` 返回的 `y <临时账号ID>` 为后续命令的账号 ID。以下写操作以返回 `y 8` 为例;若实际返回其他 ID,需将命令中的 `0x08` 替换为该 ID 对应的十六进制值,并将 `Set Account Password` 中的用户字节替换为 `0x80 + 账号ID`。 ```bash # 创建临时账号。0 表示由系统分配未占用的账号 ID。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts \ bmc.kepler.AccountService.ManagerAccounts \ New a{ss}ysayiaii \ 3 Interface CLI UserName Administrator ClientAddr 127.0.0.1 \ 0 itipmi06a 10 84 109 112 64 50 48 50 54 88 89 4 1 4 1 ``` 响应示例:`y 8` ```bash # 14. Set User Name:将临时账号 ID 8 的用户名改为 itipmi06b。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x45 0x08 \ 0x69 0x74 0x69 0x70 0x6d 0x69 0x30 0x36 0x62 \ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # 回读用户名,确认设置生效。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x46 0x08 ``` 响应示例:设置成功时无输出;回读结果包含 `69 74 69 70 6d 69 30 36 62`。 ```bash # 15. Set User Access:设置临时账号 ID 8 在通道 1 上的访问权限。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x43 0xf1 0x08 0x04 0x00 # 回读通道 1 上的用户访问权限。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x44 0x01 0x08 ``` 响应示例:设置成功时无输出;回读结果为四字节用户访问配置。 ```bash # 16. Set User Interface:设置临时账号 ID 8 的登录接口为 IPMI(0x04)。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x68 0x08 0x00 0x04 0x00 0x00 # 回读登录接口。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x79 0x08 ``` 响应示例:设置成功返回 `db 07 00`;回读结果为 `db 07 00 04`。 ```bash # 17. Set Account Password:将临时账号 ID 8 的密码设置为 Temp@2026XY。 # 第一个用户字节 0x88 = 0x80 + 账号 ID 8;密码字段以 20 字节补零传入。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x47 0x88 0x02 \ 0x54 0x65 0x6d 0x70 0x40 0x32 0x30 0x32 0x36 0x58 0x59 \ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ``` 响应示例:成功时无输出。 ```bash # 18. Disable Account:禁用临时账号 ID 8。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x47 0x08 0x00 ``` 响应示例:成功时无输出。 ```bash # 19. Enable Account:重新启用临时账号 ID 8。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x47 0x08 0x01 ``` 响应示例:成功时无输出。 ```bash # 清理:删除临时账号 ID 8。 busctl --user call bmc.kepler.account \ /bmc/kepler/AccountService/Accounts/8 \ bmc.kepler.AccountService.ManagerAccount \ Delete a{ss} \ 4 Interface CLI UserName Administrator ClientAddr 127.0.0.1 Privilege 16 # 回读用户名;删除后该用户名称字段为空。 ipmitool -H -I lanplus \ -U -P '' \ -C 17 raw 0x06 0x46 0x08 ``` 响应示例:删除成功时无输出;回读用户名为空。 #### 返回值与异常 | Completion Code | 含义 | 典型触发条件 | 处理建议 | | :-------------- | :--- | :----------- | :------- | | 0x00 | 成功 | 命令正常完成 | 无 | | 0x80 | 资源已存在 | 用户名重复等 | 更换用户名或对象 | | 0x81 | 用户不存在 | 操作不存在的用户 | 检查用户 ID | | 0x84 | 密码复杂度检查失败 | 新密码不满足策略 | 使用满足策略的密码 | | 0x85 | 账号解锁失败或团体名长度非法 | 具体含义取决于调用命令 | 结合命令参数和组件日志排查 | | 0x86 | 团体名包含空格 | SNMP 团体名含空格 | 移除空格 | | 0x87 | 业务侧用户管理被禁用 | `HostUserManagementEnabled=false` | 开启业务侧用户管理 | | 0x92 | 公钥格式不正确 | 导入的公钥格式不合法 | 使用支持的公钥格式 | | 0x93 | 密码与历史密码相同 | 新密码命中历史密码 | 更换新密码 | | 0x94 | IPMI 密码为空 | 未设置或传入空 IPMI 密码 | 设置有效密码 | | 0x96 | 需要重置密码 | 首次登录或管理员设置后要求改密 | 完成密码重置 | | 0xC7 | 密码或请求数据长度非法 | 密码长度、请求长度不符合要求 | 检查长度及补零规则 | | 0xC9 | 参数值超出范围 | 用户 ID、枚举等越界 | 使用合法取值 | | 0xCC | 无效数据字段 | 请求参数格式或组合非法 | 检查 RAW 参数 | | 0xD5 | 不支持的属性或操作 | 当前版本或配置不支持该能力 | 检查版本和功能开关 | | 0xD7 | 不能删除 SNMPv3 Trap 用户 | 目标用户为 Trap 用户 | 调整 Trap 用户配置后再操作 | | 0xD9 | 不能删除逃生用户 | 目标用户为逃生用户 | 先迁移或取消逃生用户配置 | #### 应用场景 - 带内管理软件通过 IPMI 查询用户访问权限、用户名和登录接口; - 设备维护时核对密码策略、弱口令策略、首次登录策略和逃生用户配置; - 定位账号登录、SNMP 配置或密码策略相关问题时获取当前运行配置。 - 使用临时账号验证用户名、通道访问权限、登录接口、密码及账号启用状态的维护流程。 #### 限制条件 - 带内(Host侧)用户管理受 `HostUserManagementEnabled` / `OSAdministratorPrivilegeEnabled` 控制,关闭后 BT(SYS_CHAN_NUM/21/22)、EDMA、IPMB-SM 通道的相关 IPMI 命令被拦截 - VNC 密码(0x30/0x94)长度不超过 8 字节。 - 使用 `lanplus` 调试时,目标设备需启用 IPMI over LAN,并允许所使用的 Cipher Suite;登录账号还应启用 IPMI 登录接口并具备命令所需权限。不同环境的 Cipher Suite 或账号权限配置不同,可能在业务命令发送前即因会话协商或角色校验失败而被拒绝。 - 写操作会改变指定用户的运行配置。应使用临时账号执行,并在完成验证后删除该账号;不得对当前登录账号、逃生账号或生产业务账号直接执行示例中的写操作。 #### 调试说明 IPMI 用户管理命令需要目标设备已启用 IPMI over LAN,并受 Cipher Suite、账号 IPMI 登录接口、账号权限和网络环境影响。不同设备及版本的命令参数、支持范围和返回数据可能不同。 account 组件负责注册和处理用户管理相关 IPMI 命令;若命令在会话协商阶段失败,应优先排查 IPMI/RMCP 配置、Cipher Suite 和账号权限。 适用版本 1.70.19 及以上 ## 3. 组件扩展案例 ### 3.1 扩展能力概述 account 的扩展入口是配置管理框架,而不是直接修改持久化数据。`config_handle.lua` 已向 `mdb_config_manage` 注册导入、导出、备份、恢复、获取可信配置和获取保留配置回调。其中: - `custom` 类型由 `custom_settings.lua` 处理制造定制项; - `configuration` 类型由 `profile_adapter.lua` 处理配置导入导出; - 备份会处理弱口令字典、PAM 失败记录和用户主目录,并调用账号信息备份;恢复会按保留选项处理用户主目录。 当前 `custom_settings_adapter` 已登记的定制项覆盖管理员可写、密码有效期/历史密码、逃生账号、弱口令字典、首次登录策略、SNMP Trap 账号、VNC 登录规则、本地账号登录接口、团体名长度、扩展账号名称以及三类密码策略等。定制项的准确名称和实现以 `src/lualib/interface/config_mgmt/manufacture/customization/custom_settings.lua` 为准。 ### 3.2 扩展点说明 | 扩展点 | 作用 | 关键约束 | | :--- | :--- | :--- | | `custom_settings_adapter` | 定义定制项名称及 `import`、`export`、可选 `import_convert`、`deps` 回调 | 只有登记在该表中的普通定制项才会进入导入流程 | | `account_service_customization.lua` | 适配账户服务级配置,例如首次登录提示和密码策略开关 | 设置后需要通过 `m_config_changed:emit()` 同步资源树状态 | | `account_customization.lua` | 适配账号及账号策略类定制项 | 需遵守账号 ID、账号类型和现有策略校验 | | `password_validator_customization.lua` | 适配本地账号、SNMP 团体名、VNC 的密码规则和模式 | 修改会影响后续密码校验 | | `profile_adapter.lua` | 处理常规配置导入导出 | 不应把制造定制项放入 `configuration` 类型 | 导入时,`custom_settings.lua:on_import()` 会先根据每个定制项的 `deps` 做拓扑排序,再按顺序执行。未提供、未登记、导入值与当前值相同或没有 `import` 回调的项会被跳过。 ### 3.3 扩展示例:新增一个有依赖的制造定制项 以下是仓库已有的 `BMCSet_InitialPwdPrompt` 实现。它说明了一个需要依赖另一个定制项的扩展应如何登记;该代码不是一个需要重复新增的功能。 ```lua -- src/lualib/interface/config_mgmt/manufacture/customization/custom_settings.lua BMCSet_InitialPwdPrompt = { import_convert = AccountServiceCustomization.convert_initial_password_prompt_enable, import = AccountServiceCustomization.set_initial_password_prompt_enable, export = AccountServiceCustomization.get_initial_password_prompt_enable, deps = { 'BMCSet_InitialPasswordNeedModify' }, }, BMCSet_InitialPasswordNeedModify = { import = AccountServiceCustomization.set_first_login_enable, export = AccountServiceCustomization.get_first_login_enable, }, ``` 对应的业务实现将值写入账户服务并发送配置变更信号: ```lua -- src/lualib/interface/config_mgmt/manufacture/customization/account_service_customization.lua function AccountServiceCustomization.set_initial_password_prompt_enable(self, ctx, value) self.m_account_service:set_initial_password_prompt_enable(value) self.m_account_service.m_config_changed:emit('InitialPasswordPromptEnable', value) end ``` 新增定制项时,按以下步骤实施: 1. 在 `custom_settings_adapter` 添加唯一键,提供成对的 `import`/`export` 回调;输入格式与内部值不一致时再提供 `import_convert`。 2. 在对应的 customization 模块实现业务设置和读取;若值会映射为资源树属性,设置后发送与该属性对应的配置变更信号。 3. 存在前置开关或顺序要求时声明 `deps`;不要依赖 Lua 表遍历顺序。 4. 在定制化 JSON 的 `ConfigData.CustomSettings` 中填写该项后,经配置管理框架以 `custom` 类型导入。 5. 为导入和导出补充单元测试。现有 `test/unit/test_customization.lua` 使用 `test_data/config_customization.json` 导入上述两个定制项,并断言首次登录提示和首次登录改密均为 `true`,可作为测试结构参考。 验证命令: ```bash # 在 account 仓库根目录执行定制化单元测试集合 bingo test -ut ``` 预期:`TestAccount:test_custom_settings` 导入示例定制配置后通过;新增项应补充同类断言,并验证导出值能够再次被导入。 注意事项: - 定制化会改变设备全局账号策略,应在隔离环境验证并准备恢复配置;不要直接修改账号持久化文件或数据库。 - `BMCSet_InitialPwdPrompt` 依赖 `BMCSet_InitialPasswordNeedModify` 是实际代码中的依赖关系;新增依赖必须显式声明。 - `BMCSet_OEMNameNN` 会按实现将序号映射到扩展账号 ID;不要把这一特殊命名规则套用到普通定制项。 - 密码规则定制项会影响新建账号、改密和 SNMP/VNC 密码设置,应回归相关接口用例。 ## 4. 日志说明 ### 4.1 一键日志收集 | 文件路径 | 内容说明 | | :--- | :--- | | `/var/log/app.log` | account 组件运行日志,包括服务初始化、参数校验、资源树操作和文件传输任务失败等;使用 `account` 关键字筛选。 | | `/var/log/operation.log` | account 操作日志,包括新建/删除账号、改密、导入或导出弱口令字典、设置 SNMP 团体名和角色操作等的成功或失败。 | | `/var/log/framework.log` | account 服务启动、退出和框架异常等日志。 | 上述三个文件是平台一键日志收集的标准日志项。account 通过 `mc.logging`、`logging:operation()` 和 IPMI 操作日志接口写入相应日志通道;日志文件的轮转和最终收集路径由平台日志框架维护。 此外,若转储框架调用 `interface/dump.lua:log_dump()`,会在框架传入的合法目录生成 `account_info.txt`。其当前实现仅写入标题 `account information:`,不导出账号列表、密码、密钥或完整账号快照,不能作为账号数据恢复文件。 ### 4.2 关键日志信息 | 关键字或日志模板 | 产生位置 | 含义与下一步 | | :--- | :--- | :--- | | `account class init start` / `account class init end` | `account_app.lua:init()` | 判断 account 初始化是否进入和结束;若没有结束日志,继续查看同一时段的错误和框架堆栈 | | `Import type(%s) is invalid` | `config_handle.lua:on_import()` | 配置导入类型不是 `custom` 或 `configuration`;修正配置管理调用方的类型 | | `Import data is nil` / `No ConfigData in config.json` | `config_handle.lua:on_import()` | 导入内容为空或缺少 `ConfigData` 根节点;检查配置文件结构 | | `import weak password dictionary failed, path invalid.` | `account_service_mdb.lua:import_weak_pwd_dictionary()` | 导入路径既不是支持的远程 URL,也不符合临时目录路径规则;使用本章和 2.4 的路径限制 | | `export weak password dictionary failed, path invalid.` | `account_service_mdb.lua:export_weak_pwd_dictionary()` | 导出路径不符合临时目录或支持的远程 URL 规则 | | `file trans failed, skip import/export weak pwd dict!` | `account_service_mdb.lua` 异步任务 | account 已将远程传输交给 `file_transfer`;同时收集 file_transfer 的任务与错误日志 | | `ROCommunityName is not allowed...` / `RWCommunityName is not allowed...` | `snmp_community_mdb.lua` | 读写团体名相同;分别使用不同的非空值,或先清理冲突项 | | `Dump path is invalid` / `Open account_dump failed` | `dump.lua:log_dump()` | 转储框架传入的目录非法,或 `account_info.txt` 无法创建;归集转储框架日志与目标目录权限信息 | ## 5. 问题定界指南 ### 5.1 典型问题定界 | 现象 | 是否优先归 account | 源码依据 | 首要证据和处理方向 | | :--- | :--- | :--- | :--- | | 账号、角色、登录规则、SNMP 团体名或账户策略的 D-Bus 调用返回 account 业务错误 | 是 | `account_app.lua:register_rpc_methods()` 将这些资源树方法绑定到 account 领域服务 | 收集请求、完整错误对象、account 应用日志和操作日志;按第 2 章确认对象路径、接口和入参 | | `ImportWeakPasswordDictionary` 或 `ExportWeakPasswordDictionary` 返回 `InvalidPath` | 是 | `account_service_mdb.lua` 先校验路径,并将敏感路径替换为 `******` | 检查路径是否为支持的远程 URL 或临时目录下的本地路径;不要通过日志反推被脱敏的原路径 | | 远程弱口令字典传输任务失败 | 边界问题 | account 调用 `file_transfer:get_file_from_url()` 或 `upload_file_to_url()` 后异步等待任务 | 先保留 account 日志中任务失败信息,同时转 file_transfer 核查 URL、协议、网络和任务状态 | | `busctl` 提示对象路径不存在或接口不存在 | 待判定 | 资源树在 account 初始化及依赖检查后注册 | 先执行下方 `tree`/`introspect`;若 account 已初始化且路径仍不存在,检查版本、模型和注册回调;若服务未初始化,优先查看框架启动与依赖日志 | | `SetSnmpCommunityLoginRule` 显示为模型方法但调用提示未实现 | 是,当前实现限制 | `mds/model.json` 和生成代码声明该方法,但当前 `account_app.lua:register_rpc_methods()` 未绑定对应实现 | 不将该方法作为可用能力;保留调用错误、组件版本和 `introspect` 输出,提交为接口模型与注册实现不一致的问题 | | `ipmitool -I lanplus` 在业务命令前报 Cipher Suite、会话协商或角色错误 | 否,优先 IPMI/RMCP 配置 | account 注册账号管理 IPMI 命令,但 LAN 会话协商由 IPMI/RMCP 链路完成 | 核对 IPMI over LAN、Cipher Suite、账号 IPMI 登录接口和权限;会话建立前失败时,尚未进入 account 业务方法 | ### 5.2 最小化复现与证据收集 以下命令只读取资源树,不修改设备状态,可用于确认 account 服务、对象路径和运行时暴露的方法: ```bash # 查看 account 服务导出的资源树 busctl --user tree bmc.kepler.account # 查看账号集合对象的方法和属性 busctl --user introspect bmc.kepler.account /bmc/kepler/AccountService/Accounts # 查看指定账号对象的方法和属性;将 <账号ID> 替换为实际存在的账号 ID busctl --user introspect bmc.kepler.account /bmc/kepler/AccountService/Accounts/<账号ID> ``` 复现写操作时,使用第 2 章已验证的命令,遵循以下顺序: 1. 记录修改前的属性或资源值;账号和角色操作使用唯一的临时名称、未占用 ID。 2. 执行一个方法调用并保留完整响应;不要在工单、文档或日志中粘贴密码、私钥、SNMP Ku 等敏感值。 3. 通过读取属性、查询返回值或删除临时资源确认结果。 4. 无论成功或失败都恢复原属性,删除临时账号和临时角色。 5. 从一键收集产物中摘取同一时间窗口的 `account` 应用日志、操作日志和框架日志;远程字典传输还应附带 file_transfer 证据。 ### 5.3 调试方法 #### 开启调试日志 ```bash # 开启 account 详细日志 busctl --user call bmc.kepler.account \ /bmc/kepler/account/MicroComponent \ bmc.kepler.MicroComponent.Debug SetDlogLevel a{ss}sy 0 debug 0 # 查看实时 account 日志 tail -f /var/log/app.log | grep account ``` 预期:`SetDlogLevel` 调用成功后无业务错误返回;后续执行账号、角色、SNMP 或弱口令字典操作时,可在实时输出中看到带 `account` 标签的日志。account 的集成测试辅助函数也使用相同的服务名、对象路径、接口名和方法签名设置日志级别。 限制条件:开启 `DlogLevel` 可由具备 D-Bus 调用权限的用户执行;读取 `/var/log/app.log` 需要目标平台授予相应日志文件读取权限。普通管理用户无法读取时,应使用具备维护权限的调试环境,或通过系统一键日志收集获取日志。 #### 复现问题方法 1. 先执行本节的只读 `tree`/`introspect` 命令,确认服务、对象路径和接口已注册。 2. 仅使用第 2 章中已验证的命令复现一个最小操作;写操作使用临时账号、临时角色或已备份的属性值。 3. 保留命令、完整响应和同一时间窗口内的 `/var/log/app.log`、`/var/log/operation.log`、`/var/log/framework.log` 中 account 相关记录。 4. 操作完成后恢复属性并清理临时资源;远程弱口令字典传输失败时,补充 file_transfer 任务和日志证据。 ### 5.4 错误对象解读 account 的 D-Bus 调用失败通常以结构化错误对象返回。优先记录 `name` 和 `params`,而不是只记录显示文案。 | 错误名 | 可由当前源码确认的触发条件 | 处理建议 | | :--- | :--- | :--- | | `InvalidPath` | 弱口令字典导入/导出的路径不满足校验;错误中会脱敏路径 | 改用支持的远程 URL 或临时目录中的本地路径 | | `OperationInProcess` | 正在导入或导出弱口令字典时再次启动该类操作 | 等待已有任务结束后重试 | | `SameROCommunityName` | 设置只读团体名时与现有读写团体名相同 | 为只读团体名使用不同值,或先修改/清空读写团体名 | | `SameRWCommunityName` | 设置读写团体名时与现有只读团体名相同 | 为读写团体名使用不同值,或先修改/清空只读团体名 | 除上述名称外,应以 `mds/errors.json`、运行时错误对象和对应实现分支共同判断,避免仅凭 IPMI Completion Code 或界面提示推断根因。 ## 6. 常见问题解答 ### Q1:弱口令字典导入或导出返回 `InvalidPath` - 问题描述 调用 `ImportWeakPasswordDictionary` 或 `ExportWeakPasswordDictionary` 后返回 `InvalidPath`,且路径参数在错误中显示为 `******`。 - 一句话答案 路径没有通过 account 的本地临时目录/远程 URL 校验;路径脱敏是实现的安全行为。 - 根因说明 `account_service_mdb.lua` 仅接受支持协议的远程 URL,或符合 `TMP_PATH` 规则的本地路径。导入的本地文件在后续还要通过临时目录或共享内存目录校验;导出本地文件也会校验真实路径。失败时实现主动以 `******` 替代原始路径。 - 解决方案 使用第 2.4 节已验证的路径格式:本地文件放在目标设备的临时目录内,或使用组件支持的远程 URL;确认文件存在、进程具备访问权限后再调用。 - 规避方案 不要用任意绝对路径替代临时目录,也不要为了绕过校验修改路径校验或持久化文件。 - 适用版本 1.70.19 及以上 ### Q2:设置 SNMP 只读、读写团体名时提示名称重复 - 问题描述 设置只读团体名返回 `SameROCommunityName`,或设置读写团体名返回 `SameRWCommunityName`。 - 一句话答案 只读和读写团体名不能使用同一个非空字符串。 - 根因说明 `snmp_community_mdb.lua` 在写入前读取另一类团体名:设置只读时与读写值比较,设置读写时与只读值比较;相同即拒绝。空字符串是删除团体名流程,逻辑与设置非空值不同。 - 解决方案 先通过 `GetSnmpCommunity` 读取当前值;设置为彼此不同的名称。若确实需要移除其中一个,使用空字符串删除后再设置另一个值。 - 规避方案 批量配置前先读取并保存读写两个原值;清理和恢复时按不同名称处理,避免恢复过程短暂写入冲突值。 - 适用版本 1.70.19 及以上 ### Q3:SNMP 用户接口的对象路径加上 `/SnmpUser` 后不存在 - 问题描述 对 `/bmc/kepler/AccountService/Accounts/<账号ID>/SnmpUser` 调用 SNMP 用户方法,返回对象路径不存在。 - 一句话答案 SNMP 用户接口挂载在账号对象 `/Accounts/<账号ID>` 上,不是一个名为 `/SnmpUser` 的子对象。 - 根因说明 `account_app.lua:register_rpc_methods()` 在 `SetAuthenticationProtocol`、`SetEncryptionProtocol` 和 `GetSnmpKeys` 的回调中,从 `/Accounts/(%d+)` 解析账号 ID;实现没有注册 `/SnmpUser` 子路径。 - 解决方案 保留账号对象路径 `/bmc/kepler/AccountService/Accounts/<账号ID>`,仅把 D-Bus 接口名指定为 `bmc.kepler.AccountService.ManagerAccount.SnmpUser`,参见第 2.3 节。 - 规避方案 先用 `busctl --user introspect` 确认对象路径和接口名,再执行写操作。 - 适用版本 1.70.19 及以上 ### Q4:`SetSnmpCommunityLoginRule` 出现在模型中,但调用提示未实现 - 问题描述 资源模型或 `introspect` 中可以看到 `SetSnmpCommunityLoginRule`,但实际调用返回“method not implemented”类错误。 - 一句话答案 当前源码生成了该方法定义,但 account 的运行时注册回调没有绑定该方法实现。 - 根因说明 `mds/model.json` 与生成的 `gen/class/model.lua` 均包含该方法;但当前 `account_app.lua:register_rpc_methods()` 只绑定了 `SetRoCommunity`、`SetRwCommunity` 和 `GetSnmpCommunity`,未绑定 `ImplSnmpCommunitySnmpCommunitySetSnmpCommunityLoginRule`。 - 解决方案 不要在当前版本把该方法作为可用配置手段。提交问题时附上模型版本、`introspect` 输出、调用错误和 `register_rpc_methods()` 的对照信息,由组件维护者决定补注册实现还是从模型中移除声明。 - 规避方案 对文档、脚本和自动化用例,仅使用已在 `register_rpc_methods()` 中绑定且已在测试环境验证的方法。 - 适用版本 1.70.19 及以上 ### Q5:`ipmitool -I lanplus` 在执行账号查询前就会话失败 - 问题描述 执行第 2.10 节命令时出现 Cipher Suite 不匹配、会话协商失败或角色校验失败,未得到账号查询响应。 - 一句话答案 这是 IPMI/RMCP 会话建立阶段的问题;业务命令尚未进入 account 的账号查询实现。 - 根因说明 account 负责注册账号管理 IPMI 命令,但 LAN 会话的 Cipher Suite 协商、认证和角色校验发生在命令处理之前。会话未建立时,不会产生对应的 account 方法调用。 - 解决方案 核对目标设备是否启用 IPMI over LAN、所选 Cipher Suite 是否允许、账号是否启用 IPMI 登录接口并拥有所需权限。会话建立后,按与目标设备和软件版本匹配的《IPMI 命令操作手册》执行只读查询确认账号管理能力。 - 规避方案 在自动化脚本中先执行一个只读 IPMI 查询作为会话与权限预检;预检失败时收集 IPMI/RMCP 日志,不将其误报为 account 业务错误。 - 适用版本 1.70.19 及以上 --- # bingo > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_interface_spec/bingo.html > Language: zh # bingo ## 版本信息 | 项目 | 内容 | | :--- | :--- | | 组件版本 | 0.7.58 | | 首发版本 | 0.1.0 | | 文档作者 | 马思雨 | | 最后更新 | 2026-07-24 | ## 1. 组件概述 ### 1.1 组件简介 bingo 是 openUBMC BMC 开发的工程工具和最佳实践的承载者,提供一站式命令行工具,降低组件开发成本。bingo 作为 openUBMC 工程体系的核心枢纽,统一管理组件创建、代码自动生成、构建出包、开发者测试、依赖分析、版本发布等 BMC 开发全流程,是 openUBMC 开发者日常使用的核心工具。 ### 1.2 解决什么问题 bingo 解决 BMC 软件开发中的工程效率问题:将分散的构建脚本、代码生成工具、依赖管理、测试框架整合为统一 CLI,开发者无需手动维护 Conan 配置、交叉编译 profile、MDS 模型到代码的映射等繁琐工程细节,通过一条 bingo 命令即可完成从建模到出包的端到端流程。 ### 1.3 核心功能 - 核心功能一:组件全生命周期管理——通过 `bingo new` 创建组件脚手架、`bingo gen` 代码自动生成(Lua/C)、`bingo build` 构建、`bingo test` 测试、`bingo deploy` 部署,覆盖组件从创建到发布的完整流程 - 核心功能二:产品集成构建——在 manifest 仓库中执行 `bingo build`,基于 Conan 依赖体系自动拉取组件、交叉编译、组装 rootfs 并生成 HPM 固件包,支持多单板、多构建类型和发布阶段 - 核心功能三:工程辅助能力——包括依赖与接口分析(`bingo analysis`)、版本差异追踪(`bingo diff`)、源码拉取(`bingo fetch`)、参数配置(`bingo config`)、版本升级(`bingo upgrade`)、BMC Studio 管控(`bingo studio`)和 Skill 管理(`bingo skill`) ### 1.4 关键术语表 | 术语 | 解释 | | :--- | :--- | | Manifest | 产品仓库,包含 manifest.yml 配置、组件依赖声明和构建脚本,bingo 识别 manifest 仓后启用 Integrated commands | | Component | 组件仓库,包含 mds/service.json 配置,bingo 识别组件仓后启用 Component commands | | Conan | C/C++ 包管理器,bingo 依赖 Conan 完成组件依赖解析、下载和交叉编译,支持 Conan 1.0 和 2.0 双版本 | | MDS | 模型定义服务(Model Definition Service),组件通过 mds/service.json 描述服务模型,bingo gen 依据此模型生成代码 | | HPM | 固件升级包格式,bingo build 在 manifest 仓最终输出的产品包为 rootfs_<单板名>.hpm | | DT | 开发者测试(Developer Test),bingo test 支持单元测试(UT)、集成测试(IT)和模糊测试(FT) | | Profile | Conan 编译配置文件,描述目标平台(如 ARM64 交叉编译)的构建参数,bingo 自动管理 profile 初始化与同步 | | CSR | 组件服务资源(Component Service Resource),bingo check 用于校验 CSR 语法的正确性与模型一致性 | ### 1.5 外部交互边界图 bingo 与以下外部系统交互: - **Conan 远程仓库**:拉取/上传组件包,解析依赖关系 - **Git 仓库**:通过 gitpython 拉取源码、获取版本信息和分支差异 - **BMC Studio**:启动/停止建模服务,执行 CSR 语法检查 - **PyPI**:bingo 自身的安装和升级源(openubmc-bingo 包) - **Skills Marketplace**(GitCode):同步 AI agent 技能到本地 - **HPM 签名服务**:支持 SignServer 签名、服务器签名和自签名三种模式 - **板子部署**:通过 SFTP/HTTPS 将产品包部署到目标 BMC 设备 ## 2. API 使用说明与示例 ### 2.1 bingo build #### 功能说明 构建组件包或产品 HPM 包。bingo 具有配置探测能力:在组件目录执行时构建组件包,在 manifest 目录执行时构建产品集成包。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 **组件构建参数:** | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -bt / --build_type | 输入 | str | 构建类型,默认:debug | debug, release | | --stage | 输入 | str | 组件包发布阶段,默认:dev | dev, pre, rc, stable | | -u / --upload | 输入 | flag | 上传组件包到 Conan 仓 | true/false | | -r / --remote | 输入 | str | Conan 仓别名 | conan remote list 已配置的仓 | | --conan2 | 输入 | flag | 强制使用 Conan 2 构建组件 | true/false | | -nc / --no_cache | 输入 | flag | 强制更新 Conan 缓存依赖 | true/false | | -o / --options | 输入 | str | Conan 构建选项 | 如 Pkg/*:with_qt=True | | --user | 输入 | str | Conan 包 user 字段,未指定时依次读取 mds/service.json,都未指定时使用 openubmc | 任意合法 user | | -wb / --without_build | 输入 | flag | 不强制源码构建组件自身 | true/false | | --ccache | 输入 | flag | 使用 ccache 加速 C/C++ 编译 | true/false | **产品构建参数:** | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -b / --board_name | 输入 | str | 单板包,默认:openUBMC | openUBMC_ast2600, openUBMC_1712, openUBMC 等 | | -bt / --build_type | 输入 | str | 构建类型 | debug(调试包), release(正式包) | | --stage | 输入 | str | 包类型,默认:dev | dev(调试包), rc(预发布包), stable(发布包) | | --verbose | 输入 | flag | 使能 Conan 构建详细日志打印 | true/false | | -ucc / --update_conan_cache | 输入 | flag | 全量更新本地 Conan 缓存 | true/false | | -r / --remote | 输入 | str | Conan 仓别名 | conan remote list 已配置的仓 | | -z / --zip_code | 输入 | str | 0502 编码 | 参考单板 manifest.yml/manufacture | | -sc / --supporte_code | 输入 | str | 待发布的 SupportE 编码 | 参考单板 manifest.yml/tosupporte | | --ccache | 输入 | flag | 使用 ccache 加速 C/C++ 编译 | true/false | | --debug_platform_path | 输入 | str | 联调整包路径 | 任意合法路径 | | --signature_type | 输入 | str | 固件签名类型 | rsa4096, sm2 | | -v / --version | 输入 | str | 构建版本号,不指定时从 manifest.yml 读取 | 任意合法版本号 | | -t / --target | 输入 | str | 构建目标 | install_sdk, personal, app, publish | | --deploy | 输入 | flag | 将 HPM 包部署至 BMC 设备 | true/false | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 0 | 成功 | 构建正常完成 | 无 | | -1 | 失败 | 当前目录不是合法组件/manifest 仓、参数非法或内部错误 | 检查当前路径是否包含 .bmcgo/config 或 mds/service.json | #### 应用场景 - 在组件源码目录构建组件 Conan 包并上传到远端仓库 - 在 manifest 仓库构建产品 HPM 包或发布包 - 开发调试阶段使用 `-bt debug --stage dev` 快速构建 - 正式发布阶段使用 `-bt release --stage stable` 构建正式包 #### 限制条件 - 必须在合法组件目录(包含 mds/service.json)或 manifest 目录(包含 .bmcgo/config)下执行 - 组件构建和产品构建互斥,bingo 根据目录类型自动切换 - 多个 bingo build 进程在同一 manifest 下并发执行会被互斥锁阻止 - Conan 版本需要与组件/产品配置匹配(1.0 或 2.0),bingo 会自动检测并切换 #### 调试示例 ##### 命令行调试 组件构建: ```bash bingo build -bt debug --stage rc ``` 产品 HPM 包构建: ```bash bingo build -t personal -b openUBMC -bt release --stage rc ``` 产品发布包构建: ```bash bingo build -t publish -b openUBMC -bt release --stage stable --signature_type sm2 ``` ### 2.2 bingo gen #### 功能说明 代码自动生成,支持 Lua 和 C 语言。根据 MDS 模型定义自动生成服务端/客户端代码框架,大幅减少手工编码量。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -v / --version | 输入 | str | 指定版本号 | 任意合法版本号 | | -r / --remote | 输入 | str | Conan 远端仓,如不设置则默认读取本地 Conan 配置 | conan remote list 已配置的仓 | | -s / --service_file | 输入 | str | Service 文件路径 | 任意合法路径 | | -w / --with_template | 输入 | flag | 生成时包含模板文件 | true/false | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 0 | 成功 | 代码生成正常完成 | 无 | | -1 | 失败 | 模型文件缺失或格式错误 | 检查 mds/service.json 和 model.json 是否存在且格式正确 | #### 应用场景 - 新组件创建后首次生成代码框架 - MDS 模型变更后重新生成代码以同步接口定义 - 支持 C、C++ 和 Lua 语言代码生成,C/C++ 组件需在 service.json 中配置 `"language"` 字段 #### 限制条件 - 必须在组件目录下执行 - C/C++ 组件需要在 service.json 中配置 `"language"` 字段 - 生成代码会覆盖 gen 目录下的已有文件,手工修改的代码应放在非 gen 目录 #### 调试示例 ##### 命令行调试 ```bash bingo gen # 指定 service 文件路径生成代码 bingo gen -s mds/service.json # 生成时包含模板文件 bingo gen -w ``` ### 2.3 bingo test #### 功能说明 执行组件开发者测试(DT),支持单元测试、集成测试、模糊测试、Mock 测试和 ASAN 内存检测。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -bt / --build_type | 输入 | str | 构建类型,默认:debug | debug, release | | --stage | 输入 | str | 组件包发布阶段,默认:dev | dev, pre, rc, stable | | -r / --remote | 输入 | str | Conan 仓别名 | conan remote list 已配置的仓 | | --conan2 | 输入 | flag | 强制使用 Conan 2 构建组件 | true/false | | -s / --from_source | 输入 | flag | 从源码构建,包含依赖组件 | true/false | | -nc / --no_cache | 输入 | flag | 强制更新 Conan 缓存依赖 | true/false | | -o / --options | 输入 | str | Conan 构建选项 | 如 Pkg/*:with_qt=True | | --user | 输入 | str | Conan 包 user 字段,未指定时依次读取 mds/service.json,都未指定时使用 openubmc | 任意合法 user | | -as / --asan | 输入 | flag | 使能 Address Sanitizer | true/false | | -wb / --without_build | 输入 | flag | 不强制源码构建组件自身 | true/false | | -pr / --profile | 输入 | str | Conan 构建使用的 profile,默认为空 | profile_oee.ini, default, profile.luajit.ini, profile.ini, profile.dt.ini | | -jit / --enable_luajit | 输入 | flag | 使能 LuaJIT | true/false | | --ccache | 输入 | flag | 使用 ccache 加速 C/C++ 编译 | true/false | | -ut / --unit_test | 输入 | flag | 执行单元测试 | true/false | | -it / --integration_test | 输入 | flag | 执行集成测试 | true/false | | -ft / --fuzz_test | 输入 | flag | 执行模糊测试 | true/false | | -fg / --fuzz_gen | 输入 | flag | 生成模糊测试用例 | true/false | | -mt / --mock_test | 输入 | flag | 执行 Mock 测试 | true/false | | -mg / --mock_gen | 输入 | flag | 生成 Mock 用例 | true/false | | -lf / --log_file | 输入 | str | 监控日志文件目录路径 | 任意合法路径 | | -cnt / --fuzz_count | 输入 | str | 模糊测试次数 | 整数值 | | -f / --test_filter | 输入 | str | 单元测试过滤器 | LuaUnit 过滤表达式 | | -a / --app | 输入 | str | hica 中的 App | 任意合法 App 名 | | --coverage_exclude | 输入 | str | 覆盖率排除文件路径(白名单) | 任意合法路径 | | --minimum / -m | 输入 | flag | 获取 DT 构建的最小版本 | true/false | | -pi / --package_info | 输入 | str | package_info 文件路径,manifest 构建时在 inner 目录生成 | 任意合法路径 | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 0 | 成功 | 所有测试通过 | 无 | | -1 | 失败 | 测试失败或组件无效 | 检查测试用例是否正确、组件 mds/service.json 是否存在 | #### 应用场景 - 组件开发过程中执行单元测试验证功能正确性 - 代码提交前执行集成测试验证接口行为 - 使用模糊测试发现潜在安全漏洞 - 使用 Mock 测试隔离依赖组件进行局部验证 - 使用 ASAN(`-as`)检测内存错误 #### 限制条件 - 必须在合法组件目录下执行(包含 mds/service.json) - 测试默认会先构建组件,如需跳过构建可使用 `-wb` 参数 - 使用 ASAN 测试需添加 `-as` 参数 - 模糊测试用例可通过 `-fg` 生成,通过 `-ft` 执行 #### 调试示例 ##### 命令行调试 ```bash # 单元测试 bingo test -ut # 集成测试 bingo test -it # 不重新构建直接测试 bingo test -ut -wb # ASAN 内存检测 bingo test -ut -as # Mock 测试 bingo test -mt # 生成模糊测试用例并执行 bingo test -fg && bingo test -ft ``` ### 2.4 bingo new #### 功能说明 创建新的 openUBMC 组件,自动生成组件脚手架代码和目录结构。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -n / --name | 输入 | str | 指定组件名(必填) | 任意合法目录名 | | -t / --type | 输入 | str | 指定组件类型,默认:application | application | | -l / --language | 输入 | str | 指定组件编程语言,默认:lua | lua | | -conan / --conan_version | 输入 | str | 指定组件支持的 Conan 版本,默认:1.0 | 1.0, 2.0 | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 0 | 成功 | 组件创建完成 | 无 | | -1 | 失败 | 当前目录已存在同名子目录或选项无效 | 删除同名目录或修正选项 | #### 应用场景 - 开发新的 openUBMC 业务组件 - 快速搭建包含 MDS 模型、构建脚本、测试框架的标准组件框架 #### 限制条件 - 当前目录下不能已存在同名子目录 - 目前仅支持 Lua 语言和 application 类型 #### 调试示例 ##### 命令行调试 ```bash bingo new -n my_component -t application -l lua -conan 1.0 # 使用 Conan 2.0 模板 bingo new -n my_component -t application -l lua -conan 2.0 ``` ### 2.5 bingo deploy #### 功能说明 将组件及其依赖部署至 temp/rootfs 目录,先构建再部署。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 与 bingo build 组件构建参数一致。 #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 0 | 成功 | 构建并部署完成 | 无 | | -1 | 失败 | 组件无效(缺少 mds/service.json) | 检查当前目录是否为合法组件 | #### 应用场景 - 本地调试时将组件部署到 temp/rootfs 目录模拟运行环境 - 验证组件在目标文件系统中的安装布局 #### 调试示例 ##### 命令行调试 ```bash bingo deploy -bt debug --stage dev ``` ### 2.6 bingo analysis #### 功能说明 依赖和接口分析,支持组件和 manifest 两个级别,用于理解组件间依赖关系和接口调用链。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -r / --remote | 输入 | str | 指定 Conan 远端 | conan remote list 已配置的仓 | | --rebuild | 输入 | flag | 分析前重新构建 | true/false | | --out_dir | 输入 | str | 分析结果输出目录 | 任意合法路径 | | --lock_file | 输入 | str | manifest lock 文件路径 | 任意合法路径 | | -b / --board_name | 输入 | str | 单板名,参考 manifest/build/product 目录 | manifest/build/product 下的目录名 | #### 调试示例 ##### 命令行调试 ```bash bingo analysis -b openUBMC ``` ### 2.7 bingo fetch #### 功能说明 基于参数指定的单个、部分或全量组件版本拉取源代码。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -b / --board_name | 输入 | str | 指定单板获取配套全量源码,默认:openUBMC | build/product 目录下的单板名 | | --manifest_yml | 输入 | str | 指定 manifest.yml 文件获取源码 | 任意合法路径 | | -pi / --package_info | 输入 | str | 通过组件包名及版本拉取单个组件源码,或通过配置文件拉取部分组件源码 | package/version@user/channel 或 yml/文本配置文件路径 | | -sys / --subsystem | 输入 | str | 根据平台获取源码 | opensource, public, framework, bmc_core, security, hardware, ras, energy, om, interface, product_extension, customer_extension | | --stage | 输入 | str | 包类型,默认:stable | rc, stable | | -a / --all | 输入 | flag | 拉取全部 Conan 代码 | true/false | | -p / --path | 输入 | str | 指定拉取源代码的存放路径,默认:./source_code | 任意合法路径 | | -r / --remote | 输入 | str | Conan 仓别名 | conan remote list 已配置的仓 | #### 调试示例 ##### 命令行调试 ```bash # 拉取单个组件 bingo fetch -pi iam/1.20.31@openUBMC.release/rc # 拉取全量组件 bingo fetch --all # 指定单板拉取配套源码 bingo fetch -b openUBMC # 根据平台拉取源码 bingo fetch -sys bmc_core ``` ### 2.8 bingo diff #### 功能说明 获取两个产品版本间组件版本变更时的合并记录。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.5.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | commit id before | 输入 | str | 前一个 commit ID(位置参数) | Git commit hash | | commit id after | 输入 | str | 后一个 commit ID(位置参数) | Git commit hash | #### 调试示例 ##### 命令行调试 ```bash bingo diff abc123 def456 ``` ### 2.9 bingo config #### 功能说明 bingo 参数配置,支持代理、签名、部署、插件等运行参数的持久化管理。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.5.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -l / --list | 输入 | flag | 列出所有配置 | true/false | | --unset | 输入 | flag | 取消配置参数 | true/false | | --local | 输入 | flag | 本地配置模式(写入 .bmcgo/config) | true/false | 通过 `bingo config
.=` 格式设置配置项。可用配置项包括: | 配置项 | 描述 | 取值范围 | | :--- | :--- | :--- | | env.http_proxy | bingo 使用的 http_proxy | URL 或空 | | env.https_proxy | bingo 使用的 https_proxy | URL 或空 | | env.ftp_proxy | bingo 使用的 ftp_proxy | URL 或空 | | env.no_proxy | bingo 使用的 no_proxy | 域名/IP 列表 | | env.timestamp_sign_server | jar 文件签名的时间戳签名服务器 | URL 或空 | | env.jarsigner_http_proxy | JarSigner HTTP 代理 | URL 或空 | | env.json_checker | 检查 json 文件的工具 | 工具名或路径 | | env.hpm_signer | HPM 重签名工具 | 工具名或路径 | | env.plugins_path | 插件地址,默认 ~/.bmcgo/plugins | 路径 | | deploy-host.port | https 端口号,默认 443 | 端口号 | | deploy-host.username | 部署用户名 | 任意合法用户名 | | deploy-host.password | 部署密码 | 任意合法密码(明文存储,请注意安全) | | skill.sync | 技能自动同步开关,默认 true | true, false | #### 调试示例 ##### 命令行调试 ```bash # 关闭技能自动同步 bingo config skill.sync=false # 设置代理 bingo config env.http_proxy=http://proxy:8080 # 查看生效配置 bingo config -l # 取消全局配置 bingo config --unset env.http_proxy # 设置本地配置 bingo config --local env.http_proxy=http://proxy:8080 # 设置部署配置 bingo config deploy-192.168.1.1.port=443 ``` ### 2.10 bingo upgrade #### 功能说明 升级 bingo 自身版本,支持升级到最新版本、指定版本和版本范围。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -v / --version | 输入 | str | 目标版本号 | bingo=latest, bingo=<版本号>, bingo>=<版本号> | | -f / --force | 输入 | flag | 跳过确认,直接安装 | true/false | | -l / --list | 输入 | flag | 列出可安装版本 | true/false | #### 调试示例 ##### 命令行调试 ```bash # 升级到最新版本 bingo upgrade # 升级到指定版本 bingo upgrade --version bingo=0.7.50 # 列出可安装版本 bingo upgrade -l ``` ### 2.11 bingo studio #### 功能说明 执行 BMC Studio 启动/停止操作,用于建模服务的管控。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 调试示例 ##### 命令行调试 ```bash bingo studio start bingo studio stop ``` ### 2.12 bingo check #### 功能说明 CSR 语法正确性与模型一致性检查,用于验证组件服务资源的合规性。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.1.0 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | -b / --board_name | 输入 | str | 指定单板,默认:openUBMC | build/product 目录下的单板名 | | --stage | 输入 | str | 包类型,默认:stable | rc, stable | | -r / --remote | 输入 | str | Conan 仓别名 | conan remote list 已配置的仓 | | --csr-format | 输入 | str | CSR 检查结果输出格式,默认:human | human, json, junit | | --no-csr-incremental | 输入 | flag | 关闭 CSR 增量检查,对全仓库执行全量检查 | true/false | #### 调试示例 ##### 命令行调试 ```bash bingo check # 指定输出格式为 json bingo check --csr-format json # 全量检查 bingo check --no-csr-incremental ``` ### 2.13 bingo skill #### 功能说明 技能管理,用于从 GitCode Skills Marketplace 同步和管理 AI agent 技能到本地环境。 | 属性 | 内容 | | :--- | :--- | | 首发版本 | 0.7.0 | | 废弃状态 | 正常可用 | #### 调试示例 ##### 命令行调试 ```bash bingo skill sync ``` ## 3. 组件扩展案例 ### 3.1 扩展能力概述 bingo 提供功能模块动态加载机制,开发者可通过在 `bmcgo/functional/` 目录下编写 Python 模块来扩展 bingo 命令。每个功能模块需实现 `if_available`(可用性检查)、`command_info`(命令元信息)和 `BmcgoCommand`(命令执行类)三个接口,bingo CLI 在启动时自动扫描并注册符合条件的命令。 ### 3.2 扩展点说明 扩展点位于 `bmcgo/functional/` 目录,bingo 在初始化时通过 `_load_functional` 方法扫描该目录下所有 `.py` 文件(以 `_` 开头的除外),动态导入并注册到对应命令组(Misc/Component/Integrated/Studio/Conan Index/SDK)中。 ### 3.3 二次开发指导 #### 步骤一:创建功能模块文件 在 `bmcgo/functional/` 目录下创建新的 `.py` 文件,如 `my_command.py`。 #### 步骤二:实现三个必须接口 - `if_available(bconfig: BmcgoConfig)`:返回布尔值,控制命令是否在当前环境下显示 - `command_info: CommandInfo`:定义命令组、名称、描述、是否隐藏和帮助信息 - `class BmcgoCommand`:实现命令执行逻辑,构造函数接收 `bconfig` 和 `args`,`run()` 方法执行具体操作 #### 示例代码 ```python from bmcgo import misc from bmcgo.bmcgo_config import BmcgoConfig from bmcgo.utils.tools import Tools tools = Tools("my_command") log = tools.log command_info: misc.CommandInfo = misc.CommandInfo( group=misc.GRP_MISC, name="mycmd", description=["我的自定义命令"], hidden=False ) def if_available(bconfig: BmcgoConfig): return True class BmcgoCommand: def __init__(self, bconfig: BmcgoConfig, *args): self.bconfig = bconfig log.info("自定义命令执行") def run(self): log.success("自定义命令完成") return 0 ``` #### 验证方法 1. 在 bingo 源码目录执行 `sh install_local.sh` 安装到本地 2. 在任意 bingo 项目目录执行 `bingo help`,检查是否出现新命令 3. 执行 `bingo mycmd` 验证命令逻辑是否正确 #### 注意事项 - 功能模块文件不能以 `_` 开头 - 必须实现 `if_available`、`command_info` 和 `BmcgoCommand` 三个接口,否则 bingo 会跳过该模块 - `command_info.group` 必须属于已有命令组(Misc commands、Component commands、Integrated commands、Studio commands、Conan Index commands、SDK commands) - 新增功能模块后需重新安装 bingo(`sh install_local.sh`)才能生效 ## 4. 日志说明 ### 4.1 一键日志收集 | 文件路径 | 内容说明 | | :--- | :--- | | ~/.bmcgo_log/ | bingo 运行时日志缓存目录,每次执行前自动清理并重建 | | temp/log/ | 组件构建和测试过程中产生的详细日志 | | output/openubmc.perf | 产品构建性能分析数据 | | output/package.lock | 构建依赖锁定文件 | ### 4.2 关键日志信息 | 日志片段 | 日志级别 | 含义解读 | 建议处理动作 | | :--- | :--- | :--- | :--- | | 构建成功 | INFO | bingo build 命令正常完成 | 无需处理 | | 注意:检测到当前目录即不是合法的组件(Component)目录也不是合法的产品(Manifest)目录 | ERROR | 当前执行目录未被 bingo 识别为有效项目 | 切换到包含 .bmcgo/config 或 mds/service.json 的目录 | | 检测到依赖conan2.0但仅安装了conan1.0 | WARN | Conan 版本不匹配 | bingo 会自动安装正确版本,重新执行命令即可 | | 未检测到/opt/RTOS目录,可能未安装构建工具 | INFO | 缺少交叉编译工具链 | 执行 init.py 或 bingo build 安装构建工具 | | 检测到环境设置了https_proxy代理 | WARN | 代理可能导致网络资源访问失败 | 设置 no_proxy 或取消代理 | | Build successfully | INFO | 组件 Conan 包构建成功 | 无需处理 | | 当前skill自动更新状态已关闭 | INFO | Skill 同步功能被禁用 | 执行 `bingo config skill.sync=true` 开启 | | 构建已退出, 退出码为: N | ERROR | 命令执行异常退出 | 检查退出码含义和输入参数 | ### 4.3 日志级别控制 通过环境变量 `LOG` 控制日志详细程度: | LOG 值 | 日志级别 | 用途 | | :--- | :--- | :--- | | 不设置 | INFO(简化格式) | 日常使用 | | info | INFO(带文件名和行号) | 问题排查 | | debug | DEBUG | 详细调试 | | warn | WARNING | 仅警告和错误 | | error | ERROR | 仅错误 | 使用方式: ```bash export LOG=debug && bingo build ``` ## 5. 问题定界指南 ### 5.1 典型问题定界 | 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 | | :--- | :--- | :--- | :--- | | bingo build 报错"不是合法组件或产品目录" | 是 | bingo 根据目录下的配置文件识别项目类型 | 检查当前目录是否包含 .bmcgo/config 或 mds/service.json | | bingo build Conan 包下载失败 | 否 | 网络或 Conan 仓问题 | 检查 `conan remote list`,测试 `conan install`,检查代理配置 | | bingo gen 代码生成报错 | 是 | 模型文件格式错误或模板引擎异常 | 查看 temp/lua_codegen 日志,检查 mds/service.json 和 model.json 格式 | | bingo test 测试失败 | 否 | 通常是组件业务逻辑问题 | 查看测试输出和 temp/coverage/dt_result.json | | HPM 包签名失败 | 否 | 签名服务或证书配置问题 | 检查 .bmcgo/config 中的签名配置和证书文件 | | bingo 命令未显示预期子命令 | 是 | bingo 根据项目类型动态显示命令 | 检查 .bmcgo/config 是否正确配置 manifest/component 字段 | | Conan 版本冲突 | 是 | bingo Conan 版本自动切换失败 | 查看 `conan --version`,检查 conanfile.py 的 required_conan_version | ### 5.2 错误码速查表 | 错误码 | 含义 | 可能原因 | 排查建议 | | :--- | :--- | :--- | :--- | | -1 | 一般性失败 | 参数非法、目录无效、内部异常 | 查看 ERROR 日志,检查执行目录和参数 | | 1 | 系统退出 | 命令执行过程中触发 SystemExit | 检查子命令返回码 | | 0 | 成功 | 正常完成 | 无需处理 | | CommandNotFoundException | 命令未找到 | 输入了 bingo 不支持的命令 | 执行 `bingo help` 查看可用命令 | | NotIntegrateException | 非集成环境 | 在非 manifest 仓执行了集成构建命令 | 切换到 manifest 仓库目录 | | ConfigException | 配置错误 | 命令组不匹配或配置文件格式错误 | 检查 .bmcgo/config 配置 | | ParameterException | 参数错误 | 命令行参数不合法 | 执行 `bingo -h` 查看参数说明 | ### 5.3 调试方法 #### 开启调试日志 ```bash export LOG=debug bingo build -bt debug --stage dev ``` #### 复现问题方法 1. 前置条件设置:确保 bingo 已正确安装(`pip3 install openubmc-bingo`),在目标目录下有 .bmcgo/config 或 mds/service.json 2. 操作步骤:设置 `export LOG=debug`,执行目标 bingo 命令 3. 预期现象:命令成功完成或输出详细错误信息定位到具体代码行 #### VSCode 调试 bingo 提供了 VSCode 调试脚本 `debug.py`,修改其中的配置后可直接在 VSCode 中断点调试: ```python # debug.py DEBUG_TARGET_RELATIVE_PATH = "." # 调试目标目录 DEBUG_COMMAND = "bingo help" # 需调试的命令 ``` ## 6. 常见问题解答 ### Q1:bingo help 未显示预期命令 - 问题描述:在某个目录执行 bingo help,预期出现的命令未显示 - 一句话答案:bingo 根据目录下的配置文件动态显示可用命令 - 根因说明:bingo 通过检测 .bmcgo/config 或 mds/service.json 判断项目类型,只显示对应类型的命令组 - 解决方案:确认当前目录包含正确的配置文件,manifest 仓需要 .bmcgo/config 中配置 manifest.folder,组件仓需要 mds/service.json - 适用版本:所有版本 ### Q2:Conan 版本不匹配导致构建失败 - 问题描述:bingo build 报错 Conan 版本不匹配 - 一句话答案:bingo 会自动检测并切换 Conan 版本 - 根因说明:组件 conanfile.py 的 required_conan_version 或 manifest 的 conan.version 配置与当前安装的 Conan 版本不一致 - 解决方案:bingo 会自动安装正确版本并提示重新执行,按提示操作即可 - 适用版本:所有版本 ### Q3:bingo build 构建速度慢 - 问题描述:bingo build 执行时间过长 - 一句话答案:利用 Conan 缓存和增量构建加速 - 根因说明:全量构建每次都重新编译所有依赖,Conan 缓存未启用 - 解决方案:避免使用 `-nc`(no_cache)参数,确保 ~/.conan/data 缓存目录正常;产品构建使用 `-ucc` 更新缓存而非全量重建 - 适用版本:所有版本 ### Q4:bingo gen 后手工代码被覆盖 - 问题描述:执行 bingo gen 后之前手写的代码被覆盖 - 一句话答案:手工代码不应放在 gen 目录下 - 根因说明:bingo gen 输出到 gen 目录,每次执行会覆盖该目录内容 - 解决方案:将手工编写的业务逻辑代码放在 gen 目录之外(如 src/lualib/lib),仅通过 gen 生成框架代码 - 适用版本:所有版本 ### Q5:bingo 升级失败 - 问题描述:执行 bingo upgrade 报错 - 一句话答案:检查 pip3 网络和权限 - 根因说明:pip3 安装失败通常由网络不通、PyPI 源不可达或权限不足导致 - 解决方案:配置正确的 pip 源和代理(`bingo config env.http_proxy`),或使用 APT 源安装(`apt install openubmc-bingo`) - 适用版本:所有版本 ## 附录 ### 附录A 参考资料 - [openUBMC 官网](https://openubmc.cn) - [openubmc-bingo PyPI](https://pypi.org/project/openubmc-bingo/) - [Conan 官方文档](https://docs.conan.io/) - [openUBMC 组件构建与发布指南](https://openubmc.cn) ### 附录B 修订记录 | 版本 | 日期 | 修订人 | 修订内容 | | :--- | :--- | :--- | :--- | | v1.0 | 2026-07-24 | openUBMC | 初始版本创建 | --- # bios > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_interface_spec/bios.html > Language: zh # bios ## 版本信息 | 项目 | 内容 | | :--- | :--- | | 组件版本 | 1.110.25 | | 首发版本 | 1.70.30 | | 文档作者 | openUBMC | | 最后更新 | 2026-09-24 | ## 1. 组件概述 ### 1.1 组件简介 bios组件是OpenUBMC系统中的BIOS管理组件,主要负责与BIOS带内交互,实现BIOS配置、证书、升级和PFR(Platform Firmware Resilience)自愈等功能。 ### 1.2 解决什么问题 BIOS组件为使用者解决以下核心问题: - BIOS固件升级:支持普通升级、无感升级、装备升级等多种模式 - BIOS配置管理:支持配置导入导出、启动项设置、启动模式配置 - BIOS证书管理:支持安全启动证书、HTTPS启动证书的管理 - PFR自愈:确保BIOS固件完整性和可恢复性,防止恶意篡改 ### 1.3 核心功能 - 核心功能一:BIOS升级 - 支持普通升级、无感升级、teeos升级、krun升级等多种升级模式 - 核心功能二:BIOS配置导入导出 - 支持bios配置导入导出,启动项、启动模式设置,无感升级策略重配 - 核心功能三:BIOS证书管理 - 支持bios启动证书、安全启动证书、吊销证书管理 - 核心功能四:PFR自愈功能 - BIOS镜像校验,确保固件完整性和可恢复性 ### 1.4 关键术语表 | 术语 | 解释 | | :--- | :--- | | 装备升级 | 打包manufacture文件夹的升级模式,会执行强制上下电 | | 无感升级 | 通过ipmb通道将固件传到imu,实现在线升级 | | 普通升级 | 非装备包的升级模式,可选择缓存生效或下电生效 | | 补丁包 | 版本包含HPxxxx的升级包,用于无感升级 | | PFR | Platform Firmware Resilience,平台固件韧性,保证固件完整性和可恢复性 | | CMS签名 | 用于校验BIOS固件完整性的数字签名 | ### 1.5 外部交互边界图 ![交互视图](../images/component_interface_spec/bios/interaction.png) - **pcie_device**:订阅PcieAddrInfo对象的ReadyToEnumerate属性变化,更新PcieAddrInfo对象的SlotId、SocketId、Segment等丝印属性,为BIOS提供丝印文件数据。 - **IMU(带内)**:向IMU查询无感升级策略重配相关配置文件。 - **BIOS(带内)**:BIOS启动阶段想带内提供丝印文件等信息,获取SMBIOS、BDF等信息。 - **FruCtrl**:BIOS预上电时加上电锁进行pfr校验,BIOS启动过程中给BMC加重启锁防止交互异常。 ## 2. API 使用说明与示例 ### 2.1 BIOS升级相关接口 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .ActivateFirmware method a{ss}as - - .ExportBiosFirmware method a{ss} u - .GetFirmwareInfo method a{ss} s - ``` #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Systems.BiosUpgradeService | | 首发版本 | openUBMC 25.03 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | | ActivateFirmware | a{ss}as | - | 生效Bios固件 | 入参:
a{ss}: 额外信息,预留
as: Bios固件名,可包含 imu、imp 等
出参:无 | | ExportBiosFirmware | a{ss} | u | 导出Bios固件信息 | 入参:
a{ss}: 额外信息,预留
出参:
u: 返回任务Id | | GetFirmwareInfo | a{ss} | s | 获取Bios固件信息 | 入参:
a{ss}: 额外信息,预留
出参:
s: Bios固件信息 | #### 属性参数说明 | 属性名 | 类型 | 读写 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | ActivatedStatus | U8 | RO | Bios无感升级固件生效状态 | 枚举值0/1/2,0:生效完成; 1:待生效; 2:生效中 | | FirmwareEffectiveStatus | U8 | RO | Bios普通升级固件生效状态 | 枚举值1/2/3,1:待生效; 2:生效中; 3:生效完成 | | PreserveConfigEnabled | Boolean | RW | Bios配置保留使能 | true: 升级后保留配置; false: 升级后不保留配置 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | 0 (成功) | 操作成功 | 固件生效/导出正常执行 | 无 | | TaskId | 返回任务Id | Bios固件导出 | 无 | #### 应用场景 - 执行无感升级后,激活新版本的BIOS固件 - 导出当前BIOS固件 - 获取BIOS固件信息 #### 限制条件 - ActivateFirmware需要是可生效固件,必须先执行过无感升级 - PreserveConfigEnabled仅在bmc.kepler.UpdateService的StartUpgrade方法未传保留配置参数时生效 #### 调试示例 ##### 命令行调试 ```bash # 激活Bios固件 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BiosUpgradeService bmc.kepler.Systems.BiosUpgradeService \ ActivateFirmware a{ss}as 0 1 "None" # 导出Bios固件 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BiosUpgradeService bmc.kepler.Systems.BiosUpgradeService \ ExportBiosFirmware a{ss} 0 响应:u 1 # 获取Bios固件信息 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BiosUpgradeService bmc.kepler.Systems.BiosUpgradeService \ GetFirmwareInfo a{ss} 0 响应:s "{...}" # 读取生效状态属性 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/BiosUpgradeService bmc.kepler.Systems.BiosUpgradeService \ ActivatedStatus 响应:y 0 # 读取固件生效状态属性 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/BiosUpgradeService bmc.kepler.Systems.BiosUpgradeService \ FirmwareEffectiveStatus 响应:y 3 ``` ### 2.2 BIOS配置相关接口 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .ClearCmos method a{ss} i - .ResetSetupConfig method a{ss} i - .ChangePassword method a{ss}sss i - .ImportBiosSetup method a{ss}ss i - .ExportBiosSetup method a{ss}s s - .GetCurrentValueSetting method a{ss}s s - .RemoveCachedSettings method a{ss} i - .VerifyPassword method a{ss}ss - - .SetBiosLogEnabled method a{ss}y i - .SetBiosConfigActiveMode method a{ss}t - - .ExportFirmware method a{ss}s u - ``` #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Systems.Bios | | 首发版本 | openUBMC 25.03 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | |ClearCmos |a{ss} |i |清除BIOS配置信息(CMOS) |入参:
a{ss}: 额外信息,预留
出参:
i: 清除结果,0成功,-1失败| |ResetSetupConfig |a{ss} |i |清除BIOS配置以及待生效配置 |入参:
a{ss}: 额外信息,预留
出参:
i: 清除结果,0成功,-1失败| |ChangePassword |a{ss}sss |i |修改BIOS密码 |入参:
a{ss}: 额外信息,预留
s: PasswordType,密码类型(Supervisor/User)
s: OldPassword,旧密码
s: NewPassword,新密码
出参:
i: 修改结果,0成功,-1失败| |ImportBiosSetup |a{ss}ss |i |导入Bios配置 |入参:
a{ss}: 额外信息,预留
s: FileType,导入文件类型(Registry/CurrentValue/Setting/Result/ConfigValue)
s: Content,导入文件内容
出参:
i: 导入结果,0成功,-1失败| |ExportBiosSetup |a{ss}s |s |导出Bios的配置 |入参:
a{ss}: 额外信息,预留
s: FileType,导出文件类型(Registry/CurrentValue/Setting/Result/ConfigValue)
出参:
s: 导出配置结果| |GetCurrentValueSetting |a{ss}s |s |获取属性当前配置的值 |入参:
a{ss}: 额外信息,预留
s: ReqKey,属性名
出参:
s: 属性当前配置的值| |RemoveCachedSettings |a{ss} |i |清除待生效的配置 |入参:
a{ss}: 额外信息,预留
出参:
i: 清除结果,0成功,-1失败| |VerifyPassword |a{ss}ss |- |校验待生效BIOS密码 |入参:
a{ss}: 额外信息,预留
s: PasswordType,密码类型
s: Password,待校验密码
出参:无| |SetBiosLogEnabled |a{ss}y |i |设置BIOS日志全打印开关 |入参:
a{ss}: 额外信息,预留
y: BiosLogPrintEnabled,0关闭,1开启
出参:
i: 设置结果,0成功,-1失败| |SetBiosConfigActiveMode |a{ss}t |- |设置BIOS配置导入的生效模式 |入参:
a{ss}: 额外信息,预留
t: Mode,0:导入待生效配置重启后生效,1:恢复默认再导入重启后生效
出参:无| |ExportFirmware |a{ss}s |u |导出对应系统的BIOS FLASH内容 |入参:
a{ss}: 额外信息,预留
s: OutputFilePath,FLASH 数据文件导出路径
出参:
u: TaskId,导出BIOS FLASH的任务Id| #### 属性参数说明 | 属性名 | 类型 | 读写 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | SystemStartupState | U8 | RO | Bios启动状态 | 枚举值:0未启动, 32初始化ME完成, 64PCIe信息上报完成, 96SMBIOS write prepare, 99SMBIOS write start, 102SMBIOS write finish, 111进入PXE, 254Post完成 | | Version | String | RO | Bios版本信息 | NA | | BackupVersion | String | RO | Bios备份版本信息 | NA | | CurrentValueFileName | String | RO | 当前生效的配置文件 | NA | | ResultFileName | String | RO | 配置生效结果文件 | NA | | SettingFileName | String | RO | 待生效配置文件 | NA | | RegistryFileName | String | RO | 标准配置文件 | NA | | BiosConfigActiveMode | U64 | RO | BIOS配置导入的生效模式 | 0:导入待生效配置, 1:恢复默认再导入 | | ResetBiosToDefaultsPending | Boolean | RO | 恢复默认命令是否未生效 | true:存在(未生效),false:不存在(已生效) | | UpgradeFailed | U8 | RO | 正常升级后Flash完整性校验状态 | NA | | RecoverFailed | U8 | RO | 自恢复后Flash完整性校验状态 | NA | | SystemId | U8 | RO | 系统Id | NA | | MenuData | String | RO | 菜单数据 | NA | | MenuChangeFlag | U8 | RO | 菜单变动标志 | NA | | RegistryVersion | String | RO | 标准配置文件的版本 | NA | | DEMTConfig | U8 | RO | DEMT配置 | NA | | PcieCardBDF | U8[] | RO | Pcie卡BDF | NA | | PcieDiskBDF | U8[] | RO | 硬盘BDF | NA | | OCPCardBDF | U8[] | RO | OCP卡BDF | NA | | BiosBootStage | U8 | RO | Bios启动阶段 | NA | | BiosLogPrintEnabled | U8 | RO | Bios的日志全打印使能状态 | NA | | SettingsEffectiveStatus | String | RO | Bios配置文件的生效状态 | NA | | TeeOSVersion | String | RO | TeeOS版本号 | NA | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | 0 (成功) | 操作成功 | 正常执行 | 无 | | -1 (失败) | 操作失败 | 密码错误/配置格式不符/权限不足 | 检查输入参数 | | TaskId | 返回任务Id | Bios FLASH导出 | 无 | #### 应用场景 - 导入BIOS配置,包括配置标准文件验证和依赖关系校验 - 导出当前BIOS配置 - 获取指定BIOS配置属性的当前值 - 修改BIOS密码 - 清除BIOS配置信息(CMOS) - 清除BIOS待生效配置 - 设置BIOS日志全打印开关 - 校验BIOS密码 - 导出对应系统的BIOS FLASH内容 #### 限制条件 - ImportBiosSetup导入配置必须符合格式和BIOS依赖关系 - ChangePassword旧密码必须正确,新密码必须符合BIOS密码校验规则 - ClearCmos/ResetSetupConfig需要用户配置权限 - ExportFirmware当前只支持本地导出 #### 调试示例 ##### 命令行调试 ```bash # 导入BIOS配置 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ ImportBiosSetup a{ss}ss 3 Interface "Setting" "{}" 响应:i 0 # 导出BIOS配置 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ ExportBiosSetup a{ss}s 0 "Setting" 响应:s "{...}" # 获取指定属性的当前值 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ GetCurrentValueSetting a{ss}s 0 "NetworkProtocol" 响应:s "DHCP" # 修改BIOS密码 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ ChangePassword a{ss}sss 0 "Supervisor" "Admin@9000" "Admin@90000" 响应:i 0 # 清除CMOS busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ ClearCmos a{ss} 0 响应:i 0 # 清除待生效配置 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ ResetSetupConfig a{ss} 0 响应:i 0 # 设置BIOS全打印开关 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ SetBiosLogEnabled a{ss}y 0 1 响应:i 0 # 校验BIOS密码 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ VerifyPassword a{ss}ss 0 "Supervisor" "Admin@9000" # 读取BIOS版本 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ Version 响应:s "5.xx.xxx" # 读取BIOS启动状态 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/Bios bmc.kepler.Systems.Bios \ SystemStartupState 响应:y 254 ``` ### 2.3 启动项相关接口 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .SetBootMode method a{ss}s i - .SetBootOrder method a{ss}s iss - .SetStartOption method a{ss}s i - .SetStartOptionFlag method a{ss}s i - .ShieldIpmiModifyBootModeSupport method a{ss}b i - ``` #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Systems.BootOptions | | 首发版本 | openUBMC 25.03 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | |SetBootMode |a{ss}s |i |设置Bios启动模式 |入参:
a{ss}: 额外信息,预留
s: mode,启动模式(UEFI)
出参:
i: RespCode,设置结果| |SetBootOrder |a{ss}s |iss |设置Bios启动顺序 |入参:
a{ss}: 额外信息,预留
s: BootOrderJson,启动顺序JSON
出参:
i: OutCode,返回码
s: ErrName,错误名
s: ErrValue,错误值| |SetStartOption |a{ss}s |i |设置Bios启动项 |入参:
a{ss}: 额外信息,预留
s: StartOption,启动项(None/Pxe/Floppy/Cd/Hdd/BiosSetup)
出参:
i: Result,设置结果| |SetStartOptionFlag |a{ss}s |i |设置Bios启动项生效次数 |入参:
a{ss}: 额外信息,预留
s: StartOptionFlag,生效次数(Disabled/Once/Continuous)
出参:
i: Result,设置结果| |ShieldIpmiModifyBootModeSupport |a{ss}b |i |屏蔽是否可以通过ipmi设置启动模式 |入参:
a{ss}: 额外信息,预留
b: ModeSwitch,屏蔽开关
出参:
i: RespCode,屏蔽结果| #### 属性参数说明 | 属性名 | 类型 | 读写 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | BootSourceOverrideMode | String | RO | 系统启动模式 | Legacy或UEFI,默认UEFI | | BootSourceOverrideEnabled | String | RO | 系统启动项生效次数 | Disabled/Once/Continuous,默认Disabled | | BootSourceOverrideTarget | String | RO | 系统启动项 | 默认HDD | | BootOrder | String[] | RO | 系统启动项启动顺序 | NA | | BootModeSupport | Boolean | RO | BIOS启动模式是否支持设置 | 默认true | | BootModeIpmiSettable | Boolean | RO | BIOS启动模式是否支持通过IPMI设置 | 默认true | | BootOptionPolicy | U8 | RW | 定制化启动项策略 | 0:不定制; 1:设置永久启动项联动修改启动顺序 | | PreviousBootSourceOverrideTarget | String | RO | 上次设置的永久启动项类型 | NA | | BootOptionReference | String[] | RO | 唯一启动选项标识符 | NA | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | 0 (成功) | 操作成功 | 正常执行 | 无 | | -1 (失败) | 操作失败 | 启动模式/顺序不符合规则 | 检查输入参数 | | ErrName/ErrValue | 错误名/错误值 | 启动顺序不符合规则 | 检查启动顺序是否符合BIOS规则 | #### 应用场景 - 设置BIOS启动模式 - 设置BIOS启动顺序 - 设置BIOS启动项 - 设置BIOS启动项生效次数 - 屏蔽IPMI设置启动模式 #### 限制条件 - 启动顺序必须符合BIOS规则 - 启动模式当前只支持UEFI #### 调试示例 ##### 命令行调试 ```bash # 设置启动模式 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ SetBootMode a{ss}s 0 "UEFI" 响应:i 0 # 设置启动顺序 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ SetBootOrder a{ss}s 0 '{"BootTypeOrder0":"DVDROMDrive","BootTypeOrder1":"PXE","BootTypeOrder2":"HardDiskDrive","BootTypeOrder3":"Others"}' 响应:i 0 s "" s "" # 设置启动项 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ SetStartOption a{ss}s 0 "Pxe" 响应:i 0 # 设置启动项生效次数 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ SetStartOptionFlag a{ss}s 0 "Continuous" 响应:i 0 # 屏蔽IPMI修改启动模式 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ ShieldIpmiModifyBootModeSupport a{ss}b 0 true 响应:i 0 # 读取当前启动模式 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ BootSourceOverrideMode 响应:s "UEFI" # 读取当前启动项 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ BootSourceOverrideTarget 响应:s "HDD" ``` ### 2.4 安全启动证书相关接口 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .ImportCertificate method a{ss}sss - - .ResetCertificate method a{ss}ss - - .GetCertificate method a{ss} s - ``` #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Systems.SecureBootOptions | | 首发版本 | openUBMC 25.03 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | |ImportCertificate |a{ss}sss |- |导入Bios安全启动证书 |入参:
a{ss}: 额外信息,预留
s: DatabseType,数据库类型(db/dbx)
s: CertString,证书内容
s: CertType,证书类型(PEM)
出参:无| |ResetCertificate |a{ss}ss |- |重置Bios安全启动证书 |入参:
a{ss}: 额外信息,预留
s: DatabseType,数据库类型(db/dbx)
s: ResetType,重置类型(DeleteAllKeys/ResetAllKeysToDefault)
出参:无| |GetCertificate |a{ss} |s |获取Bios安全启动证书 |入参:
a{ss}: 额外信息,预留
出参:
s: CertInfo,证书内容| #### 属性参数说明 | 属性名 | 类型 | 读写 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | SystemId | U8 | RO | 系统Id | NA | | CertificateExpired | U8 | RO | 证书过期标记 | 默认0 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | CertInfo | 证书内容 | 获取成功 | 无 | | 无返回值 | 操作成功 | 导入/重置成功 | 无 | #### 应用场景 - 导入BIOS安全启动证书 - 重置BIOS安全启动证书 - 获取BIOS安全启动证书 #### 限制条件 - 导入证书格式必须正确,目前只支持PEM格式 - BIOS不能处于启动阶段 #### 调试示例 ##### 命令行调试 ```bash # 获取安全启动证书 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/SecureBootOptions bmc.kepler.Systems.SecureBootOptions \ GetCertificate a{ss} 0 响应:s "{...}" # 导入安全启动证书 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/SecureBootOptions bmc.kepler.Systems.SecureBootOptions \ ImportCertificate a{ss}sss 0 "db" "<证书内容>" "PEM" # 重置安全启动证书 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/SecureBootOptions bmc.kepler.Systems.SecureBootOptions \ ResetCertificate a{ss}ss 0 "db" "DeleteAllKeys" # 读取证书过期标记 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/SecureBootOptions bmc.kepler.Systems.SecureBootOptions \ CertificateExpired 响应:y 0 ``` ### 2.5 HTTPS启动证书相关接口 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .ImportCertificate method a{ss}ss - - .ImportCrl method a{ss}ss - - .ResetCertificate method a{ss}s - - .ResetCrl method a{ss}s - - .GetCertificate method a{ss} s - ``` #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Systems.BootOptions | | 首发版本 | openUBMC 25.03 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | |ImportCertificate |a{ss}ss |- |导入Bios的Https启动证书 |入参:
a{ss}: 额外信息,预留
s: CertString,Https证书内容
s: CertType,Https证书类型(PEM)
出参:无| |ImportCrl |a{ss}ss |- |导入Bios的Https启动证书吊销列表 |入参:
a{ss}: 额外信息,预留
s: CertString,Https吊销证书内容
s: CertType,Https吊销证书类型(PEM)
出参:无| |ResetCertificate |a{ss}s |- |重置Bios的Https启动证书 |入参:
a{ss}: 额外信息,预留
s: ResetType,重置类型(DeleteAllKeys/ResetAllKeysToDefault)
出参:无| |ResetCrl |a{ss}s |- |重置Bios的Https启动证书吊销列表 |入参:
a{ss}: 额外信息,预留
s: ResetType,重置类型(DeleteAllKeys/ResetAllKeysToDefault)
出参:无| |GetCertificate |a{ss} |s |获取Bios的Https启动证书 |入参:
a{ss}: 额外信息,预留
出参:
s: CertInfo,证书数据| #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | CertInfo | 证书数据 | 获取成功 | 无 | | 无返回值 | 操作成功 | 导入/重置成功 | 无 | #### 应用场景 - 导入BIOS的HTTPS启动证书 - 导入BIOS的HTTPS启动证书吊销列表 - 重置BIOS的HTTPS启动证书 - 重置BIOS的HTTPS启动证书吊销列表 - 获取BIOS的HTTPS启动证书 #### 限制条件 - 证书格式必须正确,目前只支持PEM格式 - BIOS不能处于启动阶段 #### 调试示例 ##### 命令行调试 ```bash # 获取Https启动证书 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ GetCertificate a{ss} 0 响应:s "{...}" # 导入Https启动证书 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ ImportCertificate a{ss}ss 0 "<证书内容>" "PEM" # 导入Https证书吊销列表 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ ImportCrl a{ss}ss 0 "" "PEM" # 重置Https启动证书 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ ResetCertificate a{ss}s 0 "DeleteAllKeys" # 重置Https证书吊销列表 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/BootOptions bmc.kepler.Systems.BootOptions \ ResetCrl a{ss}s 0 "DeleteAllKeys" ``` ### 2.6 IPMI接口 | 命令 | 描述 | | :--- | :--- | | SetBootOption | 设置启动项 | | GetBootOption | 获取启动项 | | GetBiosGoldValid | 获取固件备份状态 | | GetBiosBootInfo | 获取bios启动参数 | | GetFileChanged | 获取bios配置文件修改状态 | | GetSmBiosInfo | 获取smbios信息 | | ReadFileFromBmc | 从bmc读取配置文件 | | SetBiosBootInfo | 设置bios启动参数 | | SetBiosVersion | 设置bios版本 | | SetCertificateAssertion | 设置bios证书过期告警 | | SetFileChanged | 设置bios配置文件修改状态 | | SetSmBiosInfo | 设置smbios信息 | | UpdateBiosPassword | 设置bios密码 | | UpdateBiosStatus | 设置bios启动状态 | | UpdatePostStatus | 设置bios完成启动状态 | | WriteFileToBmc | 上报bios配置文件 | | WriteSmbiosData | 上报smbios配置文件 | | GetAllowedPackageType | 获取装备模式允许升级的Bios包的安全类型 | | SetAllowedPackageType | 设置装备模式允许升级的Bios包的安全类型 | | SetBaseOSBootEvent | 设置bios传感器告警 | | GetBiosConfiguration | 获取bios配置项 | | SetBiosConfiguration | 设置bios配置项 | | SetKrunVersion | 设置Krun固件版本号 | ### 2.7 SMBIOS信息相关接口 #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Systems.SmBios | | 首发版本 | openUBMC 25.03 | | 废弃状态 | 正常可用 | #### 属性参数说明 | 属性名 | 类型 | 读写 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | SerialNumber | String | RO | SmBios序列号 | NA | | Version | String | RO | SmBios版本 | NA | | SKUNumber | String | RO | SmBios SKU编号 | NA | | Family | String | RO | 处理器家族 | NA | | SmBiosStatus | U8 | RO | SmBios状态 | NA | | SmBiosUpdatedFlag | U8 | RO | SmBios状态更新标记 | NA | | FileChange | U8 | RO | SmBios文件变化标记 | NA | | FileName | String | RO | SmBios文件名 | NA | | DiffFileName | String | RO | SmBios差异文件名 | NA | | SystemId | U8 | RO | 系统Id | NA | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | 属性值 | 返回SmBios信息 | 属性读取正常执行 | 无 | #### 应用场景 - 查询系统SMBIOS序列号、版本、SKU编号等信息 - 查询处理器家族信息 - 监控SMBIOS文件变化状态 #### 限制条件 - 所有属性均为只读 #### 调试示例 ##### 命令行调试 ```bash # 查询SMBIOS序列号 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/SmBios bmc.kepler.Systems.SmBios \ SerialNumber # 查询SMBIOS版本 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/SmBios bmc.kepler.Systems.SmBios \ Version ``` ### 2.8 BIOS配置管理接口(BIOSConfiguration) ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .SetDEMTEnabled method a{ss}b - - .SetRefreshRate method a{ss}u - - ``` #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Systems.BIOSConfiguration | | 对象路径 | /bmc/kepler/Systems/:SystemId/EnergyEfficiencyOptimization | | 首发版本 | openUBMC 25.03 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :---- | :------ | :------------------- | :----------------------------------------------------------- | |SetDEMTEnabled |a{ss}b |- |设置DEMT功能是否开启 |入参:
a{ss}: 额外信息,预留
b: DEMTEnabled,DEMT功能是否开启
出参:无| |SetRefreshRate |a{ss}u |- |设置内存刷新频率 |入参:
a{ss}: 额外信息,预留
u: RefreshRate,内存刷新频率
出参:无| #### 属性参数说明 | 属性名 | 类型 | 读写 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | DEMTEnabled | Boolean | RO | DEMT功能是否开启 | NA | | RefreshRate | U32 | RO | 内存刷新频率 | NA | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :------------ | :----------- | :----------- | :----------------------- | | 无返回值 | 设置成功 | 参数合法且设置生效 | 无 | #### 应用场景 - 开启或关闭DEMT功能 - 设置内存刷新频率 #### 限制条件 - 需要BIOS处于可配置状态 - RefreshRate取值需符合平台内存规格 #### 调试示例 ##### 命令行调试 ```bash # 设置DEMT功能开关 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/EnergyEfficiencyOptimization bmc.kepler.Systems.BIOSConfiguration \ SetDEMTEnabled a{ss}b 0 true # 设置内存刷新频率 busctl --user call bmc.kepler.bios \ /bmc/kepler/Systems/1/EnergyEfficiencyOptimization bmc.kepler.Systems.BIOSConfiguration \ SetRefreshRate a{ss}u 0 1 # 读取DEMT功能开关 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/EnergyEfficiencyOptimization bmc.kepler.Systems.BIOSConfiguration \ DEMTEnabled 响应:b true # 读取内存刷新频率 busctl --user get-property bmc.kepler.bios \ /bmc/kepler/Systems/1/EnergyEfficiencyOptimization bmc.kepler.Systems.BIOSConfiguration \ RefreshRate 响应:u 1 ``` > **未收录接口说明**:mdb_interface 中另有 `bmc.kepler.Systems.SystemFirmwareProgress.Status` > 接口(属性 `KBCError`/`VideoError`,均为 U8 只读,POST 自检错误状态),经评估属固件自检 > 进度域,不纳入本组件接口文档范围;如需查询可通过 `mdbctl introspect` 获取。 ## 3. 组件扩展案例 ### 3.1 扩展能力概述 不适用 ### 3.2 扩展点说明 不适用 ### 3.3 二次开发指导 不适用 ## 4. 日志说明 ### 4.1 一键日志收集 | 文件路径 | 内容说明 | | :--- | :--- | | dump_info/AppDump/bios/setting.json | 用户的Bios配置数据 | | dump_info/AppDump/bios/currentValue.json | 当前生效的Bios配置 | | dump_info/AppDump/bios/Registry.json | 配置的标准文件 | | dump_info/AppDump/bios/result.json | Bios运行的记录文件 | | dump_info/AppDump/bios/silkconfig.json | 丝印配置文件 | | dump_info/AppDump/bios/SMBIOS_CONF | SMBIOS配置信息 | ### 4.2 关键日志信息 | 日志片段 | 日志级别 | 含义解读 | 建议处理动作 | | :--- | :--- | :--- | :--- | | Switch spi to BMC(BIOS) | INFO | SPI链路切换到BMC侧 | 正常流程,无需处理 | | Switch spi to BMC(BIOS) failed | ERROR | SPI链路切换失败 | 检查硬件连接和驱动 | | verify signature error, code 88200312 | ERROR | 包签名校验失败 | 替换与BMC签名一致的HPM包 | | sys-uid not in update.cfg's ProductUIDList | ERROR | HPM包与机型不符 | 使用符合机型的HPM包 | | parse package failed, ret:InvalidFirmwarePackage | ERROR | HPM包缺少cfg文件 | 获取带外升级使用的HPM包 | | [spi]check_device_ready: ready fail | ERROR | SPI设备未就绪 | 检查硬件问题,联系厂商 | | PackageCheckExecutor: upgrade patch package in equipment mode | ERROR | 装备模式不能升级补丁包 | 更换为普通包或非装备模式 | | ComponentFilter: skip component | INFO | 无感升级跳过版本一致的固件 | 正常流程,无需处理 | ## 5. 问题定界指南 ### 5.1 典型问题定界 | 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 | | :--- | :--- | :--- | :--- | | BIOS升级显示无效的升级包 | 是 | 包签名校验失败或包类型不匹配 | 查看app.log中的签名错误日志 | | BIOS升级成功后版本号未变 | 否 | 依赖BIOS上报版本号 | 确认BIOS在新版本上报过版本号 | | 非装备包OS上电升级无法用reboot生效 | 是 | 默认下电生效模式 | 检查csr配置或使用ipmi命令设置 | | BIOS升级完成后未保留配置 | 是 | 装备包默认全擦 | 检查是否为装备包,装备包默认不保留配置 | | 无感升级失败 | 是 | 多种可能原因 | 检查BIOS启动状态、包类型、升级模式 | ### 5.2 错误码速查表 | 错误码 | 含义 | 可能原因 | 排查建议 | | :--- | :--- | :--- | :--- | | 0x03000049 | PSU.PSULinkAbnormal | 主板AVSBUS、PMBUS链路异常 | 更换CPU板 | | 0x01000073 | Memory.MemoryI2CI3CLinkAbnormal | 1、内存故障 2、主板I2C/I3C链路异常 | 1、更换内存 2、更换主板 | | 0x24000031 | CPUBoard.VRPowerRedundancyFailure | VR电源(单相)工作异常 | 更换主板 | ### 5.3 调试方法 #### 开启调试日志 bios组件的调试日志随app.log输出,日志级别由系统统一配置。在调试场景下,可通过以下方式增加日志获取量: busctl --user call bmc.kepler.bios /bmc/kepler/compute/MicroComponent bmc.kepler.MicroComponent SetDlogLevel a{ss}sy 0 debug 2 #### 复现问题方法 1. 确认升级包类型和升级模式匹配 2. 确认BIOS启动状态(无感升级需要BIOS启动完成) 3. 检查SPI链路状态 4. 查看app.log中的详细错误信息 ## 6. 常见问题解答 ### Q1:BIOS升级显示无效的升级包 - 问题描述:升级BIOS时提示无效的升级包 - 一句话答案:包签名校验失败或包与机型不匹配 - 根因说明:可能是签名与BMC不匹配、HPM包与实际机型不符、HPM包缺少必要的cfg文件 - 解决方案:根据具体错误日志更换正确的HPM包 - 规避方案:确保使用与BMC签名一致且符合机型的HPM包 - 适用版本:所有版本 ### Q2:BIOS升级成功后版本号未变 - 问题描述:BIOS升级完成但版本号未更新 - 一句话答案:BIOS未上报新版本号 - 根因说明:bios版本号更新依赖bios侧上报版本号,BMC无法主动获取 - 解决方案:升级结束后需要确认BIOS在新版本上报过版本号 - 规避方案:检查关键日志确认版本上报 - 适用版本:所有版本 ### Q3:非装备包OS上电升级BIOS,无法使用强制重启或者带内reboot生效 - 问题描述:OS上电状态下升级BIOS,通过reboot无法生效 - 一句话答案:默认生效条件为下电生效 - 解决方案:通过修改csr配置实现重启生效,或使用ipmi命令SetCachedBiosUpgradeMode设置 - 适用版本:所有版本 ### Q4:BIOS升级完成后未保留配置 - 问题描述:升级BIOS后配置未保留 - 一句话答案:装备包默认全擦,非装备包默认保留 - 根因说明:对于装备包升级BIOS默认不保留配置,对于非装备包默认保留配置 - 解决方案:使用非装备包升级或在bios下设置manufacture: false - 适用版本:所有版本 ### Q5:BIOS升级过程中失败 - 问题描述:BIOS升级过程中失败 - 一句话答案:多种原因可能导致升级失败 - 根因说明: - 包的类型与升级模式不匹配(无感升级只能用补丁包) - BIOS未启动完成(无感升级需要BIOS POST完成) - SPI链路切换失败 - 解决方案: - 确认升级包类型与升级模式匹配 - 确认BIOS启动状态 - 检查SPI链路和驱动 - 适用版本:所有版本 ### Q6:丝印上报是怎么回事? - 问题描述:什么是丝印上报,作用是什么 - 一句话答案:BIOS通过IPMI命令从BMC读取丝印信息并更新到BIOS人机界面和SMBIOS - 根因说明:BIOS启动时通过ReadFileFromBmc命令从BMC读取silkconfig.json,解析后更新丝印信息 - 解决方案:这是正常流程,不需要干预 - 适用版本:所有版本 ## 附录 ### 附录A 参考资料 - [自签名CA创建以及HPM签名指导](https://discuss.openubmc.cn/t/topic/215) - [鲲鹏社区](https://www.hikunpeng.com/forum/) - [昇腾社区](https://www.hiascend.com/forum/) ### 附录B 修订记录 | 版本 | 日期 | 修订人 | 修订内容 | | :--- | :--- | :--- | :--- | | v1.0 | 2025-01-16 | openUBMC | 初始版本创建 | | v1.1 | 2026-08-24 | runan-2026 | 对照 mdb_interface 真值 JSON 查漏补缺,补全缺失方法与属性、修正签名与描述 | | v1.2 | 2026-08-31 | renxiaolin-2026 | 对照 mdb_interface 真值 JSON 修正 ImportBiosSetup/ExportBiosSetup 的 FileType 枚举描述 | | v1.3 | 2026-09-16 | renxiaolin-2026 | 补全 BIOSConfiguration 接口(SetDEMTEnabled/SetRefreshRate 及属性);属性表增加「读写」列并同步 mdb readOnly;无限制取值范围标注 NA | | v1.4 | 2026-09-24 | renxiaolin-2026 | 统一 ActivateFirmware 入参描述为 mdb 语义;修正调试命令对象路径拼写(kepelr→kepler)| --- # bmc_network > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_interface_spec/bmc_network.html > Language: zh # bmc_network ## 版本信息 | 项目 | 内容 | | :------- | :--------------------------- | | 组件版本 | 1.120.38 | | 首发版本 | openUBMC 25.3.0 | | 文档作者 | mkdlf | | 最后更新 | 2026-06-23 | ## 1. 组件概述 ### 1.1 组件简介 bmc_network主要负责bmc的网络通信,从两个角度保障BMC的正常网络通信:
1、配置对外网络,用户可以通过BMC配置的管理IP带外访问BMC;
2、配置对内网络,主要用于管理板与BMC节点之间,同一机框内多个BMC之间,BMC与服务器内部其他固件的网络通信。
### 1.2 解决什么问题 bmc_network组件主要解决网络连通性、协议兼容性、故障恢复效率等问题,致力于提升服务可用性、优化运维效率、保障安全合规以及支撑未来扩展性等。 ### 1.3 核心功能 - 配置IPv4 IPv4有两种方式设置
1、设置静态IPv4信息:IP、掩码、网关;
2、设置DHCP模式由DHCP服务器动态分发IPv4信息,配置成DHCP时,还可配置备份IPv4地址、掩码,当DHCP未获取到IP地址时,还可以通过备份IP访问,详情见[DHCP介绍](https://www.51cto.com/article/760008.html)。 - 配置IPv6 IPv6地址有三种方式设置
1、设置静态IPv6信息:IP、前缀、网关;
2、设置DHCPv6模式动态分发IPv6信息,详情见[DHCPv6介绍](https://blog.csdn.net/m0_49864110/article/details/131076144);
3、通过[SLAAC](https://blog.csdn.net/ThinPikachu/article/details/106212233)自动配置无状态地址。 - 外网网口切换 BMC的网络设备通常分为两种(专用网口、NCSI网口),专用网口是BMC自身的管理网口(通常对应eth2),NCSI网口指BMC通过[NCSI技术](https://blog.csdn.net/qq_38583464/article/details/109329348)与服务器内其他网络设备实现共享的网口(通常对应eth0);这里的网口切换指的是对外网络的配置在专用网口、NCSI网口之间切换,例如从专用网口切换到NCSI网口时,eth2上的对外IP会被清除,eth0上会重新配置对外IP,外网网口切换有两种模式:
1、手动切换到指定网口;
2、设置自适应模式,自动选择优先级高且是连接状态的网口(通常专用网口优先级最高)。 - NCSI网口添加、删除 BMC支持NCSI能力,bmc_network提供了NCSI网口的添加和删除接口,该接口由network_adapter组件调用,初始化时network_adapter识别到NCSI网口的信息后来添加NCSI网口,如果该网口通信出现异常,network_adapter再调用删除接口将网口删除。 - 外网VLAN配置 [VLAN](https://cloud.tencent.com/developer/article/1412795)配置分为专用网口VLAN和NCSI网口VLAN两种配置,当配置了VLAN后,BMC的网口只会处理带了对应VLAN tag的报文,相当于划分了虚拟的局域网。 - 内网配置 BMC除了配置对外IP,还需要配置内网与服务器内部的固件网络通信,内网的配置通常是在已有的网口上划分不同的VLAN用于和不同的固件进行通信;内网相对外网配置来说,要稳定许多,可供修改的接口较少,每种机型的内网配置在对应机型的CSR中,初始化时将网口、VLAN、IP等信息设置即可。 - 节点与管理板链路检测 在机柜环境中,BMC的节点与管理板之间还有心跳检测,若链路检测失败,外网会切换到另一条通信正常的链路保障正常通信。 - iptables配置 1、BMC想要通过web、ssh等服务被访问,不只是需要配置基本的网口和IP,还需要配置[iptables](https://blog.csdn.net/shujuliu818/article/details/125649998)的nat转发规则实现对不同服务报文的转发,才能让服务正常工作;
2、BMC配置filter表过滤规则,只接收对应网口收到的指定IP的报文,对报文的接收来源和速率进行限制,预防泛洪攻击。 - LLDP 1、通过接收[LLDP](https://blog.csdn.net/chen1415886044/article/details/131366824)报文,获取对端交换机的端口描述,常用于解析节点槽位号,生成节点的内网IP等;
2、支持BMC往外发送LLDP报文,其中LLDP报文的发送周期是可配置的。 - 网口相关配置 1、网口mac配置,可通过ipmi命令修改BMC网口的mac地址,mac地址一般在装备阶段设置一次后就固化下来;
2、网口速率配置,支持配置自协商或者非自协商模式下自定义网口速率和半/全双工模式;
3、支持up/down网口,初始化时会将所有网口全部up起来,同时也提供接口up/down网口。 - 主机名、域名、FQDN配置 设置BMC的对外主机名(Host Name)和域名(Domain Name),全称域名[FQDN](https://blog.csdn.net/m0_45406092/article/details/118889898),外界可通过域名和主机名访问BMC。 ### 1.4 关键术语表 | 术语 | 解释 | | :--- | :--- | | 专用网口 | BMC自身的网络设备,通常对应环境中的eth2 | | NCSI网口 | NC-SI(Network Controller – Sideband Interface)技术,即网络控制器边带接口技术,NCSI网口指BMC通过NCSI线缆直连的网络设备,也可以理解除专用网口外所有的网口统称为NCSI网口。NCSI网口又可以分为PCIe/LOM/OCP等类型 | | VLAN | VLAN(Virtual Local Area Network)即虚拟局域网,是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。每个VLAN是一个广播域,VLAN内的主机间可以直接通信,而VLAN间则不能直接互通。这样,广播报文就被限制在一个VLAN内 | ### 1.5 外部交互边界图 ![image](../images/component_interface_spec/bmc_network/image.png) ## 2. API 使用说明与示例 ### 2.1 IPv4 配置管理 设置 IPv4 地址、掩码、网关等网络参数。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .SetIpMaskGateway method a{ss}sss s - .SetIpAddr method a{ss}ss b - .SetDefaultGateway method a{ss}s b - .SetDedicatedMaintIpMask method a{ss}ss b - ``` #### 功能说明 | 属性 | 内容 | | :------- | :---------------------------------------- | | 接口名 | bmc.kepler.Managers.EthernetInterfaces.Ipv4 | | 首发版本 | openUBMC 25.3.0 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------------------ | :------- | :------- | :----------------------- | :------------------------------------------------------------------------------------ | | SetIpMaskGateway | sss | s | 同步设置IPv4地址、掩码、网关 | s: IPv4地址
s: 子网掩码
s: 默认网关
出参: 设置成功后的IPv4地址 | | SetIpAddr | ss | b | 设置IPv4地址与掩码 | s: IPv4地址
s: 子网掩码
出参: true 成功,false 失败 | | SetDefaultGateway | s | b | 单独设置IPv4网关 | s: 默认网关
出参: true 成功,false 失败 | | SetDedicatedMaintIpMask | ss | b | 设置专用运维IP与掩码 | s: 专用运维IPv4地址
s: 子网掩码
出参: true 成功,false 失败 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :--------- | :------------- | :----------------------------- | :------------------------------ | | IpAddr | IPv4设置成功 | 参数校验通过,网络配置成功 | 无 | | true | 操作成功 | 各项设置正常执行 | 无 | | false | 操作失败 | IP格式错误/网段不匹配/网关不可达 | 检查IP、掩码、网关格式及网络连通性 | | InvalidIp | IP地址无效 | IP地址格式不符合IPv4规范 | 使用正确的IPv4地址 | #### 应用场景 - BMC初始配置静态IPv4地址、掩码和网关 - 修改BMC管理网段的IPv4配置 - 设置备份IPv4地址(当主DHCP失效时使用) - 配置专用运维IP用于特殊维护场景 #### 限制条件 - IPv4地址与子网掩码必须属于同一网段 - 网关地址不能与主机地址相同 - DHCP模式下手动设置的静态IP不生效 #### 调试示例 ##### 命令行调试 ```bash # 同步设置IPv4地址、掩码、网关 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/Ipv4 bmc.kepler.Managers.EthernetInterfaces.Ipv4 \ SetIpMaskGateway a{ss}sss <掩码> <网关> 响应示例: 成功:s 失败:Call failed: Invalid IP address # 设置IPv4地址与掩码 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/Ipv4 bmc.kepler.Managers.EthernetInterfaces.Ipv4 \ SetIpAddr a{ss}ss <掩码> 响应示例: 成功:b true 失败:b false # 单独设置IPv4网关 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/Ipv4 bmc.kepler.Managers.EthernetInterfaces.Ipv4 \ SetDefaultGateway a{ss}s 响应示例: 成功:b true 失败:b false ``` ### 2.2 IPv6 配置管理 设置 IPv6 地址、前缀、网关等网络参数。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .SetIpv6PrefixGateway method a{ss}sis s - .SetIpv6Addr method a{ss}si b - .SetDefaultGateway method a{ss}s b - ``` #### 功能说明 | 属性 | 内容 | | :------- | :---------------------------------------- | | 接口名 | bmc.kepler.Managers.EthernetInterfaces.Ipv6 | | 首发版本 | openUBMC 25.3.0 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------------------ | :------- | :------- | :------------------------- | :-------------------------------------------------------------------------------- | | SetIpv6PrefixGateway | si | s | 一步设置IPv6地址、前缀和网关 | s: IPv6地址
i: 前缀长度(0~128)
s: 默认网关
出参: 设置成功后的IPv6地址 | | SetIpv6Addr | si | b | 设置IPv6地址和前缀长度 | s: IPv6地址
i: 前缀长度
出参: true 成功,false 失败 | | SetDefaultGateway | s | b | 单独设置IPv6网关 | s: 默认IPv6网关
出参: true 成功,false 失败 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :--------- | :------------- | :----------------------------- | :------------------------------ | | IpAddr | IPv6设置成功 | 参数校验通过,网络配置成功 | 无 | | true | 操作成功 | 各项设置正常执行 | 无 | | false | 操作失败 | IPv6格式错误/前缀长度超限 | 检查IPv6地址格式及前缀长度 | | InvalidIpv6 | IPv6地址无效 | IPv6地址格式不符合规范 | 使用正确的IPv6地址 | #### 应用场景 - BMC配置静态IPv6管理地址 - 设置DHCPv6模式动态获取IPv6地址 - 配置IPv6默认网关实现外部通信 #### 限制条件 - IPv6前缀长度有效范围为 0~128 - SLAAC模式下地址由路由器通告自动生成 - IPv6网关仅在Global作用域下需要配置 #### 调试示例 ##### 命令行调试 ```bash # 一步设置IPv6地址、前缀和网关 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/Ipv6 bmc.kepler.Managers.EthernetInterfaces.Ipv6 \ SetIpv6PrefixGateway a{ss}sis <前缀> <网关> 响应示例: 成功:s 失败:Call failed: Invalid IPv6 address # 设置IPv6地址和前缀长度 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/Ipv6 bmc.kepler.Managers.EthernetInterfaces.Ipv6 \ SetIpv6Addr a{ss}si <前缀> 响应示例: 成功:b true 失败:b false # 单独设置IPv6网关 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/Ipv6 bmc.kepler.Managers.EthernetInterfaces.Ipv6 \ SetDefaultGateway a{ss}s <网关> 响应示例: 成功:b true 失败:b false ``` ### 2.3 网口与网络配置 管理网口状态、网络模式和VLAN配置等。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .GetAllPort method a{ss} a(aya{ss}) - .SetNetworkConfig method a{ss}ssbu - - .AddMgmtPort method a{ss}uuissu u - .DeleteMgmtPort method a{ss}u - - .AddIptablesRule method a{ss}ss b - .AddIp6tablesRule method a{ss}ss b - .SetVLANConfig method a{ss}bu b - .SetEthState method a{ss}sb b - .NetworkFailover method a{ss}ss b - .SetChassisLanSubNet method a{ss}s - - ``` #### 功能说明 | 属性 | 内容 | | :------- | :------------------------------------ | | 接口名 | bmc.kepler.Managers.EthernetInterfaces | | 首发版本 | openUBMC 25.3.0 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :--------------- | :---------------------- | :------- | :------------------- | :------------------------------------------------------------------------------------------ | | GetAllPort | - | a(aya{ss}) | 获取所有网口port列表 | 出参: port数组,每个元素包含Id、EthId、DeviceId、DevicePortId、Silkscreen、Type、AdaptiveFlag、LinkStatus、Mac | | SetNetworkConfig | sbu | - | 设置网络配置信息 | s: 网络模式(Fixed/Automatic)
b: 激活端口
u: VLAN使能状态
u: VLANId | | AddMgmtPort | uuissu | u | 添加管理网口 | u: 设备ID
u: 设备端口ID
s: 丝印信息
s: EthId
s: 网卡类型(ExternalPCIe/Dedicated)
u: 端口ID | | DeleteMgmtPort | u | - | 删除管理网口 | u: 端口ID | | AddIptablesRule | ss | b | 添加IPv4 iptables规则 | s: 接口名称
s: IPv4地址
出参: true 成功,false 失败 | | AddIp6tablesRule | ss | b | 添加IPv6 ip6tables规则 | s: 接口名称
s: IPv6地址
出参: true 成功,false 失败 | | SetVLANConfig | bu | b | 设置端口VLAN | b: VLAN使能状态
u: VLANId(1~4094)
出参: true 成功,false 失败 | | SetEthState | sb | b | 启用/禁用BMC网口 | s: 网口名(如eth2、usb0)
b: true启用/false禁用
出参: true 成功,false 失败 | | NetworkFailover | ss | b | 双平面切换外部网络 | s: 当前网口
s: 目标网口
出参: true 成功,false 失败 | | SetChassisLanSubNet | s | - | 设置内网网段 | s: 机框内网通信网段 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :-------------- | :------------- | :------------------------------- | :-------------------------------- | | a(aya{ss}) | 获取网口列表成功 | 正常查询 | 无 | | PortId (u) | 添加网口成功 | 网口信息有效且添加成功 | 无 | | true | 操作成功 | 配置项设置成功 | 无 | | false | 操作失败 | 参数校验失败/网口不存在/规则冲突 | 检查参数格式及目标网口状态 | | Unknown object | 网口不存在 | 删除或操作不存在的网口 | 检查目标网口是否存在 | | InvalidVlanId | VLAN ID无效 | VLANId超出有效范围 | 使用有效的VLANId(1~4094) | | PortInUse | 网口已被占用 | 切换到正在使用中的网口 | 等待原网口释放后重试 | #### 应用场景 - 获取当前所有可用网口信息及状态 - 添加/删除NCSI网口(由network_adapter组件调用) - 配置网口VLAN实现网络隔离 - 网口切换:当主网口链路故障时自动或手动切换到备用网口 - iptables端口映射规则配置,使外部访问通过指定网口转发 #### 限制条件 - 添加网口时端口ID从1开始,新增传入0由系统分配 - VLANId有效范围为1~4094,0表示关闭VLAN - 网口切换需源网口与目标网口均处于正常连接状态 - iptables规则添加后仅在当前会话生效,重启需重新配置 #### 调试示例 ##### 命令行调试 ```bash # 获取所有网口列表 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ GetAllPort a{ss} 0 响应示例: 成功:a(aya{ss}) [{"id":1,"ethid":2,"deviceid":1,"deviceportid":1,"silkscreen":"Mgmt1","type":"Dedicated","adaptiveflag":true,"linkstatus":"Connected","mac":"22:22:22:22:22:22"}] # 设置网络配置(固定模式,激活端口1,关闭VLAN) busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ SetNetworkConfig a{ss}sbu "Fixed" 1 false 0 响应示例: 成功:无 失败:Call failed: Port is not available # 添加管理网口 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ AddMgmtPort a{ss}uuissu 1 1 "Mgmt1" 2 "Dedicated" 1 响应示例: 成功:u 1 失败:Call failed: Port already exists # 删除管理网口 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ DeleteMgmtPort a{ss}u 1 响应示例: 成功:无 失败:Call failed: Unknown object path /bmc/kepler/Managers/1/EthernetInterfaces/1 # 添加IPv4 iptables映射规则 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ AddIptablesRule a{ss}ss "eth2" "192.168.2.100" 响应示例: 成功:b true 失败:b false # 添加IPv6 iptables映射规则 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ AddIp6tablesRule a{ss}ss "eth2" "2001:db8::100" 响应示例: 成功:b true 失败:b false # 设置端口VLAN(使能VLAN,VLANId为100) busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ SetVLANConfig a{ss}bu true 100 响应示例: 成功:b true 失败:b false # 启用/禁用网口(启用eth2) busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ SetEthState a{ss}sb "eth2" true 响应示例: 成功:b true 失败:b false # 双平面切换(从eth2切换到eth0) busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ NetworkFailover a{ss}ss "eth2" "eth0" 响应示例: 成功:b true 失败:b false # 设置内网网段 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ SetChassisLanSubNet a{ss}s "192.168.100.0/24" 响应示例: 成功:无 失败:Call failed: Invalid subnet format ``` ### 2.4 LLDP 配置管理 配置 LLDP(Link Layer Discovery Protocol)参数,实现邻居发现和网络拓扑识别。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS -.Enabled property b <-- - -.WorkMode property s <-- - -.TxDelaySeconds property i <-- - -.TxIntervalSeconds property i <-- - -.TxHold property i <-- - ``` #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Managers.LldpConfig | | 首发版本 | openUBMC 25.3.0 | | 废弃状态 | 正常可用 | ##### 属性参数说明 | 属性名 | 类型 | 只读 | 描述 | 取值范围 | | :--------------- | :--- | :--- | :------------------------ | :------------------------------- | | Enabled | b | 否 | LLDP使能状态 | true: 使能,false: 禁用 | | WorkMode | s | 否 | LLDP工作模式 | 仅支持Tx(发送模式) | | TxDelaySeconds | i | 否 | LLDP发送延时 | 1~8192秒 | | TxIntervalSeconds| i | 否 | LLDP发送间隔 | 5~32768秒 | | TxHold | i | 否 | LLDP信息保持时间倍数 | 2~10(实际保持时间=间隔×倍数) | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :--------- | :----------- | :----------------------------- | :----------------------- | | true | 操作成功 | 属性设置成功 | 无 | | false | 操作失败 | 写入值超出取值范围 | 检查属性值是否符合范围 | #### 应用场景 - 使能LLDP实现交换机端口信息自动发现 - 配置LLDP发送周期获取邻居网络设备信息 - 解析LLDP报文获取对端交换机端口描述(Port Desc),用于解析节点槽位号 #### 限制条件 - WorkMode仅支持Tx,不支持Rx接收模式 - TxIntervalSeconds最小值为5秒 - TxHold有效范围为2~10 #### 调试示例 ##### 命令行调试 ```bash # 查看LLDP配置 busctl --user get-property bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/LldpConfig bmc.kepler.Managers.LldpConfig Enabled busctl --user get-property bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/LldpConfig bmc.kepler.Managers.LldpConfig TxIntervalSeconds # 使能LLDP busctl --user set-property bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/LldpConfig bmc.kepler.Managers.LldpConfig Enabled b true # 设置LLDP发送间隔为30秒 busctl --user set-property bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/LldpConfig bmc.kepler.Managers.LldpConfig TxIntervalSeconds i 30 # 设置LLDP发送延时为2秒 busctl --user set-property bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/LldpConfig bmc.kepler.Managers.LldpConfig TxDelaySeconds i 2 # 设置LLDP保持倍数 busctl --user set-property bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/LldpConfig bmc.kepler.Managers.LldpConfig TxHold i 4 响应示例: 成功:无 失败:Call failed: value is out of range ``` ### 2.5 网口组(EthGroup)配置管理 配置多网口组场景下的网络参数,支持同时管理多个网口组。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .SetNetworkConfig method a{ss}ssbu - - .SetIpMaskGateway method a{ss}sss s - .SetIpAddr method a{ss}ss - - .SetDefaultGateway method a{ss}s - - .SetIpv6PrefixGateway method a{ss}sis s - .SetIpv6Addr method a{ss}si - - .SetIpv6DefaultGateway method a{ss}s - - .EnableFloatIp method a{ss}b b - ``` #### 功能说明 | 属性 | 内容 | | :------- | :---------------------------------------- | | 接口名 | bmc.kepler.Managers.EthernetInterfaces.EthGroup | | 首发版本 | openUBMC 25.3.0 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------------------- | :---------- | :------- | :----------------------- | :----------------------------------------------------------------------------------- | | SetNetworkConfig | sbu | - | 设置网口组网络配置 | s: 网络模式(Fixed/Automatic)
b: 激活端口
u: VLANId | | SetIpMaskGateway | sss | s | 设置IPv4地址掩码网关 | s: IPv4地址
s: 子网掩码
s: 默认网关 | | SetIpv6PrefixGateway | sis | s | 设置IPv6地址前缀网关 | s: IPv6地址
i: 前缀长度
s: 默认网关 | | EnableFloatIp | b | b | 使能/禁用浮动IP | b: true使能,false禁用
出参: true成功,false失败 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :--------- | :----------- | :--------------------------- | :--------------------------- | | IpAddr | 设置成功 | IPv4/IPv6配置成功 | 无 | | true | 操作成功 | 浮动IP功能配置成功 | 无 | | false | 操作失败 | 参数校验失败 | 检查参数格式及网口组状态 | #### 应用场景 - 多网口组环境下独立配置各网口组的网络参数 - 三网口组场景:同时管理NCSI口(eth0)和专用口(eth3)对外IP - 启用浮动IP实现双机热备网络切换 #### 限制条件 - 每个网口组可有多个MgmtPort,但同时只能有一个处于激活状态 - EthGroup路径格式:`/bmc/kepler/Managers/${ManagerId}/EthernetInterfaces/EthGroup/${Id}` - 浮动IP功能需硬件平台支持 #### 调试示例 ##### 命令行调试 ```bash # 获取网口组路径 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces bmc.kepler.Managers.EthernetInterfaces \ GetAllPort a{ss} 0 # 设置第一个网口组(OutEthGroup1)的IPv4配置 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/EthGroup/EthGroup_OutEthGroup1_00 \ bmc.kepler.Managers.EthernetInterfaces.EthGroup \ SetIpMaskGateway a{ss}sss <掩码> <网关> 响应示例: 成功:s 失败:Call failed: Invalid IP address # 设置第一个网口组的IPv6配置 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/EthGroup/EthGroup_OutEthGroup1_00 \ bmc.kepler.Managers.EthernetInterfaces.EthGroup \ SetIpv6PrefixGateway a{ss}sis <前缀> <网关> 响应示例: 成功:s # 使能浮动IP busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/EthGroup/EthGroup_OutEthGroup1_00 \ bmc.kepler.Managers.EthernetInterfaces.EthGroup \ EnableFloatIp a{ss}b true 响应示例: 成功:b true # 设置网口组网络模式为自适应 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/EthGroup/EthGroup_OutEthGroup1_00 \ bmc.kepler.Managers.EthernetInterfaces.EthGroup \ SetNetworkConfig a{ss}sbu "Automatic" 0 false 0 响应示例: 成功:无 ``` ### 2.6 网口速率配置 配置网口的自协商模式、速率和工作模式。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .SetSpeed method a{ss}sbib - - ``` #### 功能说明 | 属性 | 内容 | | :------- | :--------------------------------------- | | 接口名 | bmc.kepler.Managers.EthernetInterfaces.EthConfig | | 首发版本 | openUBMC 25.3.0 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :------- | :------- | :------- | :---------------------- | :---------------------------------------------------------- | | SetSpeed | sbib | - | 设置网口速率配置 | s: 网口名称
b: 自协商使能
i: 速率(0:不涉及 1:10M 2:100M 3:1000M)
b: 双工模式(0:不涉及 1:半双工 2:全双工) | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :--------- | :----------- | :------------------------ | :--------------------- | | true | 操作成功 | 速率配置成功 | 无 | | false | 操作失败 | 网口不支持/参数不合法 | 检查网口名称和参数值 | #### 应用场景 - 固定网口速率为1000M全双工以获得最佳性能 - 禁用自协商并手动指定速率以兼容老旧网络设备 #### 限制条件 - 自协商使能时,SpeedSetting和DuplexSetting参数不生效 - 半双工模式仅在非自协商且速率为10M/100M时可用 #### 调试示例 ##### 命令行调试 ```bash # 设置eth2为自协商模式 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/Eth bmc.kepler.Managers.EthernetInterfaces.EthConfig \ SetSpeed a{ss}sbib "eth2" true 0 0 响应示例: 成功:无 失败:b false # 设置eth2为1000M全双工(禁用自协商) busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/EthernetInterfaces/Eth bmc.kepler.Managers.EthernetInterfaces.EthConfig \ SetSpeed a{ss}sbib "eth2" false 3 2 响应示例: 成功:无 失败:b false ``` ### 2.7 NAT 与 Filter 规则管理 配置网络地址转换(NAT)和过滤(Filter)规则。 ```bash NAME TYPE SIGNATURE RESULT/VALUE FLAGS .AddNatRule method a{ss}saa{ss} - - .UpdateNatRule method a{ss}saa{ss} - - .AddExactNatRule method a{ss}a{ss} - - .DeleteExactNatRule method a{ss}a{ss} - - .AddFilterRule method a{ss}a{ss} - - .DeleteFilterRule method a{ss}a{ss} - - ``` #### 功能说明 | 属性 | 内容 | | :------- | :----------------------------- | | 接口名 | bmc.kepler.Managers.NatConfig | | 首发版本 | openUBMC 25.3.0 | | 废弃状态 | 正常可用 | ##### 方法配置参数 | 方法名 | 入参类型 | 出参类型 | 描述 | 取值范围 | | :--------------- | :-------------- | :------- | :---------------- | :----------------------------------------------------------- | | AddNatRule | saa{ss} | - | 添加NAT规则 | s: 服务名称
aa{ss}: 协议信息键值对数组(如Protocol、DPort、ToPort等) | | UpdateNatRule | saa{ss} | - | 更新NAT规则 | s: 服务名称
aa{ss}: 更新的协议信息 | | AddExactNatRule | a{ss} | - | 针对IP和端口添加NAT | a{ss}: 键值对字典(包含IP、端口等配置信息) | | DeleteExactNatRule | a{ss} | - | 针对IP和端口删除NAT | a{ss}: 键值对字典 | | AddFilterRule | a{ss} | - | 添加Filter规则 | a{ss}: 过滤规则键值对(SourceIp、DestPort等) | | DeleteFilterRule | a{ss} | - | 删除Filter规则 | a{ss}: 过滤规则键值对 | #### 返回值与异常 | 返回值类型 | 含义 | 触发条件 | 处理建议 | | :--------- | :----------- | :-------------------------- | :--------------------- | | - | 操作成功 | 规则添加/更新/删除成功 | 无 | | false | 操作失败 | 规则格式错误/服务不存在 | 检查规则配置及服务状态 | #### 应用场景 - 为Web、SSH等服务配置端口映射规则实现外部访问 - 配置源/目的IP过滤规则实现访问控制 - 更新已有NAT规则中的端口映射关系 #### 限制条件 - NAT规则仅在临时持久化存储,重启后需重新配置 - Filter规则由SecurityMgmt权限用户操作 - 不允许添加冲突的NAT规则 #### 调试示例 ##### 命令行调试 ```bash # 添加NAT规则 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/NatConfig bmc.kepler.Managers.NatConfig \ AddNatRule a{ss}saa{ss} 1 "ServiceName" "https" "ProtocolInfo" 2 "Protocol" "tcp" "DPort" "443" "ToPort" "443" 响应示例: 成功:无 失败:Call failed: Service already exists # 添加精确NAT规则 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/NatConfig bmc.kepler.Managers.NatConfig \ AddExactNatRule a{ss}a{ss} 2 "key" "SrcIp" "value" "192.168.1.0/24" "key" "DPort" "value" "8080" 响应示例: 成功:无 失败:Call failed: Invalid NAT config # 添加Filter规则 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/FilterConfig bmc.kepler.Managers.FilterConfig \ AddFilterRule a{ss}a{ss} 2 "SourceIp" "10.0.0.0/8" "DestPort" "22" 响应示例: 成功:无 失败:Call failed: Filter rule conflict # 删除Filter规则 busctl --user call bmc.kepler.bmc_network \ /bmc/kepler/Managers/1/FilterConfig bmc.kepler.Managers.FilterConfig \ DeleteFilterRule a{ss}a{ss} 2 "SourceIp" "10.0.0.0/8" "DestPort" "22" 响应示例: 成功:无 失败:Call failed: Filter rule not found ``` ### 2.2 cli、IPMI接口使用样例 #### 2.2.1 设置IPv4信息 cli设置IPv4静态IP、掩码、网关,-v后面依次传入四段式的IP、掩码、网关(网关可不传): ```bash ipmcset -d ipaddr -v [gateway] ``` cli设置IPv4静态网关: ```bash ipmcset -d gateway -v ``` cli设置IPv4模式为DHCP/Static: ```bash ipmcset -d ipmode -v ``` ipmi设置IPv4地址: ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 0x03 <四个字节的IP地址> ``` ipmi设置IPv4掩码: ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 0x06 <四个字节的掩码> ``` ipmi设置IPv4网关: ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 0x0c <四个字节的网关> ``` ipmi设置IPv4模式,mode位置传1表示Static,传2表示DHCP: ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 0x04 <1字节的mode> ``` #### 2.2.2 设置IPv6信息 资源树接口:`bmc.kepler.Managers.EthernetInterfaces.Ipv6`
cli设置IPv6静态IP、前缀、网关,-v后面依次传入IP、掩码、网关(网关可以不传): ```bash ipmcset -d ipaddr6 -v [gateway] ``` cli设置IPv6静态网关: ```bash ipmcset -d gateway6 -v ``` cli设置IPv6模式为DHCPv6/Static: ```bash ipmcset -d ipmode6 -v ``` ipmi设置IPv6地址(IP地址按小端方式传入): ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 0xcc <3字节的厂商ID> <16字节的IPv6地址> ``` ipmi设置IPv6前缀: ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 0xcd <3字节的厂商ID> <1字节的前缀> ``` ipmi设置IPv6网关(网关地址按小端方式传入): ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 0xce <3字节的厂商ID> <16字节的网关> ``` ipmi设置IPv6模式,mode位置传1表示Static,传2表示DHCP: ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 0xd0 <3字节的厂商ID> <1字节的mode> ``` #### 2.2.3 外网网口切换 cli设置网络模式,传1表示固定网口,传2表示自适应模式: ```bash ipmcset -d netmode -v <网络模式> ``` cli切换网口(网络模式为固定模式才能切换网口): ```bash ipmcset -d activeport -v <网口类型> 参数说明: 网口类型:0-专用网口 1-LOM 2-PCIe port id: 切换到该类型网口的第几个port(port id从0开始,网口类型传0时,该参数可不传) ``` ipmi设置网络模式: ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x0c 0x01 0x01 <3字节的厂商ID> <1字节的网络模式> 参数说明: 网络模式:1-专用网口 3-自适应模式 4-PCIe (默认切换到该类型网口的第一个port) ``` #### 2.2.4 外网VLAN配置 cli设置VLAN: ```bash ipmcset -d vlan -v [port type] 参数说明: VLAN使能:关闭VLAN时传off,开启VLAN时传1~4094的数字; port type:0表示设置NCSI的VLAN,1表示设置专用网口的VLAN,可以不传,不传时默认设置NCSI的VLAN; ``` ipmi设置VLAN: ```bash ipmitool -H -I lanplus -p 623 -U <用户名> -P <密码> -C 17 raw 0x30 0x93 <3字节的厂商ID> 0x5a 0x1a 0x00 0x04 0x00 <1字节的port type> <1字节的VLAN使能> <2字节的VLAN id> 参数说明: port type:0表示设置NCSI的VLAN,1表示设置专用网口的VLAN; VLAN使能:0表示关闭,1表示使能; VLAN id:由两个字节组成,由前一个字节的低四位和后一个字节组成12位数字 ``` ## 3. 组件扩展案例 ### 3.1 扩展能力概述 不适用。 ## 4 配置介绍 ### 4.1 配置导入导出项 ```plain NetMode:网络模式(Automatic/Fixed) ActivePort:对外网口 IpMode:IPv4模式(DHCP/Static) IpAddr: IPv4地址 SubnetMask:IPv4子网掩码 DefaultGateway:IPv4网关 BackupIpAddr: 备份IPv4地址 BackupSubnetMask:备份IPv4掩码 Ipv6Mode:IPv6模式(DHCPv6/Static) Ipv6Addr:IPv6地址 Ipv6Prefix:IPv6前缀 Ipv6DefaultGateway:IPv6网关 IpVersion:IP协议(IPv4、IPv6、IPv4AndIPv6) VlanID:NCSI VLAN id VlanState:NCSI VLAN使能 DedicatedVlanID:专用网口VLAN id DedicatedVlanState:专用网口VLAN使能 SLAACEnable:SLAAC使能 ------------ LLDPEnable:LLDP使能 TxDelaySeconds:LLDP延迟发送时间 TxIntervalSeconds:LLDP发送周期 TxHold:LLDP发送间隔 WorkMode:LLDP工作模式,目前只支持Tx ------------ HostName:主机名 ------------ DomainName:域名 ------------ ChassisLan: 机框内网网段 ``` ### 4.2 装备定制化项 通用定制项 ```plain BMCSet_ETH0_DHCPMode:IPv4是否为DHCP BMCSet_Eth0_Ipv4:IPv4是否为Static Custom_Eth0_Ip_Addr:IPv4地址和掩码 Custom_ipv4_gateway:IPv4网关 BMCSet_Ipv6_DHCPMode:IPv6是否为DHCPv6 BMCSet_NCSI_VLAN_ID:NCSI VLAN id BMCSet_DEDICATED_VLAN_ID:专用网口VLAN id BMCSet_DedicatedNCSIEnable:专用网口模式下是否使能NCSI BMCSet_LLDPEnable:LLDP使能 BMCSet_NET_Mode:网络模式 Custom_NCSI_Port_Num:NCSI的端口号,对应NCSI网口对象的DevicePortId BMCSet_Hostname:主机名 BMCSet_DDSN_DomainName:域名 BMCSet_IPVersion:IP协议 BMCSet_SLAACEnable:SLAAC使能 BMCSet_ChassisLan_SubNet: 机框内网网段 Custom_Ipv6_IpAddr:默认网口组上Ipv6的地址和前缀 Custom_Ipv6_Gateway:默认网口组上Ipv6的网关 ``` ### 4.3 多网口特性CSR配置介绍 #### 4.3.1 网口组CSR配置 网口组CSR配置的字段为"EthGroup"。历史网口组仅有一个,由EthernetInterfaces、Ipv4、Ipv6三个资源树接口共同构成,它们由bmc_network组件自上树,不依赖CSR加载。新增网口组由EthGroup接口承载,可以通过CSR加载。新增网口组可以有多个对象,每个对象承载一组网络配置。 EthGroup的CSR配置示例如下所示: ```plain "EthGroup_OutEthGroup1": { "Name": "OutEthGroup1", //网口组名字 "GroupId": 1, //网口组ID "OutType": 2, //网口组类型(2即为对外网口) "ActiveEthId": 0, //网口组对应的ethid(此处指eth0,需对应实际情况) "InnerNetWork": "", "VLANId": 0, //网口组对应的vlanID "VLANEnabled": false, //网口组对应的vlan使能 "EthAlias": 255, "IpAddr":"192.168.2.102", //网口组对应的Ipv4地址 "BackupIpAddr": "192.168.2.102", //备份IP地址 "BaseIpAddr": "", "SubnetMask": "255.255.255.0", //网口组对应的Ipv4子网掩码 "BackUpSubnetMask": "255.255.255.0", //网口组对应的备份Ipv4子网掩码 "DefaultGateway": "192.168.2.200", //网口组对应的Ipv4默认网关 "IpPolicy": 0, "Status": true, //网口组使能 "IpMode": "DHCP", //网口组对应的Ipv4模式 "Ipv6Mode": "Static", //网口组对应的Ipv6模式 "Ipv6Addr": "", //网口组对应的Ipv6地址 "PrefixLength": 0, //网口组对应的Ipv6前缀长度 "Ipv6DefaultGateway": "", //网口组对应的Ipv6默认网关 "AssociatedPortType": 1, //网口组关联的Port类型,1代表NCSI口,2代表专用口 "Channel": 2 //网口组对应的LAN通道号 }, ``` 对于三网口组环境,目前可以配置两个网口组,一个用于承载NCSI口(eth0),另一个用于承载专用口(eth3),实现三网口同时使能。三网口组环境的多网口组配置可以参考如下: ```plain "EthGroup_OutEthGroup1": { "Name": "OutEthGroup1", "GroupId": 1, "OutType": 2, "ActiveEthId": 0, "InnerNetWork": "", "VLANId": 0, "VLANEnabled": false, "EthAlias": 255, "IpAddr":"192.168.2.102", "BackupIpAddr": "192.168.2.102", "BaseIpAddr": "", "SubnetMask": "255.255.255.0", "BackupSubnetMask": "255.255.255.0", "DefaultGateway": "192.168.2.102", "IpPolicy": 0, "Status": true, "IpMode": "Static", "Ipv6Mode": "Static", "Ipv6Addr": "", "PrefixLength": 0, "Ipv6DefaultGateway": "", "AssociatedPortType": 1, "Channel": 2 }, "EthGroup_OutEthGroup2": { "Name": "OutEthGroup2", "GroupId": 2, "OutType": 2, "ActiveEthId": 3, "InnerNetWork": "", "VLANId": 0, "VLANEnabled": false, "EthAlias": 255, "IpAddr":"192.168.2.103", "BackupIpAddr": "192.168.2.103", "BaseIpAddr": "", "SubnetMask": "255.255.255.0", "BackUpSubnetMask": "255.255.255.0", "DefaultGateway": "192.168.2.103", "IpPolicy": 0, "Status": true, "IpMode": "Static", "Ipv6Mode": "Static", "Ipv6Addr": "", "PrefixLength": 0, "Ipv6DefaultGateway": "", "AssociatedPortType": 2, "Channel": 3 }, ``` #### 4.3.2 网口组CSR配置 网口CSR配置的字段为"EthMac"。该CSR用于配置需要拉起的网口信息,包括Id,MAC等。EthMac的CSR配置示例如下所示: 双网口组环境示例: ```plain "EthMac_Eth0": { "EthId": 0, //网口组对应的ethid(此处指eth0,需对应实际情况) "EthName": "eth0", //网口名 "GroupId": "EthGroup0", //网口对应的网口组 "Mac": "20:22:01:75:BC:60", //网口对应的MAC地址 "MacUseEnabled": false, //是否使能该网口(对于每个网口组,仅有一个网口需要使能,此处不使能eth0) "SpeedDuplexEnable": true, "SpeedSetting": 0, "DuplexSetting": 0 }, "EthMac_Eth2": { "EthId": 2, "EthName": "eth2", "GroupId": "EthGroup0", "Mac": "20:22:01:75:BC:60", "MacUseEnabled": true, //是否使能该网口(对于每个网口组,仅有一个网口需要使能,此处使能eth2) "SpeedDuplexEnable": true, "SpeedSetting": 0, "DuplexSetting": 0 } ``` 三网口组环境示例: ```plain "EthMac_Eth0": { "EthId": 0, "EthName": "eth0", "GroupId": "EthGroup0", "Mac": "20:22:01:75:BC:60", "MacUseEnabled": false, "SpeedDuplexEnable": true, "SpeedSetting": 0, "DuplexSetting": 0 }, "EthMac_Eth2": { "EthId": 2, "EthName": "eth2", "GroupId": "EthGroup0", "Mac": "20:22:01:75:BC:60", "MacUseEnabled": true, "SpeedDuplexEnable": true, "SpeedSetting": 0, "DuplexSetting": 0 }, "EthMac_Eth3": { "EthId": 3, "EthName": "eth3", "GroupId": "EthGroup0", "Mac": "20:22:01:75:BC:60", "MacUseEnabled": false, "SpeedDuplexEnable": true, "SpeedSetting": 0, "DuplexSetting": 0 } ``` #### 4.3.3 专用网口CSR配置 专用网口CSR配置的字段为"DedicatedPort"。该CSR用于配置专用网口信息,三网口组环境的专用网口CSR配置示例如下所示: ```plain "DedicatedPort_Eth2": { "Id": 1, //专用网口对应的PortId(eth2固定为1) "EthId": 2, //专用网口对应的EthId "DeviceId": 1, //专用网口对应的设备ID "DevicePortId": 1, //专用网口对应的设备PortID "Silkscreen": "Mgmt1", //专用网口对应的丝印 "NcsiInitPortFlag": true, "VLANId": 0, //专用网口对应的VlanId(专用网口vlan需配置一致) "VLANEnabled": false, //专用网口对应的Vlan使能 "OriginalGroupId": 0, //专用网口对应的默认网口组归属 "CurrentGroupId": 0 //专用网口对应的当前网口组归属 }, "DedicatedPort_Eth3": { "Id": 2, "EthId": 3, "DeviceId": 1, "DevicePortId": 2, "Silkscreen": "Mgmt2", "NcsiInitPortFlag": false, "VLANId": 0, "VLANEnabled": false, "OriginalGroupId": 2, "CurrentGroupId": 0 } ``` #### 4.3.4 LAN通道CSR配置 LAN通道CSR配置的字段为"IPMIChannel",该CSR用于配置IPMI的lan通道信息,于网口组EthGroup中的”Channel“字段对应。三网口组环境的LAN通道CSR配置示例如下所示: ```plain "IPMIChannel_LAN1": { "ChanType": 4, "Instance": 1, //与LAN通道ID一致 "ChanPro": 1, "ChannelID": 1, //与LAN通道ID一致 "DestAddr": 32, "SrcAddr": 0, "MedType": 4 }, "IPMIChannel_LAN2": { "ChanType": 4, "Instance": 2, "ChanPro": 1, "ChannelID": 2, "DestAddr": 32, "SrcAddr": 0, "MedType": 4 }, "IPMIChannel_LAN3": { "ChanType": 4, "Instance": 3, "ChanPro": 1, "ChannelID": 3, "DestAddr": 32, "SrcAddr": 0, "MedType": 4 }, ``` ## 5. 日志说明 ### 5.1 一键日志收集 | 文件路径 | 内容说明 | | :--- | :--- | | dump_info\AppDump\bmc_network\lldp_info.txt | lldp配置信息 | | dump_info\AppDump\bmc_network\mdb_info.log | 资源树信息 | | dump_info\AppDump\bmc_network\network_info.txt | 网络配置信息 | ### 5.2 关键日志信息 | 日志片段 | 日志级别 | 含义解读 | 建议处理动作 | | :--- | :--- | :--- | :--- | | ===== network service init ======= | NOTICE | 网络初始化 | 无 | | eth mac self discovery finish | NOTICE | 自发现对象分发完成 | 无 | | set_ipv4_mask_gateway: ip_mode = [Static], ip_addr = [x.x.x.x], ip_submask = [x.x.x.x], ip_gateway = [x.x.x.x] | NOTICE| rpc设置ipv4静态地址 | 无 | | set_ipv6_prefix_gateway: [Static], ip_addr = [xxxx], PrefixLength = [x], DefaultGateway = [xxxx] | NOTICE | 自发现对象rpc设置ipv6静态地址分发完成 | 无 | | dhcp get out eth(ethx) new ipv4 info, ip: x.x.x.x, mask: x.x.x.x, gateway: x.x.x.x | NOTICE | DHCP获取到ipv4地址 | 无 | | dhcpv6 get out eth(ethx) new ipv6 info, ip: xxxx, prefix: x, gateway: xxxx | NOTICE | DHCPv6获取到ipv6地址 | 无 | ## 6. 问题定界指南 ### 6.1 典型问题定界 | 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 | | :--- | :--- | :--- | :--- | | ssh登录bmc失败,可以ping通BMC | 否 | - | - | | ssh登录bmc失败,不能ping通BMC | 是 | - | - | | ping BMC环境或者用ssh登录BMC环境,一会通一会不通 | 是 | MAC地址冲突,在OS修改MAC地址后解决 | - | ### 6.2 调试方法 #### 6.2.1 开启调试日志 - 定制互联网仓 ```text ##设置xx定制仓 busctl --user set-property bmc.kepler.maca /bmc/kepler/Managers/1/Package bmc.kepler.Managers.Package Customer s "xx" ##定制完互联网仓后需重启BMC生效 ipmcset -d reset ##查询当前环境定制类型 busctl --user get-property bmc.kepler.maca /bmc/kepler/Managers/1/Package bmc.kepler.Managers.Package Customer ``` - 查看与删除持久化数据 由于单网口和多网口环境中持久化数据不一致,在使用多网口环境回退到单网口环境时,可能存在某些持久化数据不一致的问题,因此可以在环境内进行持久化数据的查看与清理。 持久化数据主要分为临时持久化、复位持久化、掉电持久化和永久持久化,其数据库存储路径如下: >**临时持久化(TemporaryPer):** /run/persistence/per_temporary.db >**
复位持久化(ResetPer):** /opt/bmc/pram/persistence/per_reset.db >**
掉电持久化(PoweroffPer):** /data/trust/persistence/per_poweroff.db >**
永久持久化(PermanentPer):** /dev/mmcblk0p8 - 查看与清除持久化的命令示例 ```text /usr/sbin/sqlite3 /data/trust/persistence/per_poweroff.db //查看 select * from persist_table where table_name='t_ncsi_nc_info'; select * from persist_table where table_name='t_channel_number_mappings'; select * from persist_table where table_name='t_network_mgmtport'; select * from persist_table where table_name='t_network_ethernetInterface'; select * from persist_table where table_name='t_network_ipv4'; select * from persist_table where table_name='t_network_ipv6'; select * from persist_table where table_name='t_network_eth_group'; //删除 DELETE FROM t_update_mgmt WHERE ID = 1; DELETE FROM persist_table WHERE table_name='t_channel_number_mappings'; DELETE FROM persist_table WHERE table_name='t_network_eth_group'; DELETE FROM persist_table WHERE table_name='t_network_mgmtport'; DELETE FROM persist_table WHERE table_name='t_network_ethernetInterface'; DELETE FROM persist_table WHERE table_name='t_ncsi_nc_info'; ``` - 常用的CLI命令 CLI命令分为ipmcset和ipmcget,使用CLI命令是主要关注-d、-t参数,可以参考: ```text Usage: ipmcget -d dataitem [-v value] -d ipinfo Get ip information lldpinfo Get LLDP information version Get openUBMC version Usage: ipmcset -d dataitem [-v value] -d activeport Set EthGroup active port backupipaddr Set backup ip address gateway Set gateway gateway6 Set ipv6 gateway ipaddr Set ip address ipaddr6 Set ipv6 address ipmode Set ip mode ipmode6 Set ipv6 mode ipversion Set ip version netmode Set net mode vlan Set sideband vlan ``` 详细使用案例见2.2章节。 - 查看资源树属性 ```text //查看网络模块相关资源树 busctl --user tree bmc.kepler.bmc_network | egrep -v "IpmiCmds" //查看第一个网口组资源树 busctl --user introspect bmc.kepler.bmc_network /bmc/kepler/Managers/1/EthernetInterfaces busctl --user introspect bmc.kepler.bmc_network /bmc/kepler/Managers/1/Ipv4 busctl --user introspect bmc.kepler.bmc_network /bmc/kepler/Managers/1/Ipv6 //查看新增网口组资源树(OutEthGroup1代表第一个新增网口组) busctl --user introspect bmc.kepler.bmc_network /bmc/kepler/Managers/1/EthernetInterfaces/EthGroup/EthGroup_OutEthGroup1_00 //查看网口资源树(最后一个数字代表网口的PortId) busctl --user introspect bmc.kepler.bmc_network /bmc/kepler/Managers/1/EthernetInterfaces/1 ``` - 查看系统协议栈 ```text //查看系统协议栈网口信息 ifconfig sbin/ifconfig //查询过滤规则,是否每个对外网口均添加 iptables -t filter -nvL ip6tables -t filter -nvL //查询转发规则,是否每个对外网口均添加 iptables -t nat -nvL ip6tables -t nat -nvL ``` >注意: 以上均配置正常则可能需要抓包处理。 可能不连通的原因:(1)局域网中存在相同的IP或MAC地址;(2)Vlan没有和交换机匹配;(3)能ping通,转发规则正常,ssh、web服务不能连通则需联系运维组件。 ## 7. 常见问题解答 ### 7.1 pingBMC环境或者用ssh登录bmc环境,一会通一会不通 | 原因 | 解决方案 | | :--- | :--- | | MAC地址冲突 | 在OS修改MAC地址解决 ipmitool raw 0x30 0x90 0x44 0x02 <6字节的mac> | | IP地址冲突 | 可切换DHCP模式或修改静态IP | 更多常见问题请查阅[《网络管理常见问题》](../feature_dev/network_mgmt/network_FAQ.md)。 ## 附录 ### 附录A 参考资料 - [《网络管理常见问题》](../feature_dev/network_mgmt/network_FAQ.md) ### 附录B 修订记录 | 版本 | 日期 | 修订人 | 修订内容 | | :--- | :--- | :--- | :--- | | v1.0 | 2026-04-30 | mkdlf | 修改文档格式、补充bmc_network说明 | --- # bmc_soc > URL: https://openubmc.cn/docs/zh/latest/feature_dev/component_interface_spec/bmc_soc.html > Language: zh # bmc_soc ## 版本信息 | 项目 | 内容 | | :--- | :--- | | 组件版本 | 1.120.3 | | 首发版本 | openUBMC 25.3.0| | 文档作者 | mkdlf | | 最后更新 | 2026-05-09 | ## 1. 组件概述 ### 1.1 组件简介 BMC SOC管理为BMC基本功能特性,主要提供BMC片上资源的管理和监控功能,包括UART串口管理、串口连接管理、NAND Flash健康管理、SOC状态监控、生产自检等功能。 ### 1.2 解决什么问题 bmc_soc主要涉及与芯片相关的功能,包括串口管理、串口日志导出、efuse升级、温度信息、同步DIEID信息、电源事件、nandflash监控等功能。对于串口管理、串口日志导出、nandflash写保护、PCIe通道使能、Efuse升级等功能均通过调用soctrl组件来实现;对于获取BMC的自检结果、BMC核温、BMC复位原因、DIEID信息、nandflash信息(厂商、EMMC型号、寿命、写入量、擦写次数)等数据,通过调用libsoc_adapter库方法来实现。 ### 1.3 核心功能 - UART串口管理 支持BMC多个UART串口的配置和管理,包括串口参数配置(波特率、数据位、校验位、停止位)和串口连接管理。支持串口数据的监听和日志记录功能。 - 串口连接管理 提供串口源和目的地的动态连接管理,支持串口连接的持久化策略(掉电保留/复位保留),支持面板串口SwitchCMD命令切换。 - NAND Flash健康管理 对BMC的NAND Flash存储介质进行健康度监控,包括寿命监控、擦写次数统计、坏块管理、写保护等功能,支持Flash健康度告警。 - SOC状态监控 监控SOC芯片的工作状态,包括温度监控、黑匣子功能、PCIe控制器使能、DDR自检结果、启动时间等关键指标。 ### 1.4 关键术语表 | 术语 | 解释 | | :--- | :--- | | SOC | 系统级芯片(System on Chip) | | NAND Flash| NAND闪存 | | UART | 串口,全称为通用异步收发器(Universal Asynchronous Receiver/Transmitter) | ## 2. API 使用说明与示例 ### 2.1 资源协作接口概览 #### 2.1.1 SOC串口端口资源协作接口 资源协作接口: **path**: `/bmc/kepler/Managers/${ManagerId}/UartPorts/${Id}` **interface**: `bmc.kepler.Managers.UartPort` **properties** | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **Id** | `U8` | ✓ | false | 端口ID | `0` | | **BusType** | `String` | ✓ | false | 串口协议类型,取值如下:
- `Uart`: Uart通用端口
- `UartOverHisport`: 基于Hisport通道的Uart端口
- `UartOverEspi`: 基于ESPI通道的Uart端口 | `Uart` | | **UartConnection** | `U8` | ✓ | - | UART连接编号 | - | | **PortConnection** | `U8` | ✓ | - | 端口连接编号 | - | | **BaudRate** | `U32` | ✗ | - | 波特率 | `115200` | | **DataBit** | `U8` | ✗ | - | 数据位 | `8` | | **ParityBit** | `U8` | ✗ | - | 校验位 | - | | **StopBit** | `U8` | ✗ | - | 停止位 | `1` | | **SerialSwitch** | `U8` | ✗ | - | 串口切换开关 | - | **methods** | 方法名 | 权限 | 描述 | 请求参数 | 响应参数 | | --- | --- | --- | --- | --- | | **Reset** | BasicSetting | 打开启动Uart设备,并对设备进行参数设置等初始化 | 无 | 无 | #### 2.1.2 SOC串口数据配置资源协作接口 **path**:`/bmc/kepler/Managers/${ManagerId}/UartData` **interface**: `bmc.kepler.Managers.UartData` **properties** | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **Enabled** | `Boolean` | ✗ | - | 设置SOL使能状态 | `true` | | **SystemLogSize** | `U32` | ✓ | - | 系统串口日志大小 | `2097152` | | **Id** | `U8` | ✓ | - | UART数据ID | - | | **SerialListenSwitchEnabled** | `Boolean` | ✗ | - | 面板串口SwitchCMD命令使能 | `false` | | **UartIdforSerialListen** | `U8` | ✗ | - | 监听SwitchCMD命令的串口 | `0` | **methods** | 方法名 | 权限 | 描述 | 请求参数 | 响应参数 | | --- | --- | --- | --- | --- | | **Export** | DiagnoseMgmt | 导出串口日志 | `Type`: String - 导出数据的类型,可选值:SYS COM/ALL
`FilePath`: String - 导出数据的文件路径 | `TaskId`: U32 - 任务标识 | #### 2.1.3 SOC串口互联配置资源协作接口 **path**:`/bmc/kepler/Managers/${ManagerId}/SerialManagement` **interface**: `bmc.kepler.Managers.SerialManagement.Config` **methods** | 方法名 | 权限 | 描述 | 请求参数 | 响应参数 | | --- | --- | --- | --- | --- | | **Reset** | BasicSetting | 恢复串口管理配置 | 无 | 无 | #### 2.1.4 SOC串口互联关系资源协作接口 **path**:`/bmc/kepler/Managers/${ManagerId}/SerialManagement/${Id}` **interface**: `bmc.kepler.Managers.SerialManagement` **properties** | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **Id** | `U8` | ✓ | false | 串口链路的ID | `3` | | **Availability** | `U8` | ✓ | false | 串口链路的可用性 | `1` | | **CurrentConnectStatus** | `U8` | ✓ | - | 当前串口连接状态,0:未连接,1:已连接 | `0` | | **Source** | `String` | ✓ | false | 链路关系源端 | `PANEL COM` | | **Destination** | `String` | ✓ | false | 链路关系对端 | `openUBMC COM` | | **SrcSerial** | `U8` | ✓ | false | 源Uart或Port口,其中取值大于16是Port,否则是Uart | `18` | | **DestSerial** | `U8` | ✓ | false | 目的Uart或Port口,其中取值大于16是Port,否则是Uart | `2` | | **SourceId** | `U8` | ✗ | - | 源ID | - | | **DestinationId** | `U8` | ✗ | - | 目的ID | - | | **RetainedPolicy** | `U8` | ✗ | - | 串口的持久化方案,取值:0-掉电保留,1-复位保留 | - | | **ConnectStatus** | `U8` | ✗ | - | 掉电保留的串口连接状态 | - | | **ConnectStatusResetPer** | `U8` | ✗ | - | 复位保留的串口连接状态 | - | | **SystemId** | `U8` | ✓ | - | 复位后自动恢复的多host串口连接状态 | `0` | | **CPLDValue** | `U8` | ✓ | - | 切换串口方向寄存器的值 | `255` | | **ConnectMode** | `U8` | ✓ | - | 串口连接方式 | `0` | | **ListenSwitchCmdEnabled** | `Boolean` | ✗ | - | 面板串口SwitchCMD命令使能 | `false` | | **ListenSwitchCmd** | `String` | ✗ | - | 面板串口SwitchCMD命令 | - | **methods** | 方法名 | 权限 | 描述 | 请求参数 | 响应参数 | | --- | --- | --- | --- | --- | | **SetConnectStatus** | BasicSetting | 设置串口链路状态 | `NeedSaved`: Boolean - 此次串口连接方向是否持久化 | 无 | #### 2.1.5 SOC Flash资源协作接口 **path**:`/bmc/kepler/Managers/:ManagerId/NandFlash` **interface**: `bmc.kepler.Managers.NandFlash` **properties** | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **Vendor** | `String` | ✓ | - | nand厂商 | `Hynix` | | **WriteProtection** | `U8` | ✗ | false | Nand Flash写保护状态,写入与否:0(允许)/1(禁止) | `0` | | **LifeTime** | `U8` | ✓ | - | 剩余寿命百分比,支持Nand Flash已用寿命超限严重告警 | `99` | | **LifeTimeThreshold** | `U8` | ✓ | - | 寿命阈值 | `10` | | **PreEOL** | `U8` | ✓ | - | (end of life)Nand Flash的PreEOL信息(通过平均预留块来反映设备寿命) | `1` | | **OverWrite** | `U8` | ✓ | - | 写入量是否超过门限,1:超过/0:未超过 | `0` | | **WriteThreshold** | `U8` | ✓ | false | Nand Flash写入量,单位GB | `12` | | **RWTestState** | `U8` | ✓ | - | 读写测试状态 | `0` | | **MaxEraseCount** | `S32` | ✓ | false | 最大擦除次数(非JPR型号海力士支持),不支持厂商置-1 | `3000` | | **RemainingEraseCount** | `S32` | ✓ | false | 剩余擦除次数(非JPR型号海力士支持),不支持厂商置-1 | `2917` | | **EraseCountPerDays** | `S32[]` | ✓ | false | 最近15天每天擦除次数(非国产海力士支持),不支持或无数据为空 | `[1, 0]` | | **TotalWriteAmount** | `Double` | ✓ | false | 开机至今总写入量,单位GB | `0.112` | | **TotalWriteAmountIn15Days** | `Double` | ✓ | false | 最近15天总写入量,单位GB | `0.112` | | **WriteAmountPerDay** | `Double[]` | ✓ | false | 最近15天每天写入量,无数据时为空,单位GB | `[1, 0.112]` | | **ReservedBlocks** | `S32` | ✓ | false | 剩余预留块(非JPR型号海力士支持),不支持厂商置-1 | `81` | | **RuntimeBadBlocks** | `S32` | ✓ | false | 坏块数量(非JPR型号海力士支持),不支持厂商置-1 | `0` | | **Id** | `U8` | ✓ | - | NAND Flash ID | - | | **WriteAmountOver800mOneDay** | `U8` | ✗ | - | 单日写入量超过800MB标志 | - | | **FlashRecoverPolicy** | `U8` | ✗ | - | 用于配置连续读写测试失败后是否支持自愈。取值,0:不采取动作;1:重启BMC | - | | **FlashRecovered** | `U8` | ✗ | - | 用于标记BMC是否重启修复过。取值,0:未重启修复过;1:重启修复过 | - | **methods** | 方法名 | 权限 | 描述 | 请求参数 | 响应参数 | | --- | --- | --- | --- | --- | | **ClearStatistics** | BasicSetting | 清除写入量统计 | 无 | 无 | #### 2.1.6 SOC 资源协作接口 **path**:`/bmc/kepler/Managers/:ManagerId/SOC` **interface**: `bmc.kepler.Managers.SOC` **properties** | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **BlackBoxEnabled** | `Boolean` | ✗ | - | 设置黑匣子使能开关状态,false(关闭)/true(打开) | `false` | | **PCIeControllerEnabled** | `Boolean` | ✗ | - | 设置PCIe接口使能开关状态,false(关闭)/true(打开) | `false` | | **Temperature** | `S32` | ✓ | - | BMC核心温度 | `43` | | **TemperatureThreshold** | `S32` | ✓ | - | BMC核心温度告警阈值 | `105` | | **Name** | `String` | ✓ | false | 芯片名字 | `SocNameExample` | | **Version** | `String` | ✓ | false | 芯片版本,如V100 | `100` | | **Designator** | `String` | ✓ | false | 芯片位置,如U82 | `U82` | | **DIEID** | `String` | ✓ | false | DIE(裸片)ID(标识) | `12345678 90ABCDEF` | | **ResetType** | `U8` | ✓ | false | BMC复位原因,0 AC复位,2 软复位 | `2` | | **DDRSelfTestResult** | `U8` | ✓ | - | DDR自检结果,BMC启动检查一次,1 自检成功 0 自检失败 | `1` | | **DDRSingleBitECCStatistics** | `U32` | ✓ | false | DDR ECC错误检查,1小时例测一次单bit结果 | `0` | | **DDRMultiBitECCStatistics** | `U32` | ✓ | false | DDR ECC错误检查,1小时例测一次多bit结果 | `0` | | **StartupDuration** | `U16` | ✓ | false | BMC启动时间规格 | `160` | | **LastResetTime** | `String` | ✓ | false | 表征BMC上一次重启时间 | `2025-10-10T07:39:59+00:00` | | **BootStatus** | `U8` | ✓ | true | 加载状态,1:表示BMC已启动;0为默认值,表示未完成启动 | - | | **BmcHardResetFlag** | `U8` | ✗ | - | BMC硬复位标志 | `0` | | **ProcessRestartFlag** | `U8` | ✗ | - | 进程重启标志 | `0` | | **CoreEnableTemp** | `U8[]` | ✗ | - | 开核的温度,有3个值,分别代表开第一个,第二个,第三个从核开核的芯片温度 | - | | **CoreDisableTemp** | `U8` | ✗ | - | 高温关核温度 | - | | **CoreDisablePowerOffTime** | `U8` | ✗ | - | 下电关核的超时时间,为0表示下电不关核 | - | | **DCAEnable** | `U8` | ✗ | - | 动态开关核功能使能 1使能 0关闭 | - | ### 2.2 Reset #### 功能说明 打开启动UART设备,并对设备进行参数设置等初始化。 | 属性 | 内容 | | :--- | :--- | | 接口名 | bmc.kepler.Managers.UartPort | | 首发版本 | bmcsdk 25.12 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | - | - | - | - | - | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 空 | 成功 | 正常执行完成 | 无 | #### 应用场景 打开启动UART设备,并对设备进行参数设置等初始化。 #### 调试示例 ##### 命令行调试 ```text busctl --user call bmc.kepler.bmc_soc /bmc/kepler/Managers/1/UartPorts/Uart_0_01 bmc.kepler.Managers.UartPort Reset a{ss} 0 响应:无 ``` ### 2.3 Export #### 功能说明 导出串口日志。 | 属性 | 内容 | | :--- | :--- | | 接口名 | bmc.kepler.Managers.UartData | | 首发版本 | bmcsdk 25.03 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | Type | 输入 | String | 导出数据的类型 | “SYS COM”或“ALL” | | FilePath | 输入 | String | 导出数据的文件路径 | String | | TaskId | 输出 | U32 | 任务标识 | U32 | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 抛错Call failed: {"format":"Failed to operate because the current status does not support it.","registry_prefix":"BMC","name":"FeatureDisabledAndNotSupportOperation"} | 日志导出校验失败 | 未打开日志使能开关 | 打开日志使能开关 | | 抛错Call failed: {"registry_prefix":"BMC","format":"The value %s of the property %s is invalid.","name":"InvalidValue","params":["SYS COMM","Type"]} | 入参Type校验失败 | 输入的参数Type值不合法 | Type值需为“SYS COM”或“ALL” | | 抛错Call failed: {"registry_prefix":"BMC","format":"The value %s of the property %s does not contain the file name or does not exist in the tmp directory.","name":"InvalidPath","params":["******","Content"]} | 入参FilePath校验失败 | 输入的参数FilePath值不合法 | 输入有效的文件本地导出路径 | | Call failed: {"format":"The transfer protocols specified in the image URI and in the action parameter do not match.","registry_prefix":"BMC","name":"FileTransferProtocolMismatch"} | 输入的参数FilePath值不合法 | 输入有效的文件远程导出路径 | #### 应用场景 导出串口日志,前提是日志使能开关打开。 #### 调试示例 ##### 命令行调试 ```text busctl --user call bmc.kepler.bmc_soc /bmc/kepler/Managers/1/UartData bmc.kepler.Managers.UartData Export a{ss}ss 0 'SYS COM' '/tmp/ee.txt' 响应:u 2088034522 ``` ### 2.4 Reset #### 功能说明 恢复串口管理配置。 | 属性 | 内容 | | :--- | :--- | | 接口名 | bmc.kepler.Managers.SerialManagement.Config | | 首发版本 | bmcsdk 25.03 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | - | - | - | - | - | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 空 | 成功 | 正常执行完成 | 无 | #### 应用场景 恢复串口管理配置。 #### 调试示例 ##### 命令行调试 ```text busctl --user call bmc.kepler.bmc_soc /bmc/kepler/Managers/1/SerialManagement bmc.kepler.Managers.SerialManagement.Config Reset a{ss} 0 响应:0 ``` ### 2.5 SetConnectStatus #### 功能说明 设置串口链路状态。 | 属性 | 内容 | | :--- | :--- | | 接口名 | bmc.kepler.Managers.SerialManagement | | 首发版本 | bmcsdk 25.03 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | NeedSaved | 输入 | Boolean | 此次串口连接方向是否持久化 | true或false | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 空 | 成功 | 正常执行完成 | 无 | #### 应用场景 设置串口链路状态。 #### 调试示例 ##### 命令行调试 ```text busctl --user call bmc.kepler.bmc_soc /bmc/kepler/Managers/1/SerialManagement/SerialManagement_5_00 bmc.kepler.Managers.SerialManagement SetConnectStatus a{ss}b 0 false 响应:无 ``` ### 2.6 ClearStatistics #### 功能说明 清除写入量统计。 | 属性 | 内容 | | :--- | :--- | | 接口名 | bmc.kepler.Managers.NandFlash | | 首发版本 | bmcsdk 25.03 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | - | - | - | - | - | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 无抛错 | 设置成功 | 输入参数在合法的范围内 | 无 | #### 应用场景 清除写入量统计。 #### 调试示例 ##### 命令行调试 ```text busctl --user call bmc.kepler.bmc_soc /bmc/kepler/Managers/1/NandFlash bmc.kepler.Managers.NandFlash ClearStatistics a{ss} 0 响应:无 ``` ### 2.7 SetDebugValue #### 功能说明 调试模式下设置参数。 | 属性 | 内容 | | :--- | :--- | | 接口名 | bmc.kepler.Debug.Managers.NandFlashMock | | 首发版本 | bmcsdk 25.03 | | 废弃状态 | 正常可用 | #### 参数说明 | 参数名 | 方向 | 类型 | 描述 | 取值范围 | | :--- | :--- | :--- | :--- | :--- | | LifeTime | 输入 | U8 | 调试模式下flash使用的寿命,百分比 | [0,100] | | PreEOL | 输入 | U8 | 调试模式下预留块状态 | [1,3] | | DelayTime | 输入 | U32 | 调试模式下计算使用寿命及使用块的间隔时间,单位秒 | U32 | | TimeInterval | 输入 | U32 | 调试模式下写入量统计时间间隔,单位秒 | U32 | | WriteThreshold | 输入 | U64 | 调试模式下写入量的阈值,单位字节 | U64 | | ClearStatisticsInterval | 输入 | U32 | 调试模式下重置写入量的时间间隔,单位秒 | U32 | #### 返回值与异常 | 返回值 | 含义 | 触发条件 | 处理建议 | | :--- | :--- | :--- | :--- | | 抛错Call failed: {"registry_prefix":"BMC","format":"The value for the property %s is out of range.","name":"ValueOutOfRange","params":["PreEOL"]} | 输入参数PreEOL的值不在允许的范围 | 参数PreEOL的值小于1或大于3 | 控制输入参数PreEOL的值属于区间[1,3] | | 无抛错 | 设置成功 | 输入参数在合法的范围内 | 无 | #### 应用场景 调试模式下设置参数。 #### 调试示例 ##### 命令行调试 ```text busctl --user call bmc.kepler.bmc_soc /bmc/kepler/Debug/Managers/1/NandFlashMock bmc.kepler.Debug.Managers.NandFlashMock SetDebugValue a{ss}yyuutu 0 50 2 60 30 10 60 响应:无 ``` ## 3. 组件扩展案例 ## 4 CSR配置介绍 ### 4.1 SerialManagement 对象配置介绍 此对象用于配置串口链路连接管理,表名:t_serial_management。 | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **Id** | `U8` | ✓ | false | 串口链路ID(主键) | - | | **Availability** | - | ✓ | false | 串口链路的可用性 | - | | **Source** | - | ✓ | false | 链路关系源端 | - | | **Destination** | - | ✓ | false | 链路关系对端 | - | | **SrcSerial** | - | ✓ | false | 源Uart或Port口,其中取值大于16是Port,否则是Uart | - | | **DestSerial** | - | ✓ | false | 目的Uart或Port口,其中取值大于16是Port,否则是Uart | - | | **SourceId** | `U8` | ✗ | false | 源ID | - | | **DestinationId** | `U8` | ✗ | false | 目的ID | - | | **RetainedPolicy** | `U8` | ✗ | false | 串口的持久化方案,取值:0-掉电保留,1-复位保留 | - | | **ConnectStatus** | `U8` | ✗ | false | 掉电保留的串口连接状态 | - | | **ConnectStatusResetPer** | `U8` | ✗ | false | 复位保留的串口连接状态 | - | | **SystemId** | `U8` | ✓ | false | 复位后自动恢复的多host串口连接状态 | `0` | | **CPLDValue** | `U8` | ✓ | false | 切换串口方向寄存器的值 | `255` | | **ConnectMode** | `U8` | ✓ | false | 串口连接方式 | `0` | | **ListenSwitchCmdEnabled** | `Boolean` | ✗ | false | 面板串口SwitchCMD命令使能 | `false` | | **ListenSwitchCmd** | `String` | ✗ | false | 面板串口SwitchCMD命令 | - | ### 4.2 UartCircularLog对象配置介绍 此对象用于配置UART循环日志功能。 | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **Id** | `U8` | ✓ | false | UART日志ID | - | | **LogDirection** | `U8` | ✗ | false | 日志方向 | - | | **RxSize** | `U8` | ✗ | false | 接收缓冲区大小 | - | | **TxSize** | `U8` | ✗ | false | 发送缓冲区大小 | - | | **IsSysCom** | `U8` | ✗ | false | 是否系统串口 | - | | **LogEnable** | `U8` | ✗ | false | 日志使能 | - | | **AutoCollect** | `U8` | ✗ | false | 自动收集 | - | | **LastOffset** | `U32` | ✗ | false | 上次偏移量 | - | | **SystemId** | `U8` | ✓ | false | 系统ID | `255` | | **LogFileName** | `String` | ✗ | false | 日志文件名 | - | ### 4.3 NandInfo对象配置介绍 此对象用于配置NAND Flash的基本信息。 | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **VID** | `U8` | ✓ | false | 厂商ID | - | | **Vendor** | `String` | ✓ | false | 厂商名称 | - | | **LifeThreshold** | `U8` | ✓ | false | 寿命阈值 | - | | **WriteThreshold** | `U8` | ✓ | false | 写阈值 | - | | **DftLifeThreshold** | `U8` | ✓ | false | 默认寿命阈值 | - | | **ProductName** | `String` | ✓ | false | 产品名称 | `` | | **MaxWriteTimes** | `S16` | ✓ | false | 最大写入次数 | `-1` | | **LifeInfoOffset** | `U16` | ✓ | false | 寿命信息偏移量 | `269` | ### 4.4 BMCFileSystemCheck对象配置介绍 此对象用于配置BMC文件系统健康检查功能。 | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **Id** | `U8` | ✓ | false | 文件系统检查ID | - | | **Enabled** | `U8` | ✗ | false | 文件系统健康检查使能,状态定义0:禁止;1:使能 | - | | **MountType** | `U8` | ✗ | false | 数据分区挂载方式,0:Read-Write;1:Read-Only | - | ### 4.5 SerialSwitchAction对象配置介绍 此对象用于配置串口切换动作的寄存器关联。 | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **SerialSwitchAccessor** | `U8` | ✓ | false | 串口切换关联第一级寄存器,CPLDValue对应的寄存器 | `255` | | **RemoteAccessor** | `U8` | ✓ | false | 串口切换关联第二级寄存器 | `255` | ### 4.6 McuLog对象配置介绍 此对象用于配置MCU日志相关参数。 | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **SystemId** | `U8` | ✓ | false | 系统ID | - | | **ValidSlot** | `Boolean` | ✓ | false | 有效Mcu片 | - | | **BoardLogChip** | `U8[]` | ✓ | false | 板载日志芯片 | - | | **GetLenthCmd** | `U32` | ✗ | false | 读取flash长度命令 | - | | **SetStartPosCmd** | `U32` | ✗ | false | 设置读取flash起点命令 | - | ### 4.7 UartDynamicConfig对象配置介绍 此对象用于配置支持动态配置的串口参数。 | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **SysComId** | `U8` | ✗ | false | 支持动态配置的输入端口Id, Uart:0~15,Port:16~31 | - | | **RawConfigData** | `U64` | ✗ | false | 从cpld获取到的原始串口配置数据 | `0` | | **BaudRate** | `U32` | ✗ | false | 从cpld获取到的串口波特率配置 | `115200` | | **DataBit** | `U8` | ✗ | false | 从cpld获取到的串口数据位长配置 | `8` | | **ParityBit** | `U8` | ✗ | false | 从cpld获取到的串口校验开关配置 | `78` | | **StopBit** | `U8` | ✗ | false | 从cpld获取到的串口停止位配置 | `1` | | **FlowControl** | `U8` | ✗ | false | 从cpld获取到的串口控制流配置 | `0` | ### 4.8 NandFlashRecord对象配置介绍 此对象用于记录NAND Flash的历史数据,表类型为PoweroffPer。 | 属性名 | 数据类型 | 只读 | emitsChangedSignal | 描述 | 示例值 | | --- | --- | --- | --- | --- | --- | | **RecordId** | `U32` | ✓ | false | 记录ID(主键) | - | | **Time** | `U32` | ✓ | false | 该条数据记录时的时间戳 | - | | **WriteAmount** | `String` | ✓ | false | nandflash写入量 | - | | **RemainingLife** | `U32` | ✓ | false | nandflash剩余寿命 | - | | **ReservedBlocks** | `S32` | ✓ | false | 剩余预留块 | - | | **BadBlocks** | `S32` | ✓ | false | 坏块数量 | - | | **EraseCount** | `S32` | ✓ | false | 擦除次数 | - | ## 5. 日志说明 ### 5.1 一键日志收集 | 文件路径 | 内容说明 | | :--- | :--- | | dump_info/AppDump/bmc_soc/nandflash_info.txt | 记录NAND Flash信息,包括NAND Flash写入量、剩余寿命、剩余预留块、坏块历史数据记录等 | ### 5.2 关键日志信息 | 日志片段 | 日志级别 | 含义解读 | 建议处理动作 | | :--- | :--- | :--- | :--- | | download failed, the sol is disabled | ERROR | SOL未使能 | 确保SOL使能后再收集串口日志 | | bmc_soc start failed, err: %s | ERROR | bmc_soc组件服务没起来 | 根据具体的报错信息定位失败原因 | ## 6. 问题定界指南 ### 6.1 典型问题定界 | 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 | | :--- | :--- | :--- | :--- | | | | | | ### 6.2 调试方法 #### 开启调试日志 **busctl资源协作接口方法调试见文档第二章节** **查看串口连接** ```bash ipmcget -d serialdir ``` **切换串口** ```bash ipmcset -d serialdir -v Usage: ipmcset -d serialdir -v