เหตุใดหมายเลขการโทรระบบ Linux ใน x86 และ x86_64 จึงแตกต่างกัน?


35

ฉันรู้ว่าส่วนต่อประสานการโทรของระบบมีการใช้งานในระดับต่ำและด้วยเหตุนี้ขึ้นอยู่กับสถาปัตยกรรม / แพลตฟอร์มไม่ใช่รหัส "ทั่วไป"

แต่ฉันไม่สามารถเห็นได้อย่างชัดเจนว่าทำไมการเรียกระบบในเคอร์เนล x86 แบบ 32 บิตมีหมายเลขที่ไม่เหมือนกันในสถาปัตยกรรมที่คล้ายกัน Linux 64-bit x86_64 แรงจูงใจ / เหตุผลเบื้องหลังการตัดสินใจนี้คืออะไร?

การเดาครั้งแรกของฉันคือเหตุผลเบื้องหลังที่ทำให้แอปพลิเคชันแบบ 32 บิตสามารถทำงานได้บนระบบ x86_64 ดังนั้นการชดเชยออฟเซตที่เหมาะสมกับหมายเลขการโทรของระบบระบบจะรู้ว่าพื้นที่ผู้ใช้เป็น 32 บิตหรือ 64 บิต ตามลำดับ อย่างไรก็ตามนี่ไม่ใช่กรณี อย่างน้อยก็สำหรับฉันที่ read () เป็นสายระบบ 0 ใน x86_64 ไม่สามารถปรับให้เข้ากับความคิดนี้

อีกข้อหนึ่งคือการเปลี่ยนหมายเลขโทรศัพท์ของระบบอาจมีพื้นหลังด้านความปลอดภัย / แข็งตัวซึ่งเป็นสิ่งที่ฉันไม่สามารถยืนยันตัวเองได้

ด้วยความไม่รู้ถึงความท้าทายของการใช้งานส่วนของโค้ดที่ขึ้นอยู่กับสถาปัตยกรรมฉันยังสงสัยว่าการเปลี่ยนหมายเลขการโทรของระบบเมื่อดูเหมือนว่าไม่จำเป็น (เพราะแม้แต่การลงทะเบียนแบบ 16 บิตจะเก็บไว้มากกว่านั้นในปัจจุบัน ~ 346 การเรียกใช้) จะช่วยให้บรรลุผลทุกอย่างนอกเหนือจากความเข้ากันได้ของการแบ่ง (แม้ว่าการใช้การเรียกของระบบผ่านทางไลบรารี libc จะช่วยลดความมัน)


3
ฉันคิดว่าคุณกำลังถามคำถามที่ผิด คำถามที่ถูกต้องคือเหตุผลที่ทำให้พวกเขาเหมือนกัน: คำตอบที่เข้ากันได้ ดังนั้นหาก x86 และ x86_64 ไม่เข้ากันจึงไม่มีแรงที่จะขัดขวางไม่ให้เปลี่ยนแปลง ตอนนี้กองกำลังทั้งหมดจาก 20 ปีที่ต้องการการเปลี่ยนแปลงจะครอง (เราได้รับโอกาสในการเปลี่ยนแปลง) [หมายเหตุนี่เป็นเพียงความคิดเห็นและไม่ได้ขึ้นอยู่กับใจภายในของนักออกแบบของระบบใหม่]
ctrl-alt-delor

คำตอบ:


34

สำหรับเหตุผลที่อยู่เบื้องหลังการกำหนดหมายเลขเฉพาะซึ่งไม่ตรงกับสถาปัตยกรรมอื่นใด [ยกเว้น "x32" ซึ่งเป็นเพียงส่วนหนึ่งของสถาปัตยกรรม x86_64]: ในวันแรก ๆ ของการสนับสนุน x86_64 ในเคอร์เนลลินุกซ์ก่อนที่จะมี ร้ายแรง จำกัด ร่วมกันหลังทั้งหมดของระบบโทรศัพท์เป็นลำดับเพื่อเพิ่มประสิทธิภาพการใช้งานในระดับ cacheline

