用户7878
发布于

写入到EMMC的数据没有落盘

韦老师,请教个问题,我用这个指令写一个文件echo "1234" > 1.txt & sync,断电之后这个文件就不见了,或者恢复到了写入之前的状态,写完之后用reboot指令重启,数据都在的,请教下这个可能是什么原因?
存储设备是一个EMMC,我在内核里打印了一些数据,如下:
static void mmc_blk_mq_complete_rq(struct mmc_queue *mq, struct request *req)
{
struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
unsigned int nr_bytes = mqrq->brq.data.bytes_xfered;

#define MIN(a,b) ((a) < (b) ? (a) : (b))

    // 检查是否为写请求
    if (req_op(req) == REQ_OP_WRITE) {
        struct bio *bio = req->bio;
        struct bio_vec bvec;
        struct bvec_iter iter;
        void *data_ptr;

        // 遍历 bio 中的每个段(数据块)
        bio_for_each_segment(bvec, bio, iter) {
            // 映射物理页到内核虚拟地址
            data_ptr = kmap_atomic(bvec.bv_page);

            // 打印数据的前 8 字节(避免过多输出)
            print_hex_dump(KERN_DEBUG, "eMMC WRITE Data(D): ",
                     DUMP_PREFIX_OFFSET, 16, 1,
                     data_ptr + bvec.bv_offset,
                     MIN(bvec.bv_len, 8), true);

            // 解除映射
            kunmap_atomic(data_ptr);
            break; // 仅打印第一个段(避免性能问题)
        }

        sector_t sector = blk_rq_pos(req);
        unsigned int nr_sectors = blk_rq_sectors(req);
        u64 offset = (u64)sector * 512;
        
        printk(KERN_DEBUG"WRITE: Sector=%llu, Offset=%llu, Length=%u sectors\n",
            (unsigned long long)sector,
            (unsigned long long)offset,
            nr_sectors);
    }
    ...

}

mmc_blk_mq_complete_rq这个函数的开头是可以看到写入的数据和扇区的,然后根据打印的扇区,用dd if=/dev/mmcblk1 bs=512 skip=5959728 count=8 | hexdump -C,这个指令也是可以看到mmc上的数据的,但是断电就没了,还有一个现象,测试2次之后(每次测试完都断电),再用同样的方法测试,用dd就看不到对应扇区的数据了,用reboot指令启动之后,数据都是保存的,reboot之后测试几次数据保存,断电重启之后都是在的,一旦出错之后,怎么测试数据都不会保存了,除非用reboot重启,数据才能保存

浏览 (154)
点赞
收藏
1条评论
韦东山
韦东山
emmc驱动程序比较完善了,你无需深入内核添加这些打印。我认为你先总结一下必定能复现的操作,我们再分析
点赞
评论