龙芯3A使用qemu运行MegaCli配置raid卡

		                                     raid卡功能配置(完善中)
问题如下:
在龙芯3a双路板子上无法支持raid卡的配置,即无法在开机启动的时候像x86下机器那样,通过按ctrl+H来配置LSI raid卡的level(只要求raid0,raid1)。(同时raid卡可以通过在x86下配置好后,拿到3a板子上使用,在pmon下使用pciscan可以看到raid卡的mem,io空间等信息)。

思路:
解决方案1,通过在pmon中加入适当的代码来配置。

首先,通过学习pci规范,和学习pmon源码。确定pmon在开机的时候可以将raid卡插入设备链表,并且能将raid的mem映射空间地址(通过PCI_allocate_mem函数分配)写入raid卡扩展rom基址寄存器中(在_pci_query_dev_func函数的最后,有reg=PCI_MAPREG_ROM,只有当扩展rom基址寄存器中有硬件接地的情况,即有mask!=0&&mask != 0xffffffff时,有pm->reg=reg。这样便可通过pm->reg=10或者30来区分pci设备有无扩展rom)。
有了以上基础之后,通过设置一个全局变量,如struct pci_dev* raid_dev来接受raid卡的设备信息。
(pci_dev结构体有pmon获得的设备的所有信息。)这样通过raid_dev就可获得raid卡的mem空间地址,也就可以通过memcpy函数将扩展rom的代码拷贝到内存中。接着在扩展rom的头中有一条jmp指令,这样就可以执行代码了。
同时也通过ioctl函数加入了按r键来执行raid rom的拷贝。(就像window下开机时按某个键后,才能设置bios,不按就不设置)
不过问题是代码是x86的二进制文件无法直接执行。于是想通过参考vga的代码来解决这个问题。因为,显卡是emulate的,也是通过二进制翻译来执行的。emu的代码很多,其中最核心的是X86EMU_exec中的op1=(*sys_rdb)(((u32)M.86.R_CS<<4)+(M.86.R_IP++));和(*86emu_op+ab[op1])(op1);。但是pmon中定义了很多的结构体来模拟x86下的寄存器,他们的初值问题很不好解决。而且通过解释执行的代码,要是遇到了问题,很难调试,所以这条路基本就很难实现了。

解决方案2,通过qemu运行MegaCli来配置raid卡。
主题思想:
LSIMegaRAID卡在Linux命令行有配置工具,可在网上下载。在龙芯服务器上启动最小Linux系统,跑个qemu,然后在qemu环境下跑LSI RIAD卡在Linux命令行上的工具。

背景介绍:

qemu是一款可以跨平台执行的虚拟机,而且可以通过用户模式执行其他平台的程序。利用它这种特性,可以尝试在龙芯平台上运行X86的可执行程序,比如,MegaCLI(RAID卡配置工具),以实现龙芯平台上RAID配置的功能。
qemu的源码可以从网上下载,比如http://wiki.qemu.org/download/qemu-0.15.1.tar.gz。
在编译qemu之前,需要安装几个库文件,操作如下(这里使用的是debian系统):
1 apt-get update
2 apt-get install libsdl1.2-dev
3 apt-get install zlib1g-dev zlib1g-dbg libesd0-dev
具体的编译方法如下:
1 在3a双路启动系统后,将源码包解压: tar -xzf qemu-0.15.1.tar.gz
2 解压完会生成qemu-0.15.1文件夹,进到这个文件夹: cd qemu-0.15.1
3 如果清楚配置选项和编译的目标,可以在执行配置文件时指定变量。但是我不清楚,所以就按照默认配置的来编译了(默认的配置会编译所有支持的目标系统): ./configure
4 配置文件执行完,就可以编译安装了:make
make install
qemu分userspace和system两种模式。system模式是对操作系统全系统的模拟(包括对底层硬件的模拟),由于底层硬件是模拟的,所以在system态的qemu里看不到需要配置的raid卡。userspace模式相当于只是对二进制程序做一个二进制翻译(具体原理不是很清楚),所以理论上用它来翻译MegaCli是可行的。安装完成之后,qemu用户态的可执行程序在/usr/local/bin/下。

