Linux kernel v4.4에서 간단한 블록 장치 드라이버 만들어보기

실험

커널 부팅

[    0.298833] mybrd: start init_hctx: hctx=ffff88000643c400 mybrd=ffff88000771c600 priv[0]=ffff880006871eb0
[    0.299741] mybrd: info hctx: numa_node=0 queue_num=0 queue->ffff880007750000
[    0.300318] mybrd: end init_hctx
[    0.300668] mybrd: start queue_rq: request-ffff880007740000 priv-ffff880006871eb0 request->special=          (null)
[    0.301506] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.4.0+ #74
[    0.301961] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[    0.302707]  ffff880006871eb0 ffff88000750b848 ffffffff8130dadf ffff880007740000
[    0.303310]  ffff88000750b868 ffffffff814faa83 ffff88000643c400 ffff88000750b890
[    0.303927]  ffff88000750b8f0 ffffffff812f95b9 ffff880007750000 ffff88000643c408
[    0.304544] Call Trace:
[    0.304744]  [<ffffffff8130dadf>] dump_stack+0x44/0x55
[    0.305138]  [<ffffffff814faa83>] mybrd_queue_rq+0x43/0xb0
[    0.305582]  [<ffffffff812f95b9>] __blk_mq_run_hw_queue+0x1b9/0x340
[    0.306079]  [<ffffffff812f93e9>] blk_mq_run_hw_queue+0x89/0xa0
[    0.306552]  [<ffffffff812faa2f>] blk_sq_make_request+0x1bf/0x2b0
[    0.307027]  [<ffffffff812efc8e>] generic_make_request+0xce/0x1a0
[    0.307520]  [<ffffffff812efdc2>] submit_bio+0x62/0x140
[    0.307924]  [<ffffffff8119fa78>] submit_bh_wbc.isra.38+0xf8/0x130
[    0.308569]  [<ffffffff8119fdef>] block_read_full_page+0x24f/0x2f0
[    0.309050]  [<ffffffff811a1e50>] ? I_BDEV+0x10/0x10
[    0.309442]  [<ffffffff8111a96b>] ? __add_to_page_cache_locked+0x11b/0x1b0
[    0.309996]  [<ffffffff811a2820>] ? blkdev_readpages+0x20/0x20
[    0.310452]  [<ffffffff811a2833>] blkdev_readpage+0x13/0x20
[    0.310905]  [<ffffffff8111ad08>] do_read_cache_page+0x78/0x1a0
[    0.311377]  [<ffffffff8111ae44>] read_cache_page+0x14/0x20
[    0.311834]  [<ffffffff81301358>] read_dev_sector+0x28/0x90
[    0.312248]  [<ffffffff813043f6>] read_lba+0x126/0x1e0
[    0.312660]  [<ffffffff81304ab7>] efi_partition+0xe7/0x720
[    0.313063]  [<ffffffff8131763b>] ? string.isra.4+0x3b/0xd0
[    0.313508]  [<ffffffff81318fec>] ? vsnprintf+0x24c/0x510
[    0.313904]  [<ffffffff81319339>] ? snprintf+0x39/0x40
[    0.314281]  [<ffffffff813049d0>] ? compare_gpts+0x260/0x260
[    0.314740]  [<ffffffff813025e9>] check_partition+0x139/0x220
[    0.315157]  [<ffffffff81301b63>] rescan_partitions+0xb3/0x2a0
[    0.315627]  [<ffffffff811a2e22>] __blkdev_get+0x282/0x3b0
[    0.316031]  [<ffffffff811a3ae2>] blkdev_get+0x112/0x300
[    0.316418]  [<ffffffff81185fae>] ? unlock_new_inode+0x3e/0x70
[    0.316909]  [<ffffffff811a26fc>] ? bdget+0x10c/0x120
[    0.317288]  [<ffffffff814dbc32>] ? put_device+0x12/0x20
[    0.317728]  [<ffffffff812ff921>] add_disk+0x3e1/0x470
[    0.318225]  [<ffffffff812ffbc2>] ? alloc_disk_node+0x102/0x130
[    0.318738]  [<ffffffff81f7d865>] ? brd_init+0x153/0x153
[    0.319132]  [<ffffffff81f7da76>] mybrd_init+0x211/0x277
[    0.319562]  [<ffffffff810003b1>] do_one_initcall+0x81/0x1b0
[    0.319983]  [<ffffffff81f3b08e>] kernel_init_freeable+0x158/0x1e3
[    0.320443]  [<ffffffff81889b00>] ? rest_init+0x80/0x80
[    0.320876]  [<ffffffff81889b09>] kernel_init+0x9/0xe0
[    0.321260]  [<ffffffff8188f50f>] ret_from_fork+0x3f/0x70
[    0.321736]  [<ffffffff81889b00>] ? rest_init+0x80/0x80
[    0.322128] mybrd: queue-rq: req=ffff880007740000 len=4096 rw=READ
[    0.322615] mybrd:     sector=0 bio-info: len=4096 p=ffffea0000000940 offset=0
[    0.323091] mybrd: lookup: page-          (null) index--1 sector-0
[    0.323501] mybrd: copy: ffff880000025000 <- 0 (4096-bytes)
[    0.323903] mybrd: 0 0 0 0 0 0 0 0
[    0.324114] mybrd: end queue_rq
[    0.324487] mybrd: start queue_rq: request-ffff880007740000 priv-ffff880006871eb0 request->special=          (null)
[    0.325273] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.4.0+ #74
[    0.325840] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[    0.326619]  ffff880006871eb0 ffff88000750b8e8 ffffffff8130dadf ffff880007740000
[    0.327199]  ffff88000750b908 ffffffff814faa83 ffff88000643c400 ffff88000750b930
[    0.327923]  ffff88000750b990 ffffffff812f95b9 ffff880007750000 ffff88000643c408
[    0.328538] Call Trace:
[    0.328723]  [<ffffffff8130dadf>] dump_stack+0x44/0x55
[    0.329106]  [<ffffffff814faa83>] mybrd_queue_rq+0x43/0xb0
[    0.329570]  [<ffffffff812f95b9>] __blk_mq_run_hw_queue+0x1b9/0x340
[    0.330038]  [<ffffffff812f93e9>] blk_mq_run_hw_queue+0x89/0xa0
[    0.330517]  [<ffffffff812faa2f>] blk_sq_make_request+0x1bf/0x2b0
[    0.330974]  [<ffffffff812efc8e>] generic_make_request+0xce/0x1a0
[    0.331430]  [<ffffffff812efdc2>] submit_bio+0x62/0x140
[    0.331857]  [<ffffffff8119fa78>] submit_bh_wbc.isra.38+0xf8/0x130
[    0.332321]  [<ffffffff8119fdef>] block_read_full_page+0x24f/0x2f0
[    0.332830]  [<ffffffff811a1e50>] ? I_BDEV+0x10/0x10
[    0.333227]  [<ffffffff8111a96b>] ? __add_to_page_cache_locked+0x11b/0x1b0
[    0.333795]  [<ffffffff811a2820>] ? blkdev_readpages+0x20/0x20
[    0.334229]  [<ffffffff811a2833>] blkdev_readpage+0x13/0x20
[    0.334679]  [<ffffffff8111ad08>] do_read_cache_page+0x78/0x1a0
[    0.335118]  [<ffffffff8111ae44>] read_cache_page+0x14/0x20
[    0.335575]  [<ffffffff81301358>] read_dev_sector+0x28/0x90
[    0.335985]  [<ffffffff81302783>] amiga_partition+0x53/0x410
[    0.336405]  [<ffffffff81303fe0>] ? sgi_partition+0x190/0x190
[    0.336863]  [<ffffffff81304298>] ? sun_partition+0x2b8/0x2f0
[    0.337288]  [<ffffffff81303e3a>] ? osf_partition+0x15a/0x170
[    0.337937]  [<ffffffff81302730>] ? put_partition+0x60/0x60
[    0.338394]  [<ffffffff813025e9>] check_partition+0x139/0x220
[    0.338863]  [<ffffffff81301b63>] rescan_partitions+0xb3/0x2a0
[    0.339300]  [<ffffffff811a2e22>] __blkdev_get+0x282/0x3b0
[    0.339805]  [<ffffffff811a3ae2>] blkdev_get+0x112/0x300
[    0.340224]  [<ffffffff81185fae>] ? unlock_new_inode+0x3e/0x70
[    0.340696]  [<ffffffff811a26fc>] ? bdget+0x10c/0x120
[    0.341093]  [<ffffffff814dbc32>] ? put_device+0x12/0x20
[    0.341518]  [<ffffffff812ff921>] add_disk+0x3e1/0x470
[    0.341924]  [<ffffffff812ffbc2>] ? alloc_disk_node+0x102/0x130
[    0.342387]  [<ffffffff81f7d865>] ? brd_init+0x153/0x153
[    0.342814]  [<ffffffff81f7da76>] mybrd_init+0x211/0x277
[    0.343230]  [<ffffffff810003b1>] do_one_initcall+0x81/0x1b0
[    0.343688]  [<ffffffff81f3b08e>] kernel_init_freeable+0x158/0x1e3
[    0.344174]  [<ffffffff81889b00>] ? rest_init+0x80/0x80
[    0.344590]  [<ffffffff81889b09>] kernel_init+0x9/0xe0
[    0.344996]  [<ffffffff8188f50f>] ret_from_fork+0x3f/0x70
[    0.345417]  [<ffffffff81889b00>] ? rest_init+0x80/0x80
[    0.345839] mybrd: queue-rq: req=ffff880007740000 len=4096 rw=READ
[    0.346326] mybrd:     sector=8 bio-info: len=4096 p=ffffea0000000980 offset=0
[    0.346971] mybrd: lookup: page-          (null) index--1 sector-8
[    0.347462] mybrd: copy: ffff880000026000 <- 0 (4096-bytes)
[    0.347905] mybrd: 0 0 0 0 0 0 0 0
[    0.348176] mybrd: end queue_rq

부팅을 해보겠습니다. mybrd_init_hctx() 가 호출되었네요. hw-queue 번호가 0번인게 확인됐습니다.

그리고 디스크가 추가되니 커널이 어떤 디스크인가하고 읽어봤네요. request가 2개 발생했습니다. 각각 priv가 init_hctx()에서 설정한 값인지 확인해보니 맞네요. init_hctx()에서 제대로 hw-queue를 설정했음을 알 수 있습니다. request처리 자체는 request-mode와 동일하니 자세히 볼 필요는 없습니다.

mkfs.vfat이나 dd 툴을 써서 테스트해보는 것은 별로 새로운게 없으니 각자 해보시기 바랍니다.

PS. 한가지 아쉬운건 request가 여러 sw-queue중 어느 큐에서 온건지를 알아보고싶은데, request에서 어느 필드를 봐야할지 잘 모르겠습니다. 이제 막 읽기 시작했으니 좀더 봐야지요.

 

댓글

댓글 본문
작성자
비밀번호
버전 관리
gurugio
현재 버전
선택 버전
graphittie 자세히 보기