Allokera minne ur non-paged pool (windows)

Permalänk

Allokera minne ur non-paged pool (windows)

Hej
Kan börja med att säga att detta tillhör mitt exjobb och jag har skrivit på en NDA så därför är jag lite sparsmakad med vissa detaljer.

Jag undersöker möjligheten att i windows allokera kontinuerligt "non-paged" fysiskt minne, detta minne vill jag sedan dela med ett realtids OS som körs på samma maskin och har tillgång till samma fysiska minne.
På realtids sidan tar jag sedan emot den fysiska adressen och mappar in det i virtuella adressområdet hos en process.

Det finns ingen som helst synkronisering/kommunikation mellan minneshaterarna i de båda operativsystemen, så därför krävs det att det fysiska minnet som ska delas är ordnat i ett sammanhängande block och aldrig får swappas ut på disk.

Nu till min frågor/funderingar:

Är detta möjligt att åstadkomma?
Jag har läst om en funktion som heter MmAllocateContiguousMemory som skulle kunna åstadkomma just detta, men den används bara för drivrutiner men jag kommer köra i user space.
Men det finns kanske något annat sätt?

Finns det risk att jag äventyrar stabiliteten hos operativsystemet? Vad är det man måste tänka på om man vill göra detta?

Vart jag är nu:
Har lyckats att allokera minne på realtids sidan, mappa in detta i en windows process och läsa/skriva från/till det.
Anledningen till att jag vill göra tvärt om är att det handlar om kod som ska portas och det skulle spara enormt mycket tid.

Men frågan är om det är värt besväret.

PS: Har inte järnkoll när det gäller detta område så jag kan ha blandat ihop vissa termer och svamlat till det lite

Permalänk
Datavetare

Är inte helt 100 på detta, men är rätt säker på att du inte kan begära fysiskt kontinuerligt minne från en "user space" program då det helt enkelt aldrig borde vara något ett sådan program behöver.

Det enda fall jag själv snubblat på där fysiska adresser spelar roll i "user-space" är under Linux tillsammans med en modul som kallas uio (userland I/O). Den modulen gör det möjligt att m.h.a. kärnan göra minnesmappad I/O direkt åtkomlig från "user space".
http://www.kernel.org/doc/htmldocs/uio-howto.html#userspace_driver

Du vill ju egentligen göra samma sak fast under Windows och din "HW" i detta fall är ditt RTOS, så du kan ju kolla om det finns något motsvarande UIO för Windows alternativt skriva en egen kernelmodul till Windows som just använder MmAllocateContiguousMemory() och sedan mappar in det minnen i den virtuella adressrymden för ditt Windows-program.

Det du kommer att behöva tänka på är framförallt hur du ska implementera synkronisering i det delade minnet, då jag antar att det är just för att kommunicera mellan Windows och RTOS:et som är anledningen till det delade minnet. Om du inte kan skicka meddelanden på sätt som orsakar IPI (InterProcess Interrupt) så kommer du behöva någon form av "spinlock". Om du sedan kör på ARM, PowerPC eller MIPS så måste du tänka på att skrivningar i delat minne inte nödvändigtvis blir synliga i den ordning du skrev data (x86 garanterar dock detta), lösningen här är att skriva all data, köra en s.k. minnesbarriär och sedan skriva något som säger åt den andra sidan att det finns data att läsa.

Om minnet inte används av Windows på något annat sätt än att bara vara allokerat av Windows-kärnan, så kan det inte orsaka instabilitet.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Skrivet av Yoshman:

Är inte helt 100 på detta, men är rätt säker på att du inte kan begära fysiskt kontinuerligt minne från en "user space" program då det helt enkelt aldrig borde vara något ett sådan program behöver.

Det enda fall jag själv snubblat på där fysiska adresser spelar roll i "user-space" är under Linux tillsammans med en modul som kallas uio (userland I/O). Den modulen gör det möjligt att m.h.a. kärnan göra minnesmappad I/O direkt åtkomlig från "user space".
http://www.kernel.org/doc/htmldocs/uio-howto.html#userspace_driver

Du vill ju egentligen göra samma sak fast under Windows och din "HW" i detta fall är ditt RTOS, så du kan ju kolla om det finns något motsvarande UIO för Windows alternativt skriva en egen kernelmodul till Windows som just använder MmAllocateContiguousMemory() och sedan mappar in det minnen i den virtuella adressrymden för ditt Windows-program.

Det du kommer att behöva tänka på är framförallt hur du ska implementera synkronisering i det delade minnet, då jag antar att det är just för att kommunicera mellan Windows och RTOS:et som är anledningen till det delade minnet. Om du inte kan skicka meddelanden på sätt som orsakar IPI (InterProcess Interrupt) så kommer du behöva någon form av "spinlock". Om du sedan kör på ARM, PowerPC eller MIPS så måste du tänka på att skrivningar i delat minne inte nödvändigtvis blir synliga i den ordning du skrev data (x86 garanterar dock detta), lösningen här är att skriva all data, köra en s.k. minnesbarriär och sedan skriva något som säger åt den andra sidan att det finns data att läsa.

Om minnet inte används av Windows på något annat sätt än att bara vara allokerat av Windows-kärnan, så kan det inte orsaka instabilitet.

Hej
Tack för ett bra och informativt svar.
Mellan windows och RTOS så finns det stöd för semaforer,mailslots,event objekt mm. Så någon spinlock behövs inte och det skulle vara en katastrof för prestandan.
Synkronisering kommer att ske med user-space semaforer där man använder sig av interlocked exchange, jag har inte undersökt denna biten än för detta kräver att det delade minnet först fungerar.
All hårdvara är x86.

Jag har i alla fall kommit lite längre och lyckats lista ut att jag kan uppnå detta med mitt delade minne, genom att skriva en "software driver" med hjälp av KMDF (Kernel-Mode Driver Framework).
Detta framework är inkluderat i WDK (windows driver kit), som jag kommer att ladda ned och labba lite med.

Så det är ungefär så långt jag har kommit, vi får helt enkelt se hur pass komplicerat det blir att implementera och testa detta.