[modif] Чего нет в С для работы с железом?
От: Shmj Ниоткуда  
Дата: 30.04.23 13:25
Оценка:
Вот есть типа лабораторная работа по созданию свой ОС — https://github.com/cfenollosa/os-tutorial Для глубины понимания как все работает, скажем так.

Ну и там идея какая. Делаем на ассемблере подготовку (переход в защищеный режим и пр.) — а потом уже переходим на уровень выше и пишем на голом С. ОК вроде.

Но вот при написании видео-драйвера, к примеру, есть момент, который на голом С никак не сделать. Конкретно тут: https://github.com/cfenollosa/os-tutorial/blob/master/16-video-driver/drivers/ports.c А именно — прерывания тьфу ты епта — работу с портами ввода-вывода. Их пришлось реализовать ассемблерными вставками.

Т.е. все остальное — обращение к видео-памяти и пр. — все это делается на голом С. Видео-память просто через указатель с константным адресом 0xb8000 — тут все ОК. А вот прерывания работу с портами ввода-вывода никак не сделать на голом С — эта концепция как бы не вписывается в язык.

Т.е. если сделать мин. загрузчик и передачу в библиотеку на голом С — то эта библиотека целиком и полностью может обойтись без ассемблерных вставок, окромя вызова прерываний работы с портами ввода-вывода?

По идее порты ввода-вывода такая же базовая концепция как и память? так ведь? Они на уровне железа как и память, верно? Так почему же их не добавили а память добавили?

Прав ли я? Так же интересует мнение по этому поводу.
Отредактировано 30.04.2023 20:48 Shmj . Предыдущая версия . Еще …
Отредактировано 30.04.2023 20:08 Shmj . Предыдущая версия .
Отредактировано 30.04.2023 20:07 Shmj . Предыдущая версия .
Re: Чего (идеологически важного) нет в С?
От: reversecode google
Дата: 30.04.23 13:28
Оценка:
S>Так же интересует мнение по этому поводу.

зачем, для ваших курсов/обзоров на ютубчике?
Re[2]: Чего (идеологически важного) нет в С?
От: Shmj Ниоткуда  
Дата: 30.04.23 13:29
Оценка:
Здравствуйте, reversecode, Вы писали:

S>>Так же интересует мнение по этому поводу.

R>зачем, для ваших курсов/обзоров на ютубчике?

У меня нет таких курсов или обзоров. Просто для философского понимания сути.
Re: Чего (идеологически важного) нет в С?
От: Ip Man Китай  
Дата: 30.04.23 13:36
Оценка: +7 -1
я за бан
Re: Чего (идеологически важного) нет в С?
От: BSOD  
Дата: 30.04.23 13:57
Оценка: 7 (1)
Здравствуйте, Shmj, Вы писали:

S>Т.е. все остальное — обращение к видео-памяти и пр. — все это делается на голом С. Видео-память просто через указатель с константным адресом 0xb8000 — тут все ОК. А вот прерывания никак не сделать на голом С — эта концепция как бы не вписывается в язык.


В досовские времена были раcширения Borland C++ — отдельное соглашение о вызовах что-то вроде interrupt.
Такие процедуры автоматом сохраняли и восстанавливали регистры.
На современном gcc наверняка есть расширения для системных целей, ибо gcc для юниксов и был изначально написан.
Тем более, для защищенного режима сохранение и восстановление регистров не нужно. Насколько помню, там автоматически происходит переключение задачи на обработчик прерывания. (Знатоки поправят).
Sine vilitate, sine malitiosa mente
Re: Чего (идеологически важного) нет в С?
От: rg45 СССР  
Дата: 30.04.23 14:59
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>Чего (идеологически важного) нет в С?


RAII
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: Чего (идеологически важного) нет в С?
От: Zhendos  
Дата: 30.04.23 15:58
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Т.е. если сделать мин. загрузчик и передачу в библиотеку на голом С — то эта библиотека целиком и полностью может обойтись без ассемблерных вставок, окромя вызова прерываний? Ведь прерывания то не мапятся на адрес с возможность дернуть указатель на функцию.

