linux硬碟識別過程
目錄
1. 硬碟啟動協議
2.SCSI匯流排掃描的方法
-
SCSI匯流排掃描是通過協議特定或者晶片特定的方法探測出掛接在主機介面卡後面的目標節點和邏輯單元,為它們在記憶體中構建相應的資料結構並把它們新增到系統中。
方法:
- scsi中間層以可能的ID和LUN構造INQUIRY命令,之後將這些命令提交給I/O子系統後,通過SCSI上層磁碟驅動處理生成請求,後通過SCSI中間層將請求轉換成CDB,最後呼叫SCSI底層驅動的queuecommand回撥函式實現命令傳送。
3. 核心列印資訊
-
硬碟開機.核心函式跟蹤列印資訊
ata1.
02
: SATA link down (SStatus
0
SControl
310
)
ata1.
03
: hard resetting link
ata1.
03
: SATA link down (SStatus
0
SControl
310
)
ata1.
04
: hard resetting link
ata1.
04
: SATA link down (SStatus
0
SControl
310
)
ata1.
00
: ATA-
9
: WDC WD5000LUCT-63C26Y0,
01
.01A01, max UDMA/
133
ata1.
00
:
976773168
sectors, multi
0
: LBA48 NCQ (depth
31
/
32
)
ata1.
00
: configured
for
UDMA/
133
ata1: EH complete
scsi
0
:
0
:
0
:
0
: Direct-Access ATA WDC WD5000LUCT-
6
01.0
PQ:
0
ANSI:
5
------------[ cut here ]------------
WARNING: at drivers/scsi/sd.c:
2936
sd_probe+
0x1c
/
0x378
()
Modules linked in:
CPU:
2
PID:
6
Comm: kworker/u8:
0
Not tainted
3.10
.0_hi3536 #
6
Workqueue: events_unbound async_run_entry_fn
[<80019e10>] (unwind_backtrace+
0x0
/
0xf4
) from [<80016ea4>] (show_stack+
0x10
/
0x14
)
[<80016ea4>] (show_stack+
0x10
/
0x14
) from [<8002c278>] (warn_slowpath_common+
0x54
/
0x6c
)
[<8002c278>] (warn_slowpath_common+
0x54
/
0x6c
) from [<8002c32c>] (warn_slowpath_null+
0x1c
/
0x24
)
[<8002c32c>] (warn_slowpath_null+
0x1c
/
0x24
) from [<
80338860
>] (sd_probe+
0x1c
/
0x378
)
[<
80338860
>] (sd_probe+
0x1c
/
0x378
) from [<8031a224>] (driver_probe_device+
0x78
/
0x214
)
[<8031a224>] (driver_probe_device+
0x78
/
0x214
) from [<
80318898
>] (bus_for_each_drv+
0x58
/
0x8c
)
[<
80318898
>] (bus_for_each_drv+
0x58
/
0x8c
) from [<8031a17c>] (device_attach+
0x74
/
0x88
)
[<8031a17c>] (device_attach+
0x74
/
0x88
) from [<803197a0>] (bus_probe_device+
0x84
/
0xa8
)
[<803197a0>] (bus_probe_device+
0x84
/
0xa8
) from [<80317efc>] (device_add+
0x4ec
/
0x59c
)
[<80317efc>] (device_add+
0x4ec
/
0x59c
) from [<80331f34>] (scsi_sysfs_add_sdev+
0x84
/
0x294
)
[<80331f34>] (scsi_sysfs_add_sdev+
0x84
/
0x294
) from [<803300d0>] (scsi_probe_and_add_lun+
0x8bc
/
0x98c
)
[<803300d0>] (scsi_probe_and_add_lun+
0x8bc
/
0x98c
) from [<803304a0>] (__scsi_add_device+
0xf4
/
0x104
)
[<803304a0>] (__scsi_add_device+
0xf4
/
0x104
) from [<8034ac5c>] (ata_scsi_scan_host+
0xb0
/
0x234
)
[<8034ac5c>] (ata_scsi_scan_host+
0xb0
/
0x234
) from [<80050df4>] (async_run_entry_fn+
0x48
/
0x184
)
[<80050df4>] (async_run_entry_fn+
0x48
/
0x184
) from [<800452c8>] (process_one_work+
0x10c
/
0x370
)
[<800452c8>] (process_one_work+
0x10c
/
0x370
) from [<80045fd0>] (worker_thread+
0x138
/
0x3fc
)
[<80045fd0>] (worker_thread+
0x138
/
0x3fc
) from [<8004b24c>] (kthread+
0xb4
/
0xb8
)
[<8004b24c>] (kthread+
0xb4
/
0xb8
) from [<800130d8>] (ret_from_fork+
0x14
/
0x3c
)
---[ end trace 63dc1c18fe366fe2 ]---
sd
0
:
0
:
0
:
0
: Fix disk[
0
:
0
:
0
:
0
] to sde
sd
0
:
0
:
0
:
0
: [sde]
976773168
512
-
byte
logical blocks: (
500
GB/
465
GiB)
sd
0
:
0
:
0
:
0
: Attached scsi generic sg0 type
0
<ata_scsi_scan_host>:hd [
0
:
0
:
0
:
0
] change hd status to HD_STATUS_OK
sd
0
:
0
:
0
:
0
: [sde]
4096
-
byte
physical blocks
sd
0
:
0
:
0
:
0
: [sde] Write Protect is off
sd
0
:
0
:
0
:
0
: [sde] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
sde: sde1 sde2 sde3 sde4
sd
0
:
0
:
0
:
0
: [sde] Attached SCSI disk
ata2: SATA link down (SStatus
0
SControl
300
)
ata3: SATA link down (SStatus
0
SControl
300
)
ata4: SATA link down (SStatus
0
SControl
300
)
-
資訊解讀
-
基本引數:
-
ata1.02表示的是ata的prot1,複用埠號2
-
max UDMA/133:最大讀取速度133MB/s
-
LBA48:指以48位邏輯定址的方式使用硬碟
-
NCQ:原生命令佇列技術是一種使硬碟內部優化工作負荷執行順序,通過對內部佇列中的命令進行重新排序實現智慧資料管理,改善硬碟因機械部件而受到的各種效能制約。
-
EH complete:error handler complete
-
- 流程處理
- 首先是ata卡硬體初始化與故障處理,並列印了硬碟的相關資訊
- 之後開始掃描硬碟資訊,上面為掃描過程中的呼叫關係
- 列印識別資訊
- 依次掃描其他ata埠
- dump_stack資訊
- 通過工作佇列async_run_entry_fn掃描scsi的host,chanle,target,device
- 最後通過sd_probe關聯到block_device,到通用塊層。
-
-
硬碟熱插拔.核心函式跟蹤列印資訊
硬碟斷電:
ata1.
00
: exception Emask
0x10
SAct
0x0
SErr
0x10002
action
0xf
ata1.
00
: SError: { RecovComm PHYRdyChg }
ata1.
00
: hard resetting link
ata1.
00
: SATA link down (SStatus
0
SControl
310
)
ata1.
00
: hard resetting link
ata1.
00
: SATA link down (SStatus
0
SControl
310
)
ata1.
00
: limiting SATA link speed to
1.5
Gbps
ata1.
00
: hard resetting link
ata1.
00
: SATA link down (SStatus
0
SControl
310
)
ata1.
00
: disabled
ata1: EH complete
<ata_scsi_remove_dev>:hd [
0
:
0
:
0
:
0
] change hd status to HD_STATUS_NOEXIST
ata1.
00
: detaching (SCSI
0
:
0
:
0
:
0
)
sd
0
:
0
:
0
:
0
: [sde] Synchronizing SCSI cache
sd
0
:
0
:
0
:
0
: [sde]
Result: hostbyte=
0x04
driverbyte=
0x00
sd
0
:
0
:
0
:
0
: [sde] Stopping disk
sd
0
:
0
:
0
:
0
: [sde] START_STOP FAILED
sd
0
:
0
:
0
:
0
: [sde]
Result: hostbyte=
0x04
driverbyte=
0x00
#
硬碟上電:
ata1.
00
: exception Emask
0x10
SAct
0x0
SErr
0x4050000
action
0xf
//ata_eh_link_report
ata1.
00
: SError: { PHYRdyChg CommWake DevExch }
ata1.
00
: hard resetting link
//ata_eh_reset --> postreset(slave, classes)(.postreset = ata_std_postreset)
ata1.
00
: SATA link up
1.5
Gbps (SStatus
113
SControl
310
)
//ata_std_postreset--> sata_print_link_status
ata1.
00
: ATA-
9
: WDC WD5000LUCT-63C26Y0,
01
.01A01, max UDMA/
133
//ata_dev_configure
ata1.
00
:
976773168
sectors, multi
0
: LBA48 NCQ (depth
31
/
32
)
//ata_dev_configure
ata1.
00
: configured
for
UDMA/
133
//generic_set_mode
ata1: EH complete
//ata_scsi_port_error_handler
scsi
0
:
0
:
0
:
0
: Direct-Access ATA WDC WD5000LUCT-
6
01.0
PQ:
0
ANSI:
5
//scsi_add_lun
------------[ cut here ]------------
WARNING: at drivers/scsi/sd.c:
2936
sd_probe+
0x1c
/
0x378
()
Modules linked in:
CPU:
0
PID:
4
Comm: kworker/
0
:
0
Tainted: G W
3.10
.0_hi3536 #
6
Workqueue: events ata_scsi_hotplug
[<80019e10>] (unwind_backtrace+
0x0
/
0xf4
) from [<80016ea4>] (show_stack+
0x10
/
0x14
)
[<80016ea4>] (show_stack+
0x10
/
0x14
) from [<8002c278>] (warn_slowpath_common+
0x54
/
0x6c
)
[<8002c278>] (warn_slowpath_common+
0x54
/
0x6c
) from [<8002c32c>] (warn_slowpath_null+
0x1c
/
0x24
)
[<8002c32c>] (warn_slowpath_null+
0x1c
/
0x24
) from [<
80338860
>] (sd_probe+
0x1c
/
0x378
)
[<
80338860
>] (sd_probe+
0x1c
/
0x378
) from [<8031a224>] (driver_probe_device+
0x78
/
0x214
)
[<8031a224>] (driver_probe_device+
0x78
/
0x214
) from [<
80318898
>] (bus_for_each_drv+
0x58
/
0x8c
)
[<
80318898
>] (bus_for_each_drv+
0x58
/
0x8c
) from [<8031a17c>] (device_attach+
0x74
/
0x88
)
[<8031a17c>] (device_attach+
0x74
/
0x88
) from [<803197a0>] (bus_probe_device+
0x84
/
0xa8
)
[<803197a0>] (bus_probe_device+
0x84
/
0xa8
) from [<80317efc>] (device_add+
0x4ec
/
0x59c
)
[<80317efc>] (device_add+
0x4ec
/
0x59c
) from [<80331f34>] (scsi_sysfs_add_sdev+
0x84
/
0x294
)
[<80331f34>] (scsi_sysfs_add_sdev+
0x84
/
0x294
) from [<803300d0>] (scsi_probe_and_add_lun+
0x8bc
/
0x98c
)
[<803300d0>] (scsi_probe_and_add_lun+
0x8bc
/
0x98c
) from [<803304a0>] (__scsi_add_device+
0xf4
/
0x104
)
[<803304a0>] (__scsi_add_device+
0xf4
/
0x104
) from [<8034ac5c>] (ata_scsi_scan_host+
0xb0
/
0x234
)
[<8034ac5c>] (ata_scsi_scan_host+
0xb0
/
0x234
) from [<8034ae88>] (ata_scsi_hotplug+
0x70
/
0x7c
)
[<8034ae88>] (ata_scsi_hotplug+
0x70
/
0x7c
) from [<800452c8>] (process_one_work+
0x10c
/
0x370
)
[<800452c8>] (process_one_work+
0x10c
/
0x370
) from [<80045fd0>] (worker_thread+
0x138
/
0x3fc
)
[<80045fd0>] (worker_thread+
0x138
/
0x3fc
) from [<8004b24c>] (kthread+
0xb4
/
0xb8
)
[<8004b24c>] (kthread+
0xb4
/
0xb8
) from [<800130d8>] (ret_from_fork+
0x14
/
0x3c
)
---[ end trace 63dc1c18fe366fe3 ]---
sd
0
:
0
:
0
:
0
: Fix disk[
0
:
0
:
0
:
0
] to sde
sd
0
:
0
:
0
:
0
: Attached scsi generic sg0 type
0
sd
0
:
0
:
0
:
0
: [sde]
976773168
512
-
byte
logical blocks: (
500
GB/
465
GiB)
sd
0
:
0
:
0
:
0
: [sde]
4096
-
byte
physical blocks
sd
0
:
0
:
0
:
0
: [sde] Write Protect is off
sd
0
:
0
:
0
:
0
: [sde] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
<ata_scsi_scan_host>:hd [
0
:
0
:
0
:
0
] change hd status to HD_STATUS_OK
sde: sde1 sde2 sde3 sde4
sd
0
:
0
:
0
:
0
: [sde] Attached SCSI disk
-
資訊解讀
- 流程處理:
- 斷電
- 斷電後會重連幾次,進行錯誤處理,直到完成
- 移除磁碟,同步scsi快取
-
hostbyte=0x04表示DID_BAD_TARGET
- 上電
- 和開機啟動基本相同
- dump_stack資訊
- 磁碟的掃描是通過ata_scsi_hotplug工作佇列實現的
- 斷電
- 流程處理:
4. 硬碟識別過程
- 系統啟動時初始化各檔案系統的超級塊,分配超級塊操作函式
- AHCI平臺裝置初始化
- 通過驅動和裝置匹配,初始化AHCI平臺裝置
- 新增ATA的SCSI主機介面卡,包括兩部分,為主機介面卡分配資料結構,然後將主機介面卡新增到系統
- 初始化並執行錯誤處理執行緒scsi_error_handler
- 初始化上電識別硬碟的工作佇列async_run_entry_fn和熱插拔識別工作佇列ata_scsi_hotplug
- ata檢測及錯誤處理
- 執行ahci錯誤處理函式
- 連線報告
- 傳送ata id查詢命令獲取硬碟基本資訊,共512位元組
- 將ata命令轉換成FIS,設定host暫存器,
- 傳輸層傳送FIS給鏈路層,鏈路層加上SOF,EOF,CRC,加擾,8b/10b轉換
- 傳送到物理層,物理層發出
- 相反過程接收
- 列印硬碟型號、扇區數、工作模式、定址方式等
- 硬碟檢測
- 探測lun裝置,為裝置分配了請求佇列,設定回撥處理函式,設定超時處理函式,設定請求處理函式
- 通過傳送SCSI INQUIRY命令探測lun單元
- 該命令先轉換成通用塊層的request,再把請求進行I/O後加入請求佇列。把請求佇列傳送到請求處理函式scsi_requeset_fn。
- 初始化完成量,定義回撥函式,並等待完成量,阻塞
- 在SCSI中間層把請求轉換成SCSI CDB。再把命令傳送給ata host處理。
- 根據CDB選擇合適的處理函式,INQUIRY命令不需要轉換成ata命令,通過載入硬碟時獲取的ata id 處理。處理完成後呼叫SCSI中間層回撥函式scsi_done。
- 再呼叫回撥函式結束request,傳送完成量給阻塞的lun探測。結果返回前其一直阻塞(完成量),根據返回引數註冊scsi_device到scsi總線上。
- 總線上的每個driver來匹配device。
- 匹配成功則呼叫函式sd_probe初始化scsi_device,對映其對應的<host,channel,target,lun>和裝置檔名稱,同時分配主次裝置號。
- 然後通過add_disk註冊到通用塊層,在通用塊層根據初始化的超級塊操作函式關聯到inode指向的block_device。
- 識別完成。
5. 硬碟識別過程程式碼呼叫
|