Introduction au sous-système d'entrée Linux
Le sous-système d'entrée Linux est un ensemble de pilotes qui prennent en charge tous les périphériques d'entrée du système Linux, notamment les claviers, les souris, les écrans tactiles, les tablettes, les contrôleurs de jeu, etc. Le cœur du sous-système d'entrée est le module d'entrée, qui est responsable de la transmission des événements entre les deux types de modules :
- Modules de pilote de périphérique : ces modules communiquent avec le matériel (par exemple via USB) et fournissent des événements (appuis sur des touches, mouvements de la souris, etc.) au module d'entrée.
- Modules de gestion d'événements : ces modules récupèrent les événements du module d'entrée et les transmettent là où ils sont nécessaires (par exemple, noyau, GPM, X, etc.) via diverses interfaces.
Dans cet article, nous présenterons les concepts de base et la structure du sous-système d'entrée Linux, ainsi que certaines commandes et outils couramment utilisés. Nous utiliserons Ubuntu 20.04 comme exemple de système, mais le contenu s'applique également à d'autres distributions Linux.

Couche pilote
Convertissez l'entrée matérielle sous-jacente en un formulaire d'événement unifié et signalez-la à l'Input Core.
Couche centrale du sous-système d'entrée
Il fournit à la couche pilote des interfaces d'enregistrement et de fonctionnement du périphérique d'entrée, telles que : input_register_device ; notifie la couche de traitement des événements pour traiter l'événement ; génère les informations de périphérique correspondantes sous /Proc.
Couche de traitement des événements
Interagit principalement avec l'espace utilisateur (sous Linux, tous les périphériques sont traités comme des fichiers dans l'espace utilisateur. Puisque l'interface fops est fournie dans les pilotes généraux et que le nœud de fichier de périphérique correspondant est généré sous /dev, ces L'opération est complétée par le traitement des événements couche dans le sous-système d’entrée).
Description de l'appareil
La structure input_dev consiste à implémenter le travail de base du pilote de périphérique : signaler les pressions sur les touches, les écrans tactiles et autres événements d'entrée (événements, décrits via la structure input_event) au système, et n'a plus besoin de se soucier de l'interface d'exploitation des fichiers. Le pilote signale les événements à l'espace utilisateur via inputCore et Eventhandler.
Fonction d'enregistrement du périphérique d'entrée :
int input_register_device(struct input_dev *dev)
Fonction de désenregistrement du périphérique d'entrée :
void input_unregister_device(struct input_dev *dev)
Implémentation du pilote - initialisation (prise en charge des événements) set_bit() indique au sous-système d'entrée quels événements et clés sont pris en charge. Par exemple :
set_bit(EV_KEY,button_dev.evbit) (其中button_dev是struct input_dev类型)
struct input_dev**** :
**1)** Type d'événement evbit (y compris EV_RST, EV_REL, EV_MSC, EV_KEY, EV_ABS, EV_REP, etc.).
**2)**Type de clé keybit (y compris BTN_LEFT, BTN_0, BTN_1, BTN_MIDDLE, etc. lorsque le type d'événement est EV_KEY).
Implémentation du pilote - reporting des événements Les fonctions utilisées pour signaler les événements EV_KEY, EV_REL, EV_ABS sont :
void input_report_key(struct input_dev *dev,unsigned int code,int value) void input_report_rel(struct input_dev *dev,unsigned int code,int value) void input_report_abs(struct input_dev *dev,unsigned int code,int value)
Implémentation du pilote - la synchronisation input_sync() de fin de rapport est utilisée pour indiquer au sous-système principal d'entrée que le rapport est terminé. Dans le pilote de périphérique à écran tactile, l'ensemble du processus de reporting en un seul clic est le suivant :
input_reprot_abs(input_dev,ABS_X,x); //x坐标 input_reprot_abs(input_dev,ABS_Y,y); // y坐标 input_reprot_abs(input_dev,ABS_PRESSURE,1); input_sync(input_dev);//同步结束
Exemple d'analyse (programme d'interruption de clé) :
//按键初始化 static int __init button_init(void) {//申请中断 if(request_irq(BUTTON_IRQ,button_interrupt,0,”button”,NUll)) return –EBUSY; set_bit(EV_KEY,button_dev.evbit); //支持EV_KEY事件 set_bit(BTN_0,button_dev.keybit); //支持设备两个键 set_bit(BTN_1,button_dev.keybit); // input_register_device(&button_dev);//注册input设备 } /*在按键中断中报告事件*/ Static void button_interrupt(int irq,void *dummy,struct pt_regs *fp) { input_report_key(&button_dev,BTN_0,inb(BUTTON_PORT0));//读取寄存器BUTTON_PORT0的值 input_report_key(&button_dev,BTN_1,inb(BUTTON_PORT1)); input_sync(&button_dev); }
Résumé : Le sous-système input est toujours un pilote de périphérique de caractères, mais la quantité de code est considérablement réduite. Le sous-système ****input n'a besoin d'effectuer que deux tâches : l'initialisation et le rapport d'événements (ici dans linux*. *** est obtenu grâce à des interruptions).
Instances
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct input_dev *button_dev; struct button_irq_desc { int irq; int pin; int pin_setting; int number; char *name; }; /*定义一个结构体数组*/ static struct button_irq_desc button_irqs [] = { {IRQ_EINT8 , S3C2410_GPG0 , S3C2410_GPG0_EINT8 , 0, "KEY0"}, {IRQ_EINT11, S3C2410_GPG3 , S3C2410_GPG3_EINT11 , 1, "KEY1"}, {IRQ_EINT13, S3C2410_GPG5 , S3C2410_GPG5_EINT13 , 2, "KEY2"}, {IRQ_EINT14, S3C2410_GPG6 , S3C2410_GPG6_EINT14 , 3, "KEY3"}, {IRQ_EINT15, S3C2410_GPG7 , S3C2410_GPG7_EINT15 , 4, "KEY4"}, {IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG11_EINT19, 5, "KEY5"}, }; static int key_values = 0; static irqreturn_t buttons_interrupt(int irq, void *dev_id) { struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id; int down; udelay(0); /*获取按键值*/ down = !s3c2410_gpio_getpin(button_irqs->pin); //down: 1(按下),0(弹起) if (!down) { /*报告事件*/ key_values = button_irqs->number; //printk("====>rising key_values=%d\n",key_values); if(key_values==0) input_report_key(button_dev, KEY_1, 0); if(key_values==1) input_report_key(button_dev, KEY_2, 0); if(key_values==2) input_report_key(button_dev, KEY_3, 0); if(key_values==3) input_report_key(button_dev, KEY_4, 0); if(key_values==4) input_report_key(button_dev, KEY_5, 0); if(key_values==5) input_report_key(button_dev, KEY_6, 0); /*报告结束*/ input_sync(button_dev); } else { key_values = button_irqs->number; //printk("====>falling key_values=%d\n",key_values); if(key_values==0) input_report_key(button_dev, KEY_1, 1); if(key_values==1) input_report_key(button_dev, KEY_2, 1); if(key_values==2) input_report_key(button_dev, KEY_3, 1); if(key_values==3) input_report_key(button_dev, KEY_4, 1); if(key_values==4) input_report_key(button_dev, KEY_5, 1); if(key_values==5) input_report_key(button_dev, KEY_6, 1); input_sync(button_dev); } return IRQ_RETVAL(IRQ_HANDLED); } static int s3c24xx_request_irq(void) { int i; int err = 0; for (i = 0; i if (button_irqs[i].irq continue; } /* IRQ_TYPE_EDGE_FALLING,IRQ_TYPE_EDGE_RISING,IRQ_TYPE_EDGE_BOTH */ err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH, button_irqs[i].name, (void *)&button_irqs[i]); if (err) break; } /*错误处理*/ if (err) { i--; for (; i >= 0; i--) { if (button_irqs[i].irq continue; } disable_irq(button_irqs[i].irq); free_irq(button_irqs[i].irq, (void *)&button_irqs[i]); } return -EBUSY; } return 0; } static int __init dev_init(void) { /*request irq*/ s3c24xx_request_irq(); /* Initialise input stuff */ button_dev = input_allocate_device(); if (!button_dev) { printk(KERN_ERR "Unable to allocate the input device !!\n"); return -ENOMEM; } button_dev->name = "s3c2440_button"; button_dev->id.bustype = BUS_RS232; button_dev->id.vendor = 0xDEAD; button_dev->id.product = 0xBEEF; button_dev->id.version = 0x0100; button_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT(EV_SYN); //set_bit(EV_KEY, button_dev->evbit)//支持EV_KEY事件 /*设置支持哪些按键*/ set_bit(KEY_1, button_dev->keybit); set_bit(KEY_2, button_dev->keybit); set_bit(KEY_3, button_dev->keybit); set_bit(KEY_4, button_dev->keybit); set_bit(KEY_5, button_dev->keybit); set_bit(KEY_6, button_dev->keybit); //printk("KEY_RESERVED=%d ,KEY_1=%d",KEY_RESERVED,KEY_1); input_register_device(button_dev); //注册input设备 printk ("initialized\n"); return 0; } static void __exit dev_exit(void) { int i; for (i = 0; i if (button_irqs[i].irq continue; } free_irq(button_irqs[i].irq, (void *)&button_irqs[i]); } input_unregister_device(button_dev); } module_init(dev_init); module_exit(dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Xie");
Dans cet article, nous avons appris les concepts de base et la structure du sous-système d'entrée Linux, ainsi que certaines commandes et outils couramment utilisés. Nous avons appris comment afficher et contrôler les propriétés et l'état des périphériques d'entrée, et comment utiliser les outils evtest et libinput pour tester et déboguer les périphériques d'entrée. Nous avons également appris à utiliser les règles udev pour personnaliser le comportement et la configuration des périphériques d'entrée.
Le sous-système d'entrée Linux est un framework puissant et flexible qui vous permet de mieux gérer et utiliser vos périphériques d'entrée. En utilisant le sous-système de saisie Linux, vous pouvez améliorer votre productivité et votre expérience utilisateur. Nous vous recommandons d'utiliser souvent le sous-système d'entrée Linux pour optimiser vos périphériques d'entrée lorsque vous utilisez un système Linux.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Étapes pour démarrer Nginx dans Linux: Vérifiez si Nginx est installé. Utilisez SystemCTL Start Nginx pour démarrer le service NGINX. Utilisez SystemCTL Activer Nginx pour activer le démarrage automatique de Nginx au démarrage du système. Utilisez SystemCTL Status Nginx pour vérifier que le démarrage est réussi. Visitez http: // localhost dans un navigateur Web pour afficher la page de bienvenue par défaut.

Comment confirmer si Nginx est démarré: 1. Utilisez la ligne de commande: SystemCTl Status Nginx (Linux / Unix), netStat -ano | Findstr 80 (Windows); 2. Vérifiez si le port 80 est ouvert; 3. Vérifiez le message de démarrage NGINX dans le journal système; 4. Utilisez des outils tiers, tels que Nagios, Zabbix et Icinga.

Le démarrage d'un serveur Nginx nécessite différentes étapes en fonction des différents systèmes d'exploitation: Système Linux / Unix: Installez le package NGINX (par exemple, en utilisant Apt-Get ou Yum). Utilisez SystemCTL pour démarrer un service NGINX (par exemple, sudo systemctl start nginx). Système Windows: téléchargez et installez les fichiers binaires Windows. Démarrer Nginx à l'aide de l'exécutable Nginx.exe (par exemple, nginx.exe -c conf \ nginx.conf). Peu importe le système d'exploitation que vous utilisez, vous pouvez accéder au serveur IP

Dans Linux, utilisez la commande suivante pour vérifier si Nginx est démarré: SystemCTL Status Nginx Juges Basé sur la sortie de la commande: si "Active: Active (Running)" s'affiche, Nginx est démarré. Si "Active: Inactive (Dead)" est affiché, Nginx est arrêté.

Le serveur n'a pas l'autorisation d'accéder à la ressource demandée, ce qui donne une erreur NGINX 403. Les solutions incluent: vérifier les autorisations de fichiers. Vérifiez la configuration .htaccess. Vérifiez la configuration de Nginx. Configurez les autorisations Selinux. Vérifiez les règles du pare-feu. Dépanner d'autres causes telles que les problèmes de navigateur, les défaillances du serveur ou d'autres erreurs possibles.

Réponse à la question: 304 Erreur non modifiée indique que le navigateur a mis en cache la dernière version de ressource de la demande du client. Solution: 1. Effacer le cache du navigateur; 2. Désactiver le cache du navigateur; 3. Configurer Nginx pour permettre le cache client; 4. Vérifier les autorisations du fichier; 5. Vérifier le hachage du fichier; 6. Désactiver le CDN ou le cache proxy inversé; 7. Redémarrez Nginx.

Le journal d'erreur est situé dans / var / log / nginx (linux) ou / usr / local / var / log / nginx (macOS). Utilisez la ligne de commande pour nettoyer les étapes: 1. Sauvegarder le journal d'origine; 2. Créez un fichier vide en tant que nouveau journal; 3. Redémarrez le service Nginx. Le nettoyage automatique peut également être utilisé avec des outils tiers tels que Logrotate ou configurés.

Les principales différences entre Centos et Ubuntu sont: l'origine (Centos provient de Red Hat, pour les entreprises; Ubuntu provient de Debian, pour les particuliers), la gestion des packages (Centos utilise Yum, se concentrant sur la stabilité; Ubuntu utilise APT, pour une fréquence de mise à jour élevée), le cycle de support (CentOS fournit 10 ans de soutien, Ubuntu fournit un large soutien de LT tutoriels et documents), utilisations (Centos est biaisé vers les serveurs, Ubuntu convient aux serveurs et aux ordinateurs de bureau), d'autres différences incluent la simplicité de l'installation (Centos est mince)
