如何在内核直接读写一个ide 磁盘扇区 ? 不用中断,dma,定时器

发布于 2022-10-15 04:38:27 字数 39 浏览 19 评论 0

哥们搞了两天,发现状态寄存器总是返回0x7f, 读不出来,郁闷中, 谁解哥忧啊

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

挖鼻大婶 2022-10-22 04:38:27

貌似很简单,见过这种代码,找找看。。。。。

何止钟意 2022-10-22 04:38:27
  1. void
  2. waitdisk(void)
  3. {
  4.         // wait for disk reaady
  5.         while ((inb(0x1F7) & 0xC0) != 0x40)
  6.                 /* do nothing */;
  7. }
  8. void
  9. readsect(void *dst, uint32_t offset)
  10. {
  11.         // wait for disk to be ready
  12.         waitdisk();
  13.         outb(0x1F2, 1);                // count = 1
  14.         outb(0x1F3, offset);
  15.         outb(0x1F4, offset >> 8);
  16.         outb(0x1F5, offset >> 16);
  17.         outb(0x1F6, (offset >> 24) | 0xE0);
  18.         outb(0x1F7, 0x20);        // cmd 0x20 - read sectors
  19.         // wait for disk to be ready
  20.         waitdisk();
  21.         // read a sector
  22.         insl(0x1F0, dst, SECTSIZE/4);
  23. }

复制代码

温柔女人霸气范 2022-10-22 04:38:27

试了不行,擦的,读出来的全是ff

ide_drive_t * panic_log_driver;

static void rw_log_raw(ide_drive_t *drive, task_ioreg_t cmd, char *buf, int len, int write)
{
        unsigned long flags;
        u8 stat;
       
        int cnt=0;
        //ide_hwgroup_t *hwgroup = HWGROUP(drive);
        ide_hwif_t *hwif = HWIF(drive);
        int nsect = ((len % SECTOR_SIZE) == 0) ? len/SECTOR_SIZE : len/SECTOR_SIZE + 1 ;
        printk(KERN_INFO "nsect is %d \n", nsect);
        //spin_lock_irqsave(&ide_lock, flags);
#if 0
        BUG_ON(hwgroup->handler);
        hwgroup->handler        = handler;
        hwgroup->expiry                = expiry;
        hwgroup->timer.expires        = jiffies + timeout;
        add_timer(&hwgroup->timer);
#endif
        printk("write cmd to ide: 0x%02x \n", cmd);
        hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG);
        /* Drive takes 400nS to respond, we must avoid the IRQ being
           serviced before that.
          
           FIXME: we could skip this delay with care on non shared
           devices
        */
        ndelay(1000);
        //spin_unlock_irqrestore(&ide_lock, flags);
       
judge:
        ndelay(1000);
        stat = hwif->INB(IDE_STATUS_REG);
        cnt++;
        /* new way for dealing with premature shared PCI interrupts */
        if ( (stat & 0xc0) != 0x40) {
               
                /* No data yet, so wait for another IRQ. */
                #if 0
                ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
                return ide_started;
                #endif
                if (cnt >= 1000) {
                        printk(KERN_INFO " error stat dont ok cnt > 1000,stat:%02x  force to read or write now\n",stat);
                        goto rwnow;
                }
                       
                goto judge;
        }
       
        printk(KERN_INFO " good state , now to read or write,stat:%02x  \n",stat);