S>Прав ли я? Так же интересует мнение по этому поводу.

Ну если есть желание обойтись почти без ассебмлера,
то можно теоретически подсократить в этом данном проекте использование
ассемблера с помощью чего-то типа "__attribute__((__interrupt__))".

Но насколько это нужно не очень понятно, все равно в настоящей ОС
без ассемлера не обойтись.

Даже если не обращать внимание на что-то специфичное типа:
— загрузчика, который должен стартовать скажем из ROM и включить DDR контролер, поэтому он не может использовать
оперативную память и должен работать только с регистрами процессора
— криптографии, когда должно быть константное время выполнения чтобы противостоять https://ru.wikipedia.org/wiki/%D0%90%D1%82%D0%B0%D0%BA%D0%B0_%D0%BF%D0%BE_%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%B8

то даже банальное вычисление количества "замыкающих" нулевых битов
может потребоваться сделать в ОС очень быстро, в x86 есть инструкция "bsf",
которая сделает то что нужно, а без всяких расширений конкретного компилятора типа "__builtin_ctz" (gcc, clang)
фиг ты до него доберешься.
Re: Чего (идеологически важного) нет в С?
От: kov_serg Россия  
Дата: 30.04.23 16:29
Оценка: +1
Здравствуйте, Shmj, Вы писали:

Чего (идеологически важного) нет в С?
Возможности ограничивать и контролировать ресурсы. Например вы не можете попросить выполняться функцию не более 10мс и не хавать более 25кб. Или например вызывать метод не реже чем через n тактов.
Нет локальный функций, нет анонимных функций. Всего один стэк нет возможности возможности оперировать с алгоритмом для его последовательной модификации.
Re: Чего (идеологически важного) нет в С?
От: LuciferSaratov Россия  
Дата: 30.04.23 20:06
Оценка: +3 :)
Здравствуйте, Shmj, Вы писали:

S>А вот прерывания никак не сделать на голом С — эта концепция как бы не вписывается в язык.


боже мой, ну ты это всё на серьёзных щах что ли?
в кросс-платформенный язык "как бы не вписывается концепция" аппаратных особенностей конкретных платформ, вот это поворот!
вот это неожиданность, ну кто бы мог такое представить!
Re[2]: Чего (идеологически важного) нет в С?
От: Shmj Ниоткуда  
Дата: 30.04.23 20:12
Оценка: :))
Здравствуйте, LuciferSaratov, Вы писали:

LS>боже мой, ну ты это всё на серьёзных щах что ли?

LS>в кросс-платформенный язык "как бы не вписывается концепция" аппаратных особенностей конкретных платформ, вот это поворот!
LS>вот это неожиданность, ну кто бы мог такое представить!

Подправил — там же не прерывания а работа с портами ввода-вывода, это такая же базовая концепция железа как и память. Но для работы с памятью есть механизм почему то а для портов нету

Но тут как посмотреть, конечно, ведь некоторые как бы мапят и порты а память.

Видимо так же и прерывания можно мапить на память в виде указателей на функцию.

Кстати, на каком уровне произведен мапинг видеопамяти как бы в обычную память? Это на уровне BIOS или на уровне железа?
Re[2]: Чего (идеологически важного) нет в С?
От: Shmj Ниоткуда  
Дата: 30.04.23 20:15
Оценка:
Здравствуйте, rg45, Вы писали:

S>>Чего (идеологически важного) нет в С?

R>RAII

Да опять вы за свое. Я не об этом.

Вопрос в другом. Вот есть голое железо и язык С. Почему мы не можем полностью работать с этим железом на голом С а нужны некие ассемблерные вставки? По каким причинам?

Вот одно из что я привел — нет поддержки портов ввода-вывода как в примере выше.

