Устройство flash диск на PCI плате, нужно обеспечить разбиение его на разделы. Исходников просмотрел много. Понял, что для работы таких утилит как mount, mkfs, и для разбиения его на разделы, достаточно реализовать чтение запись и IOCTL, помимо всего остального типа open release cleanup. Но проблема заключается в следующем: -когда записываю в устройство какой-нибудь файл с помощью обычного cat f3 > /dev/flashdisc, а потом читаю таким же образом, то вижу, что не весь файл читается (или не весь пишется...отследить не могу). В прочитанном файле видны дыры т.е. например первые 512байт соответствуют тексту исходного файла, потом какая-нибудь дыра объёмом кратным 256 байт, потом опять нормальный текст. Если заменить низкоуровневые функции чтения записи на простое memcpy, то никаких дыр нет. Под ДОСом похожий драйвер работает, и там такие же (абсолютно одинаковые) низкоуровневые функции чтения записи... Вот и ищу причину... Может кто-нибудь имеет опыт написания драйверов блочных устройств?
мне кажется, что исходник ваших функций чтения/записи/probe а так же название флеша заметно бы оживили дискуссию
Код (Text): static int fd_make_request(request_queue_t * q, int rw, struct buffer_head *sbh) { unsigned int minor; unsigned long offset, len; minor = MINOR(sbh->b_rdev); if (minor >= NUM_FDISKS) goto fail; offset = sbh->b_rsector << 9; len = sbh->b_size; if ((offset + len) > 0x400000) goto fail; if (rw==READA) rw=READ; if ((rw != READ) && (rw != WRITE)) { printk(KERN_INFO "FLASHDISK: bad command: %d\n", rw); goto fail; } if (fd_blkdev_IO(rw, sbh, minor)) goto fail; sbh->b_end_io(sbh,1); return 0; fail: buffer_IO_error(sbh); return 0; } //========================================= static int fd_blkdev_IO(int rw, struct buffer_head * sbh, int minor) { int offset, size; char * pt; uc KS; offset = sbh->b_rsector << 9; if(minor==1) offset += (32 << 9); size = sbh->b_size; pt = bh_kmap(sbh); do { if (rw == READ) { //memcpy(pt, h+offset, 512); PageRead((offset>>9), pt, &KS); //читаем по секторам } else { KS = CalcSectorKS(pt); //контрольная сумма //memcpy(h+offset, pt, 512); PageProg((offset>>9), pt, KS); //пишем по секторам } offset += FLASH_SEC_SIZE; pt += FLASH_SEC_SIZE; size -= FLASH_SEC_SIZE; } while (size>0); bh_kunmap(sbh); return 0; } PageRead-чтение PageProg-запись (в ДОСе работают!!! там только обращение к портам через inb() outb() ) всё писалось по аналогии с RAM диском...
флешка сама 4МБ, чтение запись организована по секторам т.е. по 512б +1б контрольная сумма. Не смущает что чтение и запись работает под ДОСом?
смущает. попробуйте инвалидейтить кеш-линейки с буфера данных перед чтением флешки и сбрасывать их после записи
Так, с чтением/записью разобрался!!! Оказалось, что там флешка не успевала обрабатывать запросы inb(), outb(). Заменил на inb_p(), outb_p() и заработало =) Теперь вопрос следующий: какие методы достаточно реализовать чтобы можно было флешку делить на разделы? посмотрел, как реализовано в hd.c, может его и брать за основу???
Люди, такой не скромный вопрос!!! Как в драйвере сделать, чтобы вызываемое его приложение отвалилось с ошибкой??? Ну например, если установлен флаг защиты от записи, я хочу чтобы простая "cat" завершилась с ошибкой....????
Пробовал, но приложение типа fdisk /dev/myflash после редактирования таблицы разделов, и выхода с сохранением уходит в бесконечный цикл...как сделать чтобы она завершалась с ошибкой и выходила???
В общем в другом месте поставил проверку, вроде пашет и не пишет =) , но как добиться, чтобы само приложение выдало ошибку???А то получается, что пользователь не увидит, что записи не было...
Всё разобрался, надо было в методе open реализовать проверку file->f_flags и file->f_mode на наличие обращения на запись. Если нельзя писать, то вернуть EROFS (read only FS)
Обнаружил следующую багу: после разбиения флешки на 2 раздела и создания на втором разделе(!!!) файловой системы, убиваются оба раздела!!! Т.е. после этих действий вызываю fdisk, а там разделов нет!!! Подскажите в чём может быть проблема и куда смотреть???
Вопрос другой. Как mkfs определяет адрес начала раздела, чтобы писать туда boot сектор, и как номер minor с этим связан???