当前,Linux下sd/mmc卡的驱动已经实现。需要在此基础上实现,给这个mmc/sd块设备加多个分区。有人会问,那等系统启动后,通过fdisk工具去分区不也可以吗?回答是,本身sd/mmc驱动加载后,只有一个区,而我rootfs就是放在sd卡中,然后kernel 通过sd挂载rootfs的,所以,系统启动后,sd卡处于使用中,好像fdisk对于已经使用的sd卡进行分区,估计也会有些问题的。

所以,就需要在驱动加载过程中,加入多个分区。然后我后期向卡的不同的分区去写东西,就很方便了。插入卡,可以显示类似如下信息(16GB的SD卡):

[    3.807124] mmc0: new high speed SDHC card at address 59b4
[    3.814754] [richard debug] mmc_blk_alloc_req devidx=0,perdev_minors=8,md->disk->first_minor =0
[    3.824690] mmcblk0: mmc0:59b4 00000 14.9 GiB
[    3.832774]  mmcblk0: p1
[    3.838205] mmcblk mmc0:59b4: Card claimed for testing.
[    3.844199] mmc0:59b4: 00000 14.9 GiB

现在要做的,就是对其支持多分区“Check Setup

After rebooting and inserting a SD card you should have a device file like:

/dev/mmcblk0

And a partition on it:

/dev/mmcblk0p1 ”

让人明白,mmcblk0就是mmc block 0和mmcblk0p1就是mmc block 0 partition 1之外,其他的可以说是一无所获,所以,只能去通过上面的信息,搞清楚到底何时去加的/dev/mmcblk0p1,然后在对应的地方加上自己要的多分区。

不过,具体是什么地方输出这些信息的,自己去mmc驱动里面,一直无法找到。而且mmc驱动只是针对host controller而言的,而这些信息输出是在卡插上的时候,识别了卡的之后,才能显示具体信息的。不过,在mmc驱动至少能知道,大概信息,就是在这些函数里面:

mmc_rescan -> mmc_attach_sd - -> mmc_add_card() ->device_add() ->

然后在device_add里面,太多相关的系统函数kobject_add,blocking_notifier_call_chain,device_create_file,device_create_file,device_create_sys_dev_entry,device_add_class_symlinks,device_add_attrs,bus_add_device,device_pm_add,bus_attach_device,。。。。。

所以,实现没法搞清楚,具体是哪个函数具体去实现的底层加了/dev/mmcblk0p1这个节点的。

继续debug,加打印信息,在插入卡后,出现:

[    3.807124] mmc0: new high speed SDHC card at address 59b4
[    3.814754] [richard debug] mmc_blk_alloc_req devidx=0,perdev_minors=8,md->disk->first_minor =0
[    3.824690] mmcblk0: mmc0:59b4 00000 14.9 GiB
[    3.832774]  mmcblk0: p1
[    3.838205] mmcblk mmc0:59b4: Card claimed for testing.
[    3.844199] mmc0:59b4: 00000 14.9 GiB

所以,由:

mmcblk0: mmc0:59b4 00000 14.9 GiB
判断是

bus_attach_device(dev);
if (parent)
   klist_add_tail(&dev->knode_parent, &parent->klist_children);
去实现的/dev/mmcblk0p1,但是去看了这bus_attach_device和klist_add_tail,也仍然是看不懂具体,不知道哪里去具体实现的。

不过,在看代码过程中,发现 kobject_uevent(&dev->kobj, KOBJ_ADD);
中有个dev->kobj,这个kobj是驱动的一个核心数据结构,其中有个name变量,所以,就想,打印这些kobj的name看看,都是哪些名称所以去掉其他打印,加上这个:

printk("--SD-- 10, obj_name:%s\n", dev->kobj.name);

/drivers/base/core.c:1049:     kobject_uevent(&dev->kobj, KOBJ_ADD);

然后debug结果输出是:

[    3.807124] mmc0: new high speed SDHC card at address 59b4
[    3.814754] [richard debug] mmc_blk_alloc_req devidx=0,perdev_minors=8,md->disk->first_minor =0
[    3.824690] mmcblk0: mmc0:59b4 00000 14.9 GiB
[    3.832774]  mmcblk0: p1
[    3.838205] mmcblk mmc0:59b4: Card claimed for testing.
[    3.844199] mmc0:59b4: 00000 14.9 GiB

因此,知道了mmcblk0p1是从这里:

mmcblk0: p1
--SD-- 1
--SD-- 10, obj_name:mmcblk0p1

实现的,但是仍旧不知道是哪些函数调用到这里的device_add,

此时,由于以前遇到过,dump_stack()函数,知道这个函数可以打印堆栈信息,也就是当前栈上的函数调用信息,所以,此时可以派上用场了。同时,也知道“179:0”是mmc的主次设备号,所以继续debug,加上这些:

/drivers/base/core.c:1049:     kobject_uevent(&dev->kobj, KOBJ_ADD);
//kobject_uevent(&dev->kobj, KOBJ_ADD);

if((0==strcmp("mmcblk0p1", dev->kobj.name)) ||
    (0==strcmp("mmcblk0", dev->kobj.name)) ||
    (0==strcmp("179:0", dev->kobj.name)) ||
    (0==strcmp("179:1", dev->kobj.name)) ||
    (0==strcmp("179:8", dev->kobj.name)) ||
    (0==strcmp("179:9", dev->kobj.name))) {
    printk("[richard debug], obj_name:%s\n", dev->kobj.name);
    dump_stack();
 }

最后打印出来我想要的函数调用信息:

[    4.456880] --SD-- 10, obj_name:mmcblk0
[    4.461387] Backtrace:
[    4.464315] [<c0013410>] (dump_backtrace+0x0/0x110) from [<c0313524>] (dump_stack+0x18/0x1c)
[    4.473899]  r6:00000000 r5:c0e23540 r4:c0e24c50 r3:c045c740
[    4.480735] [<c031350c>] (dump_stack+0x0/0x1c) from [<c019bef8>] (device_add+0x468/0x614)
[    4.490004] [<c019ba90>] (device_add+0x0/0x614) from [<c011273c>] (add_disk+0x1a4/0x3d8)
[    4.504200] [<c0112598>] (add_disk+0x0/0x3d8) from [<c025c0a8>] (mmc_add_disk+0x1c/0xf0)
[    4.513301] [<c025c08c>] (mmc_add_disk+0x0/0xf0) from [<c025c98c>] (mmc_blk_probe+0x21c/0x28c)
[    4.523050]  r7:c1a15da4 r6:00000001 r5:c0c44000 r4:c0c44400
[    4.529841] [<c025c770>] (mmc_blk_probe+0x0/0x28c) from [<c0251d74>] (mmc_bus_probe+0x1c/0x20)
[    4.539510] [<c0251d58>] (mmc_bus_probe+0x0/0x20) from [<c019e26c>] (driver_probe_device+0xd0/0x1f4)
[    4.549845] [<c019e19c>] (driver_probe_device+0x0/0x1f4) from [<c019e460>] (__device_attach+0x44/0x48)
[    4.560368]  r7:00000000 r6:c019e41c r5:c0c44408 r4:c0489c84
[    4.567149] [<c019e41c>] (__device_attach+0x0/0x48) from [<c019cb14>] (bus_for_each_drv+0x58/0x94)
[    4.577197]  r5:c1a15e30 r4:c0c44408
[    4.581556] [<c019cabc>] (bus_for_each_drv+0x0/0x94) from [<c019e148>] (device_attach+0x7c/0xa8)
[    4.591412]  r7:00000000 r6:c0c44408 r5:c0c4443c r4:c0c44408
[    4.598279] [<c019e0cc>] (device_attach+0x0/0xa8) from [<c019d73c>] (bus_probe_device+0x30/0xa0)
[    4.608220]  r6:c0c44408 r5:c04898b4 r4:c0c44408 r3:00000001
[    4.615007] [<c019d70c>] (bus_probe_device+0x0/0xa0) from [<c019bf00>] (device_add+0x470/0x614)
[    4.624850]  r6:00000000 r5:c0e23980 r4:c0c44408 r3:00000031
[    4.631643] [<c019ba90>] (device_add+0x0/0x614) from [<c025220c>] (mmc_add_card+0x17c/0x1d8)
[    4.641207] [<c0252090>] (mmc_add_card+0x0/0x1d8) from [<c02564c8>] (mmc_attach_sd+0x180/0x204)
[    4.651051]  r6:c0339194 r5:00000000 r4:c1ab0800
[    4.656571] [<c0256348>] (mmc_attach_sd+0x0/0x204) from [<c0251a5c>] (mmc_rescan+0x200/0x29c)
[    4.666223]  r5:c1ab0800 r4:c1ab09cc
[    4.670505] [<c025185c>] (mmc_rescan+0x0/0x29c) from [<c004238c>] (process_one_work+0x1e0/0x338)
[    4.680447]  r7:00000000 r6:c025185c r5:c18d3800 r4:c19b6ac0
[    4.687314] [<c00421ac>] (process_one_work+0x0/0x338) from [<c004316c>] (worker_thread+0x1c0/0x2c8)
[    4.697553] [<c0042fac>] (worker_thread+0x0/0x2c8) from [<c0046a1c>] (kthread+0x94/0xa0)
[    4.706644] [<c0046988>] (kthread+0x0/0xa0) from [<c0031d20>] (do_exit+0x0/0x660)
[    4.715138]  r6:c0031d20 r5:c0046988 r4:c1833ed8
[    4.721147] usbcore: registered new interface driver uvcvideo
[    4.727744] USB Video Class driver (v1.0.8_SONiX_v2.6.36.04)