ฉันไม่รู้เพียงพอเกี่ยวกับการพัฒนาเคอร์เนลที่จะรู้พื้นฐานที่เฉพาะเจาะจงสำหรับตัวเลือกเหล่านี้ แต่เห็นได้ชัดว่ามีตรรกะบางอย่างที่อยู่เบื้องหลังตัวเลือกในการจัดเรียงใหม่ทุกอย่างด้วยหมายเลขเฉพาะเหล่านี้แทนที่จะคัดลอกรายการจากสถาปัตยกรรมที่มีอยู่ ดูเหมือนว่าคำสั่งอาจจะขึ้นอยู่กับว่าพวกเขาถูกเรียกโดยทั่วไปเช่นอ่าน / เขียน / เปิด / ปิดอยู่ด้านหน้า Exit and fork อาจดูเป็น "พื้นฐาน" แต่แต่ละตัวเรียกว่าหนึ่งครั้งต่อกระบวนการ

อาจมีบางสิ่งเกิดขึ้นเกี่ยวกับการรักษาการเรียกระบบที่ใช้ร่วมกันภายในบรรทัดแคชเดียวกัน (ค่าเหล่านี้เป็นจำนวนเต็มเท่านั้น แต่มีตารางในเคอร์เนลที่มีตัวชี้ฟังก์ชั่นสำหรับแต่ละกลุ่มดังนั้นการเรียกระบบ 8 กลุ่มแต่ละกลุ่ม บรรทัดแคช 64- บิตสำหรับตารางนั้น)


1
fork may seem "fundamental", but [...] called only once per process.เอ่ออะไรนะ? ฉันเข้าใจว่าคุณคาดว่าจะโทรออกครั้งเดียว แต่คุณอาจแยกด้านในพ่อแม่และลูกของfork()สาย
แมว

5
@cat หากคุณเห็นforkว่าเป็นกระบวนการของเด็ก (เช่นดูว่าเป็นการเรียกการสร้างกระบวนการ) แทนที่จะเป็นกระบวนการหลักดังนั้นคำสั่งของ Random832 จึงถูกต้อง
icarus

4
@cat ตกลงคุณอาจจะเรียก fork () สองหรือสามครั้งอาจจะมีอีกไม่กี่อย่าง แต่คุณสามารถโทรไปอ่าน () ล้านครั้งหรือพันล้านครั้ง
Michael Hampton

1
ใช่นั่นคือสิ่งที่ฉันหมายถึง จำนวนการเรียก fork และจำนวนกระบวนการตลอดอายุการใช้งานของระบบจะเท่ากันโดยไม่สนใจรายละเอียดเช่น init, clone [ซึ่งสามารถสร้างกระบวนการหรือเธรด] ฯลฯ
Random832

15

ดูคำตอบสำหรับคำถามที่ว่า "ทำไมหมายเลขโทรศัพท์ของระบบต่างกันใน amd64 linux" บน Stack Overflow

เพื่อสรุป: เพื่อประโยชน์ของความเข้ากันได้รายการการเรียกระบบมีความเสถียรและสามารถเติบโตได้เท่านั้น เมื่อสถาปัตยกรรม x86 64 ปรากฏขึ้น ABI (การส่งอาร์กิวเมนต์กลับค่าที่ส่งคืน) จะแตกต่างกันดังนั้นผู้พัฒนาเคอร์เนลจึงมีโอกาสนำการเปลี่ยนแปลงที่รอมานาน


เท่เดาฉันถูกต้อง
Ctrl-Alt-Delor

