在 Linux 核心或 Android 系統開發中,有時需要繞過檔案系統,直接對區塊裝置(如 SD 卡、eMMC 分區)進行扇區級的原始讀寫。這在韌體更新、資料救援、檔案系統底層測試等場景極為常見。本文以 Android 2.1 環境下的 TF 卡操作為例,說明核心步驟與關鍵程式碼實作。
/dev/block/mmcblk0(整張卡)或 /dev/block/mmcblk0p1(第一分區),絕非 掛載點 /sdcard 或 /mnt/sdcard。adb shell 取得 root 權限後執行:
chmod 777 /dev/block/mmcblk0p1
O_DIRECT 旗標的讀寫程式: 繞過頁面快取,直接對扇區操作。int fd = open("/dev/block/mmcblk0", O_RDWR | O_DIRECT, 0666);
關鍵點: 必須加上 O_DIRECT 旗標,告知核心略過頁面快取直接存取磁碟。此外,讀寫緩衝區的記憶體位址與大小必須符合扇區大小(通常 512 位元組)的整數倍對齊需求,否則 O_DIRECT 會失敗返回 EINVAL。
char *iobuf = NULL;
iobuf = memalign(getpagesize(), getpagesize()); // 取得頁面大小對齊的緩衝區(通常 4096 bytes)
或使用 posix_memalign()。配置大小建議為頁面大小(4KB)的整數倍,以滿足 O_DIRECT 的對齊限制。
以下範例示範如何定位至特定扇區(此處為第 2 個扇區,偏移 1024 位元組)進行讀寫:
// 寫入單一扇區 (512 bytes)
int WriteSectors(int fd, char *buf) {
if (lseek(fd, 1024, SEEK_SET) == -1) return -1; // 定位至第 2 扇區起始處
return write(fd, buf, 512);
}
// 讀取單一扇區 (512 bytes)
int ReadSectors(int fd, char *buf) {
if (lseek(fd, 1024, SEEK_SET) == -1) return -1;
return read(fd, buf, 512);
}
注意: 實際專案中應根據扇區號動態計算偏移量 sector_num * 512,並檢查 read/write 返回值是否為 512,以確保完整讀寫。
umount 卸載。.te 政策檔。ioctl(fd, BLKSSZGET, §or_size) 動態取得。掌握扇區級讀寫,能讓你在檔案系統層失效時,仍能直搗黃龍進行底層資料操作與診斷。
Linux 系統時間與時區設定完整指南:date、hwclock、timedatectl
Oracle Redo Log 原理深度解析:實例恢復與介質恢復的核心機制、Checkpoint、Log Force at Commit
Linux 安全加固實戰(一):從硬體到啟動載入器的纵深防禦
Nginx 配置 SSL/TLS 完整指南:OpenSSL 自簽證書生成、虛擬主機配置、安全優化與證書鏈部署
X 電容與 Y 電容應用差異:針對差模/共模干擾的濾波選型指南
Linux 上網配置經典兩式:共享 Windows 主機上網與 ADSL 直撥完整參數