--SD-- 10, obj_name:mmcblk0p1
[    4.754979] Backtrace:
[    4.757937] [<c0013410>] (dump_backtrace+0x0/0x110) from [<c0313524>] (dump_stack+0x18/0x1c)
[    4.767522]  r6:00000000 r5:c0e3b3c0 r4:c0e24610 r3:c045c740
[    4.774327] [<c031350c>] (dump_stack+0x0/0x1c) from [<c019bef8>] (device_add+0x468/0x614)
[    4.783606] [<c019ba90>] (device_add+0x0/0x614) from [<c01144a0>] (add_partition+0x1a8/0x294)
[    4.793269] [<c01142f8>] (add_partition+0x0/0x294) from [<c011479c>] (rescan_partitions+0x210/0x280)
[    4.808619] [<c011458c>] (rescan_partitions+0x0/0x280) from [<c00bb53c>] (__blkdev_get+0x15c/0x368)
[    4.818774] [<c00bb3e0>] (__blkdev_get+0x0/0x368) from [<c00bb8e4>] (blkdev_get+0x19c/0x294)
[    4.828342] [<c00bb748>] (blkdev_get+0x0/0x294) from [<c01127f4>] (add_disk+0x25c/0x3d8)
[    4.837527] [<c0112598>] (add_disk+0x0/0x3d8) from [<c025c0a8>] (mmc_add_disk+0x1c/0xf0)
[    4.846705] [<c025c08c>] (mmc_add_disk+0x0/0xf0) from [<c025c98c>] (mmc_blk_probe+0x21c/0x28c)
[    4.856369]  r7:c1a15da4 r6:00000001 r5:c0c44000 r4:c0c44400
[    4.863300] [<c025c770>] (mmc_blk_probe+0x0/0x28c) from [<c0251d74>] (mmc_bus_probe+0x1c/0x20)
[    4.873066] [<c0251d58>] (mmc_bus_probe+0x0/0x20) from [<c019e26c>] (driver_probe_device+0xd0/0x1f4)
[    4.883317] [<c019e19c>] (driver_probe_device+0x0/0x1f4) from [<c019e460>] (__device_attach+0x44/0x48)
[    4.893840]  r7:00000000 r6:c019e41c r5:c0c44408 r4:c0489c84
[    4.900716] [<c019e41c>] (__device_attach+0x0/0x48) from [<c019cb14>] (bus_for_each_drv+0x58/0x94)
[    4.910850]  r5:c1a15e30 r4:c0c44408
[    4.915119] [<c019cabc>] (bus_for_each_drv+0x0/0x94) from [<c019e148>] (device_attach+0x7c/0xa8)
[    4.925061]  r7:00000000 r6:c0c44408 r5:c0c4443c r4:c0c44408
[    4.931851] [<c019e0cc>] (device_attach+0x0/0xa8) from [<c019d73c>] (bus_probe_device+0x30/0xa0)
[    4.941792]  r6:c0c44408 r5:c04898b4 r4:c0c44408 r3:00000001
[    4.948572] [<c019d70c>] (bus_probe_device+0x0/0xa0) from [<c019bf00>] (device_add+0x470/0x614)
[    4.958418]  r6:00000000 r5:c0e23980 r4:c0c44408 r3:00000031
[    4.965296] [<c019ba90>] (device_add+0x0/0x614) from [<c025220c>] (mmc_add_card+0x17c/0x1d8)
[    4.974775] [<c0252090>] (mmc_add_card+0x0/0x1d8) from [<c02564c8>] (mmc_attach_sd+0x180/0x204)
[    4.984617]  r6:c0339194 r5:00000000 r4:c1ab0800
[    4.990240] [<c0256348>] (mmc_attach_sd+0x0/0x204) from [<c0251a5c>] (mmc_rescan+0x200/0x29c)
[    4.999794]  r5:c1ab0800 r4:c1ab09cc
[    5.004165] [<c025185c>] (mmc_rescan+0x0/0x29c) from [<c004238c>] (process_one_work+0x1e0/0x338)
[    5.014015]  r7:00000000 r6:c025185c r5:c18d3800 r4:c19b6ac0
[    5.020900] [<c00421ac>] (process_one_work+0x0/0x338) from [<c004316c>] (worker_thread+0x1c0/0x2c8)
[    5.031152] [<c0042fac>] (worker_thread+0x0/0x2c8) from [<c0046a1c>] (kthread+0x94/0xa0)
[    5.040332] [<c0046988>] (kthread+0x0/0xa0) from [<c0031d20>] (do_exit+0x0/0x660)

