OSDev
http://osdev.su/

проблемы чтения с hdd
http://osdev.su/viewtopic.php?f=6&t=448
Страница 1 из 2

Автор:  qeos [ 04 окт 2011, 12:25 ]
Заголовок сообщения:  проблемы чтения с hdd

чтение с hdd через порты ВВ..


есть у меня такой код.. собсно он прост..
Код:
void hdd_read(ATA_DEVICE * dev, u16 count, u32 lba, u16 *buf){
    hdd_wait_busy(dev);
    outb(0x40 | dev->slavebit<<4, dev->base + REG_DEVICE);
    outb((count>>8) & 0x0f, dev->base + REG_SECTORS);    // hi part
    outb((lba>>12) & 0x0f,  dev->base + REG_LBA_LO);
    outb((lba>>16) & 0x0f,  dev->base + REG_LBA_MID);
    outb((lba>>24) & 0x0f,  dev->base + REG_LBA_HI);
    outb((count) & 0x0f,    dev->base + REG_SECTORS);    // low part
    outb((lba) & 0x0f,      dev->base + REG_LBA_LO);
    outb((lba>>4) & 0x0f,   dev->base + REG_LBA_MID);
    outb((lba>>8) & 0x0f,   dev->base + REG_LBA_HI);

    int i,j;
    for(i = 0; i<count; i++){
        sys_log("Get sector %i\r\n",i);
        outb(0x24, dev->base + REG_COMMAND);
        hdd_wait_ready(dev);
        if(inb(dev->base+REG_COMMAND) & 1){
            sys_log("filesystem.c\tHDD\tGot some error while reading sector %i\r\n",lba+i);
            return;
        }
        for(j = 0; j<256; j++){
            buf[i*512+j] = inw(dev->base);
        }
    }


вот при чтении с 3 сектора 8 секторов он мне как то странно читает..
00 +
01 +
02 -
03 +
04 +
05 -
06 -
07 +
08 +
09 -
10 -
11 +
12 +
и т.д.

т.е. чтение странным образом идет по два сектора.. однако циклы проходят все..
есть идеи что может быть?

Автор:  Himik [ 04 окт 2011, 12:57 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

Он не читает по 2 сектора, а растягивает данные одного сектора на 2. Ошибка в индексации элементов буфера. Если i является индексом 512-байтового сектора, то индексировать buf надо с умножением на 256, а не 512, т.к. это буфер двухбайтовых элементов (2 * 256 = 512).

Ещё здесь похоже на нелогичность
outb((count>>8) & 0x0f, dev->base + REG_SECTORS); // hi part
Здесь count скорее всего надо сдвигать на 4, т.к. записываются младшие 4 бита и старшие 4 бита, судя по маске 0x0F на 4 бита.

Автор:  qeos [ 04 окт 2011, 13:38 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

Himik писал(а):
Он не читает по 2 сектора, а растягивает данные одного сектора на 2. Ошибка в индексации элементов буфера. Если i является индексом 512-байтового сектора, то индексировать buf надо с умножением на 256, а не 512, т.к. это буфер двухбайтовых элементов (2 * 256 = 512).

Ещё здесь похоже на нелогичность
outb((count>>8) & 0x0f, dev->base + REG_SECTORS); // hi part
Здесь count скорее всего надо сдвигать на 4, т.к. записываются младшие 4 бита и старшие 4 бита, судя по маске 0x0F на 4 бита.


да! пасибо именно на 4 ))

а по первому:
чтение идет WORD.. его надо класть в буфер WORD*..
если я пишу buf[i*256+j], то у меня они аккуратно ложатся друг за другом, но также пропуская сектора..
т.е.
00 01 03 04 07 08 11 12 ...

Автор:  qeos [ 04 окт 2011, 13:57 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

не.. можете глянуть по реализации правильно ли делается?
а то мож у меня гдето-чтото с параметрами работы с ATA не так делается?
чтото у меня данные какието неправильные идут..

Автор:  qeos [ 04 окт 2011, 14:42 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

доработал немного для наглядности..

Код:
Total blocks: 10080     Block type: 0   Size of hdd: 4 Mbytes
 lba: 3 count: 8
 (lba>>12) & 0x0f: 00   (lba>>16) & 0x0f: 00    (lba>>24) & 0x0f: 00
 (lba) & 0x0f: 03       (lba>>4) & 0x0f: 00     (lba>>8) & 0x0f: 00
Get sector 0
0 0001 0000 ffff ffff ffff ffff 0004 0000 | 8888 0000 8888 0000 8888 0000
Get sector 1
1 0003 0000 8888 0000 8888 0000 8888 0000 | 8888 0000 8888 0000 8888 0000
Get sector 2
2 0007 0000 8888 0000 8888 0000 8888 0000 | 8888 0000 8888 0000 8888 0000
Get sector 3
3 000b 0000 8888 0000 8888 0000 8888 0000 | 8888 0000 8888 0000 8888 0000
Get sector 4
4 000f 0000 8888 0000 8888 0000 8888 0000 | 8888 0000 8888 0000 8888 0000
Get sector 5
5 0013 000П 8888 0000 8888 0000 8888 0000 | 8888 0000 8888 0000 8888 0000
Get sector 6
6 0017 0000 8888 0000 8888 0000 8888 0000 | 8888 0000 8888 0000 8888 0000
Get sector 7
7 001b 0000 8888 0000 8888 0000 8888 0000 | 8888 0000 8888 0000 8888 0000


Get sector 1
1 0003 0000 8888 0000 8888 0000 8888 0000 | 8888 0000 8888 0000 8888 0000
^ номер итерации, i
___^^^^^^ номер 512 байтового блока
остальное содержимое блока, до вертикальной черты это начало, после - конончание

т.е. тут видно, что чтение идет не по порядку, а "перескакивая"..

Автор:  qeos [ 04 окт 2011, 14:54 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

или мож поделитесь просто своей процедурой чтения.. мне надо читать через порты, без использования прерывания, в режиме LBA..

Автор:  qeos [ 04 окт 2011, 15:32 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

может это изза того что данные на виртуальном диске в bochs находятся не по порядку?

Автор:  Himik [ 04 окт 2011, 16:17 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

qeos писал(а):
а по первому:
чтение идет WORD.. его надо класть в буфер WORD*..

В одном 512-байтном секторе 256 значений WORD, понимаешь?
qeos писал(а):
если я пишу buf[i*256+j], то у меня они аккуратно ложатся друг за другом, но также пропуская сектора..

Значит ещё где-то ошибка. У меня процедуры чтения ATA нет, ни чем помочь не могу. Могу только посоветовать почитать книжки, типа "Программирование на аппаратном уровне", "Программирование дисковых подсистем" Владимир Кулаков.

Автор:  qeos [ 04 окт 2011, 21:43 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

видимо чтото с компилятором было связано.. переделал на
Код:
        asm("cld \r\n\
            rep insw"::"c"(256),"d"(dev->base+REG_DATA),"D"(buf));


все заработало

Автор:  Himik [ 09 окт 2011, 18:40 ]
Заголовок сообщения:  Re: проблемы чтения с hdd

Похоже, вся соль во флаге направления, который ты в этом месте обнуляешь, хотя он должен быть обнулён ещё до вызова данной функции. Компилятор тут не причём, т.к. он считает, что флаг всегда сброшен. Наверно, ты не обнуляешь его на входе в обработчик прерывания от винчестера, а надо бы.

В принципе, у компилятора есть опция, которая принудительно сбрасывает флаг направления перед каждой строковой инструкцией, точно так же, как ты написал. Но это не оптимальное решение.

Кстати, в asm вставке ты предаёшь buf без индекса сектора i, что странно.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/