BUG: impossible de gérer noyau de pagination à la demande
Je suis en train d'écrire une carte PCI pilote pour un simple appareil de test.
Matériel est reconnu correctement avec lspci (comme vous pouvez le voir mon pilote abc a été enregistré):
04:02.0 Non-VGA unclassified device: Device bace:55aa
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Region 0: Memory at f0000000 (32-bit, prefetchable) [size=16M]
Kernel driver in use: vabs
De l'Initialisation et deinitalisation de pilote et PCI subystem fonctionne très bien. Je reçois un numéro de périphérique, et udev crée un fichier de périphérique.
Lors de la lecture du fichier de périphérique j'obtiens le message d'erreur suivant:
BUG: unable to handle kernel paging request at 00000000f0000000
Je demande PCI ressources dans l'initialisation avec succès. Cela renvoie 00000000f0000000 pour memstart0, qui est mon adresse de base 0 pour le PCI.
memstart0 = pci_resource_start( pdev, 0 );
memlen = pci_resource_len( pdev, 0 );
if( request_mem_region(memstart0,memlen,pdev->dev.kobj.name)==NULL ) {
dev_err(&pdev->dev,"Memory address conflict for device\n");
goto cleanup_mem;
}
Essayer de lire à partir de ce memio adresse avec le code suivant donne l'erreur mentionné:
ssize_t driver_read(struct file *instance, char __user *buffer, size_t max_bytes_to_read, loff_t *offset) {
u32 test;
dev_dbg(vabs_dev,"copying from %p\n", (void *) memstart0);
test = readl((void *) memstart0);
return max_bytes_to_read;
}
J'ai aussi essayé d'autres fonctions d'accès comme memcpy_fromio, ioread32, et de diriger le pointeur de l'accès avec le même résultat.
Le matériel fonctionne sur une machine Windows. La seule différence notable est que Windows se réserve la base de l'adresse 0 comme 00000000fd000000 alors que Linux se réserve comme 00000000f0000000.
C'est à but non lucratif à des fins didactiques, dans une école publique. Merci pour votre aide!
OriginalL'auteur kohpe | 2012-12-10
Vous devez vous connecter pour publier un commentaire.
Lire Documentation/IO-mapping.txt (de la recherche pour "iomap") et/ou Le chapitre 15 de LDD3.
request_mem_region
s'assure juste aucun autre pilote a déjà attrapé que la mémoire de la région. Vous avez encore besoin de la carte dans le noyau de l'espace de machine virtuelle à l'aide deiomap
avant de pouvoir lire/écrire.Noter que l'ensemble de la
pci_resource_start
etc. la danse est quelque peu obsolète. Je crois que l'approche recommandée est ces jours-ci:Alors:
Alors:
Et enfin, à la fin:
Vous pouvez faire les deux premières manuellement en combinant
pci_resource_start
,pci_resource_len
,request_mem_region
, etiomap
. Mais le ci-dessus est (un) plus courtes et (b) générique entre mappés en mémoire des appareils et ceux qui utilisent l'ancien x86 I/O de l'espace. (Pas qu'il y a tout un tas de ceux qui l'entourent plus.)Content d'avoir pu aider. Vous pourriez envisager d'accepter ma réponse 🙂
OriginalL'auteur Nemo