1. SMP语言中的硬盘操作基础原理
在SMP(软件制作平台)语言中,硬盘操作是系统级编程的核心基础之一。不同于高级语言对存储设备的抽象封装,SMP需要开发者直接面对硬盘的物理特性和底层协议。这里我们需要理解几个关键概念:
硬盘在SMP中被视为块设备(Block Device),每个扇区(Sector)通常是512字节或4K字节的存储单元。通过INT 13h中断(传统BIOS)或AHCI协议(现代系统)进行访问时,需要明确三个参数:柱面号(Cylinder)、磁头号(Head)和扇区号(Sector),即CHS寻址方式。不过现代SMP环境更多采用LBA(Logical Block Addressing)线性寻址。
重要提示:直接硬盘操作具有风险性,错误的写入可能导致数据永久丢失。建议在虚拟机环境或专用开发设备上练习。
2. SMP语言中的硬盘I/O操作实现
2.1 基础读写函数实现
SMP语言通常提供以下核心函数进行硬盘操作:
; 示例:SMP风格汇编代码 DISK_READ: MOV AH, 02h ; 读扇区功能号 MOV AL, 01h ; 读取扇区数 MOV CH, 00h ; 柱面号 MOV CL, 01h ; 起始扇区号 MOV DH, 00h ; 磁头号 MOV DL, 80h ; 驱动器号(80h=主硬盘) MOV BX, buffer ; 数据缓冲区 INT 13h ; 调用BIOS磁盘服务 JC error ; 出错处理对应的现代SMP实现可能使用更高级的接口:
// SMP-C风格示例 #include <smp/disk.h> int sector_read(uint32_t lba, void *buffer) { struct smp_disk_request req = { .command = SMP_DISK_READ, .lba = lba, .buffer = buffer, .count = 1 }; return smp_syscall(SMP_SYS_DISK, &req); }2.2 硬盘状态检测与错误处理
可靠的硬盘操作必须包含完善的错误检测机制。SMP语言通常通过以下方式获取硬盘状态:
| 状态检测项 | 检测方法 | 典型返回值 |
|---|---|---|
| 硬盘是否存在 | INT 13h AH=15h | AH=01h(存在) |
| 扇区读取校验 | INT 13h AH=14h | CF=0(成功) |
| 驱动器参数 | INT 13h AH=08h | CH=最大柱面 |
现代SMP环境可能使用更先进的SMART检测技术:
struct smp_smart_data { uint8_t attr_id; uint16_t flags; uint8_t current; uint8_t worst; uint32_t data; }; int check_bad_sectors() { struct smp_smart_data data; if(smp_disk_smart_read(0x05, &data)) { // 重分配扇区计数 if(data.current < threshold) { return DISK_FAILURE; } } return DISK_OK; }3. 高级硬盘操作技术
3.1 分区表解析与操作
MBR分区表位于硬盘第一个扇区(LBA 0)的446字节之后,包含4个16字节的分区表项。SMP语言解析示例:
#pragma pack(push, 1) struct mbr_partition { uint8_t status; uint8_t chs_start[3]; uint8_t type; uint8_t chs_end[3]; uint32_t lba_start; uint32_t sector_count; }; #pragma pack(pop) void read_partitions() { uint8_t mbr[512]; disk_read(0, mbr); struct mbr_partition *parts = (struct mbr_partition*)(mbr + 0x1BE); for(int i=0; i<4; i++) { if(parts[i].type != 0) { printf("Partition %d: Type=0x%02X, LBA=%u\n", i, parts[i].type, parts[i].lba_start); } } }对于GPT分区表,需要解析更复杂的结构:
- 读取LBA 1获取GPT头
- 验证签名"EFI PART"
- 定位分区条目数组
- 遍历分区条目
3.2 文件系统底层访问
即使不依赖现成文件系统驱动,SMP语言也能直接操作常见文件系统结构。以FAT32为例:
// FAT32 BPB结构 struct fat32_bpb { uint8_t jump[3]; char oem[8]; uint16_t bytes_per_sector; uint8_t sectors_per_cluster; // ...其他字段 uint32_t sectors_per_fat; uint32_t root_cluster; }; int read_fat32_info() { struct fat32_bpb bpb; disk_read(0, &bpb); // 读取引导扇区 uint32_t fat_begin = bpb.reserved_sectors; uint32_t data_begin = fat_begin + bpb.sectors_per_fat * bpb.fat_count; // 计算根目录位置 uint32_t root_sector = data_begin + (bpb.root_cluster - 2) * bpb.sectors_per_cluster; // 现在可以读取目录条目了 // ... }4. 性能优化与安全实践
4.1 DMA传输与缓存策略
直接PIO模式访问硬盘效率低下,现代SMP环境应使用DMA:
void setup_dma(uint32_t lba, void *buffer, uint16_t count) { // 1. 禁止中断 asm volatile("cli"); // 2. 编程DMA控制器 outb(0x0B, 0x06); // 设置模式:读、自动初始化 outb(0x0C, 0x00); // 清除字节指针 outb(0x04, (uint8_t)((uint32_t)buffer & 0xFF)); // 地址低字节 outb(0x04, (uint8_t)((uint32_t)buffer >> 8)); // ...继续设置地址和计数 // 3. 设置硬盘DMA命令 outb(0x1F0, 0xC8); // DMA读命令 // 4. 恢复中断 asm volatile("sti"); }4.2 原子写入与事务保护
确保关键数据写入的原子性:
#define SECTOR_SIZE 512 int atomic_write(uint32_t lba, void *data) { uint8_t temp[SECTOR_SIZE * 2]; // 1. 读取原始数据 if(disk_read(lba, temp) != 0) return -1; // 2. 准备新数据(保留校验信息等) memcpy(temp + SECTOR_SIZE, data, SECTOR_SIZE); calculate_crc(temp + SECTOR_SIZE); // 3. 原子写入(先写副本扇区) if(disk_write(lba + 1, temp + SECTOR_SIZE) != 0) return -2; // 4. 提交主扇区 if(disk_write(lba, temp + SECTOR_SIZE) != 0) { // 回滚 disk_write(lba + 1, temp); return -3; } return 0; }5. 现代存储技术适配
5.1 NVMe设备支持
对于NVMe固态硬盘,SMP需要实现更复杂的队列机制:
struct nvme_sq { uint64_t dma_addr; uint16_t size; uint16_t head; uint16_t tail; uint16_t cq_vector; }; struct nvme_cq { uint64_t dma_addr; uint16_t size; uint16_t head; uint16_t phase; }; int nvme_init() { // 1. 发现PCIe设备 struct pci_device *nvme = pci_find_class(0x010802); if(!nvme) return -1; // 2. 映射BAR空间 void *regs = pci_map_bar(nvme, 0); // 3. 配置Admin队列 struct nvme_sq *asq = dma_alloc(4096); struct nvme_cq *acq = dma_alloc(4096); // 4. 初始化控制器 uint32_t cc = readl(regs + NVME_REG_CC); cc |= NVME_CC_EN; writel(regs + NVME_REG_CC, cc); // 等待RDY置位 while(!(readl(regs + NVME_REG_CSTS) & NVME_CSTS_RDY)); return 0; }5.2 混合存储管理
处理SSD+HDD混合环境时,SMP可以实现智能分层:
#define HOT_THRESHOLD 10 // 访问次数阈值 #define COLD_TIMEOUT 3600 // 1小时未访问 struct storage_tier { uint32_t lba_start; uint32_t lba_end; uint8_t media_type; // 0=SSD, 1=HDD uint32_t access_count; time_t last_access; }; void promote_to_ssd(struct storage_tier *tier) { if(tier->media_type == 1 && tier->access_count > HOT_THRESHOLD) { // 1. 在SSD上分配空间 uint32_t new_lba = ssd_alloc(tier->lba_count()); // 2. 迁移数据 disk_copy(tier->lba_start, new_lba, tier->lba_count()); // 3. 更新映射表 update_lba_map(tier->lba_start, new_lba); tier->media_type = 0; } } void demote_to_hdd(struct storage_tier *tier) { if(tier->media_type == 0 && time_now() - tier->last_access > COLD_TIMEOUT) { // 反向迁移过程 // ... } }6. 调试与性能分析
6.1 硬盘操作跟踪
实现一个简单的调试跟踪器:
#define DISK_TRACE_SIZE 1024 struct disk_trace_entry { uint32_t lba; uint16_t count; uint8_t operation; // 0=read, 1=write uint32_t timestamp; }; struct disk_trace_entry trace_buffer[DISK_TRACE_SIZE]; uint16_t trace_index = 0; void trace_disk_op(uint32_t lba, uint16_t count, uint8_t op) { if(trace_index >= DISK_TRACE_SIZE) { trace_index = 0; // 环形缓冲区 } trace_buffer[trace_index] = (struct disk_trace_entry){ .lba = lba, .count = count, .operation = op, .timestamp = get_tick_count() }; trace_index++; } void analyze_trace() { uint32_t read_total = 0, write_total = 0; for(int i=0; i<DISK_TRACE_SIZE; i++) { if(trace_buffer[i].operation == 0) { read_total += trace_buffer[i].count; } else { write_total += trace_buffer[i].count; } } printf("Read: %u sectors, Write: %u sectors\n", read_total, write_total); }6.2 延迟测量与优化
精确测量硬盘延迟:
uint64_t measure_latency(uint32_t lba, uint8_t op) { uint64_t start, end; // 确保缓存无效 flush_disk_cache(); start = rdtsc(); if(op == 0) { disk_read(lba, temp_buffer); } else { disk_write(lba, test_pattern); } end = rdtsc(); return end - start; } void latency_profile() { uint64_t total = 0; const int runs = 100; for(int i=0; i<runs; i++) { total += measure_latency(test_lba, 0); } printf("Average read latency: %llu cycles\n", total/runs); }7. 安全增强实践
7.1 安全擦除实现
符合标准的硬盘安全擦除:
int secure_erase(uint8_t drive) { // 1. 检查支持性 uint16_t word106 = identify_drive(drive, 106); if(!(word106 & 0x0004)) { return -1; // 不支持安全擦除 } // 2. 设置密码(可选) set_security_password(drive, "smp_erase"); // 3. 发送擦除命令 send_ata_command(drive, ATA_CMD_SECURE_ERASE, 0, 0); // 4. 等待完成(可能耗时较长) while(get_drive_status(drive) & STATUS_BSY) { sleep(1); } return 0; }7.2 加密存储实现
基于硬件的透明加密:
struct encrypted_disk { uint32_t base_lba; uint8_t aes_key[32]; uint8_t iv[16]; }; int encrypt_sector(struct encrypted_disk *disk, uint32_t lba, void *data) { // 1. 生成唯一的IV(结合LBA) uint8_t unique_iv[16]; memcpy(unique_iv, disk->iv, 16); unique_iv[0] ^= (lba >> 24) & 0xFF; unique_iv[1] ^= (lba >> 16) & 0xFF; // ...其他字节混合 // 2. AES-CTR加密 aes_ctr_encrypt(data, SECTOR_SIZE, disk->aes_key, 256, unique_iv); return 0; } int decrypt_sector(struct encrypted_disk *disk, uint32_t lba, void *data) { // 解密过程与加密相同(CTR模式对称) return encrypt_sector(disk, lba, data); }8. 实际案例:实现简易磁盘工具
8.1 磁盘健康监测工具
void check_disk_health() { // 1. 读取SMART数据 struct smart_data smart; if(get_smart_data(&smart) != 0) { printf("SMART not supported\n"); return; } // 2. 检查关键属性 int bad = 0; if(smart.realloc_sectors > warning_threshold) { printf("WARNING: %u bad sectors reallocated\n", smart.realloc_sectors); bad++; } if(smart.power_on_hours > lifespan_hours) { printf("WARNING: Exceeded expected lifespan (%u hrs)\n", smart.power_on_hours); bad++; } // 3. 综合评估 if(!bad) { printf("Disk health: GOOD\n"); } else { printf("Disk health: WARNING (%d issues)\n", bad); } }8.2 低级磁盘克隆工具
#define CLONE_BUF_SECTORS 128 // 64KB缓冲区 void disk_clone(uint8_t src, uint8_t dst) { uint8_t buffer[CLONE_BUF_SECTORS * SECTOR_SIZE]; uint32_t lba = 0; uint32_t total = get_disk_size(src); printf("Cloning %u sectors...\n", total); while(lba < total) { uint32_t remain = total - lba; uint32_t count = (remain > CLONE_BUF_SECTORS) ? CLONE_BUF_SECTORS : remain; // 读取源盘 if(disk_read_ex(src, lba, buffer, count) != count) { printf("Read error at LBA %u\n", lba); break; } // 写入目标盘 if(disk_write_ex(dst, lba, buffer, count) != count) { printf("Write error at LBA %u\n", lba); break; } // 进度显示 if(lba % (total/100) == 0) { printf("\r%3u%% completed", lba*100/total); fflush(stdout); } lba += count; } printf("\nClone %s\n", (lba >= total) ? "completed" : "failed"); }9. 性能基准测试框架
实现全面的磁盘性能测试:
struct disk_benchmark { uint32_t block_size; // 测试块大小(字节) uint32_t total_size; // 总测试数据量(MB) uint32_t seq_read; // 顺序读速度(MB/s) uint32_t seq_write; // 顺序写速度 uint32_t rand_read; // 随机读速度 uint32_t rand_write; // 随机写速度 uint32_t latency; // 平均延迟(us) }; void run_benchmark(struct disk_benchmark *result) { uint8_t *buffer = malloc(result->block_size); uint64_t start, end; // 1. 顺序读测试 start = get_nanotime(); for(uint32_t i=0; i<result->total_size*1024*1024/result->block_size; i++) { disk_read(i * result->block_size/SECTOR_SIZE, buffer); } end = get_nanotime(); result->seq_read = calculate_speed(start, end, result->total_size); // 2. 顺序写测试 // ...类似实现 // 3. 随机访问测试 srand(time(NULL)); start = get_nanotime(); for(uint32_t i=0; i<10000; i++) { uint32_t lba = rand() % (result->total_size*1024*1024/SECTOR_SIZE); disk_read(lba, buffer); } end = get_nanotime(); result->rand_read = calculate_iops(start, end, 10000); // 其他测试项... free(buffer); }10. 跨平台兼容性处理
10.1 字节序处理
uint32_t read_uint32_le(uint8_t *data) { return (uint32_t)data[0] | ((uint32_t)data[1] << 8) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 24); } uint32_t read_uint32_be(uint8_t *data) { return (uint32_t)data[3] | ((uint32_t)data[2] << 8) | ((uint32_t)data[1] << 16) | ((uint32_t)data[0] << 24); } void write_uint32_le(uint8_t *buf, uint32_t val) { buf[0] = val & 0xFF; buf[1] = (val >> 8) & 0xFF; buf[2] = (val >> 16) & 0xFF; buf[3] = (val >> 24) & 0xFF; }10.2 扇区大小适配
int detect_sector_size() { // 尝试读取超出512字节的数据 uint8_t buffer[4096]; // 方法1:尝试4K读取 if(disk_read_ex(0, 0, buffer, 8) == 8) { // 检查是否实际读取了更多数据 if(memcmp(buffer+512, zero_buffer, 512) != 0) { return 4096; // 检测到4K扇区 } } // 方法2:查询设备参数 struct disk_params params; if(get_disk_params(¶ms) == 0) { return params.sector_size; } // 默认值 return 512; }11. 虚拟化环境适配
11.1 虚拟机磁盘检测
int detect_virtual_disk() { // 1. 检查厂商字符串 char model[40]; get_drive_identify(model, sizeof(model)); if(strstr(model, "Virtual") || strstr(model, "VMware") || strstr(model, "QEMU")) { return 1; } // 2. 检查不存在的物理特性 if(get_rotation_rate() == 0) { // SSD或虚拟磁盘 if(!has_nvme_features() && !has_ssd_attributes()) { return 1; // 可能是虚拟磁盘 } } return 0; }11.2 虚拟磁盘优化
void optimize_for_virtual() { // 1. 调整队列深度 set_queue_depth(virtual_queue_depth); // 2. 禁用不必要的缓存 disable_write_cache(); // 3. 使用更小的IO块 set_optimal_block_size(4096); // 匹配hypervisor // 4. 启用TRIM(如果支持) if(supports_trim()) { enable_trim(1); } }12. 异常处理与恢复
12.1 坏道处理策略
#define MAX_BAD_SECTORS 256 struct bad_sector { uint32_t lba; uint32_t replacement; // 重映射地址 }; struct bad_sector bad_list[MAX_BAD_SECTORS]; uint16_t bad_count = 0; int handle_bad_sector(uint32_t lba) { // 1. 检查是否已记录 for(int i=0; i<bad_count; i++) { if(bad_list[i].lba == lba) { return bad_list[i].replacement; } } // 2. 寻找备用扇区 uint32_t spare = find_spare_sector(); if(spare == 0) return -1; // 无备用空间 // 3. 尝试恢复数据 uint8_t buffer[SECTOR_SIZE]; if(recover_data(lba, buffer) == 0) { disk_write(spare, buffer); } // 4. 更新坏道表 if(bad_count < MAX_BAD_SECTORS) { bad_list[bad_count].lba = lba; bad_list[bad_count].replacement = spare; bad_count++; return spare; } return -2; // 坏道表已满 }12.2 电源故障恢复
struct journal_entry { uint64_t sequence; uint32_t lba; uint8_t old_data[SECTOR_SIZE]; uint8_t new_data[SECTOR_SIZE]; }; void journaled_write(uint32_t lba, void *data) { // 1. 读取原始数据 uint8_t old[SECTOR_SIZE]; disk_read(lba, old); // 2. 写入日志 struct journal_entry entry = { .sequence = get_next_seq(), .lba = lba }; memcpy(entry.old_data, old, SECTOR_SIZE); memcpy(entry.new_data, data, SECTOR_SIZE); write_journal(&entry); // 3. 执行实际写入 disk_write(lba, data); // 4. 提交日志 commit_journal(entry.sequence); } void recovery_after_crash() { // 1. 检查未提交的日志 struct journal_entry entry; while(read_journal(&entry) == 0) { // 2. 验证数据一致性 uint8_t current[SECTOR_SIZE]; disk_read(entry.lba, current); // 3. 决定恢复策略 if(memcmp(current, entry.new_data, SECTOR_SIZE) != 0) { // 写入未完成,需要回滚或重试 if(is_data_valid(entry.old_data)) { disk_write(entry.lba, entry.old_data); // 回滚 } else { disk_write(entry.lba, entry.new_data); // 重试 } } // 4. 清除日志 clear_journal_entry(entry.sequence); } }13. 固件级开发技巧
13.1 自定义引导加载程序
; 示例:简易SMP引导扇区代码 [ORG 0x7C00] [BITS 16] start: cli xor ax, ax mov ds, ax mov es, ax mov ss, ax mov sp, 0x7C00 ; 加载第二阶段 mov ah, 02h ; 读扇区 mov al, 4 ; 扇区数 mov ch, 0 ; 柱面 mov cl, 2 ; 起始扇区 mov dh, 0 ; 磁头 mov dl, 80h ; 驱动器 mov bx, 0x7E00 ; 目标地址 int 13h jc error ; 跳转到第二阶段 jmp 0x0000:0x7E00 error: mov si, msg_error call print_string hlt print_string: lodsb or al, al jz .done mov ah, 0Eh int 10h jmp print_string .done: ret msg_error db "Boot failed!", 0 times 510-($-$$) db 0 dw 0xAA5513.2 直接硬件控制
绕过BIOS直接控制IDE控制器:
void ide_write(uint8_t reg, uint16_t value) { switch(reg) { case IDE_REG_DATA: outw(IDE_BASE + 0, value); break; case IDE_REG_ERROR: outb(IDE_BASE + 1, value); break; // ...其他寄存器 default: outb(IDE_BASE + reg, value); } } uint16_t ide_read(uint8_t reg) { switch(reg) { case IDE_REG_DATA: return inw(IDE_BASE + 0); // ...其他寄存器 default: return inb(IDE_BASE + reg); } } int ide_poll(uint8_t mask, uint8_t val, int timeout) { while(timeout-- > 0) { uint8_t status = ide_read(IDE_REG_STATUS); if((status & mask) == val) { return 0; } io_delay(); } return -1; }14. 测试与验证方法
14.1 磁盘表面扫描
实现完整的磁盘扫描工具:
#define SCAN_BUF_SECTORS 64 void surface_scan() { uint8_t buffer[SCAN_BUF_SECTORS * SECTOR_SIZE]; uint32_t lba = 0; uint32_t total = get_disk_size(); uint32_t bad_count = 0; printf("Starting surface scan...\n"); while(lba < total) { uint32_t remain = total - lba; uint32_t count = (remain > SCAN_BUF_SECTORS) ? SCAN_BUF_SECTORS : remain; // 读取测试 if(disk_read_ex(lba, buffer, count) != count) { printf("Bad sector at LBA %u\n", lba); bad_count++; // 尝试单独读取每个扇区 for(uint32_t i=0; i<count; i++) { if(disk_read(lba + i, buffer) != 0) { mark_bad_sector(lba + i); } } } // 进度显示 if(lba % (total/100) == 0) { printf("\r%3u%% scanned, %u bad sectors found", lba*100/total, bad_count); fflush(stdout); } lba += count; } printf("\nScan completed. Total bad sectors: %u\n", bad_count); }14.2 数据完整性验证
void verify_disk(uint32_t start_lba, uint32_t count) { uint8_t read1[SECTOR_SIZE], read2[SECTOR_SIZE]; uint32_t errors = 0; for(uint32_t i=0; i<count; i++) { uint32_t lba = start_lba + i; // 第一次读取 if(disk_read(lba, read1) != 0) { printf("Read failed at LBA %u\n", lba); errors++; continue; } // 第二次读取 if(disk_read(lba, read2) != 0) { printf("Read failed at LBA %u\n", lba); errors++; continue; } // 比较结果 if(memcmp(read1, read2, SECTOR_SIZE) != 0) { printf("Data mismatch at LBA %u\n", lba); errors++; } // 进度显示 if(i % 1000 == 0) { printf("\rVerified %u/%u sectors, errors: %u", i, count, errors); fflush(stdout); } } printf("\nVerification completed. Errors: %u\n", errors); }15. 高级主题:实现简易文件系统
15.1 数据结构设计
#define MAX_FILES 1024 #define BLOCK_SIZE 4096 struct superblock { uint32_t magic; uint32_t block_size; uint32_t total_blocks; uint32_t free_blocks; uint32_t inode_table; uint32_t root_inode; uint32_t journal_block; }; struct inode { uint32_t mode; uint32_t size; uint32_t blocks; uint32_t direct[12]; uint32_t indirect; uint32_t dindirect; uint32_t ctime; uint32_t mtime; }; struct directory_entry { uint32_t inode; char name[28]; };15.2 关键操作实现
int read_file(uint32_t inode_num, void *buffer) { // 1. 读取inode struct inode ino; if(read_inode(inode_num, &ino) != 0) { return -1; } uint32_t remaining = ino.size; uint8_t *ptr = buffer; // 2. 读取直接块 for(int i=0; i<12 && remaining>0; i++) { uint32_t to_read = (remaining > BLOCK_SIZE) ? BLOCK_SIZE : remaining; if(disk_read(ino.direct[i], ptr) != 0) { return -2; } ptr += to_read; remaining -= to_read; } // 3. 读取间接块 if(remaining > 0 && ino.indirect != 0) { uint32_t indirect[BLOCK_SIZE/sizeof(uint32_t)]; if(disk_read(ino.indirect, indirect) != 0) { return -3; } for(int i=0; i<BLOCK_SIZE/sizeof(uint32_t) && remaining>0; i++) { if(indirect[i] == 0) continue; uint32_t to_read = (remaining > BLOCK_SIZE) ? BLOCK_SIZE : remaining; if(disk_read(indirect[i], ptr) != 0) { return -4; } ptr += to_read; remaining -= to_read; } } return 0; } int write_file(uint32_t inode_num, const void *data, uint32_t size) { // 类似的写入实现 // 需要处理块分配、间接块设置等 // ... }16. 硬件检测与识别
16.1 识别硬盘参数
struct disk_geometry { uint32_t cylinders; uint16_t heads; uint16_t sectors; uint64_t total_sectors; uint16_t sector_size; }; int get_disk_geometry(struct disk_geometry *geo) { // 1. 尝试通过IDENTIFY获取 uint16_t id_data[256]; if(ata_identify(id_data) == 0) { geo->cylinders = id_data[1]; geo->heads = id_data[3]; geo->sectors = id_data[6]; geo->sector_size = (id_data[106] & 0x2000) ? 4096 : 512; // 计算总扇区数 if(id_data[83] & 0x0400) { // 支持48位LBA geo->total_sectors = ((uint64_t)id_data[100] << 32) | ((uint64_t)id_data[99] << 16) | id_data[98]; } else { geo->total_sectors = geo->cylinders * geo->heads * geo->sectors; } return 0; } // 2. 回退到CHS参数 uint8_t params[8]; if(bios_get_disk_params(0x80, params) == 0) { geo->cylinders = ((params[0] & 0xC0) << 2) | params[1]; geo->heads = params[0] & 0x3F; geo->sectors = params[2] & 0x3F; geo->sector_size = 512; // 传统CHS总是512 geo->total_sectors = geo->cylinders * geo->heads * geo->sectors; return 0; } return -1; }16.2 检测SSD特性
struct ssd_info { uint8_t is_ssd; uint32_t wear_leveling_count; uint32_t tb_written; uint8_t