Sabit diskten yalnızca bir sektörü bellekteki belirli bir sayfaya okumak istiyorum, bu sayfa ayrılmış ve herhangi bir adres eşlemesiyle eşlenmiyor. this solution'u buldum, ancak bir dosyayı bir blok aygıtına ve bir sektöre nasıl çevireceğimi bilmiyorum. Hedef sayfa aynı işlevi kullanamazsınız herhangi eşleme olmadığındanLinux çekirdeğinde biyo isteği kullanarak bir sektör nasıl okunmalı
error = mapping->a_ops->readpage(filp, page);
, ama cihazı ve bir sektöre FILP çevirmek gerekir: Örneğin, dosyanın mm/filemap.c
işlev do_generic_file_read
orada bu çizgidir Kendi biyo isteğimi üretebilmek. bunu nasıl yapabilirim?
Düzenleme
Bunu ekleyerek, olası bir çözüm olarak bu çalıştı 1, ilk sonra doğrudan cihaz almak için ext2_get_block
çağırır sektörünü hesaplar Daha sonra istenen sayfa konumunu ekler ve biyo gönderir istek:
struct page *myPage;
int myRet;
struct buffer_head bh;
struct bio *bio = bio_alloc(GFP_NOIO,1);
myPage = pfn_to_page(Some_Location);
bio_init(bio);
bio->bi_sector = (sector_t)page_offset << (PAGE_CACHE_SHIFT - mapping->host->i_blkbits);
myRet = ext2_get_block(mapping->host, bio->bi_sector, &bh, 0);
bio->bi_bdev = bh.b_bdev;
bio->bi_next = NULL;
bio->bi_size = PAGE_SIZE;
bio_add_page(bio, myPage, PAGE_SIZE, 0);
submit_bio(READ, bio);
Bu istenen sayfa bir adres eşleştirmesi olmadığı için, biyo isteği oluşturmak için fonksiyonu mevcut adres eşleştirmesi kullanır. Bu tek bir sorunu var, submit_bio
hat bu neden:
[ 4.792142] ------------[ cut here ]------------
[ 4.792892] WARNING: at arch/x86/kernel/pci-nommu.c:63 nommu_map_sg+0xd9/0x100()
[ 4.793674] Hardware name: Standard PC (i440FX + PIIX, 1996)
[ 4.794149] Modules linked in:
[ 4.794607] Pid: 153, comm: kblockd/0 Not tainted 2.6.32.65 #308
[ 4.795077] Call Trace:
[ 4.795545] [<ffffffff81056875>] ? warn_slowpath_common+0x65/0xa0
[ 4.796024] [<ffffffff810380a9>] ? nommu_map_sg+0xd9/0x100
[ 4.796446] [<ffffffff8121ef4a>] ? ide_dma_prepare+0xda/0x180
[ 4.796900] [<ffffffff81219923>] ? do_rw_taskfile+0x253/0x330
[ 4.797532] [<ffffffff8122311c>] ? ide_do_rw_disk+0x22c/0x320
[ 4.797983] [<ffffffff81215c3a>] ? do_ide_request+0x11a/0x600
[ 4.798416] [<ffffffff81051450>] ? __dequeue_entity+0x30/0x40
[ 4.798854] [<ffffffff810519a1>] ? finish_task_switch.constprop.110+0x31/0xc0
[ 4.799391] [<ffffffff8141fdd6>] ? thread_return+0x2a/0x1d4
[ 4.799816] [<ffffffff81052116>] ? check_preempt_wakeup+0x76/0xe0
[ 4.800279] [<ffffffff811a3be0>] ? blk_unplug_work+0x0/0x20
[ 4.800754] [<ffffffff811a5b2a>] ? generic_unplug_device+0x1a/0x30
[ 4.801218] [<ffffffff810661dc>] ? worker_thread+0x13c/0x210
[ 4.802710] [<ffffffff81069cb0>] ? autoremove_wake_function+0x0/0x30
[ 4.804130] [<ffffffff810660a0>] ? worker_thread+0x0/0x210
[ 4.805357] [<ffffffff810660a0>] ? worker_thread+0x0/0x210
[ 4.806356] [<ffffffff81069907>] ? kthread+0x77/0x80
[ 4.807302] [<ffffffff81033eaa>] ? child_rip+0xa/0x20
[ 4.808500] [<ffffffff81069890>] ? kthread+0x0/0x80
[ 4.809060] [<ffffffff81033ea0>] ? child_rip+0x0/0x20
[ 4.809620] ---[ end trace 61d7e1478dbb58eb ]---
ve daha sonra bu neden:
[ 4.871857] hda: task_pio_intr: status=0x58 { DriveReady SeekComplete DataRequest }
[ 4.872553] hda: possibly failed opcode: 0x29
[ 4.873346] hda: DMA disabled
[ 4.885478] Clocksource tsc unstable (delta = 115822911 ns)
[ 4.886364] Switching to clocksource jiffies
[ 4.919051] ide0: reset: success
ve bu:
[ 48.957807] hda: lost interrupt
ben
mm/readahead.c
içinde
__do_page_cache_readahead
çalışması için bu katma ama
mm/filemap.c
ya da benzeri işlevlere benzer şekilde eklenebilir. belki birisi bu sorunu çözebilir!
Bunu bir ISR'de yapmaya mı çalışıyorsunuz? – stark