智能平台管理接口 (IPMI) 是一种开放标准的硬件管理接口规格,定义了嵌入式管理子系统进行通信的特定方法。IPMI 信息通过基板管理控制器 (BMC)(位于 IPMI 规格的硬件组件上)进行交流。使用低级硬件智能管理而不使用操作系统进行管理,具有两个主要优点: 首先,此配置允许进行带外服务器管理;其次,操作系统不必负担传输系统状态数据的任务。
ipmi在linux下的实现由几个模块组成:ipmi_msghandler,ipmi_devintf,ipmi_serial,ipmi_serial_codec*这几个模块分别负责不同的功能,它们互相协作完成ipmi的功能。其中ipmi serial被移除了linux内核,原因在linux的文档中关于ipmi serial串口驱动中有所描述。但是在社区中仍有对它的支持。

一、ipmi_msghandler

该模块是ipmi消息处理的核心,它不依赖于其它模块,但是它也需要调用其它模块的接口。为了实现这一点,它了解所有的IPMI的核心数据结构,它所需要调用的其它模块的函数接口都通过数据结构中的指针来实现。因此可以这么说,该模块对外提供了接口,当其它模块需要该模块提供服务时就直接调用其提供的接口,而当该模块需要其他模块的服务时,就通过相应数据结构中的指针来实现。该模块维护了一个链表ipmi_interfaces,它包括了所有的ipmi接口。IPMI所涉及到的核心数据结构的关系如图:

1.初始化/卸载

该模块的初始化相对比较简单,主要完成了
  • 注册驱动
  • 创建proc文件
  • 启动定时器ipmi_timer
  • 注册到panic_block上
该模块的卸载也相对比较简单,就是初始化的逆过程

2.定时器处理

该模块包括了一个定时器,它的处理函数中会重新启动自己,因此它是一个定时到期的定时器。它完成的功能包括:
  • 每超时IPMI_REQUEST_EV_TIME次就调用一次ipmi_request_event,该函数最终会为每一个不工作在maintenance模式的并且在ipmi_interfaces链表中的接口调用一次它的request_events。
  • 调用ipmi_timeout_handler,该函数会遍历所有的在ipmi_interfaces链表的接口,并且:
    • 对在接口的waiting_msgs链表中的消息调用handle_new_recv_msg处理消息
    • 对在接口的seq_table中的消息进行检查处理
    • 进行maintenance模式的处理

3.与上层以及下层的接口

该模块是ipmi消息处理的核心,它与上层,即直接用用户空间交互的模块已经下层即和真正的驱动交互的模块都有接口。
  • 与上层的接口:该模块提供了ipmi_create_user来让上层创建一个user,同时要求上层提供与该user相关的struct ipmi_user_hndl,当本模块需要向该user提交信息时,就通过该结构中的指针来完成。
  • 和下层的接口:该模块提供了ipmi_register_smi来让下层注册一个smi,同时要求注册者提供一个与该接口相关的struct ipmi_smi_handlers,当该模块需要使用下层服务时,就会使用该结构中的指针。该模块提供给下层的接口主要是ipmi_smi_msg_received
另外通过EXPORT_SYMBOL即可找到该模块对外提供的所有接口。

4.发送消息/接收消息

1).发送消息

当上层发送消息时,它们需要使用该模块提供的接口:
  • ipmi_request_settime
  • ipmi_request_supply_msgs
  • ipmi_request_with_source
来完成,这几个函数最终会调到接口的handlers->sender来把消息交给下层。

2).接收消息

当下层收到消息时,会调用ipmi_smi_msg_received来将消息提交给本模块。该函数会把消息添加到接口的waiting_msgs链表中,或者直接调用handle_new_recv_msg进行处理。handle_new_recv_msg会找到user并把消息通过与user关联的struct ipmi_user_hndl提交给用户。
需要注意的是,默认情况下只有消息会被提交给user,如果user想要接收命令,事件,就需要通过该模块提供的接口ipmi_register_for_cmd以及ipmi_set_gets_events来告诉本模块它关心这些信息。当它们不想继续接收命令,事件时就需要 通过ipmi_unregister_for_cmd以及ipmi_set_gets_events来解除这种关心。

本模块与其它模块在消息收发上的接口如图:

二、ipmi_devint

该模块用于向用户空间提供IPMI的接口。是内核和用户空间的接口。该模块依赖于模块ipmi_msghandler。

1.初始化/卸载

在模块初始化时会注册一个名字为ipmidev的字符设备,并绑定相应的文件操作ipmi_fops。同时会通过ipmi_smi_watcher_register为所有在链表ipmi_interfaces中的接口创建设备文件,创建的设备文件名为ipmi%d,其中%d为接口的编号。
卸载时会先删除所有设备文件,然后卸载字符设备ipmidev

2.和内核通信

