2012-04-28 14 views
20

मेरे पास एसपीआई फ्लैश स्टोरेज वाला एक डिवाइस है, मैं उस फ्लैश डिवाइस पर अपने रूटफिक्स के रूप में एक यूबीआईएफएस फाइल सिस्टम का उपयोग करना चाहता हूं। मुझे जिस समस्या का सामना करना पड़ रहा है वह यह है कि एसपीआई मॉड्यूल शुरू होने से पहले यूबीआई मॉड्यूल शुरू होता है। इस वजह से, जब यूबीआई लोड होता है, तो यह उस यूबीआई डिवाइस से संलग्न नहीं हो सकता है जिसे मैंने इसे बताया है (कर्नेल कमांड लाइन के माध्यम से), इसलिए कोई रूटफ नहीं है। नीचे कंसोल आउटपुट इसे दिखाता है।लिनक्स मॉड्यूल इनिट कॉल का ऑर्डर कैसे निर्धारित करता है?

मैं यह देखने के लिए पर्याप्त स्रोत में डाइविंग कर रहा हूं कि init/main.c में do_initcalls() फ़ंक्शन है जो फ़ंक्शन पॉइंटर्स की सूची को कॉल करता है। उन फ़ंक्शन पॉइंटर्स कर्नेल में अंतर्निहित मॉड्यूल के सभी module_init() फ़ंक्शंस को इंगित करते हैं। उन फ़ंक्शन पॉइंटर्स को कर्नेल बाइनरी में एक विशेष अनुभाग में रखा जाता है, इसलिए यह ऑर्डर संकलन-समय पर चुना जाता है। हालांकि, मैंने अभी तक यह नहीं पता लगाया है कि यह आदेश कैसे निर्धारित किया जाता है।

[ 0.482500] UBI error: ubi_init: UBI error: cannot initialize UBI, error -19 
    [ 0.492500] atmel_spi atmel_spi.0: Using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers 
    [ 0.500000] atmel_spi atmel_spi.0: Atmel SPI Controller at 0xf0000000 (irq 13) 
    [ 0.507500] m25p80 spi0.1: mx25l25635e (32768 Kbytes) 
    [ 0.512500] Creating 7 MTD partitions on "jedec_flash": 
    [ 0.520000] 0x000000000000-0x000000020000 : "loader" 
    [ 0.527500] 0x000000020000-0x000000060000 : "u-boot" 
    [ 0.537500] 0x000000060000-0x000000080000 : "u-boot-env" 
    [ 0.547500] 0x000000080000-0x000000280000 : "kernel0" 
    [ 0.557500] 0x000000280000-0x000000480000 : "kernel1" 
    [ 0.567500] 0x000000480000-0x000001240000 : "fs" 
    [ 0.575000] 0x000001240000-0x000002000000 : "play" 
    [ 0.590000] AT91SAM9 Watchdog enabled (heartbeat=15 sec, nowayout=0) 
    [ 0.607500] TCP cubic registered 
    [ 0.615000] VFS: Cannot open root device "ubi0:root0" or unknown-block(0,0) 
    [ 0.622500] Please append a correct "root=" boot option; here are the available partitions: 
    [ 0.630000] 1f00    128 mtdblock0 (driver?) 
    [ 0.635000] 1f01    256 mtdblock1 (driver?) 
    [ 0.640000] 1f02    128 mtdblock2 (driver?) 
    [ 0.645000] 1f03   2048 mtdblock3 (driver?) 
    [ 0.650000] 1f04   2048 mtdblock4 (driver?) 
    [ 0.655000] 1f05   14080 mtdblock5 (driver?) 
    [ 0.660000] 1f06   14080 mtdblock6 (driver?) 
    [ 0.665000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) 
+0

मैं के लिए प्रवास के लिए फ़्लैग किया [तो], क्योंकि भले ही यह नहीं हो सकता स्रोत कोड संशोधन की आवश्यकता है, इसे कम से कम Kbuild चालबाजी की आवश्यकता होती है। इसके अलावा [विशेषज्ञ] हैं जहां विशेषज्ञ हैं। मुझे संदेह है कि आपको किसी विशेष आदेश पर भरोसा नहीं करना चाहिए और यूबीआई ड्राइवर को किसी भी डिवाइस तक पहुंचने की कोशिश नहीं करनी चाहिए जब तक कि उसे कुछ माउंट करने के लिए कहा न जाए। – Gilles

+0

संभावित डुप्लिकेट [LINUX: स्थिर रूप से जुड़े मॉड्यूल लोडिंग का क्रम] (http://stackoverflow.com/questions/5669647/linux-order-of-statically-linked- मॉड्यूल- लोडिंग) जो आपको बताता है कि मॉड्यूल सुनिश्चित करने की आवश्यकता है वांछित प्रारंभिक क्रम में मेकअप के पेड़ (पेड़) में होते हैं। –

+0

'EPROBE_DEFER' का उपयोग कर समस्या का वैकल्पिक समाधान हो सकता है; मैं उसमें जांच करूँगा। –

उत्तर

0

मैं गलत हो सकता हूं, इसलिए कृपया जांचें कि यह सही है या नहीं।
मॉड्यूल (एम) के रूप में आपको आवश्यक सभी ड्राइवरों को संकलित करने का प्रयास करें, और सही क्रम में मॉड्यूल को/etc/मॉड्यूल में लोड करने के लिए रखें, इससे आपकी समस्या हल हो सकती है। बस सटीक होने के लिए, क्योंकि आप से पहले कर रहे हैं, तो आपके रूटफ्स को आरोहित किया गया है, उपरोक्त चरण shoudl initram डिस्क में किया जाना चाहिए। (मैं एक ऐसी ही परिदृश्य है और मैं सही क्रम में कुछ मॉड्यूल लोड करने के लिए, एक FS डिक्रिप्ट करने के लिए सक्षम होना चाहिए)

आशा है कि यह एक मॉड्यूल के लिए
CiaoCiao
सर्जियो

+1

यह उन्हें अलग मॉड्यूल के रूप में संकलित करने के लिए काम नहीं करेगा क्योंकि यह रूट फाइल सिस्टम पर मॉड्यूल रखेगा। इन मॉड्यूल के बारे में मैं बात कर रहा हूं वे मूल फाइल सिस्टम को आरोहित करने के लिए हैं। –

+0

@ शॉन जे। गॉफ: मैंने पोस्ट संपादित किया, जैसा कि मुझे एहसास हुआ कि मैं एक महत्वपूर्ण विवरण का उल्लेख करना भूल गया हूं। Initramfs भाग। :) – sergico

+0

एक initramfs एक विकल्प नहीं है - यह मेरे निर्माण के आकार को एक अस्वीकार्य राशि से बढ़ाता है। –

32

init दिनचर्या में मदद करता है जिसे कर्नेल द्वारा प्रारंभ किया जाता है (जब वे कर्नेल में स्थिर रूप से जुड़े होते हैं) एक initcall() मैक्रो में लिपटे होते हैं जो इंगित करता है जब स्टार्टअप अनुक्रम में उन्हें चलाया जाना चाहिए।

शामिल फ़ाइल देखें: मैक्रोज़ की सूची और उनके ऑर्डरिंग के लिए/linux/init.h शामिल करें।

क्रम निर्दिष्ट है:

  • early_initcall
  • pure_initcall
  • core_initcall
  • postcore_initcall
  • arch_initcall
  • subsys_initcall
  • fs_initcall
  • rootfs_initcall
  • device_initcall
  • late_initcall

इनमें से अधिकांश एक "initcall_sync() चरण है, जो कि चरण के भीतर सभी मॉड्यूल आरंभीकरण दिनचर्या के पूरा होने के लिए प्रतीक्षा करने के लिए इस्तेमाल किया गया है। मैक्रोज़ का उपयोग प्रत्येक चरण के लिए फ़ंक्शन पॉइंटर्स की एक तालिका बनाने के लिए किया जाता है, जिसे do_initcalls() द्वारा अनुक्रम में कहा जाता है।

यदि "मॉड्यूल_इनिट()" प्रारंभिक फ़ंक्शन को लपेटने के लिए प्रयोग किया जाता है, तो डिफ़ॉल्ट initcall() प्रारंभ में प्रारंभिक चरण में "डिवाइस" चरण में कॉल डालता है। उस चरण के भीतर, वस्तुओं को लिंक ऑर्डर द्वारा आदेश दिया जाता है। इसका अर्थ है कि तालिका को फ़ंक्शन के क्रम द्वारा बनाया गया है क्योंकि उन्हें लिंकर द्वारा का सामना करना पड़ रहा है।

आप एक पहले चरण के लिए एक प्रारंभ स्थानांतरित करने के लिए बदल रहा है जो initcall मैक्रो लपेटता मॉड्यूल आरंभीकरण समारोह से, लेकिन सावधान रहें क्योंकि वहाँ विभिन्न मॉड्यूल के बीच क्रम निर्भरता हैं सक्षम हो सकते हैं। का एक और तरीका प्रारंभिक क्रम (चरण के भीतर) को बदलना कर्नेल में मॉड्यूल के लिए ऑर्डर को समायोजित करना होगा।

0

@Tim बर्ड पहले से ही इसका उत्तर दिया - मैं दिखाने के लिए एक मॉड्यूल के लिए आदेश को बदलने का तरीका चाहते हैं: -

pure_initcall(fn)   --> Loaded first 
core_initcall(fn)   
core_initcall_sync(fn)  
postcore_initcall(fn)  
postcore_initcall_sync(fn) 
arch_initcall(fn)   
arch_initcall_sync(fn)  
subsys_initcall(fn)  
subsys_initcall_sync(fn) 
fs_initcall(fn)   
fs_initcall_sync(fn)  
rootfs_initcall(fn)  
device_initcall(fn)  
device_initcall_sync(fn) 
late_initcall(fn)   
late_initcall_sync(fn) --> Loaded last 

Usage - Replace fn by the module init function pointer, example for i2c core driver: 
....... 
postcore_initcall(i2c_init); // To delay i2c core loading use subsys_initcall(i2c_init)     
module_exit(i2c_exit); 
.......