4.121881] mmcblk0: mmc0:59b4 00000 14.9 GiB

[    4.127111] --SD-- 10, obj_name:179:0
[    4.131398] Backtrace:
[    4.134333] [<c0013410>] (dump_backtrace+0x0/0x110) from [<c0313524>] (dump_stack+0x18/0x1c)
[    4.143894]  r6:00000000 r5:c0e236c0 r4:c0e24a00 r3:c045c740
[    4.150696] [<c031350c>] (dump_stack+0x0/0x1c) from [<c019bef8>] (device_add+0x468/0x614)
[    4.159964] [<c019ba90>] (device_add+0x0/0x614) from [<c019c0c0>] (device_register+0x1c/0x20)
[    4.169619] [<c019c0a4>] (device_register+0x0/0x20) from [<c019c13c>] (device_create_vargs+0x78/0xbc)
[    4.179956]  r4:00000000 r3:00000000
[    4.184315] [<c019c0c4>] (device_create_vargs+0x0/0xbc) from [<c007e6b4>] (bdi_register+0x44/0x14c)
[    4.199554]  r8:00000001 r7:c0e24c0c r6:c0e24c50 r5:c0c44000 r4:c0d1ab90
[    4.207310] r3:c0d1ab90
[    4.210518] [<c007e670>] (bdi_register+0x0/0x14c) from [<c007e7ec>] (bdi_register_dev+0x30/0x3c)
[    4.220454]  r3:000000b3 r2:c03bb337
[    4.224714]  r6:c0e24c50 r5:c0c44000 r4:c0e24c00
[    4.230249] [<c007e7bc>] (bdi_register_dev+0x0/0x3c) from [<c01126f8>] (add_disk+0x160/0x3d8)
[    4.239909] [<c0112598>] (add_disk+0x0/0x3d8) from [<c025c0a8>] (mmc_add_disk+0x1c/0xf0)
[    4.249000] [<c025c08c>] (mmc_add_disk+0x0/0xf0) from [<c025c98c>] (mmc_blk_probe+0x21c/0x28c)
[    4.258749]  r7:c1a15da4 r6:00000001 r5:c0c44000 r4:c0c44400
[    4.265627] [<c025c770>] (mmc_blk_probe+0x0/0x28c) from [<c0251d74>] (mmc_bus_probe+0x1c/0x20)
[    4.275301] [<c0251d58>] (mmc_bus_probe+0x0/0x20) from [<c019e26c>] (driver_probe_device+0xd0/0x1f4)
[    4.285638] [<c019e19c>] (driver_probe_device+0x0/0x1f4) from [<c019e460>] (__device_attach+0x44/0x48)
[    4.296155]  r7:00000000 r6:c019e41c r5:c0c44408 r4:c0489c84
[    4.303042] [<c019e41c>] (__device_attach+0x0/0x48) from [<c019cb14>] (bus_for_each_drv+0x58/0x94)
[    4.313091]  r5:c1a15e30 r4:c0c44408
[    4.317443] [<c019cabc>] (bus_for_each_drv+0x0/0x94) from [<c019e148>] (device_attach+0x7c/0xa8)
[    4.327295]  r7:00000000 r6:c0c44408 r5:c0c4443c r4:c0c44408
[    4.334173] [<c019e0cc>] (device_attach+0x0/0xa8) from [<c019d73c>] (bus_probe_device+0x30/0xa0)
[    4.344113]  r6:c0c44408 r5:c04898b4 r4:c0c44408 r3:00000001
[    4.350903] [<c019d70c>] (bus_probe_device+0x0/0xa0) from [<c019bf00>] (device_add+0x470/0x614)
[    4.360749]  r6:00000000 r5:c0e23980 r4:c0c44408 r3:00000031
[    4.367529] [<c019ba90>] (device_add+0x0/0x614) from [<c025220c>] (mmc_add_card+0x17c/0x1d8)
[    4.377007] [<c0252090>] (mmc_add_card+0x0/0x1d8) from [<c02564c8>] (mmc_attach_sd+0x180/0x204)
[    4.386848]  r6:c0339194 r5:00000000 r4:c1ab0800
[    4.392379] [<c0256348>] (mmc_attach_sd+0x0/0x204) from [<c0251a5c>] (mmc_rescan+0x200/0x29c)
[    4.402025]  r5:c1ab0800 r4:c1ab09cc
[    4.406302] [<c025185c>] (mmc_rescan+0x0/0x29c) from [<c004238c>] (process_one_work+0x1e0/0x338)
[    4.416153]  r7:00000000 r6:c025185c r5:c18d3800 r4:c19b6ac0
[    4.423034] [<c00421ac>] (process_one_work+0x0/0x338) from [<c004316c>] (worker_thread+0x1c0/0x2c8)
[    4.433274] [<c0042fac>] (worker_thread+0x0/0x2c8) from [<c0046a1c>] (kthread+0x94/0xa0)
[    4.442369] [<c0046988>] (kthread+0x0/0xa0) from [<c0031d20>] (do_exit+0x0/0x660)
[    4.450866]  r6:c0031d20 r5:c0046988 r4:c1833ed8从上面可以看出:mmc_bus_probe ->mmc_blk_probe->add_disk,就是具体实现分区的地方了。

