ฉันมีอุปกรณ์ที่ต้องการบล็อกหน่วยความจำที่สงวนไว้ แต่เพียงผู้เดียวโดยไม่มีระบบปฏิบัติการแทรกแซง มีวิธีใดบ้างที่จะบอก BIOS หรือระบบปฏิบัติการว่ามีการสำรองบล็อกหน่วยความจำไว้และต้องไม่ใช้งานหรือไม่
ฉันใช้อุปกรณ์นี้กับเครื่อง openSUSE
ฉันมีอุปกรณ์ที่ต้องการบล็อกหน่วยความจำที่สงวนไว้ แต่เพียงผู้เดียวโดยไม่มีระบบปฏิบัติการแทรกแซง มีวิธีใดบ้างที่จะบอก BIOS หรือระบบปฏิบัติการว่ามีการสำรองบล็อกหน่วยความจำไว้และต้องไม่ใช้งานหรือไม่
ฉันใช้อุปกรณ์นี้กับเครื่อง openSUSE
คำตอบ:
สิ่งที่คุณขอเรียกว่า DMA คุณต้องเขียนไดรเวอร์เพื่อจองหน่วยความจำนี้
ใช่ฉันรู้ว่าคุณบอกว่าคุณไม่ต้องการให้ระบบปฏิบัติการแทรกแซงและไดรเวอร์กลายเป็นส่วนหนึ่งของระบบปฏิบัติการ แต่ในกรณีที่ไม่มีการจองของไดรเวอร์เคอร์เนลเชื่อว่าหน่วยความจำทั้งหมดเป็นของมัน (เว้นแต่คุณจะบอกเคอร์เนลให้เพิกเฉยต่อบล็อกหน่วยความจำตามคำตอบของแอรอนนั่นคือ)
บทที่ 15 (PDF) ของ " ไดรเวอร์อุปกรณ์ Linux, 3 / e " โดย Rubini, Corbet และ Kroah-Hartmann ครอบคลุม DMA และหัวข้อที่เกี่ยวข้อง
หากคุณต้องการรุ่น HTML นี้ฉันพบบทที่รุ่นที่สองของที่อื่นทางออนไลน์ โปรดระวังว่ารุ่นที่ 2 มีอายุเกินหนึ่งทศวรรษแล้วออกมาเมื่อเคอร์เนล 2.4 เป็นของใหม่ มีงานจำนวนมากในระบบย่อยการจัดการหน่วยความจำของเคอร์เนลตั้งแต่สมัยนั้นดังนั้นมันจึงอาจไม่ได้ใช้งานได้ดีอีกต่อไป
หากคุณต้องการให้ระบบปฏิบัติการเพิกเฉยต่อสิ่งนั้นโดยสิ้นเชิงคุณต้องสร้างรูหน่วยความจำโดยใช้ " memmap
." ดูเอกสารอ้างอิงนี้ ตัวอย่างเช่นถ้าคุณต้องการ 512M ที่กั้น 2GB คุณสามารถใส่ " memmap=512M$2G
" ในบรรทัดคำสั่งเคอร์เนล
คุณจะต้องตรวจสอบdmesg
เพื่อหาช่องโหว่ที่ต่อเนื่องกันเพื่อขโมยดังนั้นคุณจึงไม่เหยียบบนอุปกรณ์ใด ๆ ที่เฉพาะเจาะจงกับเมนบอร์ดของคุณ + การ์ด
นี่ไม่ใช่วิธีที่แนะนำในการทำสิ่งต่าง ๆ - ดูคำตอบของ Warren Young สำหรับวิธีการทำอย่างถูกต้อง (เคอร์เนลไดรเวอร์ + DMA) ฉันกำลังตอบคำถามที่คุณถาม หากคุณวางแผนที่จะทำสิ่งนี้สำหรับผู้ใช้พวกเขาจะเกลียดคุณถ้าคุณทำสิ่งนี้กับพวกเขา ... เชื่อฉันนั่นเป็นเหตุผลเดียวที่ฉันรู้คำตอบนี้
แก้ไข: ถ้าคุณกำลังใช้ grub2 w / สกปรก (เช่น CentOS 7) คุณจะต้องตรวจสอบให้แน่ใจที่จะหลบหนีที่ $ ควรจะมีเพียงครั้งเดียวก่อน\
$
ตัวอย่าง:
$ sudo -v
$ sudo grubby --update-kernel=ALL --args=memmap='128M\\$0x57EF0000'
$ sudo grubby --info $(sudo grubby --default-kernel) | grep memmap
args="ro crashkernel=auto ... memmap=128M\$0x57EF0000"
uint8_t *ptr = 0x8000000
" พร้อมกับตัวอย่างของฉันหรือไม่ หรือนั่นอาจ segfault ... อืมฉันไม่รู้จริงๆ อีกครั้งฉันรู้คำตอบเพราะฉันเป็นผู้ใช้ของการ์ด PCI ที่ออกแบบมาไม่ดีซึ่งฉันต้องจัดสรรบัฟเฟอร์ด้วยตนเองด้านล่างเครื่องหมาย 4G จากนั้นบอกคนขับว่าพื้นที่นั้นอยู่ที่ไหน มันอาจเป็นไปไม่ได้จาก userland
MMAP_FIXED | MMAP_ANON
ลึกเข้าไปในนี้และดูเหมือนว่าคุณจำเป็นต้อง หากไม่มีอุปกรณ์ DMA ที่กำหนดเองที่นี่เพื่อเล่นกับฉันไม่สามารถพูดได้ว่ามันเป็นสิ่งที่ OP ต้องการจริง ๆ แต่กล่อง CentOS ของฉันให้บล็อก 8 MB ที่ 512 MB อย่างมีความสุขเมื่อฉันพูดmemmap=8M$512M
ใน GRUB มันไม่จำเป็นต้องมีการเข้าถึงรูทเพราะฉันกลัวว่ามันอาจจะ แต่ถึงแม้ว่าสิ่งนี้จะทำในสิ่งที่ถูกต้องฉันยังคงคิดว่าคุณอาจต้องใช้ไดรเวอร์เพื่อจัดการกับการขัดจังหวะและเช่นนั้น
mmap()
หน้าเว็บจะเป็นศูนย์ก่อนที่รหัสผู้ใช้จะเห็นหน้าเหล่านั้น มันทำเพื่อความปลอดภัยเพื่อให้ข้อมูลไม่รั่วไหลจากกระบวนการหนึ่งไปยังกระบวนการถัดไป อีกเหตุผลหนึ่งในการใช้ไดรเวอร์เนื่องจากคุณอาจต้องเก็บเนื้อหาของบัฟเฟอร์ DMA ไว้ในขณะโหลดไดรเวอร์ โอ้และโดยวิธีการmmap()
โทรที่ตั้งโดยพลการสำเร็จแม้ไม่มีmemmap
ตัวเลือกการบูตเคอร์เนลอย่างน้อยตราบใดที่ยังไม่มีใครใช้หน่วยความจำที่คุณถาม ตัวเลือกการบูตอย่างไม่ต้องสงสัยเพิ่มโอกาสของความสำเร็จ แต่ไม่จำเป็นอย่างเคร่งครัด
ในการจองบล็อกหน่วยความจำจากเคอร์เนลใน Linux ที่ใช้ ARM คุณสามารถใช้reserved-memory
โหนดในไฟล์ tree tree (dts) ของอุปกรณ์ของคุณ ในเอกสารประกอบเคอร์เนล (ดูที่นี่ ) มีตัวอย่าง:
memory {
reg = <0x40000000 0x40000000>;
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
/* global autoconfigured region for contiguous allocations */
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0x4000000>;
alignment = <0x2000>;
linux,cma-default;
};
display_reserved: framebuffer@78000000 {
reg = <0x78000000 0x800000>;
};
multimedia_reserved: multimedia@77000000 {
compatible = "acme,multimedia-memory";
reg = <0x77000000 0x4000000>;
};
};
ก่อนอื่นให้ป้อนคำสั่งนี้เพื่อตรวจสอบการตั้งค่าปัจจุบันของคุณ:
sysctl vm.min_free_kbytes
/etc/sysctl.conf
การเปลี่ยนค่าที่ตั้งไว้แก้ไข มองหาเส้น:
vm.min_free_kbytes=12888
หากไม่มีอยู่ให้สร้าง (พร้อมกับค่าที่คุณต้องการ) ค่าต่อไปนี้เป็นที่ยอมรับได้:
8192
12288
16384
20480
8M ค่อนข้างอนุรักษ์นิยมมาก สามารถนั่งที่ 16M ได้อย่างสบาย เมื่อคุณเปลี่ยนค่าให้รันสิ่งนี้และไม่จำเป็นต้องรีบูต:
sudo sysctl -p