MegaCli是在系统下配置LSI MegaRAID卡的工具,LSI官网上支持rpm包下载,没有deb的包,所以在debian系列上安装需要借用alien这个工具,具体用法:
1. alien -d xxx.rpm生成xxx.deb
2. dpkg -i xxx.deb
这样就安装好了,MegaCli在linux环境下有两个rpm包需要安装,一个是库,一个是具体的软件,安装包可以在以下连接下载:http://www.lsi.com/Pages/user/eula.aspx?file=http%3a%2f%2fwww.lsi.com%2fdownloads%2fPublic%2fMegaRAID%2520Common%2520Files%2f8.00.40_Linux_MegaCLI.zip&Source=http%3a%2f%2fwww.lsi.com%2fsupport%2fproducts%2fPages%2fMegaRAID%2520SAS%25208708EM2.aspx(点击accept即可下载)
该软件会被安装在/opt/MegaRAID/MegaCli/下面,有两个可执行文件,一个是32位的一个是64为的。
MegaCli具体使用:
查看物理盘信息
./MegCli -PDList -aALL
查看缓存策略
./MegCli -GetProp -Cache -L0 -a0
添加raid阵列
./MegCli -CfgLdAdd -r0/-r1/-r5 [E:S,E:S...] WB Direct -a0
其中r0 r1 r5等是指的raid级别,中括号里面的是设备号和和槽号,用查看物理盘信息后可看到该信息。
删除raid阵列
./MegCli -CfgLdDel -L0 -a0
P.S. -a0的意义是新添加的物理盘会自动处于重建状态。
qemu的usr模式运行程序命令格式为:qemu-arch -L / /path
其中arch为架构名称,path是可执行程序的路径,如qemu-i386 -L /...path/programname。

解决问题过程:
1,首先在x86机器上使用qemu模拟x86体系结构运行MegaCli程序,这样可以知道qemu是否可以完整的支持MegeCli。在执行的时候报不支持系统调用240的错误。
解决方法:在qemu的configure里面在i386-linux-user里面加入NPTL支持;
即在
3193 case "$target_arch2" in
3194   i386)
3195     target_phys_bits=64
3196   ;;
中加入target_nptl="yes"即可。
改写后编译会有warnning,可以在qemu源文件的linux-user/syscall.c两个NPTL宏定义下把cpu_set_tls函数注释掉,这样就不会有warnning了。

2,将问题1解决后,用qemu运行MegaCli还是有bug,例如:
Unsupported ioctl:cmd=0xc1144d01
cmd是函数int ioctl(int fd, int cmd, …);的第二个参数,即用户程序对设备的控制命令。出现这种情况是MegaCli需要调用linux内核的此命令,但是qemu里缺乏对此调用的接口,故需在qemu中增加此接口。如c1144d01号命令在内核下的宏定义在drivers/scsi/megaraid/megaraidsas.h下,名为MEGASAS_IOC_FIRMWARE32。故需在qemu下linux-user/ioctl.h下加入
349   IOCTL(MEGASAS_IOC_FIRMWARE32, 0, TYPE_INT)
在linux-user/syscall_defs.h下加入
 750 #define TARGET_SIOCATMARK      0x8905
 751 
 752 #define TARGET_MEGASAS_IOC_FIRMWARE32 0xc1144d01    //added
 753 #define MEGASAS_IOC_FIRMWARE32 0xc1144d01                  //added 
 754 /* Networking ioctls */
 755 #define TARGET_SIOCADDRT       0x890B      /* add routing table entry */

这样此调用才可被qemu传递给内核。诸如此类缺乏的 cmd都通过此法加入到qemu。
总结一下第二步所要加的代码为:
linux-user/ioctl.h中加
349 /* LSI Mega RAID Support */
350   IOCTL(MEGASAS_IOC_FIRMWARE32, 0, TYPE_INT)
351   IOCTL(LINUX_SG_GET_VERSION_NUM, 0, TYPE_INT)
352   IOCTL(LINUX_SG_IO, 0, TYPE_INT)
inux-user/syscall_defs.h下加
752 /* LSI Mega RAID ioctls */
 753 #define TARGET_MEGASAS_IOC_FIRMWARE32      0xc1144d01
 754 #define MEGASAS_IOC_FIRMWARE32             0xc1144d01
 755 #define TARGET_LINUX_SG_GET_VERSION_NUM    0x2282
 756 #define LINUX_SG_GET_VERSION_NUM           0x2282
 757 #define TARGET_LINUX_SG_IO                 0x2285
 758 #define LINUX_SG_IO                        0x2285