Ведь с памятью то можем работать же напрямую. А с портами нет. Что еще кроме памяти и портов нужно для железа? И кто мапит память устройств на общую память — это на уровне железа или на уровне BIOS?
Отредактировано 30.04.2023 20:17 Shmj . Предыдущая версия .
Re[3]: Чего (идеологически важного) нет в С?
От: rg45 СССР  
Дата: 30.04.23 20:27
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>Да опять вы за свое. Я не об этом.

S>Вопрос в другом.

Вопрос был таким:

Чего (идеологически важного) нет в С?


Я на него ответил.

А если у тебя в заголовке одно, а в теле сообщения другое, то кто тебе злобный буратино?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: [modif] Чего нет в С для работы с железом?
От: Pzz Россия https://github.com/alexpevzner
Дата: 30.04.23 21:03
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>По идее порты ввода-вывода такая же базовая концепция как и память? так ведь? Они на уровне железа как и память, верно? Так почему же их не добавили а память добавили?


У Интеловских процессоров, начиная с 8086 (а, вернее, с 8080) порты не отображены на память. Чтение из порта и чтение из памяти — это разные операции на шине. Поэтому у них и команды разные.

У большинства других процессоров порты ввода-вывода, действительно, отображены на диапазон адресов памяти и с ними работают теми же командами.

Но это еще и от перефирийного устройства зависит. Среди PCI-ных устройств совершенно не редкость, когда то, что логически является портами ввода-вывода, фактически отображено на пространство памяти.
Re[3]: Чего (идеологически важного) нет в С?
От: opfor  
Дата: 30.04.23 21:15
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вопрос в другом. Вот есть голое железо и язык С. Почему мы не можем полностью работать с этим железом на голом С а нужны некие ассемблерные вставки? По каким причинам?


Железа разного много, а си один. А асм под каждую архитектуру свой.
Re: [modif] Чего нет в С для работы с железом?
От: BSOD  
Дата: 30.04.23 21:22
Оценка:
Здравствуйте, Shmj, Вы писали:

S>По идее порты ввода-вывода такая же базовая концепция как и память? так ведь? Они на уровне железа как и память, верно? Так почему же их не добавили а память добавили?


Как уже сказали выше, отдельное адресное пространство портов ввода-вывода — это специфика x86, на других архитектурах это может быть обычная память.

В Borland С++ были соответствующие интринсики.
Я помню, в студенческие годы изобретал велосипед с оператором [], чтобы пользоваться как в турбо-паскале
port[i] = j;


В современном компиляторе VC тоже есть
https://learn.microsoft.com/en-us/cpp/c-runtime-library/inp-inpw-inpd?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/outp-outpw-outpd?view=msvc-170
(вроде оно?)

В GCC можно воспользоваться ассемблерными вставками...
Sine vilitate, sine malitiosa mente
Re: [modif] Чего нет в С для работы с железом?
От: vsb Казахстан  
Дата: 30.04.23 23:17
Оценка: 7 (1) +2 -2
В С вообще нет ничего для работы с железом. Я не знаю, почему ты думаешь, что в С можно работать с памятью. В общем случае нельзя. Если и получается, то это особенность компилятора (то бишь это уже не совсем C и не переносимо, впрочем это и очевидно).

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

C это абстрактный язык над абстрактной машиной.
Отредактировано 30.04.2023 23:22 vsb . Предыдущая версия . Еще …
Отредактировано 30.04.2023 23:21 vsb . Предыдущая версия .
Отредактировано 30.04.2023 23:19 vsb . Предыдущая версия .
Re[2]: [modif] Чего нет в С для работы с железом?
От: Shmj Ниоткуда  
Дата: 01.05.23 08:16
Оценка: :)
Здравствуйте, vsb, Вы писали:

vsb>В С вообще нет ничего для работы с железом. Я не знаю, почему ты думаешь, что в С можно работать с памятью. В общем случае нельзя. Если и получается, то это особенность компилятора (то бишь это уже не совсем C и не переносимо, впрочем это и очевидно).