rwnow:
                if (write){
                          
                          while (nsect--){
                                  printk("writeing \n";
                                 HWIF(drive)->ata_output_data(drive, buf, SECTOR_WORDS);
                                   buf +=SECTOR_WORDS;
                                 goto judge;
                          }
                        }
                else {
                       
                        while (nsect--){
                                 printk("reading \n";
                                 HWIF(drive)->ata_input_data(drive, buf, SECTOR_WORDS);
                                   buf +=SECTOR_WORDS;
                                 goto judge;
                          }

                }

        /* If it was the last datablock check status and finish transfer. */
        #if 0
        if (!hwif->nleft) {
                stat = wait_drive_not_busy(drive);
                if (!OK_STAT(stat, 0, BAD_R_STAT))
                        return task_error(drive, rq, __FUNCTION__, stat);
                task_end_request(drive, rq, stat);
                return ide_stopped;
        }
        #endif
        /* Still data left to transfer. */
        //ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);

        return ;

}

/**/
void ide_log_raw(ide_drive_t *drive, sector_t block, int cmd, char * buf, int len)
{
        ide_hwif_t *hwif        = HWIF(drive);
        unsigned int dma        = drive->using_dma;
        u8 lba48                = (drive->addressing == 1) ? 1 : 0;
        task_ioreg_t command        = WIN_NOP;
        ata_nsector_t                nsectors;
        task_ioreg_t tasklets[10];
        u8 stat;
        int i=0;
        nsectors.all                = ((len % SECTOR_SIZE) == 0) ? len / SECTOR_SIZE : len / SECTOR_SIZE + 1;

        printk(KERN_INFO "%s %s dma:%d ! \n", __FUNCTION__, drive->name, dma);

        printk(KERN_INFO "%s %s first close other core   ! \n", __FUNCTION__, drive->name);

#ifdef CONFIG_SMP
        /*
         * Note smp_send_stop is the usual smp shutdown function, which
         * unfortunately means it may not be hardened to work in a panic
         * situation.
         */
        smp_send_other_cpu_stop();
#endif

        ndelay(1000);
        /*first reset drive*/
        printk(KERN_INFO "%s %s reset drive   ! \n", __FUNCTION__, drive->name, dma);

       
        //hwif->OUTBSYNC(drive, WIN_SRST, IDE_COMMAND_REG);
        hwif->OUTBSYNC(drive, 0x04, IDE_CONTROL_REG);
        udelay(1000);
        hwif->OUTBSYNC(drive, WIN_SRST, IDE_COMMAND_REG);
       
checkstat:
        udelay(1000);
       
        if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) {
                printk("%s: ATAPI reset complete,stat: %02x\n", drive->name, stat);
        } else {
                if(i++ < 1000){
                        goto checkstat;
                }
                printk("after reset, 1000 cycles,  still busy ide,force to rw,stat:%02x\n", stat);
               
        }
       
       
       
        if (hwif->no_lba48_dma && lba48 && dma) {
                if (block + nsectors.all > 1ULL << 2
                        dma = 0;
                else
                        lba48 = 0;
        }

        if (!dma) {
                printk(KERN_INFO "%s %s don't use dma ! \n", __FUNCTION__, drive->name);
                //ide_init_sg_cmd(drive, rq);
                //ide_map_sg(drive, rq);
        } else
                printk(KERN_INFO "%s %s use dma ! \n", __FUNCTION__,  drive->name);

/*
        if (IDE_CONTROL_REG)
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
*/

        tasklets[2] = 1;
        tasklets[3] = block;
        tasklets[4] = (task_ioreg_t) (block>>;
        tasklets[5] = (task_ioreg_t) (block>>16);
        tasklets[6] = (task_ioreg_t)( (block>>24) | 0xe0);

        printk("0-9 regist list: %lx %lx    %lx %lx %lx %lx %lx     %lx  %lx %lx \n",IDE_DATA_REG,IDE_ERROR_REG,
                IDE_NSECTOR_REG, IDE_SECTOR_REG, IDE_LCYL_REG, IDE_HCYL_REG, IDE_SELECT_REG,
                IDE_STATUS_REG,IDE_CONTROL_REG,IDE_IRQ_REG);
       
        printk("%s write register form 2->6 values: 0x%02x 0x%02x  0x%02x 0x%02x 0x%02x\n",
                drive->name, tasklets[2], tasklets[3],
                tasklets[4], tasklets[5], tasklets[6]);
        //hwif->OUTB(0x00, IDE_FEATURE_REG);
        hwif->OUTB(tasklets[2], IDE_NSECTOR_REG);
        hwif->OUTB(tasklets[3], IDE_SECTOR_REG);
        hwif->OUTB(tasklets[4], IDE_LCYL_REG);
        hwif->OUTB(tasklets[5], IDE_HCYL_REG);
        hwif->OUTB(tasklets[6], IDE_SELECT_REG);

        printk(KERN_INFO "%s drive->mult_count:%d  lba48:%d \n", drive->name,drive->mult_count,lba4;
        if (cmd == READ) {
                command =  WIN_READ;
                rw_log_raw(drive, command,  buf, len, 0);
                return ;
        } else {
                command = WIN_WRITE;
                rw_log_raw(drive, command,  buf, len, 1);
        }
        return;
}

/*cmd : READ or         WRITE*/
void panic_ide_log(sector_t block, int cmd, char * buf, int len)
{
        if(panic_log_driver){
                printk(KERN_INFO"%s find panic_log_driver then to rw \n",__FUNCTION__);
                ide_log_raw(panic_log_driver,  block,  cmd,  buf,  len);
        } else {
                printk(KERN_INFO"%s panic_log_driver NULL !!!\n",__FUNCTION__);
        }
}

结果:

begin run panic_ide_log
panic_ide_log find panic_log_driver then to rw
ide_log_raw hdd dma:0 !
ide_log_raw hdd first close other core   !
ide_log_raw hdd reset drive   !
hdd: ATAPI reset complete,stat: 7f
ide_log_raw hdd don't use dma !
0-9 regist list: 170 171    172 173 174 175 176     177  376 0
hdd write register form 2->6 values: 0x01 0x01  0x00 0x00 0xe0
hdd drive->mult_count:16  lba48:1
nsect is 1
write cmd to ide: 0x20
good state , now to read or write,stat:7f  
reading
good state , now to read or write,stat:7f  

ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffff

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文