Я подразумеваю, что слой, где происходит разделение на
виртуальный/реальный драйвер может архитектурно быть несколько
выше. Не обязательно симулировать I2C на уровне ножек SCL и SDA. И
не обязательно на уровне посылок пакетов через I2C. Если известно,
что к I2C подключена память и ещё микросхема способная выполнить
пяток разных команд, то делаются два (виртуальных) драйвера -- один
для памяти (на уровне чтения-записи блоков), другой для микросхемы
с пятью функциями. Первый
пишет в файл, второй, например, прокидывает команды в скриптовый язык. А реальные драйвера в свою очередь стоят над одним реализованном только в железе, но отсутствующем в синтетическом порте, драйвером I2C, который работает на уровне пересылки блоков по шине.
Для отладки драйверов в железе тоже неплохо бы иметь какой-то простенький интерпретатор (http://caxapa.ru/988688/) чтобы через него руками или скриптом подёргать за отдельные функции реальных драйверов. И их отладить таком образом, управляющее ПО отладить через синтетический порт, потом собрать всё на железе и надеяться, что оно почти сразу заработает.