Board.KolibriOS.org

Official KolibriOS board
It is currently Wed Apr 24, 2019 9:17 pm

All times are UTC+03:00




Post new topic  Reply to topic  [ 34 posts ]  Go to page Previous 1 2 3 Next
Author Message
PostPosted: Tue Jun 14, 2011 8:13 pm 
Offline
Moderator

Joined: Thu Apr 08, 2010 8:11 pm
Posts: 269
Я брал import.inc вот тут: (локальная копия svn) kolibrios.org\drivers


Top
   
PostPosted: Tue Jun 14, 2011 8:17 pm 
Offline

Joined: Mon Sep 24, 2007 11:11 am
Posts: 2814
Странно. Может, подключается imports из какой-то другой папки? Хотя вряд ли.
Вопрос остается открытым.


Top
   
PostPosted: Tue Jun 14, 2011 9:07 pm 
Offline
Moderator

Joined: Thu Apr 08, 2010 8:11 pm
Posts: 269
То есть с кодом всё в принципе в порядке?


Top
   
PostPosted: Wed Jun 15, 2011 8:02 am 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Статью не читаем, исходники не смотрим.
Code:
;public version
В папке kernel/trunk/drivers специально лежит sceletone.asm


Top
   
PostPosted: Wed Jun 15, 2011 8:37 am 
Offline
Moderator

Joined: Thu Apr 08, 2010 8:11 pm
Posts: 269
Статью я читаю раза 2 в день :) Видимо не внимательно, но если не:

Code:
;public version


он даже не пишет:

Code:
in module .....


То-есть не загружает?

Это в первом варианте, с макросами, а как быть во втором?


Top
   
PostPosted: Wed Jun 15, 2011 8:50 am 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
version ведь не случайно public объявляется. Загрузчик драйвера проверяет версию драйверной модели.


Top
   
PostPosted: Wed Jun 15, 2011 12:11 pm 
Offline
Kernel Developer
User avatar

Joined: Thu Sep 03, 2009 1:52 pm
Posts: 1619
Функция START тоже должна быть объявлена как public. Во втором случае этого не сделано.

_________________
Сделаем мир лучше!


Top
   
PostPosted: Wed Jun 15, 2011 1:38 pm 
Offline
Moderator

Joined: Thu Apr 08, 2010 8:11 pm
Posts: 269
В первом коде, действительно, нужно было public version, так заработало, тут моя невнимательность и торопливость, но во втором примере так нельзя сделать, пишет что символ переопределён...что тут можно сделать?


Top
   
PostPosted: Wed Jun 15, 2011 3:44 pm 
Offline
Kernel Developer
User avatar

Joined: Thu Sep 03, 2009 1:52 pm
Posts: 1619
popovpa, подробнее, пожалуйста. У меня этот код с добавлением "public version" и "public START" не компилируется, но только потому, что imports.inc хочет объявления "DEBUG equ 1" - или "... equ 0" - до включения, после такого объявления компиляция успешна.

_________________
Сделаем мир лучше!


Top
   
PostPosted: Wed Jun 15, 2011 3:59 pm 
Offline
Moderator

Joined: Thu Apr 08, 2010 8:11 pm
Posts: 269
Простите, но было что-то странное, не компилировалось из тинипада, на доске отладки писало что данное имя уже используется, сейчас перезагрузился и всё откомпилировалось и запустилось без проблем...извините за беспокойство...видимо солнечная активность...:) разбираюсь дальше...


Top
   
PostPosted: Wed Jun 22, 2011 8:33 pm 
Offline
Moderator

Joined: Thu Apr 08, 2010 8:11 pm
Posts: 269
Здравствуйте!

Почему не выводится сообщение в service_proc:

Code:
mov   esi, msgProc
call   SysMsgBoardStr


Code:
format MS COFF

include 'proc32.inc'
include 'imports.inc'

OS_BASE    equ 0;
new_app_base   equ 0x60400000
PROC_BASE   equ OS_BASE+0x0080000

struc IOCTL
{  .handle   dd ?
   .io_code   dd ?
   .input   dd ?
   .inp_size   dd ?
   .output   dd ?
   .out_size   dd ?
}

virtual at 0
  IOCTL IOCTL
