OSDev

для всех
Текущее время: 29 апр 2024, 07:17

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 14 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 12:25 

Зарегистрирован: 30 янв 2010, 19:44
Сообщения: 63
чтение с 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 +
и т.д.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 12:57 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
Он не читает по 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 бита.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 13:38 

Зарегистрирован: 30 янв 2010, 19:44
Сообщения: 63
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 ...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 13:57 

Зарегистрирован: 30 янв 2010, 19:44
Сообщения: 63
не.. можете глянуть по реализации правильно ли делается?
а то мож у меня гдето-чтото с параметрами работы с ATA не так делается?
чтото у меня данные какието неправильные идут..


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 14:42 

Зарегистрирован: 30 янв 2010, 19:44
Сообщения: 63
доработал немного для наглядности..

Код:
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 байтового блока
остальное содержимое блока, до вертикальной черты это начало, после - конончание

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 14:54 

Зарегистрирован: 30 янв 2010, 19:44
Сообщения: 63
или мож поделитесь просто своей процедурой чтения.. мне надо читать через порты, без использования прерывания, в режиме LBA..


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 15:32 

Зарегистрирован: 30 янв 2010, 19:44
Сообщения: 63
может это изза того что данные на виртуальном диске в bochs находятся не по порядку?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 16:17 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
qeos писал(а):
а по первому:
чтение идет WORD.. его надо класть в буфер WORD*..

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

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 04 окт 2011, 21:43 

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


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблемы чтения с hdd
СообщениеДобавлено: 09 окт 2011, 18:40 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
Похоже, вся соль во флаге направления, который ты в этом месте обнуляешь, хотя он должен быть обнулён ещё до вызова данной функции. Компилятор тут не причём, т.к. он считает, что флаг всегда сброшен. Наверно, ты не обнуляешь его на входе в обработчик прерывания от винчестера, а надо бы.

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

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


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 26


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB