From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Fri, 22 Feb 2002 19:33:51 +0300 From: Sergey Vlasov To: devel@altlinux.ru Cc: hihin@rambler.ru, smi@altlinux.ru Subject: Re: [devel] =?KOI8-R?B?4cfB1A==?= Message-Id: <20020222193351.2328e7b8.vsu@mivlgu.murom.ru> In-Reply-To: <1012136912.20020220040338@rambler.ru> References: <1012136912.20020220040338@rambler.ru> X-Mailer: Sylpheed version 0.7.2 (GTK+ 1.2.10; i586-alt-linux) Mime-Version: 1.0 Content-Type: text/plain; charset=KOI8-R Content-Transfer-Encoding: 8bit Sender: devel-admin@altlinux.ru Errors-To: devel-admin@altlinux.ru X-BeenThere: devel@altlinux.ru X-Mailman-Version: 2.0 Precedence: bulk Reply-To: devel@altlinux.ru List-Help: List-Post: List-Subscribe: , List-Id: List-Unsubscribe: , List-Archive: Archived-At: List-Archive: List-Post: On Wed, 20 Feb 2002 04:03:38 +0300 hihin_rambler wrote: > У нас на "Агате" накопилось к Вам несколько вопросов: > > По разработке драйверов нестандартных устройств: > > 1. Возможность работы с ПДП в Linux (МСВС). > Существует устройство, ведущее обмен информацией по прямому доступу. > Для передачи / приема информации надо указать устройству 24х-разрядный > адрес (ISA) из области памяти (для контроллера прямого доступа). > ВОПРОС: Как преобразовать 32х-разрядный адрес выделенной памяти к > необходимому виду или как выделить память, находящуюся в границах > 24 разрядов? Будет ли этот адрес постоянным в процессе работы? > Как это сделать на уровне ядра и на уровне пользователя? char *buffer = kmalloc (size, GFP_KERNEL | GFP_DMA) unsigned long buffer_phys = virt_to_bus (buffer); Физические адреса такого блока фиксируются в момент выделения и в дальнейшем не меняются. На пользовательском уровне это не делается - только через написание драйвера для ядра. > 2.Обработка аппаратных прерываний. > Если прерывания обрабатываются на уровне ядра,как организовать > синхронную передачу информации в пользовательский процесс? Что такое "синхронная передача" в Вашем понимании? Если Вы хотите обрабатывать прерывания в пользовательском процессе - это невозможно. Обработчик прерывания в ядре может активизировать процесс, находящийся в состоянии ожидания, но это не означает, что этот процесс начнет немедленно выполняться. Поэтому в любом случае необходима буферизация на уровне ядра. Стандартный подход следующий: процесс выполняет системный вызов (read или ioctl), запрашивая данные. Если в этот момент есть готовые данные, они копируются в буфер пользовательского процесса, и выполнение системного вызова завершается. Если данные не готовы - в зависимости от состояния флага O_NONBLOCK либо процессу немедленно возвращается ошибка EAGAIN, либо процесс переводится в состояние ожидания до поступления данных (либо прихода сигнала). Кроме того, процесс может проверять готовность с помощью системных вызовов select или poll. Наконец, можно установить O_ASYNC и получать сигнал при готовности устройства. Разумеется, для всего этого должна быть соответствующая поддержка в драйвере.