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/ |