Новая модель ядра

Kernel architecture questions
  • http://infinity-sound.narod.ru/ac97_005.rar
    Есть проблема с загрузкой ядра на некоторых компах. Загрузчик работает в unreal mode возможно это плохо сочетается с некоторыми БИОС. На мем компе и в эмуляторах все работает нормально, но это у меня.
    Я подготовил переходную версию версию на базе 0.5.8.1 (SVN.105). http://infinity-sound.narod.ru/058_006.rar Сюда вошли менеджер памяти, загружаемые драйверы, поддержка SSE и ещё некоторые незначительные изменения. Исходники драйверов и микшера/ресемплеров прилагаются. Сделаю драйвер для nForce и допишу недостающий код для ядра тогда всё выложу. Все изменения требуют большого количества тестов в разных конфигурациях, а с этим всегда проблема. Свежие новости выкладываю в ветке Драйверы/АС97.
  • Спасибо за информацию. А можно дать какой-нибудь прогноз, когда это будет закончено?
    Ушёл к умным, знающим и культурным людям.
  • Я бы и сам хотел знать когда все будет закончено. Если есть желающие потестить драйвер для nForce, отзовитесь. Это ускорит дело. Небольшая поправка
    http://infinity-sound.narod.ru/058_005.rar основной архив, а 058_006 обновление ядра до svn.116 и исправление незначительных багов в драйвере.
  • http://infinity-sound.narod.ru/060.7z бинарники
    http://infinity-sound.narod.ru/src_060.7z исходники ядра и плеера

    Это не совсем то ядро, о котором я писал но многие возможности сохранились: динамическое выделение памяти, загружаемые драйверы, поддержка SSE, большие и глобальные страницы. адресное пространство ядра 0х00000000 - 0х5FFFFFFF, приложения 60400000-0xBFFFFFFF адреса 0х60000000-0х603FFFFF занимают таблицы страниц. Вся обнаруженная VESA видеопамять отображается на свои физические адреса 4-х мегабайтными страницами, первая страница объявляется глобальной (если позволяет процессор). Первый 16 мегабайт памяти ядра также отображаются 4-х мегабайтными глобальными страницами.

    Новые функции ядра.
    kernel_alloc stdcall, size:dword - выделяет size байт в адресном пространстве ядра. Адрес выделенного блока выравнен на границу страницы.

    kernel_free stdcall, base:dword - освобождает выделенный ранее блок.
    alloc_kernel_space stdcall, size:dword - резервирует size байт в адресном пространстве ядра. Адрес зарезервированной области выравнен на границу страницы.

    free_kernel_space stdcall, base:dword - освобождает зарезервированную область.

    Блоки памяти размером 1-63 страницы выделяются по приципу best-fit больше 63 страниц first-fit.

    map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword - отображает сраницу phis_addr на линейный адрес lin_addr
    flags - флаги страницы
    PG_UNMAP equ 0x000 ;отмена отображения
    PG_MAP equ 0x001 ;страница присутствует
    PG_WRITE equ 0x002 ;запись разрешена
    PG_SW equ 0x003 ;супервизор
    PG_USER equ 0x005
    PG_UW equ 0x007 ;PG_WRITE or PG_USER
    PG_NOCACHE equ 0x018
    PG_LARGE equ 0x080 4 ;мегабайта
    PG_GLOBAL equ 0x100

    alloc_pages stdcall, count:dword - выделяет count страниц памяти.
    alloc_page - выделяет одну страницу памяти.
    free_page, eax = page address освобождает одну страницу.

    attach_int_handler stdcall, irq:dword, handler:dword - устанавливает обработчик прерываний handler() на вектор соответствующий irq В текущей версии можно установить обработчики для irq 1,3,5,7,8,9,10,11

    enable_irq stdcall, irq_line:dword размаскирует прерывание для irq_line

    get_service stdcall, sz_name:dword загружает драйвер sz_name и возвращает его логический номер.

    reg_service stdcall, sz_name:dword, handler:dword - регистрирует драйвер sz_name в системе и устанавливает функцию-обработчик драйвера handler()

    init_heap stdcall, heap_size:dword - создает кучу приложения. Размер кучи округляется до 4-х Мб в большую сторону. Выделенная из кучи память автоматически освобождается при завершении приложения.

    user_alloc stdcall, alloc_size:dword - выделяет страничную память из кучи приложения. Физические страницы страницы памяти выделяются при первом обращении.

    user_free stdcall, base:dword - возвращяет выделенный блок в кучу приложения.
  • О!Появились возможность работать с драйверами!

    А можно где-нибудь прочитать тоже самое,но в документированном виде ?

    Особенно меня заинтриговали стороки:

    > get_service stdcall, sz_name:dword загружает драйвер sz_name и возвращает его логический номер.

    reg_service stdcall, sz_name:dword, handler:dword - регистрирует драйвер sz_name в системе и устанавливает функцию-обработчик драйвера handler()
  • Драйверная модель пока не устоялась, так что вся информация предварительная. С терминологией тоже может быть путаница.
    intel.obj это типичный драйвер. Он ищет поддерживаемое устройство через вызовы PCI, настраивает, устанавливает обработчик IRQ, и обрабатывает аппаратные прерывания от контроллера. Intel.asm и Sis.asm можно использовать как общие шаблоны для подобных драйверов устройств. Infinity.obj программный драйвер. Он отвечает за создание буферов, ресемплирование и микширование звука. В исходниках встречается термин service обычно так называют драйвер, выполняющийся как отдельная задача. Таких в ОС пока нет.
    Система может загружать 32 драйвера. Каждый драйвер должен иметь своё уникальное имя. Максимальная длина имени 16 байт включая завершающий ноль. Драйвер регестрирует себя в системе вызывая функцию ядра reg_service stdcall, sz_name:dword, handler:dword
    sz_name имя драйвера, по этому имени будет происходить поиск драйвера при вызовах get_service. Проверок на совпадение имен не проводится. handler содержит адрес главной функции-обработчика драйвера.
    Взаимодействие с драйвером происходит через вызовы srv_handler, ioctl:dword если вызов из ядра, или srv_handlerEx stdcall, ioctl:dword если вызов из приложения. ioctl - адрес структуры IOCTL

    Code: Select all

    struc IOCTL
    {  .handler          dd ?   логический номер сервиса
       .io_code          dd ?   код команды
       .input            dd ?   указатель на входной буфер
       .inp_size         dd ?   размер буфера
       .output           dd ?   указатель на выходной буфер
       .out_size         dd ?   размер буфера
    }
    
    Вот пример вызова функции

    Code: Select all

    align 4
    proc SetMasterVol stdcall,hSrv:dword,vol:dword
    ;устанавливает значение регистра MASTER_VOLUME
    ;AC97 кодека
    
       ;макросы proc stdcall locals помогают
       ;передавать параметры через стек,
       ;создавать стековые переменные, избавлют от
       ;ненужных push и pop и позволяют не забивать голову
       ;вычислениями [esp+...]
       ;функцию можно вызывать как из ассемблерных программ
       ; так и из С программ объявив
       ; extern int stdcall   SetMasterVol(DWORD hSrv, int vol);
       ;для этого в asm файле функция должна быть указана как public
    
               locals
                 handle    dd ?
                 io_code    dd ?
                 input      dd ?
                 inp_size   dd ?
                 output     dd ?
                 out_size   dd ?
               endl
    
               mov eax, [hSrv]  ;логический номер драйвера "SOUND"
               lea ecx, [vol]   ;указатель на значение громкости
               xor ebx, ebx
    
               mov [handle], eax
               mov [io_code], DEV_SET_MASTERVOL  ж команда драйверу
               mov [input], ecx
               mov [inp_size], 4
               mov [output], ebx
               mov [out_size], 0
    
               lea eax, [handle]
    
               stdcall CallServiceEx, eax
    
     ;можно вызвать напрямую
     ;         mov eax, 68
     ;          mov ebx, 17
     ;          lea ecx, [handle]
     ;          int 0x40
     ;
               ret
    endp
    
    align 4
    proc CallServiceEx stdcall, ioctl:dword
               mov eax, 68
               mov ebx, 17
               mov ecx, [ioctl]
               int 0x40
               ret
    endp
    
    ;другие примеры в исходниках ac97wav.c и k_lib.asm
    
    загрузка драйверов происходит через вызов get_service stdcall, sz_name:dword эта функция ищет драйвер среди загруженных и если не находит, то загружает с диска. После чего управление передаётся точке входа драйвера "START" чтобы он выполнил настройку и зарегестрировал себя в системе. Функция возвращает логический номер драйвера (точнее это адрес структуры SRV в памяти ядра).

    Соответствие между именами драйверов(сервисов) и именами файлов пока жёстко задаются в ядре

    Code: Select all

    drv_sound      db 'INTEL   OBJ', 0  ;имена файлов
    drv_infinity   db 'INFINITYOBJ', 0
    
    szSound        db 'SOUND',0         ;регестрируемые имена
    szInfinity     db 'INFINITY',0
    
    szSTART        db 'START',0         ;имя точки входа драйвера
    szEXPORTS      db 'EXPORTS',0       ;не используется (для DLL)
    szIMPORTS      db 'IMPORTS',0       ;таблица импорта
    
    align 16
    services:                           ;таблица соответствия имя/файл
               dd szSound,    drv_sound
               dd szInfinity, drv_infinity
               dd 0                     ;последний элемент
    
    В будущем эту таблицу должен заменить текстовый файл.
    (например dev SOUND = /rd/intel.obj)

    Драйвер должен быть скомпилирован в формате MS СOFF и состоять из одной секции. Обязательно должны быть объявлены метки public START и public IMPORTS чтобы загрузчик мог найти их в таблице символов COFF файла.

    Динамическое связывание.
    Загрузчик просматривает таблицу IMPORTS и заменяет адреса строк sz... адресами функций ядра. Для этого строки с именами функций в драйвере и в ядре (exports.asm] должны совпадать. Порядок функций и строк не важен.

    Code: Select all

    align 16
    IMPORTS:
    
    AttachIntHandler   dd szAttachIntHandler
    SysMsgBoardStr     dd szSysMsgBoardStr
    PciApi             dd szPciApi
    PciRead32          dd szPciRead32
    PciRead8           dd szPciRead8
    AllocKernelSpace   dd szAllocKernelSpace
    MapPage            dd szMapPage
    KernelAlloc        dd szKernelAlloc
    KernelFree         dd szKernelFree
    GetPgAddr          dd szGetPgAddr
    RegService         dd szRegService
    GetCurrentTask     dd szGetCurrentTask
    GetService         dd szGetService
    ServiceHandler     dd szServiceHandler
    FpuSave            dd szFpuSave
    FpuRestore         dd szFpuRestore
                       dd 0               ;завершающий элемент
    
    szAttachIntHandler  db 'AttachIntHandler',0
    szSysMsgBoardStr    db 'SysMsgBoardStr', 0
    szPciApi            db 'PciApi', 0
    szPciRead32         db 'PciRead32', 0
    szPciRead8          db 'PciRead8', 0
    szAllocKernelSpace  db 'AllocKernelSpace',0
    szMapPage           db 'MapPage',0
    szRegService        db 'RegService',0
    szKernelAlloc       db 'KernelAlloc',0
    szGetPgAddr         db 'GetPgAddr',0
    szGetCurrentTask    db 'GetCurrentTask ',0
    szGetService        db 'GetService',0
    szServiceHandler    db 'ServiceHandler',0
    szKernelFree        db 'KernelFree',0
    szFpuSave           db 'FpuSave',0
    szFpuRestore        db 'FpuRestore',0
    
    ;exports.asm
    
    align 16
    kernel_export:
      dd szAttachIntHandler, attach_int_handler
      dd szSysMsgBoardStr  , sys_msg_board_str
      dd szPciApi          , pci_api
      dd szPciRead32       , pci_read32
      dd szPciRead8        , pci_read8
      dd szPciWrite8       , pci_write8
      dd szAllocKernelSpace, alloc_kernel_space
      dd szMapPage         , map_page
      dd szRegService      , reg_service
      dd szKernelAlloc     , kernel_alloc
      dd szKernelFree      , kernel_free
      dd szGetPgAddr       , get_pg_addr
      dd szGetCurrentTask  , get_curr_task
      dd szGetService      , get_service
      dd szServiceHandler  , srv_handler
      dd szFpuSave         , fpu_save
      dd szFpuRestore      , fpu_restore
      dd 0
    
      szAttachIntHandler  db 'AttachIntHandler',0
      szSysMsgBoardStr    db 'SysMsgBoardStr', 0
      szPciApi            db 'PciApi', 0
      szPciRead32         db 'PciRead32', 0
      szPciRead8          db 'PciRead8', 0
      szPciWrite8         db 'PciWrite8',0
      szAllocKernelSpace  db 'AllocKernelSpace',0
      szMapPage           db 'MapPage',0
      szRegService        db 'RegService',0
      szKernelAlloc       db 'KernelAlloc',0
      szKernelFree        db 'KernelFree',0
      szGetPgAddr         db 'GetPgAddr',0
      szGetCurrentTask    db 'GetCurrentTask ',0
      szGetService        db 'GetService',0
      szServiceHandler    db 'ServiceHandler',0
      szFpuSave           db 'FpuSave',0
      szFpuRestore        db 'FpuRestore',0
    
    После связывания функцию можно вызывать косвенно
    stdcall [KernelAlloc], 16*512 ; из infinity.asm

    Способ передачи параметров может быть любым.

    Code: Select all

         if DEBUG                          ;из  infinity.asm
               mov esi, msgFail
               call [SysMsgBoardStr]
         end if
    
    msgFail      db 'Sound service not found',13,10,0
    
  • Я подумал насчет видеодрайверов.

    Работа с графикой в Колибри производиться посредством вызова системных функций.Представим себе,что у нас есть для Колибри родной драйвер видеокарты.Вопрос,как сделать так,чтобы всем програмам были доступны возможности аппаратного ускорения ?
    Переписывать ВСЕ программы- это не дело.Остаётся только одно - изменять код ядра.Сейчас,при обращении к системным вызовам,вызываются функции работающие через VESA.Если,создать массив указателей на эти графические функции,и при загрузке выполнять такое действие:

    IF (родной_драйвер_есть==true) {заносить адреса его графических функций в таблицу}

    ELSE {заносить в таблицу адреса графических vesa функций}

    то проблема с доступом к драйверу будет решена.А для 3D возможностей можно предусмотреть отдельную системную функцию.

    Что вы об этом думаете ?
  • serge: can you please take a look at http://programmersheaven.com/download/3 ... nload.aspx
    it's a dos program based on the dos program the ac97 player was originally ported from.
    I have such a card (ES1373) but dont have the knowledge to port it myself.

    http://www.hh.iij4u.or.jp/~tokumi/ES137 ... e%3Apdf%22
  • hidnplayr
    I looked on source and pdf. It's possible to write driver , but "remote e-mail debugging" takes lot of time.
  • ok i understand, thanks anyway

    I should be able to write the driver myself someday :)
  • К сожалению, у меня глючит новое ядро. Симптоиы похожи на те, что были в стандартном ядре, когда неправильно включался A20: не запускается большинство программ; kfar запустился, но правая панель черная. Разница лишь в том, что раньше у меня подобные глюки проявлялись только при загрузке с дискеты, а в этом ядре независимо от способа загрузки. По исходникам посмотрел, вклюение A20 такое же как и в стандартном ядре.
    Потестить звук нет возможности, т. к. AC97 у меня дохлый
  • Про неработоспособность запуска программ(программы не запускаютя не из kfar не из syxtree) я упомянул в разделе ./дистрибутивы/k600/
  • Может я несколько сумбурно описал проблему: ядро ревизии 155 у меня работает нормально, модифицированное Сержем глючит
  • У меня такая же проблема.
  • Who is online

    Users browsing this forum: No registered users and 33 guests