Comment le noyau linux peut-il être forcé d'énumérer le bus PCI-e?
noyau Linux 2.6
j'ai un fpga qui est chargé sur GPIO connecté à une carte de développement fonctionnant sous linux. La fpga transmettra et recevra les données par l'intermédiaire du bus pci-express. Toutefois, ce point est énuméré au démarrage et en tant que tel, aucun lien n'est découvert (parce que le fpga n'est pas chargé au démarrage).
Comment puis-je forcer la ré-énumération du bus pci-e sous linux? Est-il une commande simple ou vais-je devoir faire des changements dans le noyau? J'ai besoin de l' capacité de hotplug PCIe.
3 réponses
je me demande sur quelle plate-forme vous êtes: un work around (alias hack) pour cela qui fonctionne sur les systèmes x86 est d'avoir le BIOS essentiellement statiquement configurer un périphérique PCI à n'importe quel bus, périphérique, fonction FPGA atterrit normalement, puis L'OS va énumérer le périphérique et réserver l'espace PCI pour lui (même si le périphérique n'est pas vraiment là). Ensuite, dans votre pilote de périphérique, vous devrez faire des choses supplémentaires comme configurer les barres et les lignes int manuellement après que la fpga ait été programmée. De bien sûr cela nécessite de modifier le BIOS, si vous travaillez avec un BIOS fournisseur, vous pouvez les confier à faire ce changement pour vous, si vous ne travaillez pas avec un BIOS vendeur alors il sera beaucoup plus difficile... N'oubliez pas non plus que je travaillais sur VxWorks sur x86, et que nous avions un AMI qui fabriquait un BIOS personnalisé pour nos cartes...
si vous n'avez pas de BIOS, alors envisagez de le programmer dans le bootloader, là vous avez déjà la capacité de lire à partir du disque, et L'ajout de GPIO les capacités ne sont probablement pas trop difficiles (en supposant que vous utilisez jtag et GPIOs?), en fait, selon le bootloader que vous utilisez, il pourrait déjà être capable de faire du GPIO?
le problème avec la modification du noyau pour faire cela est que vous devez trouver le point doux où vous pouvez lire le bitfile, avant l'énumération PCI... Si par exemple les pilotes de périphérique disque sont initialisés après PCI, alors évidemment vous devez faire quelques changements radicaux au noyau juste pour lire le bitfile avant l'énumération PCI, qui pourrait causer d'autres problèmes ennuyeux...
une autre option que vous avez peut-être déjà découverte, et qui n'est vraiment acceptable que pour le temps de développement: alimenter le système, programmer le forum fpga, puis faire une réinitialisation (sans cycle d'alimentation, par exemple: redémarrer sudo maintenant), le FPGA devrait garder sa configuration, et linux devrait l'énumérer...
en tant que root, essayez la commande suivante:
echo "1" > /sys/bus/pci/rescan
voir ce lien pour plus d'informations: http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci
après avoir activé votre ordinateur, le BIOS énumère le bus PCI et tente de répondre à toutes les demandes d'espace et de mémoire io (MMIO). Il met en place ces barres au départ, et lorsque le système d'exploitation charge ces barres peut être modifié par L'OS comme il le juge bon tandis que le pilote de bus PCI énumère le bus encore une fois. Il est même possible pour le superutilisateur du système d'exécuter la commande setpci
pour changer ces barres après que le BIOS ait déjà essayé de les configurer et le système D'exploitation est chargé (les pilotes peuvent tomber en panne et avoir plusieurs autres problèmes s'ils sont mal exécutés).
j'ai dû le faire dans les cas où la carte en question n'était pas assignée toute ressources par le BIOS puisque la région demandée exigeait une adresse 64 bits et le BIOS fonctionnait seulement avec des assignations d'adresse 32 bits. J'ai pu y aller après coup et changer ces adresses (attribuées à l'origine par le BIOS) à n'importe quelle adresse que j'ai trouvé appropriée, insérer le module du noyau, et mon pilote cartographierait et utiliserait ces adresses nouvellement attribuées pour la carte sans connaître la différence.
le problème qui existe avec les cartes hotplugging PCI-Express est que le pouvoir de la fente, lui-même, ne peut pas être allumé/éteint sans les contrôleurs hotplug spécifiques qui doivent exister sur la carte mère/plan arrière. Ne pas avoir ces contrôleurs hotplug pour couper le courant de la fente peut conduire à court-circuiter entre les petites broches lorsque la carte est physiquement insérée et retirée si l'alimentation est toujours présent. Les événements Hotplug, cependant, peuvent être initiés par l'une ou l'autre extrémité (l'hôte ou le dispositif d'extrémité). Cela ne semble pas être le cas, cependant si votre FPGA a déjà un lien établi avec le complexe racine, une solution possible à votre problème serait de générer des interruptions hotplug pour provoquer un rescan bus dans le système D'exploitation.
Il ya un problème majeur, cependant -- si votre carte n'obtient pas réellement un lien vers le complexe root, il ne sera pas capable de générer des évènements hotplug; ce qui semble être le cas. Après le démarrage, la FPGA devrait basculer la ligne PRESENT sur le bus PCIe pour dire à L'OS qu'il y a une carte prête à être énumérée. Une fois détecté, le système d'exploitation devrait tenter d'établir un lien avec la carte et attribuer des régions de mémoire à l'appareil. Après L'OS énumère la carte, vous serez en mesure de charger les pilotes contre elle et de le voir dans lspci
. Vous avez déclaré utiliser le noyau 2.6, qui a le support pour le hotplugging et l'allocation dynamique des ressources donc cette méthode devrait fonctionner aussi longtemps que votre FPGA prend en charge la capacité de basculer la ligne PCIe actuelle, aussi.