知道哪些函数了,剩下的找到对应C文件。在drivers/mmc/card/block.c中找到了这些相关的函数:

mmc_blk_probe,add_disk,其中,“mmcblk0: mmc0:d555 SD04G 3.79 GiB ”就是mmc_blk_probe中的

printk(KERN_INFO "%s: %s %s %s %s\n",
   md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
   cap_str, md->read_only ? "(ro)" : "");

打印的。

找到这里,要做的事情,其实才刚开始,但是也是只是时间问题了。因为我之前自己做了LBA的块设备,所以,知道怎么添加多分区。此处,只是要添加一些代码即可。

【具体代码】

drivers/mmc/card/block.c添加如下代码:

#define AS353X_MMC_SUPPORT_MULTI_PART 1

#if AS353X_MMC_SUPPORT_MULTI_PART
typedef struct
{
int32_t start_sec;
int32_t sec_num;
}as353x_blk_part_info;

/*
PatitionName FsType    PartitionSize       Rage(From-To)
(1)uImage None   (4M)         0      - (4M)
(2)Rootfs FAT/Ext2   (28M or 124M)       (4M)     - (32M or 128M)
(3)Data    Ext2/Ext3 (CardSize -496KB - (28M or 124M)) (32M or 128M) - (CardSize -496KB)
(4)uboot   None   (496KB)        (CardSize -496KB) - (CardSize )

A.not support multi partitions for <=32MB, it is too small for rootfs+uImage+uboot
B.for rootfs, if mmc/sd size > 128MB, reserved 128MB, or reserved 32MB
C.for uboot, 496KB = 0x7C000, which if fixed by BootCode
*/