end virtual

public START
public service_proc
public version

section '.flat' code readable align 16

START:
   push   ebp
   mov   ebp,esp
   mov   eax,[ebp+8]

   cmp   eax,1
   jnz   .exit

   mov   esi, msgStart
   call   SysMsgBoardStr

   push   service_proc
   push   my_service
   call   RegService

   pop   ebp
   ret   4

.exit:
   mov   esi, msgBad
   call   SysMsgBoardStr

   pop   ebp
   xor   eax,eax
   ret   4

handle      equ   IOCTL.handle
io_code    equ   IOCTL.io_code
input      equ   IOCTL.input
inp_size   equ   IOCTL.inp_size
output      equ   IOCTL.output
out_size   equ   IOCTL.out_size

service_proc:

   push   ebp
   mov   ebp,esp

      mov ebx, [ebp+4]
      mov eax, [ebx+io_code]
      cmp eax, 0
      jne @F

      mov eax, [ebx+output]
      cmp [ebx+out_size], 4
      jne .fail
      mov [eax], dword 0

   mov   esi, msgProc
   call   SysMsgBoardStr

      xor eax, eax
      ret
@@:
.fail:

   mov   esi, msgProc
   call   SysMsgBoardStr

      or eax, -1
      ret


version    dd   0x50005
my_service   db   'bcm4312',0

section '.data' data readable writable align 16


msgStart db 'Start...',0
msgProc db 'Proc...',0
msgBad db 'Bad...',0


И ещё 1 вопрос, структура ioctl служит для общения драйвера с операционной системой? И если да, то можно объяснить хоть в общих чертах что-же это всё таки такое.

Спасибо!


Top
   
PostPosted: Wed Jun 22, 2011 9:14 pm 
Offline
Kernel Developer
User avatar

Joined: Thu Sep 03, 2009 1:52 pm
Posts: 1619
popovpa, во-первых, убедись, что управляющая программа вообще вызывает функцию 68.17, потому что само по себе ядро этого делать не будет. Во-вторых, ошибка в строке
Code:
mov ebx,[ebp+4]

Я поясню, откуда вообще берутся эти смещения. В часто используемой модели вызова stdcall - которая, в частности, применяется при вызове ядром service_proc - параметры кладутся в стек, начиная с последнего; поскольку стек растёт вниз, то перед вызовом stdcall-функции с параметрами arg1, arg2, arg3 стек выглядит так:
Code:
arg3 <- esp+8
arg2 <- esp+4
arg1 <- esp - верхушка стека

Вызов функции в x86 осуществляется путём сохранения в тот же стек адреса возврата - откуда его потом может достать команда ret - и передачи управления функции. Таким образом, esp уменьшается на 4 и перед первой инструкцией функции стек выглядит так:
Code:
arg3 <- esp+12
arg2 <- esp+8
arg1 <- esp+4
адрес возврата <- esp

Поскольку esp в пределах функции часто "плавает", то везде адресовать относительно esp неудобно, хотя и можно. Кроме того, адресация через esp длиннее на байт. Поэтому часто начальное значение esp копируется в ebp, который уже не "плавает", и смещения относительно ebp постоянны. В модели вызова stdcall функция не должна разрушать регистр ebp - между прочим, к регистрам ebx, esi, edi это тоже относится - поэтому его нужно сохранить в том же стеке, а при выходе не забыть восстановить. Первая инструкция push ebp сохраняет текущее значение ebp, после чего esp ещё немного "уплывает" и стек выглядит так:
Code:
arg3 <- esp+16
arg2 <- esp+12
arg1 <- esp+8
адрес возврата <- esp+4
сохранённое значение ebp <- esp

В этот момент регистру ebp присваивается значение esp, и внутри функции дальше можно обращаться к аргументам так:
Code:
arg3 <- ebp+16
arg2 <- ebp+12
arg1 <- ebp+8
адрес возврата <- ebp+4
сохранённое значение ebp <- ebp


Структура IOCTL используется для передачи драйверу запросов из внешнего мира - обычно из приложения посредством функции 68.17. Сама структура содержит параметры этих запросов - код запроса и, опционально, указатели на входные и/или выходные данные и размеры этих данных. Драйвер обращается к внешнему миру посредством API ядра, объявленных в imports.inc.