Вот этот момент мне и не ясен — кто и почему решил, что адрес 0xb8000 — это именно видеопамять при начальной загрузке (в режиме VGA или как там)? Наверное даже не компилятор а BIOS-система это определяет, скорее всего. Или нет...

Вот если без BIOS загрузиться — как обратиться к девайсам?

vsb>Что такое порты, я не знаю.


Порт — это и есть та самая ножка микроконтроллера, к которой ты припаиваешь светодиод. Ну да, обычно оно тоже как-то мапится на память.

И тоже тут вопрос — на каком уровне оно мапится на память? На уровне компилятора или девайса?
Отредактировано 01.05.2023 8:24 Shmj . Предыдущая версия . Еще …
Отредактировано 01.05.2023 8:19 Shmj . Предыдущая версия .
Re[3]: Чего (идеологически важного) нет в С?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.05.23 09:07
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Подправил — там же не прерывания а работа с портами ввода-вывода, это такая же базовая концепция железа как и память. Но для работы с памятью есть механизм почему то а для портов нету


1. Порты как механизм специфичны только для x86 линии (начиная с 8080) и в таком виде появились от того, что методы обращения к памяти и IO предполагались разные, а сводить в одну команду авторам 8080 не хотелось. Дополнительные линии на шине помогали сократить сложность опознания обращения.
Обрати внимание, что в ранних IBM PC делали, например, что порты 44-47, 48-4B, 4C-4F, ..., 5C-5F были тем же самым что 40-43. Это чисто экономия на декодинге. Потом уже начали их использовать. Опять же, чем дешевле для первой версии, тем лучше.

Остальные архитектуры использовали отображение на память. Ну не считаем линию от S/360 до System/Z, в которой только пара базовых устройств типа таймера доступна через встроенные команды, а остальные — через каналы ввода-вывода (в качестве аналогии представь себе, что это всё висит на таком ну очень быстром USB или SCSI, что легче представить).

Так что ничего "базового" в портах в их нынешнем x86 виде нет, это локальная заморочка.

2. В большинстве Unix-систем доступ к портам идёт через функции, часто заврапленные под конкретные шинные переходники. Вот, например, сетевуха системы "старой доброй" NE2000 может отразить регистры на память, а может на порты. Драйвер пользуется универсальным bus_write_i32(), а вызвать команду out или запись в память — решает нижележащий драйвер шины.

А вот когда уже дошло до конкретной in или out, используются ассемблерные переходники или builtin-функции. Компилятор может их заинлайнить (скорее всего), а может — нет, по настроению. В любом случае платформа в виде компилятора даёт такое средство.

3. С прерываниями таки важнее — функция, пригодная напрямую из C как обработчик прерывания, должна иметь особые пролог и эпилог. Заморачиваются этим только в мелком embedded. В крупном (грубо говоря, где можно запустить Linux) используют ассемблерные переходники.

S>Но тут как посмотреть, конечно, ведь некоторые как бы мапят и порты а память.


Мапят, да. Могут вообще пространство I/O не использовать.

Если говорить об x86, есть ещё третье адресное пространство — конфигурации PCI. Ты о нём даже не пытался вспоминать а ведь самые базовые настройки железа сейчас собраны именно туда. Оно в зависимости от чипсета накладывается или на участок памяти, или на порты ввода-вывода в режиме узкого окна.

S>Видимо так же и прерывания можно мапить на память в виде указателей на функцию.


Нет. Для C нужны пролог, который создаст всю необходимую обстановку для C рантайма, и эпилог, который восстановит всё обратно.

S>Кстати, на каком уровне произведен мапинг видеопамяти как бы в обычную память? Это на уровне BIOS или на уровне железа?


Судя по формулировке вопроса, ты не понимаешь, что спрашиваешь.