#ifndef SZ_1M
#define SZ_1M                           0x00100000
#endif
#ifndef SZ_1K
#define SZ_1K                           0x00000400
#endif

#define SDMMC_BLOCK_SIZE 512

#define SDMMC_CARDSIZE_128MB     (128 *SZ_1M)
#define SDMMC_CARDSIZE_TOO_SMALL (32 *SZ_1M)

#define SDMMC_ROOTFS_SIZE_128MB    (128*SZ_1M) /* actual is 128-4=124MB*/
#define SDMMC_ROOTFS_SIZE_32MB    (32*SZ_1M)   /* actual is 32-4= 28MB*/
#define SDMMC_KERNEL_SIZE      (4*SZ_1M)
#define SDMMC_UBOOT_SIZE      (496*SZ_1K)    /* 0x7C000=496KB */

#define SDMMC_ROOTFS_128MB_BLK_NUM (SDMMC_ROOTFS_SIZE_128MB/SDMMC_BLOCK_SIZE)
#define SDMMC_ROOTFS_32MB_BLK_NUM (SDMMC_ROOTFS_SIZE_32MB/SDMMC_BLOCK_SIZE)
#define SDMMC_KERNEL_BLK_NUM     (SDMMC_KERNEL_SIZE/SDMMC_BLOCK_SIZE)
#define SDMMC_UBOOT_BLK_NUM     (SDMMC_UBOOT_SIZE/SDMMC_BLOCK_SIZE)

/* 0 is the first partion for whole disk */
#define AS353X_SDMMC_MAX_PARTITIONS   5

static as353x_blk_part_info as353x_mmc_partitions[AS353X_SDMMC_MAX_PARTITIONS];