3,将x86下qemu的代码加好后,就可在龙芯上编译一个qemu,再将x86下对qemu的修改移到mips的qemu下。移好后,通过qemu运行MegaCli,可以看到mips下缺很多的库,对于这些缺的库,可以有针对性地将x86下的库移到mips下即可。



补充:


针对硬盘掉电或者配置信息发生错误时无法配置RAID卡的解决办法:
如果RAID卡在正常工作的时候硬盘掉了或者配置信息发生错误,那么RAID卡蜂鸣器会间歇鸣叫,这时候在使用MegaCli如下命令可修复
qemu-i386 /opt/MegaRAID/MegaCli/MegaCli -CfgClr -aALL
qemu-i386 /opt/MegaRAID/MegaCli/MegaCli -CfgForeign -Clear -aALL
其中第一个命令是清除RAID卡配置信息,第二个是清除外部配置信息可能是硬盘内信息(猜测...)
修复后我们再使用添加RAID阵列命令即可恢复硬盘掉电之前的状态(注意!一定要添加和之前RAID级别相同的RAID级别),命令参考:
qemu-i386 /opt/MegaRAID/MegaCli/MegaCli -CfgLdAdd -r0 [252:0,252:1] WB -Direct -a0
MegaCli 常用命令list:

一、查看类
1 ./MegaCli -Cfgdsply -aALL 查看配置信息(RAID卡型号、RAID设置、DISK相关)
1 ./MegaCli -AdpCount 查看适配器个数
2 ./MegaCli -AdpGetTime 查看适配器时间
3 ./MegaCli -AdpAllInfo 查看所有适配器信息
4 ./MegaCli -LDList -aALL 查看所有逻辑盘组信息
5 ./MegaCli -PDList -aALL 查看所有物理盘信息
6 ./MegaCli -LDInfo -Lall -aALL 查看逻辑盘组RAID级别
7 ./MegaCli -LDGetProp -Cache -Lall -aALL 查看逻辑盘组缓存策略
8 ./MegaCli -LDInit -ShowProg -Lall -aALL 查看磁盘重建状态进度

二、控制类
1 ./MegaCli -LDSetProp arg -L0 -a0 添加缓存策略
        arg:
                WT    (Write through
                WB    (Write back)
                NORA  (No read ahead)
                RA    (Read ahead)
                ADRA  (Adaptive read ahead)
        可以或起来组成该参数。
2 ./MegaCli -CfgLdAdd -rN [E:S,E:S...] WB direct -a0 添加RAID阵列
        E:用PDList查看物理盘信息里面的设备号。
        S:同E,但是S是槽号
        N:RAID级别,可以是0、1、5、10等。
        a0:意义是新添加的物理盘会自动处于重建状态
3 ./MegaCli -CfgLdDel -L0 -a0 删除逻辑磁盘组0,也可以是1,当然对应L1
4 ./MegaCli -PDOffline -PhysDrv [E:S] -a0 指定S盘下线
5 ./MegaCli -PDOnline -PhysDrv [E:S] -a0 指定S盘上线
6 ./MegaCli -CfgRecon -Start -r5 Add -PhysDrv[E:S] -L0 -a0 在线重建逻辑磁盘组0,RAID级别5,添加物理盘号由E和S组成。添加完毕后会自动重建磁盘
7 ./MegaCli -PDHSP -Set[-Enclaffinity] [-nonRevertible] -PhysDrv[E:S] -a0 指定S号设备为全局热备份设备
8 ./MegaCli -PDHSP -Rmv -PhysDrv[E:S] -a0 删除S号设备全局热备份设备
9 ./MegaCli -CfgClr -aALL 删除RAID卡相关配置信息
10 ./MegaCli -CfgForeign -Clear -aALL 删除外围设备配置信息

三、BBU(Battery Backup Unit)类:
1 ./MegaCli -AdpBbuCmd -GetBbuStatus -aALL |grep ‘Charger Status’ 查看充电状态
2 ./MegaCli -AdpBbuCmd -GetBbuStatus -aALL 查看BBU状态信息
3 ./MegaCli -AdpBbuCmd -GetBbuCapacityInfo -aALL 查看BBU容量信息
4 ./MegaCli -AdpBbuCmd -GetBbuDesignInfo -aALL 查看BBU设计参数
5 ./MegaCli -AdpBbuCmd -GetBbuProperties -aALL 查看当前BBU属性

你可能感兴趣的:(qemu)