MP + OS Kernel

Тема в разделе "WASM.OS.DEVEL", создана пользователем SadKo, 24 окт 2007.

  1. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Собственно, по сабжу.

    Народ, сил уже нету, просвятите немного.
    Значит, в данный момент нахожусь в стадии написания ядра (кто не знает - http://xskernel.org/). Всё бы хорошо, но недавно столкнулся с одной неприятной вещью. А именно:

    Есть три компа. Это:
    - 80486 DX2 66 MHz (MB х.з какая), 16 MB Ram.
    - Pentium 4 socket 478 2.00GHz (MB Gigabyte на чипсете i845), 256 MB Ram.
    - AMD Athlon X2 3800+ (MB Bisotar на чипсете NF-550), 1 GB Ram.

    Ядро грузится с дискеты (собственный бутлоадер, читающий FAT12 + вторичный загрузчик, распаковывающий ядро в память) сначала в ОЗУ ниже первого мегабайта, а затем копируется по физическому адресу 0x110000. Точка входа - 0x110000.

    При старте ядро:
    0. Инициализирует память (распределитель динамической памяти + расположение таблиц дескрипторов).
    1. загружает GDTR, IDTR, TR, CR3.
    2. включает страничную адресацию.
    3. создаёт процесс ядра и поток, прикреплённый к процессу передаёт управление планировщику (как отдельной задаче, в самом планировщике прерывания отключены).
    4. планировщик передаёт управление потоку, инициализирующему драйверы.

    Далее работает один поток - создаёт виртуальные устройства для:
    - PIC (контроллера прерываний)
    - контроллер DMA
    - контроллер клавиатуры
    - создаёт Thread на периодическое копирование виртуального текстового буфера в видеобуфер (физ. адрес 0xb8000).
    - драйвер таймера, на который вешается sheduler и счётчик тиков + воспроизводитель звуков
    - виртуальное устройство, предоставляющее информацию о CPU (функция cpuid).

    После этого тред создаёт тестовый тред, который запускается и в цикле читает данные с клавиатуры и выводит сообщение на экран. При этом, тред видеобуфера работает параллельно с ним.

    В общем, всё бы хорошо, так как на P4 и 80486 всё работает прекрасно. НО на Athlon X2 система виснет после входа в тестовый тред, при чём в совершенно произвольном месте (вычислено посредством внедрения трапа в ядро).

    Кто может сказать, в чём может быть проблема? Я подозреваю, что для двух процессоров я что-то недоделал в инициализации ядра. Это может быть связано с APIC или ещё чем-нибудь?

    Код и образ могу привести, если будет нужно.
     
  2. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    SadKo
    ты инициализируешь все логические процессоры или у тебя вообще нет поддержки MP?
     
  3. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    В данном случае моё ядро пока не рассчитано на MP.
    Я хочу пока запустить его на одном процессоре (в Protected Mode). Но оно почему-то виснет (при этом, несколько раз переключение задач успевает срабатывать).
     
  4. 10110111

    10110111 New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2006
    Сообщения:
    319
    Адрес:
    Санкт-Петербург
    Попробуй под Bochsdbg протестить - мож чё станет понятно.
     
  5. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    На некоторых AMD64, и Win9x идет, а на некоторых нет.. :)
    Просто виснет, никаких исключений не срабатывает?
    Код (Text):
    1. Кто может сказать, в чём может быть проблема?
    Попробуй запустить загрузочную дискету SlackWare (там ее LoadLin.exe из DOS запускает), с какимнибудь реликтовым ядром (2.0.30 к примеру).
     
  6. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    В принципе MP он может симулять... ток пересобирать его надо тщательно конфигуря (лично мне версия 2.3 покатила, 2.3.5 местами куда более лагает)...
    p.s
    Под винды можно заюзать "Free Visual C++ Command Line Tools". гм.. и сварить борщъх этим батником (разве что сорцы подправить придеться в паре мест) :)
    Код (Text):
    1. @set path=c:\msdev\bin
    2. ::http://bochs.sourceforge.net/
    3. ::\BOCHS-2.3\bochs.bat - исходное размещение этого файла
    4. ::путь к компилеру и т.д
    5. @set include=c:\msdev\include
    6. ::
    7. @cl bx_debug\*.cpp bx_debug\*.c /Gr /O1 /G3 /MT /w /W0 /c /I $include /I "." /I "instrument\stubs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"obj-release/" /Fd"obj-release/"
    8. cd obj-release
    9. @link -lib *.obj /out:bx_debug.lib
    10. del *.obj
    11. @cd ../
    12. ::
    13. @cl cpu\*.cpp /Gr /O1 /G3 /MT /w /W0 /c /I $include  /I "." /I "instrument\stubs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"obj-release/" /Fd"obj-release/"
    14. cd obj-release
    15. @link -lib *.obj /out:cpu.lib
    16. del *.obj
    17. @cd ../
    18. ::
    19. @cl disasm\*.cpp /Gr /G3 /MT /w /W0 /c /I $include /I "." /I "instrument\stubs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"obj-release/" /Fd"obj-release/"
    20. cd obj-release
    21. @link -lib *.obj /out:disasm.lib
    22. del *.obj
    23. @cd ../
    24. ::
    25. @cl fpu\*.cpp /Gr /O1 /G3 /MT /w /W0 /c /I $include /I "." /I "instrument\stubs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"obj-release/" /Fd"obj-release/"
    26. cd obj-release
    27. @link -lib *.obj /out:fpu.lib
    28. del *.obj
    29. @cd ../
    30. ::
    31. @cl gui\*.cpp /Gr /O1 /G3 /MT /w /W0 /c /I $include /I "." /I "./iodev" /I "instrument\stubs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"obj-release/" /Fd"obj-release/"
    32. cd obj-release
    33. @link -lib *.obj /out:gui.lib
    34. del *.obj
    35. @cd ../
    36. ::
    37. @cl iodev\*.cpp /Gr /O1 /G3 /MT /w /W0 /c /I $include /I "." /I "instrument\stubs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"obj-release/" /Fd"obj-release/"
    38. cd obj-release
    39. @link -lib *.obj /out:iodev.lib
    40. del *.obj
    41. @cd ../
    42. ::
    43. @cl memory\*.cpp /Gr /O1 /G3 /MT /w /W0 /c /I $include /I "." /I "instrument\stubs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"obj-release/" /Fd"obj-release/"
    44. cd obj-release
    45. @link -lib *.obj /out:memory.lib
    46. del *.obj
    47. @cd ../
    48. ::
    49. @cl *.cpp /Gr /O1 /G3 /MT /w /W0 /c /I $include /I "." /I "instrument\stubs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"obj-release/" /Fd"obj-release/"
    50. cd obj-release
    51. @link -lib *.obj /out:bochs.lib
    52. del *.obj
    53. @cd ../
    54. ::
    55. rc win32res.rc
    56. copy win32res.res obj-release
    57. ::
    58. @cd obj-release
    59. link *.lib win32res.res /out:bochs.exe /subsystem:console /libpath:c:\msdev\lib winmm.lib oldnames.lib wsock32.lib shell32.lib comctl32.lib comdlg32.lib user32.lib gdi32.lib kernel32.lib advapi32.lib libcmt.lib
    60. ::
     
  7. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Я запускал через qemu обычно, в котором тоже работает. Или нужно именно в боше проверить?
     
  8. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Просто тупо виснет! Даже входа в обработчик таймера нет (по ходу, IRQ не приходит). Все исключения у меня ловятся и выводятся на экран (дескать, сработало исключение 0x0e, например). В данном случае на экран ничего не выводится.

    В ближайшее время постараюсь попробовать.

    Если тема интересна - могу выложить собранный образ дискеты.
    Сырцы можно из SVN взять - http://xskernel.svn.sf.net/
    В принципе, если есть Watcom+FASM, то можно всё собрать прямо из SVN.
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    SadKo
    причина может быть вот в чем
    прерывание диспетчеризируется APIC'ом на "спящий" логический процессор
    а т. к он у тебя не инициализирован, то и IDTR у него не валиден
    из IDTR CPU берет адрес, который не соответствует IDT и пошло-поехало
    в итоге triple-fault
    если IF сброшен, тогда к таким последствиям может привести генерация NMI, SMI
     
  10. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    rei3er, именно касательно этого у меня и есть подозрения. Хотя в драйвере PIC я уже делаю отрубание глобального APIC через MSR:

    Код (Text):
    1.         if (sys_read(cpuid, &info, sizeof(TCPUIDInfo))==sizeof(TCPUIDInfo))
    2.         {
    3.             if ((info.Extensions&CPUID_EXT_APIC)!=0) // Disable APIC if presented
    4.             {
    5.                 QWORD apic = ReadMSR(IA32_APIC_BASE);
    6.                 apic &= (~(1<<11)); // Clear global enable/disable flag
    7.                 WriteMSR(IA32_APIC_BASE, apic);
    8.             }
    9.         }
     
  11. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Посмотрел материал тут:
    http://sasm.narod.ru/docs/pm/pm_int/chap_5.htm

    У меня, похоже, логика нарушена: сначала инициализирую PIC, потом вырубаю APIC. А надо наоборот, вроде. Вечером попробую, о результатах сообщу.
     
  12. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    SadKo, тут задолбаешся гадать где глюк, лучше сперва пробить железо другими мультизадачными ОСями, минуетами/колибрями...
     
  13. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Согласен, верное решение :). Только я смогу это сделать дома, вечером.
     
  14. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Народ, всем спасибо за помощь!
    Всё-таки это оказался APIC. Просто я его отрубал после того, как переназначал векторы прерываний. А блокировать APIC надо было до программирования PIC.
    Теперь всё работает. Буду возвращать на место всё, что временно отключил в ядре.

    P.S. Зато с пользой провёл отладку: переписал планировщик, упростив его структуру и добавив новые фичи.
     
  15. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Нет, похоже я поторопился с выводами. Баг опять вернулся.

    Я решил сделать простенький тестик. Заключается он в следующем: после отрубания APIC (прерывания выключены) вхожу в "вечный" цикл, в котором выводится строчка из нечётного количества букв (не менее трёх), чтобы видно было, что проц пашет.

    Гружусь. Проц пашет. Буквы выводятся, бегают.
    Нажимаю на клавишу клавиатуры. Прерывания отключены, система никак не должна реагировать. Вместо этого буквы побежали как-то по-другому. Это ладно. Повторяю действие. Где-то начиная с 5-го нажатия клавиши комп виснет наглухо (даже кнопка Power не отрубает).
     
  16. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    Хм, похоже на приколы SMM/Supervisor-mode...
    Хотя, наврядли ВIOS передает управление 16bit -ому boot, будучи в таком невменяемом состоянии, да еще с включенным APIC...

    А так гадать неперегадать... В мультизадачке, самые "чудеса в решете" и начинаються как раз после LTR AX. Может описатели GDT/TSS чего мозги, или выравнивание данных.. Тут по идеи лучше с этим особо не мудрить, делать всё по накатаным еще в 386-ых DOS-расширителях стандартах.
     
  17. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    SadKo
    посредством MSR ты выключаешь Local APIC
    причем скорее всего только один
    в этом может быть проблема
    второй логический процессор, я так понимаю, у тебя не инициализирован
    по-умолчанию после RESET# он включен и APIC (который на чипсете) может ему диспетчеризировать прерывания
    попробуй отключить все Local APIC'и
     
  18. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Ок, попробую сделать. Сейчас прикручиваю драйвер APIC к ядру. Заодно и разбираюсь, что этот зверь из себя представляет :).
     
  19. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    В общем, ситуация какая-то непонятная.
    Я Multiprocessor-структуру _MP_ нашёл в BIOS'е, но таблица, связанная с этой структурой на qemu, p4 и Athlon X2 пустая.
    По ходу, надо искать теперь проц через ACPI?

    И вообще, как можно получить доступ к APIC'ам других процов?
     
  20. TheDeath

    TheDeath New Member

    Публикаций:
    0
    Регистрация:
    20 июл 2003
    Сообщения:
    66
    Адрес:
    Russia,Новосибирск
    Отправить IPI?