/* 1 block=512B */
static int as353x_init_sdmmc_parition(uint32_t card_size_in_blocks)
{
uint32_t rootfs_blocks;
uint64_t card_size_bytes = card_size_in_blocks * SDMMC_BLOCK_SIZE;

if(card_size_bytes <= SDMMC_CARDSIZE_TOO_SMALL)
   return -1; /* not support multi partitions here */

/* 0 is for whole disk, not used here */
as353x_mmc_partitions[0].start_sec = 0;
as353x_mmc_partitions[0].sec_num =0;

if(card_size_bytes > SDMMC_CARDSIZE_128MB)
{
   /* > 128MB, is 128MB */
   rootfs_blocks = SDMMC_ROOTFS_128MB_BLK_NUM;
}
else
{
   /* <=128MB is 32MB */
   rootfs_blocks = SDMMC_ROOTFS_32MB_BLK_NUM;
}

/* 4M uImage */
as353x_mmc_partitions[1].start_sec = 0;
as353x_mmc_partitions[1].sec_num =SDMMC_KERNEL_BLK_NUM;

/* 28 or 124 MB rootfs */
as353x_mmc_partitions[2].start_sec = SDMMC_KERNEL_BLK_NUM;
as353x_mmc_partitions[2].sec_num = rootfs_blocks - SDMMC_KERNEL_BLK_NUM;

/* carsize - 496KB- (28 or 124) MB */
as353x_mmc_partitions[3].start_sec = rootfs_blocks;
as353x_mmc_partitions[3].sec_num = card_size_in_blocks - rootfs_blocks - SDMMC_UBOOT_BLK_NUM;

/* 496KB uboot */
as353x_mmc_partitions[4].start_sec = card_size_in_blocks - SDMMC_UBOOT_BLK_NUM;
as353x_mmc_partitions[4].sec_num = SDMMC_UBOOT_BLK_NUM;

return 0;
}
#endif

static int mmc_blk_probe(struct mmc_card *card)
{

。。。。。

char cap_str[10];

#if AS353X_MMC_SUPPORT_MULTI_PART
int i;
struct hd_struct * hd;
#endif

/*
* Check that the card supports the command class(es) we need.
*/
if (!(card->csd.cmdclass & CCC_BLOCK_READ))
   return -ENODEV;
。。。。。。

mmc_set_drvdata(card, md);
add_disk(md->disk);

#if AS353X_MMC_SUPPORT_MULTI_PART
if(0==as353x_init_sdmmc_parition(get_capacity(md->disk)))
{
   for(i = 1; i < AS353X_SDMMC_MAX_PARTITIONS; i++)
   {
    hd = add_partition(md->disk, i,as353x_mmc_partitions[i].start_sec, as353x_mmc_partitions[i].sec_num, ADDPART_FLAG_NONE);
   }
}
#endif

return 0;
。。。。

}

【总结】

1.还是应了那句话,只要有源码,就不怕解决不了问题。

2.调试的时候,很多时候是看起来没有办法了,但是只要细心,额外看到的信息,可以充分利用,比如上面的dev->kobj有个name参数,就可以拿来打印出来看看到底是哪些名字,以便可能继续提供更多的信息,便于找到新的办法或线索。

3.做事情,还是要有耐力和找到有效的办法,没有办法,也要尽可能地想办法。如果具备了一定的基础知识,加上细心观察,充分利用信息,很多时候,即使没有办法了,也可能会“船到桥头自然直”,自然找到进一步前进的到道路的。

