之前幾篇有關 2220 驅動程式的相關發文:
- 在 Fedora 安裝 HighPoint RocketRAID 的驅動程式
- 安裝 HighPoint RocketRAID 2220 的 Kernel 3.8 驅動程式
- 安裝 HighPoint RocketRAID 2220 的 Kernel 3.9 驅動程式
最近發現在網路上發現了高手修改的例子,它是給 2320 用的,既然有得參考,修改起來將事半功倍,就試試看吧!
本文內容將包含:驅動程式原始碼的修改、Fedora 18 首次安裝、核心更新後驅動程式的編譯三大部份。
一、安裝前的準備工作
從官方網站下載原始碼(在各型號的『驅動程式下載』中,標示為『Linux Opensource』),編譯時並不需要 root 權限,用一般用戶帳號即可。下載後解壓縮,以 R2220 為例,[SiB@Celeron-D ~]$ tar zxf rr222x-linux-src-v1.9-090924-1445.tar.gz會在 SiB 的家目錄下產生一個新目錄『 ~/rr222x-linux-src-v1.9 』(註:後續文章以『原始碼目錄』稱之),參考 Nagilum 的「修補檔」,這是 RocketRAID 2320 的「修補檔」不能直接用來修改 RocketRAID 2220,筆者參考後,再修改 RocketRAID 2220 所用的原始碼。
為留存完整記錄,將修改處整理在後,避免將來網路下載不到修補檔。整理出的修改如下:(以 RocketRAID 2220 為例)
目錄 | 檔案名 | 修改處的列號(反序列出) |
---|---|---|
原始碼目錄/inc/linux/ | Makefile.def | 77~89 |
原始碼目錄/osm/linux/ | install.sh | 13~16 |
原始碼目錄/osm/linux/ | os_linux.c | 262~266, 210~211, 199~204 |
原始碼目錄/osm/linux/ | osm_linux.h | 11~13 |
原始碼目錄/osm/linux/ | osm_linux.c | 2100~2105, 1793~1801, 1411, 878, 477~481, 447~452 |
⑴ 檔案『原始碼目錄/inc/linux/Makefile.def』的修改
第 77 ~ 89 列,原文KERNEL_VER := 2.$(shell expr `grep LINUX_VERSION_CODE $(KERNELDIR)/include/linux/version.h | cut -d\ -f3` / 256 % 256) ifeq ($(KERNEL_VER),) $(error Cannot find kernel version. Check $(KERNELDIR)/include/linux/version.h.) endif ifneq ($(KERNEL_VER), 2.6) ifneq ($(KERNEL_VER), 2.4) $(error Only kernel 2.4/2.6 is supported but you use $(KERNEL_VER)) endif endif ifeq ($(KERNEL_VER), 2.6)修改為
VERS_HDR :=$(shell ls $(KERNELDIR)/include/linux/version.h $(KERNELDIR)/include/generated/uapi/linux/version.h 2>/dev/null|head -1) KERNEL_VER := $(shell expr `grep LINUX_VERSION_CODE $(VERS_HDR)| cut -d\ -f3` / 256 / 256).$(shell expr `grep LINUX_VERSION_CODE $(VERS_HDR) | cut -d\ -f3` / 256 % 256) ifeq ($(KERNEL_VER),) $(error Cannot find kernel version. Check $(VERS_HDR).) endif KERNTWOFOUR := $(shell expr $(KERNEL_VER) \>= 2.4) KERNTWOSIX := $(shell expr $(KERNEL_VER) \>= 2.6) ifeq ($(KERNTWOFOUR), 1) else $(error Only kernel 2.4/2.6/3.x is supported but you use $(KERNEL_VER)) endif ifeq ($(KERNTWOSIX), 1)完成以上修改後,存檔備用。
⑵ 檔案『原始碼目錄/osm/linux/install.sh』的修改
第 13 ~ 16 列,原文2.6 ) OBJ=ko MODVER=`modinfo -F vermagic ${PWD}/${TARGETNAME}.${OBJ} | cut -d' ' -f1` ;;修改為
2.6 ) OBJ=ko MODVER=`modinfo -F vermagic ${PWD}/${TARGETNAME}.${OBJ} | cut -d' ' -f1` ;; 3.* ) OBJ=ko MODVER=`modinfo -F vermagic ${PWD}/${TARGETNAME}.${OBJ} | cut -d' ' -f1` ;;完成以上修改後,存檔備用。
檔案『原始碼目錄/osm/linux/os_linux.c』的修改(由後而前)
第 262 ~ 266 列,原文#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) blkdev_get(bdev, FMODE_READ) #else blkdev_get(bdev, FMODE_READ, 0 __BDEV_RAW) #endif修改為
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) blkdev_get(bdev, FMODE_READ, NULL) #else blkdev_get(bdev, FMODE_READ) #endif #else blkdev_get(bdev, FMODE_READ, 0 __BDEV_RAW) #endif第 210 ~ 211 列,原文
if ((HPT_UPTR)ptr >= (HPT_UPTR)high_memory) kunmap_atomic(ptr, HPT_KMAP_TYPE);修改為
if ((HPT_UPTR)ptr >= (HPT_UPTR)high_memory) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) kunmap_atomic(ptr); #else kunmap_atomic(ptr, HPT_KMAP_TYPE); #endif第 199 ~ 204 列,原文
if (page) return (PageHighMem(page)? (char *)kmap_atomic(page, HPT_KMAP_TYPE) : (char *)page_address(page)) + (psg->addr.bus & 0xffffffff); else修改為
if (page) return (PageHighMem(page)? #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) (char *)kmap_atomic(page) : #else (char *)kmap_atomic(page, HPT_KMAP_TYPE) : #endif (char *)page_address(page)) + (psg->addr.bus & 0xffffffff); else完成以上修改後,存檔備用。
檔案『原始碼目錄/osm/linux/osm_linux.h』的修改
第 11 ~ 13 列,原文,將這幾列文字刪除#ifndef AUTOCONF_INCLUDED #include <linux/config.h> #endif或註解掉
//#ifndef AUTOCONF_INCLUDED //#include <linux/config.h> //#endif完成以上修改後,存檔備用。
檔案『原始碼目錄/osm/linux/osm_linux.c』的修改(由後而前)
第 2100 ~ 2105 列,原文#else /* 2.6.x */ proc_name: driver_name, proc_info: hpt_proc_info26, max_sectors: 128, #endif this_id: -1修改為
#else /* 2.6.x */ proc_name: driver_name, #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) /* 3.10.x */ proc_info: hpt_proc_info26, #else write_info: hpt_proc_info26, #endif max_sectors: 128, #endif this_id: -1第 1793 ~ 1801 列,原文
static int hpt_proc_info26(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) { if (inout) return hpt_proc_set_info(host, buffer, length); else return hpt_proc_get_info(host, buffer, start, offset, length); }修改為
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) static int hpt_proc_info26(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) { if (inout) return hpt_proc_set_info(host, buffer, length); else return hpt_proc_get_info(host, buffer, start, offset, length); } #else static int hpt_proc_info26(struct Scsi_Host *host, char *buffer, int length) { return hpt_proc_set_info(host, buffer, length); } #endif第 1411 列,原文為空白列,在這裏要加入這 5 列文字
#ifdef DEF_SCSI_QCMD DEF_SCSI_QCMD(hpt_queuecommand) #else #define hpt_queuecommand hpt_queuecommand_lck #endif第 878 列,原文
static int hpt_queuecommand (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))修改為
static int hpt_queuecommand_lck (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))第 477 ~ 481 列,原文
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) struct scatterlist *sg; sg = scsi_sglist(cmd); kunmap_atomic((char *)buf - sg->offset, HPT_KMAP_TYPE); #else修改為
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) struct scatterlist *sg; sg = scsi_sglist(cmd); /* 1-argument form of k[un]map_atomic was introduced in 2.6.37-rc1; 2-argument form was deprecated in 3.4-rc1 */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) kunmap_atomic((char *)buf - sg->offset); #else kunmap_atomic((char *)buf - sg->offset, HPT_KMAP_TYPE); #endif #else第 447 ~ 452 列,原文
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) struct scatterlist *sg; sg = scsi_sglist(cmd); *pbuf = kmap_atomic(HPT_SG_PAGE(sg), HPT_KMAP_TYPE) + sg->offset; buflen = sg->length; #else修改為
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) struct scatterlist *sg; sg = scsi_sglist(cmd); /* 1-argument form of k[un]map_atomic was introduced in 2.6.37-rc1; 2-argument form was deprecated in 3.4-rc1 */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) *pbuf = kmap_atomic(HPT_SG_PAGE(sg)) + sg->offset; #else *pbuf = kmap_atomic(HPT_SG_PAGE(sg), HPT_KMAP_TYPE) + sg->offset; #endif buflen = sg->length; #else完成以上修改後,存檔備用。
編譯「驅動程式的核心模組」
以編譯 kernel 3.6.10-4 (註:Fedora 18 初始安裝的核心版本)為例,編譯的命令為[SiB@Celeron-D ~]$ cd ~/rr222x-linux-src-v1.9/product/rr2220/linux/ [SiB@Celeron-D linux]$ make KERNELDIR=/lib/modules/3.6.10-4.fc18.i686/build/ KERNEL_VER=3.6就可以在 ~/rr222x-linux-src-v1.9/product/rr2220/linux/ 這個目錄得到一個 hptmv6.ko 的『驅動程式核心模組』。相關的詳細操作,請參考以前的發文:
如果是要編譯用來安裝 Fedora 18 之用,就要用另一台電腦或虛擬機器編譯這個「核心模組」。本文以『整個 Fedora 系統都安裝在 RocketRAID 2220 的硬碟組』為主,故編譯好的『核心模組』複製到以 “適用 Fedora 18 的「可選版本 USB 安裝隨身碟」”製做成的 USB 隨身碟中的 FedoraUISO 根目錄中,待會安裝時要使用。
註:如果是將 RAID 做為資料碟而非系統碟,整個操作會更簡單。
二、開始安裝
插入『Fedora 18 的可選版本 USB 安裝隨身碟』,設定 BIOS 由 USB 啟動。在『開機選單倒數計時』結束前,在『Install Fedora』選項按【Tab】鍵,在啟動命令列最後,加入參數『modprobe.blacklist=sata_mv』抑制 stat_mv 這個驅動程式的載入(註:這個 Linux 偵測到的硬體,若載入它則系統會無『硬體加速的 RAID』之功能,只有多幾個硬碟而已 )。接著,在『安裝語言選擇』視窗出現時,先暫停一下,
載入驅動程式的「核心模組」
為載入 RocketRAID 的正確「核心模組」,要同時按下 [Alt]-[Ctrl]-[F2] 三個鍵,切換到「主控台(Console)」,將隨身碟掛載到一個臨時性目錄,用命令『modprobe hptmv6』或『insmod hptmv6.ko』將核心模組載入。
mkdir /tmp/dd若成功載入,當切換到第四「終端機」(同時按 [Alt]-[Ctrl]-[F4] 可切換過去)時,可以看到系統偵測到 RocketRAID 的訊息。
mount /dev/sda2 /tmp/dd
insmod /tmp/dd/hptmv6.ko
同時按 [Alt]-[Ctrl]-[F6] 三個鍵,將畫面切換回原安裝圖形畫面,選「中文(臺灣)」,除安裝時為中文介面外,安裝後整個系統也是中文。接著,按【Next】鈕繼續平常的安裝步驟。
註:上例是筆者安裝時,Fedora 系統所偵測到的 USB 隨身碟編號(/dev/sdx 表示第 x 個硬碟,而 2 是第二個分割區),讀者如果在 mount 命令執行後,用『ls /tmp/dd』看不到 hptmv6.ko 這個核心模組,就要換個硬碟編號試試。
三、安裝好 Fedora 後,重新開機之前的操作
安裝好 Fedora 後,重新開機之前- 當 Fedora 系統安裝完後,在重開機前會停在一個有【重新開機】或【Reboot】按鈕的畫面。別急著按下去!
- 同時按【Alt + Ctrl + F2】三個鍵,切換至「終端機」,開始接下來安裝驅動程式的核心模組的操作。
- 待會要切換到新系統做些操作,要先複製隨身碟中的驅動程式之核心模組到新系統的 tmp 目錄中,以方便切換根目錄後還能找到這個核心模組。
[anaconda root@localhost ~]# cp hptmv6.ko /mnt/sysimage/tmp/
其中『 /mnt/sysimage/ 』是新安裝作業系統的根目錄,而『 /mnt/sysimage/tmp/ 』則是新系統的命令中的暫時目錄 /tmp。hptmv6.ko 是 RR2220 的核心模組。
- 這個操作有些複雜,請小心操作。新安裝的系統的根目錄在『 /mnt/sysimage 』,因為驅動程式是要裝在新系統上,所以要將目前檔案的根目錄切換過去,
[anaconda root@localhost ~]# chroot /mnt/sysimage/
接下來的操作,就會作用在新系統上。 - 抑制系統載入程式使用『 sata_mv.ko 』這個模組,它會測試到 RocketRAID 所用的晶片,並載入系統執行,但是又不支援 RocketRAID 的 RAID 功能,導致其不能正常運作。要抑制『 sata_mv.ko 』這個模組的載入,有兩個作法:
[anaconda root@localhost ~]# echo "blacklist sata_mv" >> /etc/modprobe.d/blacklist.conf
將『 sata_mv.ko 』列入開機載入模組的測試「黑名單」。或是直接刪除『 sata_mv.ko 』這個模組,[anaconda root@localhost ~]# rm -f /lib/modules/3.6.10-4.fc18.x86_64/kernel/drivers/ata/sata_mv.ko
其中,3.6.10-4.fc18.x86_64 是 Fedora 18 DVD 中 Linux 核心的編號。
注意:如果用直接刪除,則每次更新 Linux 核心後,都要刪除一次。 - 複製暫時目錄 /tmp 中的驅動程式核心模組到新系統的驅動程式目錄中
[anaconda root@localhost ~]# cp /tmp/hptmv6.ko /lib/modules/3.6.10-4.fc18.x86_64/kernel/drivers/ata/
命令中的 hptmv6.ko 是 RR2220 的核心模組。 - 準備建立開機載入 ramdisk 的映像檔,先檢查各模組的相依性,
[anaconda root@localhost ~]# depmod -a 3.6.10-4.fc18.x86_64
做為重新建立開機載入 ramdisk 的映像檔之用。 - 接著,建立載入 ramdisk 的映像檔的命令為
[anaconda root@localhost ~]# dracut --add-drivers hptmv6 --omit-drivers sata_mv /boot/initramfs-3.6.10-4.fc18.x86_64.img 3.6.10-4.fc18.x86_64
命令中的 hptmv6.ko 是 RR2220 的核心模組,而『--omit-drivers sata_mv』這個參數要強制令 dracut 不將 stat_mv 置入 ramdisk。
注意二:如果忘了加『--omit-drivers sata_mv』這個參數,就要在系統的啟動命令(在 /boot/grub2/grub.conf 中)加上『modprobe.blacklist=sata_mv』。
切換回原安裝過程,進行最後的安裝操作
- 在「終端機」中鍵入命令『 exit 』,將根目錄切換回原安裝過程。
注意:如果不能確定自已目前的根目錄在哪個系統,可以用命令『 ls /mnt 』測試一下,如果有其它目錄在其下,這時你應該已經回到『原安裝過程』中;如果沒有任何目錄,那就是還在『新系統」中。
- 同時按【Alt + Ctrl + F6】三個鍵,將畫面切換回原安裝圖形畫面,按【重新開機】或【Reboot】按鈕繼續安裝步驟,應該是重新開機了。
- 重新開機後,依一般安裝過程設定,可以先使用新系統,不要急著更新,看完下一段文章後,再進行更新。
五、舊系統或系統更新後,加裝驅動程式的核心模組
因為驅動程式的核心模組是用 HighPoint 提供的「開源碼驅動程式」編譯而得,因此每次只要 Linux 核心更新,這個核心模組就要再編譯一次。所幸,Linux 核心更新後,編譯驅動程式核心模組的過程比較簡單。假定更新後的 Linux 核心為 3.11.10-101.fc18.x86_64,而從 HighPoint 下載的「開源碼驅動程式」,將其解壓縮後的目錄在 root 之下,則所需的命令如下:
[root@Celeron-D ~]# cd ~/rr222x-linux-src-v1.9/product/rr2220/linux/ [root@Celeron-D linux]# make KERNELDIR=/lib/modules/3.11.10-101.fc18.x86_64/build/ KERNEL_VER=2.6 [root@Celeron-D linux]# cp hptmv6.ko /lib/modules/3.11.10-101.fc18.x86_64/kernel/drivers/ata/ [root@Celeron-D linux]# depmod -a 3.11.10-101.fc18.x86_64 [root@Celeron-D linux]# mv /boot/initramfs-3.11.10-101.fc18.x86_64.img /boot/initramfs-3.11.10-101.fc18.x86_64.img.save [root@Celeron-D linux]# dracut --add-drivers hptmv6 --omit-drivers sata_mv /boot/initramfs-3.11.10-101.fc18.x86_64.img 3.11.10-101.fc18.x86_64其中,『 mv ... 』那一列命令是將原來之映像檔換個檔名,做個備份。其他命令與文章前段相同,請參考前面說明。做個『懶人包』方便讀者剪貼使用:
cd ~/rr222x-linux-src-v1.9/product/rr2220/linux/ make KERNELDIR=/lib/modules/3.11.10-101.fc18.x86_64/build/ KERNEL_VER=2.6 cp hptmv6.ko /lib/modules/3.11.10-101.fc18.x86_64/kernel/drivers/ata/ depmod -a 3.11.10-101.fc18.x86_64 mv /boot/initramfs-3.11.10-101.fc18.x86_64.img /boot/initramfs-3.11.10-101.fc18.x86_64.img.save dracut --add-drivers hptmv6 --omit-drivers sata_mv /boot/initramfs-3.11.10-101.fc18.x86_64.img 3.11.10-101.fc18.x86_64接著,就可以重新開機,測試新系統了。
六、其它安裝時的經驗
如果整個 RAID 硬碟模組的總容量大於 2TB 以上,用一般的 MBR 分割硬碟會失敗,或效能變得很差。而 Fedora 18 在安裝時,用 GPT 分割碟碟又不太方便,有些網路的解決辦法是先用別的將 RAID 碟碟模組掛到別的系統去分割。筆者也有試過,試了幾次都沒安裝成功,最後用了一個比較偷懶的辦法。這個辦法就是:在安裝 Fedora 18 時,在分割硬碟這個步驟時,使用系統『自動分割碟碟』功能。這個功能會將硬碟分割為:『/boot』:500MB,『swap』:約是記憶體的兩倍(當記憶體超過 4GB 以上時,會降低倍數),『/root」:50GB,而其它容量全部切到『/home』這個分割。反正安裝時的分割又不常做,而且 Linux 系統的『/root』分割如果不足,可以將某些目錄用『鏈結(link)』的方式使用『/home』這個分割的空間。
七、待改進之處
這個修改步驟,只能令 RocketRAID 2220 版的驅動程式能啟用 RAID 加速功能,而 RocketRAID 2220 的管理程式(包含『命令列介面』版),都無法正確偵測到 RAID 卡資訊,也就不能管理了。
筆者的做法是保留 kernel 3.9.11-200,當要執行管理功能(硬碟檢測、更換硬碟等)時,在開機時選用 3.9 這一版本;而其它用途時,則使用最新版本的 Linux 核心。
已測試版本:
- Fedora: 18 (kernel 3.11.10-101)
- HighPoint RocketRAID: 2220
沒有留言:
張貼留言
感謝你耐心看完本文,歡迎留下任何指正、建議,筆者會儘快回應。(English is also welcome.)