Задать вопрос
  • STM32 общается с микросхемой по SPI. Считываем регистр. Почему вместо ведомого снова говорит мастер?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    STM32 общается с микросхемой по SPI.

    Что за микросхема?

    Почему вместо ведомого снова говорит мастер?

    Интерфейс с двумя сигналами MISO и MOSI дуплексный, мастер всегда может выставлять какие-то данные на MOSI, это не имеет значения для приёма данных с MISO. Т.е. в вашем случае возможно устройство на том конце отвечает нулями.

    Может у вас есть мысли какие-то?

    Я смотрю на сигналы на картинке и вижу, что они начинаются с младших битов, т.е. 0xB0 передаётся как 0-0-0-0-1-1-0-1. Это нетипичный порядок битов, нужно проверить, что устройство ожидает данные именно в этом порядке. На диаграмме из мануала порядок битов, кстати, противоположный -- от D7 к D0.
    Ответ написан
    Комментировать
  • Как сделать дальний прыжок при переключении из 16 битного в 32 битный режим?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В отладчике я видел это:

    gdb здесь ожидает увидеть 64-битный код, чтобы он корректно интерпретировал 32-битный код надо ему скомандовать что-то типа set arch i386:x86-64 перед соединением.
    Ответ написан
  • Какая ошибка в коде на С?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В строке
    while (isspace(c = getch())); // Пропуск пробелов
    \n принимается за пробел и не возвращается из функции. В результате счётчик номеров строк не меняется.
    Ответ написан
    1 комментарий
  • Как скомпоновать код ассемблере с кодом на С для ядра?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Может надо сделать их объектными elf файлами, затем скомпоновать и зачистить формат?

    Использование стандартных форматов и инструументов для работы с ними -- это традиционный способ облегчить себе жизнь. Стандартная связка при использовании gnu-тулчейна -- использовать gcc для компиляции исходников на С (*.c) и ассемблере (*.S), gcc или ld для линковки, objcopy для преобразования ELF-файла с выхода линковщика в бинарник.
    Кроме того, в QEMU можно прямо ELF загружать.
    Ответ написан
    Комментировать
  • Как выполнить кросс-компиляцию при помощи CMake?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как Cmake передать расположение библиотеки openssl под нужную архитектуру (я попытаюсь собрать openssl из исходников под aarch64).
    В CMakeLists.txt модуль обнаруживается при помощи find_package(OpenSSL REQUIRED).

    С помощью переменной CMAKE_FIND_ROOT_PATH. Если последовательно идти этой дорожкой, в конце концов можно обнаружить себя собирающим sysroot для целевой системы.
    Ответ написан
    Комментировать
  • Почему может падать качество преобразования АЦП при повышении частоты сигнала?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Если сигнал синусоидальный то погрешность не превышает 0,3% на 2 КГц, но если цифровой сигнал(мендр) то погрешность может достигать 2% на 2 КГц.

    Потому что в прямоугольном сигнале присутствуют составляющие гораздо более высоких частот, чем частота этого меандра. См.
    Ответ написан
    3 комментария
  • Почему не работают цепные команды в ассемблере?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему у меня не хотят работать корректно цепные команды?

    Что конкретно не работает? В формате: "ожидаю X, происходит Y".

    В коде два странных места. Первое:
    mov      ax,Data2
    mov      es,ax     ; запис адреси data2 в ds
    ...
    lea si, node1  ;  <---

    node1 находится в сегменте Data2, адрес которого загружен в es, но команда lodsb загружает данные из ds:si.

    Второе:
    @finish_cycle_namex:
    inc I_struc ;+1 до ітерації
    add si, 5

    Зачем здесь добавлять 5 к si? si указывает на область памяти в которой лежит массив 5-символьных имён, внутренний цикл как раз перемещает si на следующее имя.
    Ответ написан
  • Почему от добавления функций помимо main() в начало кода ядро перестает работать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему от добавления функций помимо main() в начало кода ядро перестает работать?

    смотри: ты собираешь образ kernel следующей командой:
    i686-elf-ld -Ttext 0x7E00 --oformat binary kernel.o -o kernel -e main

    а запускаешь следующей:
    ; Jump to the kernel's entry point
        JMP 0x0000:0x7E00

    как по-твоему здесь используется информация о точке входа -e main?

    Ответ
    никак, выполнение всегда начинается с начала образа kernel, куда выполняет переход начальный загрузчик; что там будет, то и начнёт выполняться. Эта информация даже никуда не записывается, потому что файл формата binary -- это тупо склеенные вместе загружаемые сегменты, там нет места для метаинформации. Если бы ты собирал ELF, то этот адрес был бы записан в поле e_entry заголовка ELF.

    Если не модифицировать загрузчик, то образ ядра должен начинаться с кода точки входа, в твоём случае -- с кода main(). Чтобы поместить нужный код в нужное место собранного образа обычно используют скрипт линковщика.
    Ответ написан
    Комментировать
  • Как с помощью buildroot можно автоматически запускать bash скрипт после загрузки ядра linux?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как ... автоматически запускать bash скрипт после загрузки ядра linux?

    В зависимости от используемого init и требуемых деталей запуска -- через файл /etc/inittab или добавлением файла с именем вида S[0-9][0-9]* в /etc/init.d (если busybox), либо добавлением юнита systemd если systemd.

    С помощью buildroot

    В buildroot есть несколько вариантов это сделать, они описаны здесь. Самый простой на мой взгляд -- BR2_ROOTFS_OVERLAY. Если добавить путь в эту переменную конфигурации, то файловая иерархия по этому пути будет скопирована в будущую корневую фс.
    Ответ написан
    Комментировать
  • Как регистры SOC отображаются на память Linux?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как узнать, какой адрес этих регистров уже после инициализации устройств и загрузки ОС?

    Физический адрес -- как и написано в dts: 0xfe600000. Виртуальный адрес -- какой-то сравнительно случайный, выделенный вызовом ioremap() или какой-нибудь его обёрткой. Если драйверу нужен доступ к регистрам -- драйвер просто вызывает ioremap() сам и получает адрес. Если доступ нужен в юзерспейсе -- можно (при наличии разрешений) сделать mmap() файлу /dev/mem по смещению равному физическому адресу устройства.

    Или обратная задача: есть процесс, который пишет в некоторую область памяти, как узнать, возможно, это какие-то регистры SOM

    Сделать cat /proc/<pid>/maps и посмотреть, что отображено в эту область виртуальных адресов.

    Но обычно люди не отображают регистры устройств напрямую в пользовательскую память, максимум -- отображают файл обрабатываемый драйвером устройства, а драйвер уже может выступить дополнительным слоем абстракции и подставить в отображение часть адресного пространства устройства, если такое им поддерживается. В этом случае для понимания что куда отображается без чтения исходников драйвера не обойтись.
    Ответ написан
    Комментировать
  • Как из одного сегмента вызвать функцию другого сегмента?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    // Получаю ошибку:
    7FFF0000: The instruction at 0x7FFF0000 referenced memory at 0x7FFF0000. The memory could not be executed -> 7FFF0000 (exc.code c0000005, tid 6332)

    В чем проблема?

    По видимому в том, что вызвать функцию получилось, но память по адресу 7FFF0000 -- не исполняемая.

    Как починить?

    Начать с того, что сделать память по адресу 7FFF0000 исполняемой. После этого вывод в лог должен заработать, но будет падать после него, потому что функция mySuperFunction не возвращается.
    Ответ написан
  • Почему ОС запускается на QEMU, а на Virtual Box нет?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему ОС не запускается на Virtual box, а на QEMU запускаеться?

    Потому что QEMU TCG не очень точно эмулирует x86. Если в командную строку qemu добавить -enable-kvm, то оно тоже не будет работать.

    А вот если добавить ret в реализацию GDT::load_gdt() и не вызывать load_tss() то оно начинает в qemu-kvm работать:
    diff --git a/src/GDT/GDT_impl.s b/src/GDT/GDT_impl.s
    index 4f69835abd9d..5476837f3d0a 100644
    --- a/src/GDT/GDT_impl.s
    +++ b/src/GDT/GDT_impl.s
    @@ -2,6 +2,7 @@
     .extern _ZN8SimpleOS3GDT7gdt_ptrE
     _ZN8SimpleOS3GDT8load_gdtEv:
            lgdt _ZN8SimpleOS3GDT7gdt_ptrE
    +       ret
     
     .global _ZN8SimpleOS3GDT8load_tssEv
     _ZN8SimpleOS3GDT8load_tssEv:

    Подозреваю, что и в virtual box оно заработает.
    Проблема в загрузке TSS, короче. Мне не знакомы дебри TSS, но для поверхностного взгляда кажется странным то, что все сегментные селекторы в твоём TSS имеют RPL=3, а селектор стека -- RPL=0.
    Если ты хочешь разбираться с тем, что происходит, то разумно было бы поменять порядок инициализации, сначала загрузить IDT, чтобы иметь возможность обрабатывать исключения, а потом загружать TSS и смотреть, что за исключение эта операция выкидывает.
    С другой стороны, непонятно зачем в текущей версии этой ОС нужен TSS. Подозреваю, что никакая функциональность не будет потеряна, если его не загружать.
    Ответ написан
    Комментировать
  • Что означает ошибка, выводящаяся при выполнении bash-скрипта?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    выводится ошибка - [: missing `]'
    Что значит эта ошибка

    Эта ошибка означает, что
    1) bash разбил команду
    if [ "$projectDir" == "video" && "$flag" != "noflag" ]; then
    следующим образом: ключевое слово if, команда [ с аргументами "$projectDir" == "video", оператор &&, команда "$flag" с аргументами != "noflag" ], разделитель ;, оператор then.
    2) первая команда [ (она же test), очевидно, не нашла в своих аргументах закрывающей скобки ], которая должна там быть при таком её вызове.

    как ее можно исправить?

    использовать -a вместо &&, как говорит man test.
    Ответ написан
    Комментировать
  • Координаты сферы?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    std::copy(arr1, arr1 + n, buf);

    Все рассчитанные в циклах значения копируются в первые 9 элементов массива buf, остальные элементы этого массива остаются неинициализированными.
    Можно поправить код следующим образом, чтобы заполнить весь массив:
    int off = 0;
    ...
    for (GLfloat i = 0; i <= 3.14; i += 0.01)
        for (GLfloat j = 0; j <= 2.0 * 3.14; j += 0.01)
        {
            ...
            std::copy(arr1, arr1 + n, buf + off);
            off += n;
        }
    Ответ написан
    Комментировать
  • При размере страницы, скажем, 4 Кбайт 32-разрядное адресное пространство имеет 1 млн страниц. Верно ли это?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Без всякого деления можно понять, что 2^32 / (4 * 2^10) = 2^(32 - 12) = 2^20, а если запомнить, что 2^10 -- это "двоичная тысяча" (1024), а 2^20 -- соответственно "двоичный миллион" (1024^2), то жизнь заметно упрощается.
    Ответ написан
    Комментировать
  • Расскажите пожалуйста как реализован sin в cmath?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    кода я не нашел, или плохо искал

    вот код из glibc.

    через ряд тейлора не вариант при больших значениях угла ряд медленно сходится

    В приведённой реализации сначала аргумент приводится к диапазону ±pi/2, потом берётся фиксированное число слагаемых ряда тейлора.
    Ответ написан
    1 комментарий
  • Как найти нетривиальную линейную комбинацию?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Где я ошибся?

    3u = (3, 6, -3)
    3v = (3, -6, 9)
    9w = (27, 0, 27)
    3u + 3v + 9w = (33, 0, 33), что вовсе не равно нулевому вектору.
    Ответ написан
    Комментировать
  • Как исправить ошибку в MakeFile?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ругается на g++ -I $(INCL) $(SRCS) -o $(TARGET), как можно исправить?

    Заменить пробелы в начале строки одним табом. Команды в makefile начинаются с табов.
    Ответ написан
    Комментировать
  • Почему название файла в моей ОС изменяется само?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Проблема, как я вижу, зарыта в реализации метода map::copy, вот в этом месте. Нельзя копировать сложные объекты функцией memcpy(), потому что при удалении копии её деструктор освободит данные оригинала. Для такого копирования следует либо использовать placement new, либо копировать целиком объект Node, типа того. Для того чтобы это работало потребуется реализовать глобальный оператор new, типа того. С этими изменениями конкретно описанная в топике проблема решается, но я вижу, что и другие методы класса map реализованы с похожими ошибками, так что не расслабляйся и не думай, что это была единственная проблема в коде.

    Отдельный вопрос: зачем FileSystem::get_root() копирует всё дерево файловой системы, когда FileSystem::tree() явно не собирается его менять, можно было бы в этом случае обойтись константной ссылкой.
    Ответ написан
    1 комментарий
  • Не работает таблица прерываний(IDT). Что делать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В чем может быть проблема?

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

    Вот эта структура:
    struct IDTPtr {
        uint16_t limit;
        uint32_t base;
    };

    должна быть определена с атрибутом packed, иначе компилятор вставляет паддинг для выравнивания поля base на границу uint32_t, из-за чего в IDT загружается неверный адрес.

    Ну и, вдобавок, нельзя делать iret из середины с++-функции, потому что компилятор организовал в ней кадр стека и вместо возврата iret снимает и интерпретирует мусор из этого кадра:
    001000e6 <SimpleOS::IDT::dividing_by_zero()>:
      1000e6:       55                      push   %ebp
      1000e7:       89 e5                   mov    %esp,%ebp
      1000e9:       53                      push   %ebx
      1000ea:       83 ec 04                sub    $0x4,%esp
      1000ed:       e8 15 01 00 00          call   100207 <__x86.get_pc_thunk.ax>
      1000f2:       05 06 11 00 00          add    $0x1106,%eax
      1000f7:       83 ec 0c                sub    $0xc,%esp
      1000fa:       8d 90 08 fe ff ff       lea    -0x1f8(%eax),%edx
      100100:       52                      push   %edx
      100101:       89 c3                   mov    %eax,%ebx
      100103:       e8 4c 00 00 00          call   100154 <SimpleOS::Terminal::print(char const*)>
      100108:       83 c4 10                add    $0x10,%esp
      10010b:       fa                      cli
      10010c:       cf                      iret
      10010d:       90                      nop
      10010e:       8b 5d fc                mov    -0x4(%ebp),%ebx
      100111:       c9                      leave
      100112:       c3                      ret
    Ответ написан
    9 комментариев