Linux驱动中SD/MMC卡增加多个分区相关推荐

  1. linux mmc分区_【经验记录】如何给嵌入式Linux的SD/MMC卡驱动中添加多个分区

    How to add multi partition for SD/MMC card in Linux Driver 之所以写这个,是因为,在这个过程中,自己明显感觉到了,做事情一定要有一定的方法,方 ...

  2. 在SD/MMC卡中可读写的FAT文件系统

    2019独角兽企业重金招聘Python工程师标准>>> FAT文件系统 关于eLua中FAT文件系统的实现是使用了来自Elm Chan的一个很好的FatFS文件包.它可以在读写模式中 ...

  3. SD/MMC卡块设备驱动程序

    SD/MMC 卡组成的存储系统是许多嵌入设备的主要存储设备,相当于PC机的硬盘,在嵌入设备上的SD/MMC卡控制器通过MMC协议来解析命令控制SD/MMC卡的操作.SD/MMC卡上有一些寄存器来控制卡 ...

  4. Linux驱动分析之MMC子系统框架

    前言 上一篇<一文搞懂SDIO>简单介绍了SDIO接口及相关的协议.接下来来看一下Linux提供的驱动框架. MMC子系统介绍 Linux内核中,MMC不仅是一个驱动,而是一个子系统.内核 ...

  5. Linux设备驱动开发-linux驱动中的阻塞访问方式

    阻塞与非阻塞是设备访问的两种不同的模式.什么是阻塞操作呢?其是指在执行设备操作的时候,如果不能获得资源,则挂起进程直到满足可操作的条件后再进行操作.而非阻塞操作则是在进程不能进行设备操作时,并不挂起到 ...

  6. SD/MMC 卡读写模块---SD/MMC 卡的外部物理接口

    转载地址:http://www.8951.com/book/jiao1n21.htm SD/MMC    卡是一种大容量(最大可达 4GB).性价比高.体积小.访问接口简单的存储卡.SD/MMC 卡大 ...

  7. linux probe函数调用,【整理】Linux驱动中,probe函数何时被调用

    [整理]Linux驱动中,probe函数何时被调用 用SourceInsight跟踪: 从driver_register看起,此处我的这里是: int driver_register(struct d ...

  8. S3C2440 Linux驱动移植——SD卡驱动

    开发板:TQ2440 内核:Linux 2.6.32 PC OS:Ubuntu 11.04 本文将对SD卡驱动的移植做简要介绍. 1.  添加板级信息 打开arch/arm/mach-s3c2440/ ...

  9. 在SD/MMC卡上实现hive (Implement WinCE HIVEROM system on NAND or SD system )

    本是个很简单的topic,但无奈的是很多客户都没有实现.所以只能写一个guide给客户,让他们依葫芦画瓢. 在SD卡上实现hive以及实现binfs最精髓的思想是,在boot stage 1依次加载s ...

最新文章

  1. 分布式图数据库在贝壳的应用实践
  2. 为什么使用HashMap需要重写hashcode和equals方法_java常见面试题敲黑板了,HashMap最全的整理,大厂必考...
  3. SpringBoot_配置-自动配置原理
  4. VS2013 C#中调用DLL
  5. 在要求输入数字处找到非数字字符_剑指 Offer 67. 把字符串转换成整数 leetcode 剑指offer系列...
  6. fread 单独测试没有问题 在正式项目里面丢数据 可能是系统资源不足 预读出了问题
  7. 引用当前网站集下的样式文件
  8. 奇妙的等式 精妙的证明
  9. jQuery:节点操作、事件操作
  10. Jmeter压力测试实例
  11. OPENSTACK超售比例之VCPU
  12. HDMI 接口电路信号完整性
  13. 图片背景处理技巧快来学学
  14. 物联网应用技术有哪些?
  15. C# IFELanguage接口获取拼音,支持多音字,音调 win10/8.1/7测试通过
  16. 微信小程序开发之小米商城
  17. LOJ2312 LUOGU-P3733「HAOI2017」八纵八横 (异或线性基、生成树、线段树分治)
  18. 复制网页上不能复制的文字
  19. 【UFUN开发板评测】小巧而不失精致,简单而不失内涵——uFun开发板开箱爆照
  20. AirTight C-65 系统启动日志

热门文章

  1. 小白学Java代码:类和对象(上)
  2. sql查询合并多个字符串
  3. 马克思手稿中的趣味数学题(百钱百鸡问题人类版)
  4. Tak and Cards(dp 背包)
  5. Centos7查看防火墙以及端口开放情况
  6. Euraka-服务注册和发现原理
  7. 写一篇4000字左右的综述,题目为《单细胞测序技术在头颈部鳞癌中的应用价值》,主要包括的内容有:单细胞图谱类研究,肿瘤异质性研究,治疗反应研究,肿瘤微环境研究。...
  8. php curl nginx 报错,【Docker】docker,nginx,php使用curl报错?
  9. onBackPress
  10. idea调试需要的快捷键_IDEA调试常用快捷键