Système d'exploitation Unix-like pour ESP32 + terminal Minitel 1B/2, développé par la Minitel Hacking Crew.
MinitelOS transforme un ESP32 couplé à un Minitel en un vrai terminal interactif : shell complet, système de fichiers, gestion d'utilisateurs, réseau WiFi, SSH, scripting, cron, et simulateur natif pour développer sans matériel.
- ESP32 (devboard compatible Minitel)
- Minitel 1B ou 2
- PlatformIO (CLI ou extension VSCode)
pio run -t upload # compile + flash
pio device monitor # moniteur série (115200 bauds)Le script minitel-sim inclus dans le repo gère le build et le lancement en une seule commande :
./minitel-sim # build auto si absent, puis lance
./minitel-sim --baud=1200 # simule la vitesse Minitel 1B (1200 bauds)
./minitel-sim --baud=4800 # simule la vitesse Minitel 2
./minitel-sim --reset # remet à zéro les fichiers de session avant le lancement
./minitel-sim --build # force un rebuild complet
./minitel-sim --help # affiche l'aidePrérequis : PlatformIO (
pip install platformio)
En mode manuel :
pio run -e native # compile uniquement
.pio/build/native/program # lance directementCe que simule le simulateur :
sim_fs/monté comme système de fichiers LittleFS- Terminal Minitel rendu en ANSI dans le terminal courant
- WiFi simulé avec internet réel via libcurl
--baudthrottle l'affichage des caractères visibles pour reproduire la vitesse série d'un vrai Minitel (les séquences de contrôle restent instantanées)
--reset supprime les fichiers générés à chaud par les sessions (/root/.groups, /etc/sudoers, /root/.fsmeta) pour repartir d'un état propre.
Au premier boot (ou après réinitialisation), un assistant de configuration se lance :
- Mot de passe root — définit le compte administrateur
- Création d'utilisateur — nom, mot de passe, niveau (user / admin)
- WiFi — scan et connexion optionnelle
- MOTD — message affiché à chaque connexion
Réinitialisation : appuyer 7× sur
CORRECTIONau démarrage (efface/etc/shadowet redémarre).
| Commande | Description |
|---|---|
help |
Aide complète |
whoami |
Utilisateur actuel |
passwd |
Changer son mot de passe |
su <user> |
Changer d'utilisateur |
sudo <cmd> |
Élévation temporaire root (sudoers ou mot de passe root) |
adduser |
Créer un utilisateur (root) |
deluser |
Supprimer un utilisateur (root) |
groupadd <nom> |
Créer un groupe (root) |
groupdel <nom> |
Supprimer un groupe (root) |
groupmem <groupe> <user> |
Ajouter un utilisateur à un groupe (root) |
groupmem -d <groupe> <user> |
Retirer un utilisateur d'un groupe (root) |
groups [user] |
Lister les groupes d'un utilisateur |
sudoedit list |
Afficher les règles sudoers (root) |
sudoedit add <sujet> <cmds> |
Ajouter une règle sudoers (root) |
sudoedit del <num> |
Supprimer une règle sudoers (root) |
login / logout / exit |
Connexion / déconnexion |
reboot |
Redémarrer l'ESP32 |
clear |
Effacer l'écran |
version |
Version du système |
env |
Variables d'environnement |
export VAR=val |
Définir une variable |
date |
Date et heure système |
uptime |
Temps de fonctionnement |
free |
Mémoire heap ESP32 |
ps |
Processus actifs + tâches cron |
kill <index> |
Supprimer une tâche cron |
motd |
Afficher le message du jour (+ exécute ~/motd_perso.txt si présent) |
motd --help |
Aide détaillée sur la commande motd |
motd -s <msg> |
Définir le message du jour système (root) |
| Commande | Description |
|---|---|
ls |
Lister le répertoire courant |
ls -l |
Listing long : permissions, propriétaire, taille |
cd <dir> |
Changer de répertoire |
pwd |
Répertoire courant |
cat <fichier> |
Afficher un fichier |
edit <fichier> |
Éditeur de texte intégré |
mkdir <dir> |
Créer un dossier |
rm <fichier> |
Supprimer un fichier |
cp <src> <dst> |
Copier |
mv <src> <dst> |
Déplacer / renommer |
touch <fichier> |
Créer un fichier vide |
grep <motif> |
Recherche dans les fichiers |
head / tail |
Début / fin d'un fichier |
chmod <mode> <fichier> |
Changer les permissions (644, rwxr-xr-x…) |
chown <user>[:<group>] <fichier> |
Changer le propriétaire |
df |
Espace disque LittleFS (barre de progression) |
du [path] |
Taille d'un fichier ou répertoire |
| Commande | Description |
|---|---|
ifconfig |
IP, masque, gateway, DNS, MAC, RSSI |
ping <host> |
Test de connectivité ICMP |
nslookup <host> |
Résolution DNS |
curl <url> |
Requête HTTP/HTTPS |
wifi <ssid> <pass> |
Connexion WiFi |
ssh <user@host> |
Client SSH |
sleep <sec> |
Pause (float accepté, ex: sleep 0.5) |
| Commande | Description |
|---|---|
crontab |
Éditer les tâches cron (/root/.crontab) |
cronpause / cronresume |
Suspendre / reprendre le cron |
Format crontab :
# intervalle_secondes commande
60 echo tick
300 curl http://exemple.fr/ping
Exécution : run monscript.msh
int compteur = 0
float temp = 20.5
string nom = "alice"
bool actif = true
x = 42 # auto-typageint res = $a + $b # avec $
int res = a + b # ou sans $ (rétrocompat)
# opérateurs : + - * / %if score ge 90
echo excellent
else
if score ge 60
echo bien
endif
endif
# opérateurs int : eq ne gt lt ge le
# opérateurs string : seq snefor i 1 10 # for i $debut $fin aussi supporté
echo $i
endfor
while cnt lt 100
cnt = $cnt * 2
if cnt gt 50
break
endif
endwhileecho rapport > /root/rapport.txt
date >> /root/rapport.txt
cat /root/rapport.txtLes fonctions peuvent être déclarées n'importe où dans le fichier (avant ou après leur appel).
func saluer
echo Bonjour $1 !
echo Vous avez $2 ans.
endfunc
func max
if $1 gt $2
echo $1
else
echo $2
endif
endfunc
call saluer Alice 30
call max 42 17Paramètres : disponibles en $1, $2, … $argc (nombre d'arguments).
Les variables globales sont partagées avec les fonctions. $1…$9 et $argc sont sauvegardés/restaurés automatiquement entre appels.
break— sort d'une boucleexit— arrête le scriptreturn— sort de la fonction courante (ne stoppe pas le script parent)read VAR— lecture utilisateur (no-op en mode pipe)
src/
├── main.cpp # Entrée ESP32
├── native_main.cpp # Entrée simulateur natif
├── globals.h / globals.cpp # État global partagé
├── applications/
│ ├── shell.h / shell.cpp # Dispatch commandes, historique
│ ├── firstboot.h / .cpp # Assistant premier démarrage
│ ├── shell_apps/
│ │ ├── shell_sys # Auth, users, session, help
│ │ ├── shell_fs # Fichiers (ls, cat, cp…)
│ │ ├── shell_edit # Éditeur vi-like
│ │ ├── shell_grep # Recherche
│ │ ├── shell_script # Interpréteur .msh
│ │ └── shell_extra # env, date, ps, sudo, df, du…
│ ├── cron/ # Planificateur de tâches
│ └── ssh/ # Client SSH (LibSSH-ESP32)
└── utils/ # I/O Minitel, WiFi, saisie
sim/
├── include/ # Stubs POSIX : Arduino, LittleFS, WiFi…
└── src/sim_impl.cpp # Implémentation simulateur
sim_fs/ # Système de fichiers simulé (monté à la racine)
├── etc/
│ └── shadow # Base d'authentification
├── root/
│ ├── demo.msh # Script de démonstration
│ ├── test_script.msh # Suite de tests
│ ├── .crontab # Tâches cron
│ └── .fsmeta # Permissions chmod/chown
└── home/
| Niveau | Description |
|---|---|
user |
Utilisateur standard — accès à son home uniquement |
admin |
Accès étendu — peut gérer certains fichiers système |
root |
Accès total — toutes les commandes, tous les fichiers |
| Commande | Comportement |
|---|---|
su <user> |
Switch permanent vers un autre utilisateur (demande son mot de passe, sauf si déjà root) |
sudo <cmd> |
Élévation temporaire root pour une commande — vérifie /etc/sudoers en premier (sans mot de passe si règle match), sinon demande le mot de passe root |
Les permissions suivent le modèle Unix (rwxrwxrwx : propriétaire / groupe / autres).
chmod <mode> <fichier>— modifiable par le propriétaire ou root (644,rwxr-xr-x…)chown <user>[:<group>] <fichier>— changer le propriétaire (root) ou le groupe (propriétaire, si membre du groupe cible)- Les métadonnées sont stockées dans
/root/.fsmeta
Les groupes contrôlent les bits groupe des permissions fichiers.
Groupes intégrés (non modifiables) :
| Groupe | Membres |
|---|---|
user |
Tous les utilisateurs connectés |
admin |
Utilisateurs de niveau admin et root |
root |
Uniquement root |
<username> |
Groupe personnel — uniquement cet utilisateur |
Groupes personnalisés : stockés dans /root/.groups (format : nom:user1,user2,...), gérés via groupadd / groupdel / groupmem (root uniquement).
Format de /etc/sudoers — une règle par ligne :
# Autoriser alice à exécuter cat et ls sans mot de passe
alice cat,ls
# Autoriser tous les membres du groupe devs à tout faire
%devs ALL
# Autoriser bob à tout faire
bob ALL
Géré via sudoedit add / sudoedit del / sudoedit list (root uniquement).
| Fichier | Contenu |
|---|---|
/etc/shadow |
user:MD5(pass):level |
/etc/sudoers |
Règles sudo : user|%group ALL|cmd1,cmd2 |
/root/.groups |
Groupes personnalisés : nom:user1,user2,... |
/root/.crontab |
Tâches cron |
/root/.fsmeta |
Permissions chmod/chown |
/.motd |
Message du jour |
/home/<user>/.msh_history |
Historique commandes |
- Déclarer dans le header approprié (
shell_extra.h,shell_sys.h…) :
void shell_ma_commande(const String &args);- Implémenter dans le
.cppcorrespondant :
void shell_ma_commande(const String &args) {
if (args.isEmpty()) { shell_println_wrapped("Usage: ma_commande <arg>"); return; }
shell_println_wrapped("Résultat : " + args);
}- Enregistrer dans
shell.cpp:
{"ma_commande", shell_ma_commande},| Bibliothèque | Rôle |
|---|---|
Minitel1B_Hard |
Contrôle terminal Minitel (affichage, clavier) |
LibSSH-ESP32 |
Client SSH |
ESP32Ping |
Ping ICMP |
mbedTLS |
Hash MD5 (mots de passe) |
libcurl |
HTTP/HTTPS (simulateur uniquement) |
- LL7Baucarré
- 0b3ud
GPL-3.0