2016-08-19 15 views
2

Ich arbeite mit einer x86-Architektur. Soweit ich verstehe (und gesagt worden) eine physikalische Adresse des zugeordneten Speichers erhalten muß ich folgendes tun:Warum der Wert der physischen Adresse hängt davon ab, wie es gedruckt wurde

struct SizeAddr { 
    size_t size; 
    u64 addr_uint64; 
    void* addr_voidp; 
    unsigned long addr_ul; 
}; 

struct SizeAddr sa; 

virtAddr = kmalloc(<some size>, GFP_KERNEL); 
physAddr = virt_to_phys(virtAddr); 

sa.addr_uint64 = (uint64_t)physAddr; 
sa.addr_voidp = (void *)physAddr; 
sa.addr_ul = (unsigned long)physAddr; 

Ich habe beschlossen, aus dem Wert der physikalischen Adresse zu drucken, also tat ich die folgenden:

printk(MODULE_NAME " virtAddr(%%p) = %p\n", virtAddr); 
    printk(MODULE_NAME " physAddr(%%pap) = %pap\n", &physAddr); 
    printk(MODULE_NAME " physAddr(%%llx) = %llx\n", sa.addr_uint64); 
    printk(MODULE_NAME " physAddr(%%p) = %p\n", sa.addr_voidp); 
    printk(MODULE_NAME " physAddr(%%lx) = %lx\n", sa.addr_ul); 

Hier ist, was ich im Protokoll bekam:

[63898.990593] my_kmodule virtAddr(%p) = 0000000000000010 
[63898.990652] my_kmodule physAddr(%pap) = ffff88020d783eb0 
[63898.990711] my_kmodule physAddr(%llx) = 780000000010 
[63898.990768] my_kmodule physAddr(%p) = 0000780000000010 
[63898.990827] my_kmodule physAddr(%lx) = 780000000010 

Und das ist, wo ich wirklich verwirrt bin. Sollten nicht alle diese Werte gleich sein? Warum physAddr(%pap) ist anders als der Rest der Werte (mit Ausnahme der virtuellen Adresse, die ich verstehe).

+1

Sie haben den Code, der 'sa' zuweist, nicht angezeigt. –

+4

'printk' # 2 ist falsch. Sie wollen 'physAddr' und _not_' & physAddr'. Außerdem ist 'phys_addr_t' entweder' u32' oder 'u64', also wird auf' u64' gewandelt und auch '% llx' versucht. –

+0

Ich weiß nicht, was 'pap' ist, aber die Art einen Zeigerwert zu drucken ist mit' printf ("% p", (void *) virtAddr) '' –

Antwort

-2

Eine virtuelle Adresse (virtAddr) von kmalloc mit einem Wert von 0x10 macht keinen Sinn. Also, danach sind alle Wetten aus?

Sind Sie sicher, dass Sie phys_addr_t physAddr (vs. (z. B. phys_addr_t *) haben)? Auf dem Stapel vermute ich?

Die Ausgabe von %pap sieht aus wie eine [stack] virtuelle Adresse, anstatt eine physische. Also, mein Original Top-Kommentar über &physAddr/physAddr könnte einige Lager abhängig von Ihrem vollständigen Code haben.

Was sagt printk("%p\n",&physAddr);? Oder, printk("%llx\n",(u64) &physAddr);? Oder andere Kombinationen (z &virtAddr)

Obwohl die Doc sagt %pap in Ordnung ist, es sagt auch, dass der Standard ist phys_addr_t (das heißt %pa). Beide sollte Arbeit [und meine Prüfung des printk Code scheint zu bestätigen dies], gibt es nur etwa 5 Verwendungen von %pap und Hunderte von Verwendungen von %pa

ich die printk Quelle untersucht haben [nachuntersucht, tatsächlich, wie ich es schon einige Male tun musste]. Gegenwärtig habe ich keine Diskrepanzen gefunden, von denen ich sprechen könnte. Aber die Quelle ist ein wenig verschachtelt, also werde ich es weiterhin tun.


Randbemerkung: Dies war die ursprüngliche Post vor dem edit [die Downvoted wurde immer] [mit etwas Klärung], aber es ist noch zu versuchen, etwas.

Nachdem Sie nun Ihren sa Code hinzugefügt haben ...

Wechsel:

struct SizeAddr 

In:

union SizeAddr 

hinzufügen phys_addr_t Mitglied und setzen nur das [mit Union] . Das ist das üblichere Idiom dafür. Dann sehen Sie, welche abgeschnitten und welche nicht. Andernfalls erhalten Sie für die Struktur %llx die übereinstimmenden Ergebnisse mit %pap.

+0

Warum sollte ich das tun wollen? Das würde alles an einem Ort speichern. – flashburn

+2

Dies beantwortet die Frage nicht, und selbst als Kommentar zum OP-Code ist es von fragwürdiger Qualität. –

Verwandte Themen