_________________
Сделаем мир лучше!


Top
   
PostPosted: Thu Jun 23, 2011 12:06 pm 
Offline

Joined: Tue Sep 12, 2006 9:44 pm
Posts: 37
Quote:
И ещё 1 вопрос, структура ioctl служит для общения драйвера с операционной системой? И если да, то можно объяснить хоть в общих чертах что-же это всё таки такое.

Попробую ответить

После команды загрузки драйвера (68.16) ядро выделяет память под драйвер загружает, и после успешной проверки передает ему управление на точку START. Далее идет твой код до точки REG_SERVICE, после передается управление этой подпрограмме в ядре которая регистрирует точку входа твоей подпрограммы с параметром service_proc ну и еще кое какой хлам.Если все пройдет нормально то подпрограмма вернет тебе HENDL твоего драйвера, и драйвер должен вернуть управление системе. После вызова функции 68.17 по ХЕНДЛУ ядро по таблице находит точку входа service_proc и передает управление ей. А структура ioctl это кусок памяти в твоем приложении, где ты сохраняешь ХКНДЛ, код функции ,длину и т.д. драйвер если сказать проще открывает ТОННЕЛЬ к ней.

_________________
Все сложное - просто!


Top
   
PostPosted: Wed Aug 24, 2011 4:44 pm 
Offline
Moderator

Joined: Thu Apr 08, 2010 8:11 pm
Posts: 269
Здравствуйте!

Я не оставил надежд написать драйвер, пишу драйвер для своей wi-fi (встроенной) карточки. Так как тема явно растянется, прошу модератором переименовать тему в что-то подобное: "Драйвер для bcm43xx"...

А теперь собственно вопросы:

Я нашёл своё устройство, спасибо sceletone.asm. Затем как я понял необходимо считать Base Address Registers, а уже зная его, считывать данные из устройства (это будут смещения относительно этого адреса?). Дальше у меня есть драйвер для моей карточки под Linux, но я так и не смог с ним разобраться, точнее если первое утверждение было верное, я не смог найти смещения которые надо считывать или записывать, может кто-то более опытный взглянет краем глаза и ткнёт носом что примерно и где искать? Буду очень благодарен. Или я всё не правильно понял? А если так может посоветуете что почитать, желательно на русском, чтобы я стал на пол миллиметра ближе к профи....

Спасибо!


Top
   
PostPosted: Wed Aug 24, 2011 8:10 pm 
Offline
Kernel Developer
User avatar

Joined: Thu Sep 03, 2009 1:52 pm
Posts: 1619
Способ обращения зависит от того, располагается BAR в I/O пространстве или в памяти. Разные BARы одного устройства могут жить в разных пространствах. Младший бит каждого BARа - read-only, 1 для BARов в I/O, 0 для BARов в памяти. Для конкретного устройства один и тот же регистр всегда находится в одном и том же пространстве, хотя конкретный адрес можно изменять. Каждый BAR задаёт базовый адрес некоторого диапазона адресов; смещения регистров внутри диапазона фиксированы. Детали
Для BARов из I/O пространства базовый адрес есть значение BARа с обнулёнными двумя младшими битами, обращение осуществляется командами in/out:
Code:
; если eax = значение BAR
and al,not 3
lea edx,[eax+DeviceRegister]
in {al|ax|eax},dx ; al/ax/eax = register value
out dx,{al|ax|eax} ; set register value to al|ax|eax

Для BARов в памяти базовый физический адрес есть значение BARа с обнулёнными четырьмя младшими битами. Прежде чем использовать такой диапазон, о нём нужно известить ОС, после чего с ним можно работать как с любой памятью:
Code:
; если eax = значение BAR
and al,not 0Fh
stdcall MapIoMem,eax,<size>,1Bh ; PG_SW+PG_NOCACHE, kernel-writable non-cacheable memory range
test eax,eax
jz die
mov ecx,[eax+DeviceRegister] ; ecx = register value
or dword [eax+DeviceRegister],10000h ; set bit in the register

_________________
Сделаем мир лучше!


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 34 posts ]  Go to page Previous 1 2 3 Next

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited