__init หมายถึงอะไรในโค้ดเคอร์เนลของลินุกซ์


91

ในซอร์สโค้ดเคอร์เนล Linux ฉันพบฟังก์ชันนี้:

ที่นี่ฉันไม่เข้าใจว่า__initหมายถึงอะไร

คำตอบ:


76

include/linux/init.h


55

นี่เป็นเพียงมาโครเพื่อค้นหาบางส่วนของโค้ดลินุกซ์ในพื้นที่พิเศษในไบนารีการรันขั้นสุดท้าย __initตัวอย่างเช่น (หรือดีกว่าที่__attribute__ ((__section__ (".init.text")))มาโครนี้จะขยายเป็น) สั่งให้คอมไพเลอร์ทำเครื่องหมายฟังก์ชันนี้ด้วยวิธีพิเศษ ในตอนท้ายตัวเชื่อมโยงจะรวบรวมฟังก์ชันทั้งหมดด้วยเครื่องหมายนี้ที่ท้าย (หรือจุดเริ่มต้น) ของไฟล์ไบนารี

เมื่อเคอร์เนลเริ่มทำงานรหัสนี้จะทำงานเพียงครั้งเดียว (การเริ่มต้น) หลังจากรันเคอร์เนลสามารถเพิ่มหน่วยความจำนี้เพื่อนำกลับมาใช้ใหม่ได้และคุณจะเห็นข้อความเคอร์เนล:

การปลดปล่อยหน่วยความจำเคอร์เนลที่ไม่ได้ใช้: ปลดปล่อย 108k

ในการใช้คุณสมบัตินี้คุณต้องมีไฟล์สคริปต์ตัวลิงก์พิเศษซึ่งจะบอกผู้เชื่อมโยงว่าจะค้นหาฟังก์ชันที่ทำเครื่องหมายไว้ทั้งหมดที่ใด


11
ฉลาด! นั่นคือสิ่งที่ "ปลดปล่อยหน่วยความจำเคอร์เนลที่ไม่ได้ใช้: 108k freed" หมายถึง :-) ฉันสงสัยมาตลอดหลายปีที่ผ่านมา ฉันคิดว่ามันเป็นบัฟเฟอร์หรืออะไรบางอย่างไม่ใช่รหัส
ศ. Falken

6

สิ่งนี้แสดงให้เห็นถึงคุณลักษณะของเคอร์เนล 2.2 และใหม่กว่า สังเกตการเปลี่ยนแปลงคำจำกัดความของฟังก์ชันinitและ แมโครทำให้ฟังก์ชั่นที่จะยกเลิกและหน่วยความจำอิสระเมื่อเสร็จสิ้นการฟังก์ชั่นในตัวคนขับรถ แต่ไม่โมดูลที่ใส่ หากคุณคิดถึงเวลาที่เรียกใช้ฟังก์ชันนี้ก็สมเหตุสมผลดีcleanup__initinitinitinit

แหล่งที่มา


5

__init เป็นมาโครที่กำหนดใน. /include/linux/init.h ซึ่งขยายเป็น__attribute__ ((__section__(".init.text"))).

มันสั่งให้คอมไพเลอร์ทำเครื่องหมายฟังก์ชันนี้ด้วยวิธีพิเศษ ในตอนท้ายตัวเชื่อมโยงจะรวบรวมฟังก์ชันทั้งหมดด้วยเครื่องหมายนี้ที่ท้าย (หรือเริ่มต้น) ของไฟล์ไบนารี เมื่อเคอร์เนลเริ่มทำงานรหัสนี้จะทำงานเพียงครั้งเดียว (การเริ่มต้น) หลังจากรันเคอร์เนลสามารถปลดปล่อยหน่วยความจำนี้เพื่อนำกลับมาใช้ใหม่และคุณจะเห็นเคอร์เนล


3

อ่านความคิดเห็น (และเอกสารในเวลาเดียวกัน) ในลินุกซ์ / init.h

คุณควรทราบด้วยว่า gcc มีส่วนขยายบางอย่างที่สร้างขึ้นเป็นพิเศษสำหรับโค้ดเคอร์เนล linux และดูเหมือนว่ามาโครนี้จะใช้หนึ่งในนั้น


1

เมื่อคุณคอมไพล์และแทรกโมดูลเคอร์เนลลินุกซ์ลงในเคอร์เนลฟังก์ชันแรกที่จะเรียกใช้คือ __init โดยทั่วไปแล้วฟังก์ชันนี้จะใช้ในการเริ่มต้นก่อนที่คุณจะดำเนินการหลักเช่นการลงทะเบียนไดรเวอร์อุปกรณ์เป็นต้นมีฟังก์ชันอื่นที่มีผลตรงกันข้าม __exit ซึ่งถูกเรียกเมื่อคุณลบโมดูลเคอร์เนลซึ่งใช้อีกครั้งเพื่อลบอุปกรณ์ที่ลงทะเบียนบางส่วนหรือฟังก์ชันที่คล้ายคลึงกันดังกล่าว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.