2
คำตอบอื่น ๆ ที่คุณลิงก์ไปนั้นเป็นการเก็งกำไร: มันบอกว่า "พวก Linux น่าจะตัดสินใจ ... " (เน้นที่การเพิ่ม) ฉันคิดว่ามันจะช่วยได้ถ้าคำตอบของคุณที่นี่ให้ข้อบ่งชี้บางอย่างว่ามันขึ้นอยู่กับการเก็งกำไรมากกว่าหลักฐาน อนึ่งความคิดเห็นเมื่อเร็ว ๆ นี้ภายใต้โพสต์คำตอบที่เชื่อมโยงมีหลักฐานว่าเหตุผลที่แท้จริงคือไม่ได้ทำความสะอาดทั่วไปของ cruft (ตามที่ตอบแทนคำตอบ) แต่เป็นพิเศษเกี่ยวกับ "การใช้งาน cacheline" ตามที่อธิบายไว้ในคำตอบอื่น ๆ ที่นี่
DW

-3

ในระยะสั้นเพราะบางคนคิดว่า " N+1วิธีการที่ไม่เข้ากันกับการทำมันก็ดีกว่าNวิธีอื่น" สำหรับซุ้มประตูประวัติศาสตร์หมายเลข syscall มักถูกเลือกให้ตรงกับยูนิกซ์ที่เป็นกรรมสิทธิ์ดั้งเดิม แต่สำหรับ x86_64 นักพัฒนาเคอร์เนลมีอิสระที่จะเลือกหมายเลขใดก็ได้ที่พวกเขาชอบ แทนที่จะเลือกอย่างง่ายและใช้หมายเลขเดิมซ้ำพวกเขาเลือกที่จะสร้างมาตรฐานใหม่ จากนั้นพวกเขาก็ทำมันอีกครั้งเพื่อ aarch64 และกลุ่มอื่น ๆ นี่เป็นรูปแบบซ้ำ ๆ กันในการพัฒนาเคอร์เนล Linux


3
การเปลี่ยนแปลงไม่ได้ฟรี มีเหตุผลทางเทคนิคที่มั่นคง หากไม่ใช่สำหรับข้อกำหนดด้านความเข้ากันได้แบบย้อนหลังการเปลี่ยนแปลงที่คล้ายกันจะถูกนำไปใช้กับสถาปัตยกรรมที่มีอยู่ด้วยเช่นกัน
Jörg W Mittag

ความแตกต่างของการนับเป็น 100% ฟรี ไม่มีข้อได้เปรียบทางเทคนิคสำหรับการกำหนดหมายเลขใด ๆ
..

2
ตามที่คำตอบอื่น ๆ นี้อธิบายไว้ syscalls จะถูกจัดกลุ่มเช่นนั้น syscalls ซึ่งใช้กันโดยทั่วไปจะแบ่งปัน cacheline เดียวกันในตาราง syscall และมีการเลือกหมายเลข syscall เพื่อให้เป็นดัชนีง่าย ๆ ในตารางนั้น ในทางทฤษฎีเราสามารถใช้เลเยอร์ของการอ้อมเพื่อแยกตำแหน่งของ syscall ในตาราง syscall จากหมายเลข syscall แต่นั่นอาจจะกินส่วนหนึ่งของการเพิ่มประสิทธิภาพที่เราได้รับจากการใส่ syscalls ร้อนใน cacheline เดียวกัน
Jörg W Mittag

@ JörgWMittag: และนั่นคือการเพิ่มประสิทธิภาพก่อนวัยอันควรและไม่ใช่การปรับปรุงที่สามารถวัดได้ เพียงดูจำนวนรอบของ syscalls ที่ใช้และจำนวนบรรทัดแคชที่ถูกขับไล่ การบันทึกที่ดีที่สุดหนึ่งแคชจากการเรียงลำดับของตารางจะไม่สร้างความแตกต่าง
..

2
@R .. "ฉันเลือกหมายเลขในการทำงานของข้อมูลการทำโปรไฟล์เคอร์เนล tpcc พร้อมกับ DBMS ยอดนิยมและเอาต์พุต strace ของเครือข่ายและแอพพลิเคชันเดสก์ท็อปบางตัว" เสียงเหมือนมีการวัดแน่นอน อย่างไรก็ตามผู้เขียนไม่ได้ให้ตัวเลขหรืออธิบายวิธีการอย่างเพียงพอ
45891
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.