如果想要和内核中的ipmi通信,首先需要打开一个设备文件ipmi%d。在打开设备文件时,本模块会调用ipmi_create_user创建一个user,同时向ipmi_msghandler提供一个该user接收信息的回调函数,当ipmi_msghandler向该user提交信息时会用到该回调函数。
在打开一个设备文件后,即可使用ioctl和内核通信。

3.向外提供的接口

通过文件操作提供给用户空间的接口
通过struct ipmi_user_hndl向ipmi_msghandler提供的接收消息的窗口

4.需要外部提供的接口

和接口设备文件相关的接口:
  • ipmi_smi_watcher_register
  • ipmi_smi_watcher_unregister
和user的创建和删除相关的接口:
  • ipmi_create_user
  • ipmi_destroy_user
ioctl命令相关:
  • ipmi_validate_addr验证地址
  • ipmi_addr_length获得地址长度
  • ipmi_request_settime发送requset
  • ipmi_free_recv_msg释放消息
  • ipmi_register_for_cmd注册命令,即声明自己关心这个命令
  • ipmi_unregister_for_cmd
  • ipmi_set_gets_events设置获取事件标记,并获取事件。甚至了标记则表明本user关心事件
  • ipmi_set_my_address
  • ipmi_get_my_address
  • ipmi_set_my_LUN
  • ipmi_get_my_LUN
  • ipmi_set_maintenance_mode
  • ipmi_get_maintenance_mode

5.发送/接收信息

接收信息:默认情况下,只有消息会被发送给user。这是通过和user关联的ipmi_msghandler实现的,ipmi_msghandler会调用ipmi_msghandler中的file_receive_handler,该接口的会把消息放入一个user私有的接收消息列表中。当用户发送接收消息的ioctl时,就会从该消息列表取出消息。
发送信息:用户空间发送的requset通过ioctl命令到达内核后,最终通过ipmi_request_settime发送出去。

本模块在收发消息上与其它模块的接口如图所示:

三、ipmi_serial

ipmi_serial模块是ipmi的串口驱动,用于支持使用串口和bmc通信。该模块是串口驱动的核心,当前串口驱动可以工作在三种模式,deriect,radysis_ascii,terminal。每种模式以一种ipmi_serial_codec表示。

该模块维护了两个链表,codec_list和info_list,前一种包括了当前系统中注册的模式,后一个列表包括了当前系统中所配置的ipmiserial接口。

1.初始化/卸载

初始化的动作:根据模块参数尝试调用ipmi_serial_setup_one以创建一个ipmi serial interface。在ipmi_serial_setup_one中,会:
  • 创建新的struct ipmi_serial_info结构
  • 设置ipmi_serial_info中的定时器,该定时器会在调用ipmi_register_smi时被启动
  • 解析参数并初始化infor结构
  • 如果是一个新的接口,就会被加入到info_list链表中,否则做清理工作后返回
  • 如果是一个新的接口,还会检查所指定的模式是否已经加载(即是否已存在于codec_list中),如果已经存在,则会尝试调用setup_intf创建一个接口。
setup_intf会完成最终的创建工作(部分工作是ipmi_serial_found完成的):
  • 找到实际的物理接口,即实际的serial接口,并将相关的信息传递给该serial接口,info->port->state->direct = &info->direct; 这一步很关键,serial驱动将使用这里的信息来完成信息的传递,即信息由serial驱动向ipmi serial接口的传递。
  • 调用串口的ops->startup
  • 设置serial的相关配置信息
  • 调用codec注册的init函数
  • 如果codec有注册start函数,则调用info->codec->init和info->codec->start来尝试向BMC发送一个请求,并等待响应,收到响应则表示可以工作,否则就表示不能工作;如果没有注册start函数,则认为是可以工作的。
  • 调用ipmi_register_smi注册接口到ipmi_msghandler,并提供相应的struct ipmi_smi_handlers给ipmi_msghandler使用
  • 创建相应的proc文件
卸载的工作:模块卸载时做的事情很简单,就是注册的逆过程。的ipmi_serial_cleanup_one会完成实际的接口清理工作。在命令的处理中,以及在codec的unregister中也有调用该函数。

2.定时器

每个ipmi_serial_info都包括了一个定时器,它的处理函数中会重新启动自己,因此它是一个定时到期的定时器。它完成的功能包括:
  • 增加timer_ticks计数
  • 调用timeout_handling,该函数在做了一些处理后,最终会调用start_next_msg,这是本模块的核心处理函数,无论是发送还是接收,最终都由它处理。

3.和外部的接口

本模块除了和上层(ipmi_msghandler)以及下层(所支持的codec)有接口外,还通过配置文件和用户空间有一个关键接口。

1).和用户空间的关键接口:

/sys/module/ipmi_serial/parameters/hotmod
可以通过如下命令来添加一个接口: echo add,ttyS3,38400N81r,RadisysAscii > hotmod
该命令的处理函数为hotmod_handler,它会调用ipmi_serial_setup_one或ipmi_serial_remove_one(进一步的ipmi_serial_cleanup_one)

