Orange's:一个操作系统的实现 源码的一处小Bug

最近在学习于渊先生《Orange's:一个操作系统的实现》这本书,源码中有关硬盘驱动程序中的一段代码,似乎有些问题,贴出来与大家分享下。

PRIVATE void hd_rdwt(MESSAGE * p)
{
     int drive = DRV_OF_DEV(p->DEVICE);

     u64 pos = p->POSITION;
     assert((pos >> SECTOR_SIZE_SHIFT) < (1 << 31));

     /**
     * We only allow to R/W from a SECTOR boundary:
     */
     assert((pos & 0x1FF) == 0);

     u32 sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT); /* pos / SECTOR_SIZE */
     int logidx = (p->DEVICE - MINOR_hd1a) % NR_SUB_PER_DRIVE;
     sect_nr += p->DEVICE < MAX_PRIM ?
          hd_info[drive].primary[p->DEVICE].base :
          hd_info[drive].logical[logidx].base;

     struct hd_cmd cmd;
     cmd.features     = 0;
     cmd.count     = (p->CNT + SECTOR_SIZE - 1) / SECTOR_SIZE;
     cmd.lba_low     = sect_nr & 0xFF;
     cmd.lba_mid     = (sect_nr >>  8) & 0xFF;
     cmd.lba_high     = (sect_nr >> 16) & 0xFF;
     cmd.device     = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF);
     cmd.command     = (p->type == DEV_READ) ? ATA_READ : ATA_WRITE;
     hd_cmd_out(&cmd);

     int bytes_left = p->CNT;
     void * la = (void*)va2la(p->PROC_NR, p->BUF);

     while (bytes_left) {
          int bytes = min(SECTOR_SIZE, bytes_left);
          if (p->type == DEV_READ) {
               interrupt_wait();
               port_read(REG_DATA, hdbuf, SECTOR_SIZE);
               phys_copy(la, (void*)va2la(TASK_HD, hdbuf), bytes);
          }
          else {
               if (!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT))
                    panic("hd writing error.");

               port_write(REG_DATA, la, bytes);
               interrupt_wait();
          }
          bytes_left -= SECTOR_SIZE;
          la += SECTOR_SIZE;
     }
}


以上是硬盘驱动程序中读写硬盘的一段代码,在while循环中向硬盘读取或写入数据。bytes_left变量记录着需要读写的剩余字节数。
while循环中的变量bytes 记录着每次循环处理的字节数,但是在while循环的末尾却是这样两行代码:
bytes_left -= SECTOR_SIZE;
la += SECTOR_SIZE;

显然不妥,正确的写法应该是:
bytes_left -= bytes ;
la += bytes ;

算法本身很简单,应该也容易理解,不知道有没有其他朋友也和我一样,发现了这个小问题。



你可能感兴趣的:(于渊,操作系统,实现,源码,BUG)