看完了block子系统的初始化之后,我曾一度迷茫过,也曾辗转反侧,也曾苦恼万分,我完全不知道下一步该怎么走,几经思索,思索着我和中国的未来,徘徊过后,彷徨过后,终于决定,和scsi disk驱动同步进行往下走,因为scsi disk那边会调用许多block层这边提供的函数,于是我们就在这边来看看这些函数究竟是干什么的.
第一个函数当然就是register_blkdev().
55 int register_blkdev(unsigned int major, const char *name)
56 {
57 struct blk_major_name **n, *p;
58 int index, ret = 0;
59
60 mutex_lock(&block_subsys_lock);
61
62 /* temporary */
63 if (major == 0) {
64 for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) {
65 if (major_names[index] == NULL)
66 break;
67 }
68
69 if (index == 0) {
70 printk("register_blkdev: failed to get major for %s/n",
71 name);
72 ret = -EBUSY;
73 goto out;
74 }
75 major = index;
76 ret = major;
77 }
78
79 p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL);
80 if (p == NULL) {
81 ret = -ENOMEM;
82 goto out;
83 }
84
85 p->major = major;
86 strlcpy(p->name, name, sizeof(p->name));
87 p->next = NULL;
88 index = major_to_index(major);
89
90 for (n = &major_names[index]; *n; n = &(*n)->next) {
91 if ((*n)->major == major)
92 break;
93 }
94 if (!*n)
95 *n = p;
96 else
97 ret = -EBUSY;
98
99 if (ret < 0) {
100 printk("register_blkdev: cannot get major %d for %s/n",
101 major, name);
102 kfree(p);
103 }
104 out:
105 mutex_unlock(&block_subsys_lock);
106 return ret;
107 }
从sd那边调用这个函数来看,咱们是指定了主设备号了的.换言之,这里的major是非零值,而struct blk_major_name的定义也在block/genhd.c中:
27 static struct blk_major_name {
28 struct blk_major_name *next;
29 int major;
30 char name[16];
31 } *major_names[BLKDEV_MAJOR_HASH_SIZE];
注意这里顺便定义了一个数组major_names,咱们这里也用到了.
这其中BLKDEV_MAJOR_HASH_SIZE定义于include/linux/fs.h:
1575 #define BLKDEV_MAJOR_HASH_SIZE 255
即数组major_names[]有255个元素,换言之,咱们定义了255个指针.
而88行这个内联函数同样来自block/genhd.c:
33 /* index in the above - for now: assume no multimajor ranges */
34 static inline int major_to_index(int major)
35 {
36 return major % BLKDEV_MAJOR_HASH_SIZE;
37 }
比如咱们传递的major是8,那么major_to_index就是8.
不难理解,register_blkdev()这个函数做的事情就是,为这255个指针找到归属.即先在79行调用kmalloc申请一个struct blk_major_name结构体并且让p指向它,接下来为p赋值,而n将指向major_names[index],比如index就是8,那么n就指向major_names[8],一开始它肯定为空,所以直接执行94行并进而95行,于是就把赋好值的p的那个结构体赋给了major_names[8],因此,major_names[8]就既有major也有name了,name就是”sd”.
那么此时此刻的效果是什么?告诉你,不是在/dev/目录下面有sda,sdb之类的文件,而是通过/proc/devices能够看到这个块设备驱动注册了.
Character devices:
1 mem
2 pty
3 ttyp
5 /dev/tty
5 /dev/console
5 /dev/ptmx
10 misc
13 input
14 sound
29 fb
90 mtd
108 ppp (not MT default dev)
116 alsa
128 ptm
136 pts
141 mtk_stp_usktrk (not MT default dev)
151 ampc0
153 mtk_wmt_WIFI_chrdev
154 mtk_wcn_detect (not MT default dev)
160 Vcodec
166 ttyACM (not MT default dev)
180 usb
182 sec
184 ccci0
184 CCCI_IPC_DEV0
184 ccci1_fs
184 vir_chr0
184 ccci_tty_drv0
189 usb_device
190 mtk_stp_wmt
191 mtk_stp_GPS_chrdev
192 mtk_stp_BT_chrdev
193 fm
196 devmap
204 ttyMT
232 ttyGS
233 camera-pipemgr
234 mt3326-gps
235 camera-sysram
236 camera-isp
237 DW9718AF
238 kd_camera_hw
239 DumChar
240 accdet
241 mtk-adc-cali
242 mtk_disp
243 MTK_SMI
244 CAM_CAL_DRV
245 pmt
246 mtkfb_vsync
247 mtk_jpeg
248 kd_camera_flashlight
249 mtk_almk
250 btif
251 MT_pmic_adc_cali
252 sched
253 BOOT
254 rtc
Block devices:
259 blkext
7 loop
8 sd
31 mtdblock
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
253 zram
254 device-mapper