Вот люди пишут "можно", но никто из них не уточняет при этом, что такое "чистый С".
Если "чистый С" -- это только то, что предоставляет сам язык, скажем, стандарта C99 или C11, то у вас возникнут проблемы в следующих областях:
- управление прерываниями: обычно выполняется через специальные регистры или специальными ассемблерными командами.
- обработчики прерываний: в зависимости от архитектуры вам нужны будут функции со специальными прологами и эпилогами, сохраняющими и восстанавливающими все регистры и, возможно, возвращающиеся особым образом.
- управление MMU: обычно выполняется через специальные регистры или специальными ассемблерными командами.
- управление кешем: обычно выполняется через специальные регистры или специальными ассемблерными командами.
- порождение процессов и переключение контекстов: теоретически можно сделать с помощью setjmp/longjmp, но вам придётся разобраться со структурой jmpbuf для вашей архитектуры, поскольку для новых процессов её нужно будет заполнить вручную.