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 ;
알고리즘 자체가 간단하고 이해하기 쉬울 텐데 다른 친구들도 나처럼 이 작은 문제를 발견했는지 모르겠다.

좋은 웹페이지 즐겨찾기