2).和上层的接口

该模块和上层即 ipmi_msghandler的接口分为两部分:
  • 本模块提供给ipmi_msghandler的通过struct ipmi_smi_handlers提供给它
  • 本模块需要的上层接口主要包括:
    • ipmi_register_smi
    • ipmi_smi_msg_received

3).本模块和下层的接口

本模块和下层(所支持的codec)的接口也分为两部分:
  • 本模块提供给下层的接口通过EXPORT_SYMBOL即可找到
  • 下层模块提供给本模块的接口包含在struct ipmi_serial_codec中,并通过ipmi_serial_codec_register提供给本模块

4.发送消息/接收消息

1).发送消息

当上层发送消息时,它使用struct ipmi_smi_handlers中的sender(即ipmi_serial_sender)来将消息交给本模块。
这个函数通过最终会通过start_next_msg调到info->codec->send_msg将信息提交给下层。之后,该消息在被codec模块处理后又会被提交给本模块的ipmi_serial_ll_xmit,最终通过uart_direct_write发送出去

2).接收消息

当下层收到消息时,会调用ipmi_serial_ll_recv来将消息提交给本模块。这个函数最终会通过start_next_msg调到ipmi_smi_msg_received将消息提交给上层。
而serial驱动的信息则是通过info->direct中的指针进入ipmi serial的,实际上即进入到了info->codec->handle_char中。相关的代码:
ipmi_serial_setup_one: info->direct.direct_data = info;
info->direct.handle_char = ipmi_serial_handle_char;
info->direct.push = ipmi_serial_push;
setup_intf:
info->port->state->direct = &info->direct;
ipmi_serial_push:
info->codec->handle_char

本模块和其它模块在消息收发上的接口如图:

四、ipmi_serial_codec

IPMI serial支持几种codec模式,这几种模式可以理解为编解码器,发送时进行编码接收时进行解码,对于每种模式来说,它只需要将其注册到ipmi_serial并提供相应的编解码功能所需的函数指针即可。

IPMI 称为 “智能平台管理接口 IPMI 能够横跨不同的操作系统、固件和硬件平台,可以智能的监视、控制和自动回报大量服务器的运作状况,以降低服务器系统成本。 用户可以利用 IPMI 监视服务器的物理健康特征,如温度、电压、风扇工作状态、电源状态等。 IPMI 接口配置 bios配置 ipmi IPMI 接口和RJ45的网口外观上一样,一般主板上带有的 IPMI 接口会和网卡分开放置,具体区分还要看主板S pe cification, 下面红色部分的即为 IPMI 接口。 找到 IPMI 接口后,我们要接上一根网线。然后开机
智能平台管理接口( IPMI ) 是一种开放标准的硬件管理接口规格,定义了嵌入式管理子系统进行通信的特定方法。 IPMI 信息通过基板管理控制器 (BMC)(位于 IPMI 规格的硬件组件上)进行交流。 使用 低级硬件智能管理而不 使用 操作系统进行管理,具有两个主要优点:首先,此配置允许进行带外服务器管理;其次,操作系统不必负担传输系统状态数据的任务。 用户可以利用 IPMI 监视服务器的物理健康特征,如温度、
2、下载安装(源码或者R PM ) [root@example1 ~]# r pm -ivh /cdrom/Server/ Open IPMI -tools-2.0.16-5.el5.i386.r pm
Ipmi tool对搞运维的哥们儿来说是一个很不错的管理工具,既支持本地操作也支持远端操作。能够不依赖服务器的CPU,内存,存储,电源等独立工作,是一种廉价远程管理方案。借用一下官方的介绍: The service processor (or Baseboard Management Controller, BMC) is the brain behind platform managemen
IPMI 协议被广泛用于服务器监控中,包括采集CPU温度、风扇转速、主板温度,以及远程开关机等等。而且 IPMI 独立于硬件和操作系统,无论是CPU、BIOS,还是OS出现故障,都不会影响 IPMI 的工作。因为 IPMI 的硬件设备BMC(Baseboard Management Controller)是一个独立的板卡,独立供电。 使用 IPMI 监控服务器主要有两种模式:本地和远程。本地监控:需要安装: IPMI
最近淘了一块永擎ECP621D8A主板,应为有现成的bmc座子所以方便更改固件,目前bmc主要是a mi open bmc两种, open bmc代码开源可玩性更大,下面就拿该主板做研究。 先瞻仰下这强大的主板 然后下载官方的手册看下bmc部分的框图 下面就可以开始我们的工作了: 1.编译固件的方式就不在此叙述,大家可以参照骑马追风大神的文章。 2. 使用 编程器烧录并上电,和原版固件相比心跳灯不亮,网络连接路由器无法获取 ip 串口 无输出emmm&hell ip ; 3.接着翻手册发现bmc用的是 串口 1,网络芯片RTL8211E是o