Непосредственно обращения отрабатывает железо. А вот правила раутинга запросов доступа для него настраивает или BIOS, или потом ОС.
The God is real, unless declared integer.
Re[3]: Чего (идеологически важного) нет в С?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.05.23 09:19
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вопрос в другом. Вот есть голое железо и язык С. Почему мы не можем полностью работать с этим железом на голом С а нужны некие ассемблерные вставки? По каким причинам?


Для настройки среды, в которой работает C код, нужно как минимум настроить:

1. Стек — выделить память, поставить указатель на её границу.
2. Для архитектур где используется global pointer (такой регистр) — его.

Это нельзя сделать сишным кодом. Настройка идёт откуда-то извне. Стандартно и удобнее всего — ассемблер.

Далее, в обработчике прерывания надо на входе сделать то же самое (в плане установки регистров) и сохранить все регистры, которые не сохраняются в обычной функции (через них передаются аргументы и забирается результат), на выходе — восстановить их.

S>Вот одно из что я привел — нет поддержки портов ввода-вывода как в примере выше.


Не смотри на x86. Смотри на ARM или MIPS. Там портов нет, с ними не надо работать.
А вот то что я выше назвал — надо.
А ещё там разные барьеры памяти, которые может не уметь компилятор сам по себе.
А ещё специфичные команды типа WFE (wait for events).

S>Ведь с памятью то можем работать же напрямую. А с портами нет. Что еще кроме памяти и портов нужно для железа? И кто мапит память устройств на общую память — это на уровне железа или на уровне BIOS?


В ARM/MIPS/etc. обычно жёстко прописано в железе.

В x86 всё сложно. Если ME не выделит заранее BIOS'у оперативную память, то и её нет! Надо сначала вытащить данные конфигурации модулей памяти и настроить маппинг через регистры.

Регистры эти в PCI configuration space, куда, пока не настроил их отображение на память, доступ только через шлюз в виде двух регистров ввода-вывода (CF8, CFC).

Начальный этап BIOS, пока она это настраивает, нельзя написать на C, потому что там даже стека нет. Потом может использовать кэш процессора как эмуляцию памяти, но он маленький. Всё равно ассемблер.
Только после этого можно подключать основную память.

EFI где-то так и сделан — после первой инициализации строится среда для кода, написанного в основном на C/C++, и он начинает выполняться.
The God is real, unless declared integer.
Re[3]: [modif] Чего нет в С для работы с железом?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.05.23 09:41
Оценка: +1
Здравствуйте, Shmj, Вы писали:

vsb>>В С вообще нет ничего для работы с железом. Я не знаю, почему ты думаешь, что в С можно работать с памятью. В общем случае нельзя. Если и получается, то это особенность компилятора (то бишь это уже не совсем C и не переносимо, впрочем это и очевидно).


S>Вот этот момент мне и не ясен — кто и почему решил, что адрес 0xb8000 — это именно видеопамять при начальной загрузке (в режиме VGA или как там)? Наверное даже не компилятор а BIOS-система это определяет, скорее всего. Или нет...


Интересно ты смешиваешь разные вещи — одинокий порт на одной ножке для микроконтроллера и адреса видеопамяти для x86. Ты понимаешь, что между ними разница в несколько уровней?

S>Вот если без BIOS загрузиться — как обратиться к девайсам?


К одним просто — они сидят на стандартных адресах в пространстве портов.
К другим сложнее — надо сходить узнать их конфигурацию и настроить, какие адреса будут использоваться, а перед этим — настроить ещё и шлюзы между шинами.

vsb>>Что такое порты, я не знаю.

S>Порт — это и есть та самая ножка микроконтроллера, к которой ты припаиваешь светодиод. Ну да, обычно оно тоже как-то мапится на память.

"Это не те порты, которые ты ищешь" (tm).

S>И тоже тут вопрос — на каком уровне оно мапится на память? На уровне компилятора или девайса?


Возьми уже базовую книжку и прочитай...
The God is real, unless declared integer.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.