कॉर्टेक्स एम 3 .bss क्षेत्र आरंभीकरण के लिए नंगे-धातु स्टार्ट-अप कोड


10

मैंने यहाँ से आर्म कॉर्टेक्स एम 3 के लिए एक नंगे धातु स्टार्ट-अप कोड से प्रेरित विकसित किया है । हालाँकि, मैं निम्नलिखित समस्या का सामना करता हूं: मान लीजिए कि मैं एक असंवैधानिक वैश्विक चर घोषित करता हूं, मुख्य सीई में टाइप किए गए चार्ट के बारे में कहता हूं

#include ...
unsigned char var; 
...
int main()
{
 ...
}

यह STM32 f103 में .bss क्षेत्र को _BSS_START = 0x20000000 से शुरू करता है और _BSS_END = 0x20000001 पर समाप्त होता है। अब, स्टार्ट अप कोड

    unsigned int * bss_start_p = &_BSS_START; 
    unsigned int * bss_end_p = &_BSS_END;

    while(bss_start_p != bss_end_p)
    {
        *bss_start_p = 0;
        bss_start_p++;
    }

पूरे .bss क्षेत्र को शून्य करने की कोशिश करता है। हालाँकि, उसके अंदर जबकि लूप पॉइंटर 4 बाइट्स के साथ बढ़ता है, इसलिए एक कदम बाद bss_start_p = 0x20000004 इसलिए यह हमेशा bss_end_p से अलग होगा जो एक अनंत लूप आदि की ओर जाता है।

क्या इसका कोई मानक समाधान है? क्या मुझे लगता है कि "बल" किसी भी तरह .bss क्षेत्र का आयाम 4 से अधिक है? या मुझे .bs क्षेत्र के माध्यम से चलने के लिए अहस्ताक्षरित चार के लिए एक सूचक का उपयोग करना चाहिए? शायद कुछ इस तरह:

    unsigned char * bss_start_p = (unsigned char *)(&_BSS_START); 
    unsigned char * bss_end_p = (unsigned char *)(&_BSS_END);

    while(bss_start_p != bss_end_p)
    {
        *bss_start_p = 0;
        bss_start_p++;
    }
```

से कम का उपयोग करें। बूटस्ट्रैप एक कारण के लिए विधानसभा में लिखे गए हैं। सबसे पहले अब आपने एक .data समस्या बनाई है। एक चिकन और अंडे का उपयोग करने के लिए / यह मान लें कि C आपके द्वारा काम करने वाले .text, .bs और .data पर कम से कम भरोसा करता है, लेकिन आप C कोड लिख रहे हैं, जो सुनिश्चित करता है कि C कोड काम करेगा, C कोड में उन चीजों का उपयोग करके जिनकी आवश्यकता है बूटस्ट्रैप संभवतः सी कोड में लिखा गया है जो सी काम करने पर निर्भर करता है।
Old_timer

कोड को कॉपी करने के लिए .data पर .bs के समान है, लेकिन यदि आप इसे ऊपर दिए गए कोड की तरह लिखते हैं तो आपको जरूरत है। .डेटा को कॉपी करने के लिए ओवरटा कॉपी करना होगा।
old_timer

जवाबों:


15

जैसा कि आपको संदेह है, यह इसलिए हो रहा है क्योंकि अहस्ताक्षरित int डेटा प्रकार आकार में 4 बाइट्स है। प्रत्येक *bss_start_p = 0;कथन वास्तव में bss क्षेत्र के चार बाइट्स को साफ़ करता है।

Bss मेमोरी रेंज को सही तरीके से संरेखित करने की आवश्यकता है। आप बस _BSS_START और _BSS_END को परिभाषित कर सकते हैं ताकि कुल आकार चार से अधिक हो, लेकिन यह आमतौर पर लिंकर स्क्रिप्ट को प्रारंभ और स्थान को परिभाषित करने की अनुमति देकर नियंत्रित किया जाता है।

एक उदाहरण के रूप में, यहाँ मेरी एक परियोजना में लिंकर खंड है:

.bss (NOLOAD) : ALIGN(4)
{
    __bss_start__ = .;
    *(.bss)
    . = ALIGN(4);
    __bss_end__ = .;
} >RAM

ALIGN(4)बयान बातों का ख्याल रखना।

इसके अलावा, आप बदलने की इच्छा कर सकते हैं

while(bss_start_p != bss_end_p)

सेवा

while(bss_start_p < bss_end_p)

यह समस्या को नहीं रोकेगा (क्योंकि आप अपनी इच्छानुसार 1-3 और बाइट्स साफ़ कर सकते हैं), लेकिन यह प्रभाव को कम कर सकता है :)


@CMarius परावर्तन पर, मुझे लगता है कि आपका चार्ट पॉइंटर विचार बहुत अच्छा काम करेगा, हालाँकि इसके लिए और अधिक चक्रों की आवश्यकता होगी। लेकिन मुझे यकीन नहीं है कि अगर बाद के मेमोरी क्षेत्र के साथ कोई समस्या नहीं होगी, तो मैं अपने उत्तर में इसका उल्लेख नहीं करने जा रहा ...
बिट्समैक्स

1
while(bss_start_p < bss_end_p - 1)शेष मेमोरी रेंज की बाइट-वार समाशोधन के बाद अंतिम चिंता को समाप्त कर दिया जाएगा।
glglgl

4

मानक समाधान है memset():

#include <string.h>
memset(&_BSS_START, 0, &_BSS_END - &_BSS_START)

यदि आप मानक पुस्तकालय का उपयोग नहीं कर सकते हैं, तो आपको यह तय करना होगा कि आपके मामले में 4 बाइट तक मेमोरी क्षेत्र के आकार को गोल करना और उपयोग करना जारी रखना ठीक है या नहीं unsigned int *; या यदि आपको इसके बारे में सख्त होने की आवश्यकता है, तो आपको किस मामले में उपयोग करने की आवश्यकता होगी unsigned char *

यदि आप अपने पहले लूप की तरह आकार को गोल करते हैं, तो bss_start_pवास्तव में इससे बड़ा हो सकता है , bss_end_pलेकिन तुलनात्मक रूप से कम-तुलना की तुलना में आसान है।< असमानता परीक्षण के बजाय ।

बेशक, आप 32-बिट ट्रांसफर के साथ अधिकांश मेमोरी क्षेत्र को भी भर सकते हैं, और 8-बिट ट्रांसफर के साथ केवल आखिरी कुछ बाइट्स, लेकिन यह थोड़ा लाभ के लिए अधिक काम है, खासकर यहां जब यह केवल स्टार्टअप कोड का एक टुकड़ा है।


1
के उपयोग से बहुत सहमत हैं memset()। लेकिन 4 बाइट्स के लिए अलाइनमेंट कम या ज्यादा होना चाहिए। तो क्यों नहीं करते?
कोडो

3
किसी भी तरह से आकार या रूप का उपयोग बूटस्ट्रैप के लिए मानक समाधान के लिए नहीं है, जो कि पागल है।
old_timer

आप उस भाषा को बूटस्ट्रैप करने के लिए उसी भाषा का उपयोग नहीं करते हैं
Old_timer

2
बूटस्ट्रैप कोड और लिंकर स्क्रिप्ट बहुत अधिक विवाहित हैं, आपको यह सामान्य लगेगा कि लिंकर स्क्रिप्ट संरेखित करता है और एक समय के निर्देश पर 4x से अधिक बाइट (बूटस्ट्रैप में) भरने के लिए कम से कम 4 बाइट सीमा पर .bss को आकार देता है। (
मान्‍यता

3
@old_timer, एक विशेष मान में मेमोरी सेट करने के लिए मानक C फ़ंक्शन है memset(), और C वह है जिसमें वे प्रोग्रामिंग करते प्रतीत होते हैं। सरल कार्यान्वयन memset()भी लूप की तुलना में बहुत अधिक है, यह ऐसा नहीं है कि यह बहुत पर निर्भर करता है। चूंकि यह एक माइक्रोकंट्रोलर है, इसलिए मैं यह भी मानता हूं कि कोई डायनेमिक लिंकिंग या ऐसा नहीं चल रहा है (और लिंक को देख रहा है, ऐसा नहीं है, यह main()उस जीरो लूप के बाद की कॉल है ), इसलिए कंपाइलर को memset()वहां छोड़ने में सक्षम होना चाहिए एनी अन्य कार्यों के साथ (या इसे इनलाइन लागू करने के लिए)।
ilkachachu

4

बस !=करने के लिए बदल जाते हैं <। यह आम तौर पर वैसे भी एक बेहतर तरीका है, क्योंकि यह इस तरह की समस्याओं से निपटता है।


3

अनगिनत अन्य साइटें और उदाहरण हैं। कई हजारों अगर हजारों नहीं। विशेष रूप से लिंकर स्क्रिप्ट और बूस्टर कोड, newlib, glibc के साथ प्रसिद्ध पुस्तकालय हैं, लेकिन कुछ अन्य हैं जिन्हें आप पा सकते हैं। C के साथ बूटस्ट्रैपिंग C का कोई मतलब नहीं है।

आपके प्रश्न का उत्तर दिया गया है कि आप उन चीजों पर सटीक तुलना करने की कोशिश कर रहे हैं जो सटीक नहीं हो सकती हैं, यह एक ज्ञात सीमा पर शुरू नहीं हो सकता है या किसी ज्ञात सीमा पर समाप्त नहीं हो सकता है। तो आप चीज़ से कम कर सकते हैं, लेकिन अगर कोड ने एक सटीक तुलना के साथ काम नहीं किया है, तो इसका मतलब है कि आप पिछले सेक्शन को शून्य कर रहे हैं। अगले भाग में खराब चीजें हो सकती हैं या नहीं हो सकती हैं, इसलिए बस isnt से कम के साथ प्रतिस्थापित करें समाधान।

तो यहाँ टीएल जाता है, डॉ। ठीक है। आप उस भाषा के साथ किसी भाषा को बूटस्ट्रैप नहीं करते हैं, आप इसे सुनिश्चित कर सकते हैं, लेकिन जब आप ऐसा करते हैं तो आप आग से खेल रहे होते हैं। यदि आप सीख रहे हैं कि यह कैसे करना है तो आपको सावधानी बरतने की आवश्यकता है, न कि गूंगे भाग्य या उन तथ्यों पर जिन्हें आपने अभी तक उजागर नहीं किया है।

लिंकर स्क्रिप्ट और बूटस्ट्रैप कोड एक बहुत ही अंतरंग संबंध हैं, वे शादीशुदा हैं, कूल्हे में शामिल हो गए हैं, आप एक दूसरे के बिना विकसित नहीं करते हैं जो बड़े पैमाने पर विफलता की ओर जाता है। और दुर्भाग्यवश लिंकर स्क्रिप्ट लिंकर और असेंबली द्वारा परिभाषित असेंबली भाषा द्वारा परिभाषित की जाती है ताकि आप टूलचिन को बदल दें, दोनों को फिर से लिखने की उम्मीद है। विधानसभा भाषा क्यों? इसे बूटस्ट्रैप की जरूरत नहीं है, संकलित भाषाएं आमतौर पर करती हैं। C करता है यदि आप लैंग्वेज के अपने उपयोग को सीमित नहीं करना चाहते हैं, तो Ill को बहुत सरल से शुरू करें जिसमें न्यूनतम टूलचैन विशिष्ट आवश्यकताएं हैं, आप यह नहीं मानते हैं। , इससे बचने की कोशिश करें, स्थानीय चरों के लिए सही नहीं है, इसलिए जब आप इसे इस्तेमाल करते हैं तो गेंद पर होना चाहिए। वैसे भी लोग ग्लोबल्स को दूर कर देते हैं। तो हम .bs और .data के बारे में क्यों बात कर रहे हैं ??? (ग्लोबल्स इस स्तर के काम के लिए अच्छे हैं, लेकिन यह एक और विषय है)) सरल समाधान के लिए अन्य नियम है घोषणा में चर शुरू न करें, इसे कोड में करें। हाँ अधिक फ्लैश जलता है, आपके पास आम तौर पर बहुत सारे होते हैं, न कि सभी चर लगातार स्थिरांक के साथ शुरू होते हैं, जो उपभोग के निर्देशों को समाप्त करते हैं।

आप कॉर्टेक्स-एम डिज़ाइन से बता सकते हैं कि वे सोच रहे होंगे कि कोई बूटस्ट्रैप कोड तो नहीं है और न ही .bss समर्थन। अधिकांश लोग जो ग्लोबल्स कैंट का उपयोग करते हैं, वे यहां नहीं रहते हैं:

मैं गन्नो टूलचिन का उपयोग करके सभी कॉर्टेक्स-एमएस के लिए यह अधिक न्यूनतम लेकिन न्यूनतम कार्यात्मक उदाहरण बना सकता हूं, मुझे याद नहीं है कि आप 5.xx के साथ किन संस्करणों को शुरू कर सकते हैं या वर्तमान 9.xx के माध्यम से मैं लिंकर स्क्रिप्ट को 3 के आसपास कहीं भी स्विच कर सकता हूं। xx या 4.xx जैसा कि मैंने और अधिक सीखा और जैसे ही गन्नू ने कुछ बदला जिससे मेरा पहला ही टूट गया।

बूटस्ट्रैप:

.thumb

.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word reset
.word done
.word done
.word done

.thumb_func
reset:
    bl centry
    b done

.thumb_func
done:   b .

.thumb_func
.globl bounce
bounce:
    bx lr

C कोड में प्रवेश बिंदु:

void bounce ( unsigned int );

unsigned int a;

int centry ( void )
{
    a = 7;
    bounce(a);
    return(0);
}

लिंक स्क्रिप्ट।

MEMORY
{
    rom : ORIGIN = 0x00000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

ये सभी छोटे हो सकते हैं और फिर भी काम कर सकते हैं, काम पर इसे देखने के लिए कुछ अतिरिक्त सामान यहाँ जोड़े।

अनुकूलित निर्माण और लिंक।

00000000 <_start>:
   0:   20001000
   4:   00000015
   8:   0000001b
   c:   0000001b
  10:   0000001b

00000014 <reset>:
  14:   f000 f804   bl  20 <centry>
  18:   e7ff        b.n 1a <done>

0000001a <done>:
  1a:   e7fe        b.n 1a <done>

0000001c <bounce>:
  1c:   4770        bx  lr
    ...

00000020 <centry>:
  20:   2207        movs    r2, #7
  22:   b510        push    {r4, lr}
  24:   4b04        ldr r3, [pc, #16]   ; (38 <centry+0x18>)
  26:   2007        movs    r0, #7
  28:   601a        str r2, [r3, #0]
  2a:   f7ff fff7   bl  1c <bounce>
  2e:   2000        movs    r0, #0
  30:   bc10        pop {r4}
  32:   bc02        pop {r1}
  34:   4708        bx  r1
  36:   46c0        nop         ; (mov r8, r8)
  38:   20000000    andcs   r0, r0, r0

Disassembly of section .bss:

20000000 <a>:
20000000:   00000000    andeq   r0, r0, r0

कुछ विक्रेताओं के लिए आप 0x08000000 या 0x01000000 या अन्य समान पतों का उपयोग करना चाहते हैं क्योंकि फ्लैश को वहां मैप किया जाता है और कुछ बूट मोड में 0x00000000 को प्रतिबिंबित किया जाता है। कुछ केवल 0x00000000 पर फ्लैश किए गए फ्लैश के बहुत सारे हैं, इसलिए आप चाहते हैं कि एप्लिकेशन फ़्लैश स्थान पर वेक्टर टेबल पॉइंट शून्य न हो। चूंकि यह वेक्टर टेबल है, इसलिए यह सभी काम करता है।

पहले ध्यान दें कि कोर्टेक्स-एमएस केवल अंगूठा है, और जो भी कारण से उन्होंने अंगूठे के कार्य का पता लगाया है, जिसका अर्थ है कि लसबिट विषम है। अपने औजारों को जानिए .thumb_func निर्देशों ने ग्नू असेम्बलर को बताया कि अगला लेबल एक थंब फंक्शन एड्रेस है। तालिका में +1 करने से विफलता होगी, इसे करने के लिए लुभाओ मत, इसे सही करो। एक फ़ंक्शन घोषित करने के लिए अन्य ग्नू कोडांतरक तरीके हैं यह न्यूनतम दृष्टिकोण है।

   4:   00000015
   8:   0000001b
   c:   0000001b
  10:   0000001b

अगर आपको वेक्टर टेबल सही नहीं लगी तो यह बूट नहीं करेगा।

यकीनन केवल स्टैक पॉइंटर वेक्टर की आवश्यकता होती है (यदि आप स्टैक पॉइंटर को स्वयं कोड में सेट करना चाहते हैं तो वहां कुछ भी डाल सकते हैं) और रीसेट वेक्टर। मैंने बिना किसी खास वजह के यहां चार लगाए। आमतौर पर 16 डालते हैं लेकिन इस उदाहरण को छोटा करना चाहते हैं।

तो क्या एक न्यूनतम सी बूटस्ट्रैप करने की आवश्यकता है? 1. स्टैक पॉइंटर को सेट करें 2. शून्य .bs 3. कॉपी .data 4. शाखा या C एंट्री पॉइंट को कॉल करने के लिए

C प्रविष्टि बिंदु को आमतौर पर मुख्य () कहा जाता है। लेकिन कुछ टूलचाइन्स मुख्य () देखते हैं और अपने कोड में अतिरिक्त कचरा जोड़ते हैं। मैं जानबूझकर एक अलग नाम का उपयोग करता हूं। YMMV।

अगर यह सब राम आधारित है तो .data की कॉपी की जरूरत नहीं है। एक कोर्टेक्स-एम माइक्रोकंट्रोलर होने के नाते यह तकनीकी रूप से संभव है लेकिन संभव नहीं है।

मेरा पहला उदाहरण और एक कोडिंग शैली इस पर निर्भर नहीं है। स्टैक पॉइंटर का आर्म ने ध्यान रखा इसलिए एंट्री पॉइंट को कॉल करने के लिए केवल एक चीज बची है। मुझे यह पसंद है इसलिए प्रवेश बिंदु वापस आ सकता है, कई लोग तर्क देते हैं कि आपको कभी ऐसा नहीं करना चाहिए। आप बस फिर ऐसा कर सकते हैं:

.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word centry
.word done
.word done
.word done

और सेंट्री से वापस नहीं आते () और रीसेट हैंडलर कोड नहीं है।

00000020 <centry>:
  20:   2207        movs    r2, #7
  22:   b510        push    {r4, lr}
  24:   4b04        ldr r3, [pc, #16]   ; (38 <centry+0x18>)
  26:   2007        movs    r0, #7
  28:   601a        str r2, [r3, #0]
  2a:   f7ff fff7   bl  1c <bounce>
  2e:   2000        movs    r0, #0
  30:   bc10        pop {r4}
  32:   bc02        pop {r1}
  34:   4708        bx  r1
  36:   46c0        nop         ; (mov r8, r8)
  38:   20000000    andcs   r0, r0, r0

Disassembly of section .bss:

20000000 <a>:
20000000:   00000000

लिंकर ने उन चीजों को रखा है जहां हमने पूछा था। और कुल मिलाकर हमारे पास एक पूरी तरह कार्यात्मक कार्यक्रम है।

तो पहले लिंकर स्क्रिप्ट पर काम करें:

MEMORY
{
    bob : ORIGIN = 0x00000000, LENGTH = 0x1000
    ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > bob

    .rodata : { *(.rodata*) } > bob

   __data_rom_start__ = .;
   .data : {
    __data_start__ = .;
    *(.data*)
   } > ted AT > bob
   __data_end__ = .;
   __data_size__ = __data_end__ - __data_start__;

   .bss  : {
   __bss_start__ = .;
   *(.bss*)
   } > ted
   __bss_end__ = .;
   __bss_size__ = __bss_end__ - __bss_start__;

}

इस बात पर जोर देते हुए कि रोम और राम का कोई अर्थ नहीं है, वे केवल अनुभागों के बीच लिंकर के लिए बिंदुओं को जोड़ते हैं।

.thumb

.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word reset
.word done
.word done
.word done

.thumb_func
reset:
    bl centry
    b done

.thumb_func
done:   b .

.thumb_func
.globl bounce
bounce:
    bx lr

.align
.word __data_rom_start__
.word __data_start__
.word __data_end__
.word __data_size__

कुछ आइटम जोड़ें ताकि हम देख सकें कि टूल ने क्या किया

void bounce ( unsigned int );

unsigned int a;

unsigned int b=4;
unsigned char c=5;

int centry ( void )
{
    a = 7;
    bounce(a);
    return(0);
}

उन अनुभागों में जगह के लिए कुछ आइटम जोड़ें। और पाओ

Disassembly of section .text:

00000000 <_start>:
   0:   20000800    andcs   r0, r0, r0, lsl #16
   4:   00000015    andeq   r0, r0, r5, lsl r0
   8:   0000001b    andeq   r0, r0, r11, lsl r0
   c:   0000001b    andeq   r0, r0, r11, lsl r0
  10:   0000001b    andeq   r0, r0, r11, lsl r0

00000014 <reset>:
  14:   f000 f80c   bl  30 <centry>
  18:   e7ff        b.n 1a <done>

0000001a <done>:
  1a:   e7fe        b.n 1a <done>

0000001c <bounce>:
  1c:   4770        bx  lr
  1e:   46c0        nop         ; (mov r8, r8)
  20:   0000004c    andeq   r0, r0, r12, asr #32
  24:   20000000    andcs   r0, r0, r0
  28:   20000008    andcs   r0, r0, r8
  2c:   00000008    andeq   r0, r0, r8

00000030 <centry>:
  30:   2207        movs    r2, #7
  32:   b510        push    {r4, lr}
  34:   4b04        ldr r3, [pc, #16]   ; (48 <centry+0x18>)
  36:   2007        movs    r0, #7
  38:   601a        str r2, [r3, #0]
  3a:   f7ff ffef   bl  1c <bounce>
  3e:   2000        movs    r0, #0
  40:   bc10        pop {r4}
  42:   bc02        pop {r1}
  44:   4708        bx  r1
  46:   46c0        nop         ; (mov r8, r8)
  48:   20000008    andcs   r0, r0, r8

Disassembly of section .data:

20000000 <c>:
20000000:   00000005    andeq   r0, r0, r5

20000004 <b>:
20000004:   00000004    andeq   r0, r0, r4

Disassembly of section .bss:

20000008 <a>:
20000008:   00000000    andeq   r0, r0, r0

यहां वह सामान है जिसे हम उस प्रयोग में ढूंढ रहे हैं (वास्तव में कोई कोड लोड करने या न चलाने का कोई कारण नोट करें ... अपने टूल को जानें, उन्हें जानें)

  1c:   4770        bx  lr
  1e:   46c0        nop         ; (mov r8, r8)
  20:   0000004c    andeq   r0, r0, r12, asr #32
  24:   20000000    andcs   r0, r0, r0
  28:   20000008    andcs   r0, r0, r8
  2c:   00000008    andeq   r0, r0, r8

इसलिए हमने यहां जो सीखा वह यह है कि चर की स्थिति गनु लिंकर लिपियों में बहुत संवेदनशील है। की स्थिति को ध्यान दें data_rom_start बनाम data_start लेकिन क्यों करता है data_end काम ? बीमार तुम्हें पता है कि चलो। पहले से ही समझ में क्यों एक linker लिपियों के साथ गड़बड़ नहीं करना चाहता है और बस सरल प्रोग्रामिंग के लिए मिल सकता है ...

इसलिए एक और चीज़ जो हमने यहाँ सीखी है वह यह है कि लिंकर ने हमारे लिए data_rom_start को गठबंधन किया है , हमें वहाँ एक ALIGN (4) की आवश्यकता नहीं है। क्या हमें यह मान लेना चाहिए कि वह हमेशा काम करेगा?

यह भी ध्यान दें कि यह बाहर जाने के रास्ते पर गद्देदार है, हमारे पास 5 बाइट्स हैं। डटा लेकिन इसे 8. पर रखा गया है। बिना किसी एलिगेंस () के हम पहले ही शब्दों का उपयोग करके कॉपी कर सकते हैं। आज हम अपने कंप्यूटर पर इस टूलचेन के साथ जो देखते हैं, उसके आधार पर, क्या यह भूत और भविष्य के लिए सही हो सकता है? कौन जानता है, यहां तक ​​कि ALIGNs के साथ समय-समय पर कुछ नए संस्करण की पुष्टि करने के लिए जाँच करने की आवश्यकता नहीं है, वे समय-समय पर ऐसा करेंगे।

उस प्रयोग से यह सुरक्षित होने के लिए आगे बढ़ता है।

MEMORY
{
    bob : ORIGIN = 0x00000000, LENGTH = 0x1000
    ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > bob

    .rodata : { *(.rodata*) } > bob

   . = ALIGN(4);
   __data_rom_start__ = .;
   .data : {
    __data_start__ = .;
    *(.data*)
   . = ALIGN(4);
   __data_end__ = .;
   } > ted AT > bob
   __data_size__ = __data_end__ - __data_start__;

   . = ALIGN(4);
   .bss  : {
   __bss_start__ = .;
   *(.bss*)
   . = ALIGN(4);
   __bss_end__ = .;
   } > ted
   __bss_size__ = __bss_end__ - __bss_start__;

}

अन्य लोगों के साथ सुसंगत होने के लिए सिरों को अंदर ले जाना। और उस ने इसे नहीं बदला:

0000001c <bounce>:
  1c:   4770        bx  lr
  1e:   46c0        nop         ; (mov r8, r8)
  20:   0000004c    andeq   r0, r0, r12, asr #32
  24:   20000000    andcs   r0, r0, r0
  28:   20000008    andcs   r0, r0, r8
  2c:   00000008    andeq   r0, r0, r8

एक और त्वरित परीक्षण:

.globl bounce
bounce:
    nop
    bx lr

दे रही है

0000001c <bounce>:
  1c:   46c0        nop         ; (mov r8, r8)
  1e:   4770        bx  lr
  20:   0000004c    andeq   r0, r0, r12, asr #32
  24:   20000000    andcs   r0, r0, r0
  28:   20000008    andcs   r0, r0, r8
  2c:   00000008    andeq   r0, r0, r8

उछाल और .ign के बीच पैड की जरूरत नहीं

ओह, ठीक है, मुझे याद है कि अब मैं _end__ अंदर क्यों नहीं डालता। क्योंकि यह काम नहीं करता है।

MEMORY
{
    bob : ORIGIN = 0x00000000, LENGTH = 0x1000
    ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > bob

    .rodata : { *(.rodata*) } > bob

   . = ALIGN(4);
   __data_rom_start__ = .;
   .data : {
    __data_start__ = .;
    *(.data*)
   } > ted AT > bob
   . = ALIGN(4);
   __data_end__ = .;
   __data_size__ = __data_end__ - __data_start__;

   . = ALIGN(4);
   .bss  : {
   __bss_start__ = .;
   *(.bss*)
   } > ted
   . = ALIGN(4);
   __bss_end__ = .;
   __bss_size__ = __bss_end__ - __bss_start__;

}

इस लिंकर स्क्रिप्ट से शादी करने के लिए कुछ सरल, लेकिन बहुत ही पोर्टेबल कोड

.thumb

.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word reset
.word done
.word done
.word done

.thumb_func
reset:

    ldr r0,blen
    cmp r0,#0
    beq bss_zero_done
    ldr r1,bstart
    mov r2,#0
bss_zero:
    stmia r1!,{r2}
    sub r0,#4
    bne bss_zero
bss_zero_done:

    ldr r0,dlen
    cmp r0,#0
    beq data_copy_done
    ldr r1,rstart
    ldr r2,dstart
data_copy:
    ldmia r1!,{r3}
    stmia r2!,{r3}
    sub r0,#4
    bne data_copy
data_copy_done:

    bl centry
    b done

.thumb_func
done:   b .

.thumb_func
.globl bounce
bounce:
    nop
    bx lr

.align
bstart: .word __bss_start__
blen:   .word __bss_size__
rstart: .word __data_rom_start__
dstart: .word __data_start__
dlen:   .word __data_size__

दे रही है

Disassembly of section .text:

00000000 <_start>:
   0:   20000800    andcs   r0, r0, r0, lsl #16
   4:   00000015    andeq   r0, r0, r5, lsl r0
   8:   0000003d    andeq   r0, r0, sp, lsr r0
   c:   0000003d    andeq   r0, r0, sp, lsr r0
  10:   0000003d    andeq   r0, r0, sp, lsr r0

00000014 <reset>:
  14:   480c        ldr r0, [pc, #48]   ; (48 <blen>)
  16:   2800        cmp r0, #0
  18:   d004        beq.n   24 <bss_zero_done>
  1a:   490a        ldr r1, [pc, #40]   ; (44 <bstart>)
  1c:   2200        movs    r2, #0

0000001e <bss_zero>:
  1e:   c104        stmia   r1!, {r2}
  20:   3804        subs    r0, #4
  22:   d1fc        bne.n   1e <bss_zero>

00000024 <bss_zero_done>:
  24:   480b        ldr r0, [pc, #44]   ; (54 <dlen>)
  26:   2800        cmp r0, #0
  28:   d005        beq.n   36 <data_copy_done>
  2a:   4908        ldr r1, [pc, #32]   ; (4c <rstart>)
  2c:   4a08        ldr r2, [pc, #32]   ; (50 <dstart>)

0000002e <data_copy>:
  2e:   c908        ldmia   r1!, {r3}
  30:   c208        stmia   r2!, {r3}
  32:   3804        subs    r0, #4
  34:   d1fb        bne.n   2e <data_copy>

00000036 <data_copy_done>:
  36:   f000 f80f   bl  58 <centry>
  3a:   e7ff        b.n 3c <done>

0000003c <done>:
  3c:   e7fe        b.n 3c <done>

0000003e <bounce>:
  3e:   46c0        nop         ; (mov r8, r8)
  40:   4770        bx  lr
  42:   46c0        nop         ; (mov r8, r8)

00000044 <bstart>:
  44:   20000008    andcs   r0, r0, r8

00000048 <blen>:
  48:   00000004    andeq   r0, r0, r4

0000004c <rstart>:
  4c:   00000074    andeq   r0, r0, r4, ror r0

00000050 <dstart>:
  50:   20000000    andcs   r0, r0, r0

00000054 <dlen>:
  54:   00000008    andeq   r0, r0, r8

00000058 <centry>:
  58:   2207        movs    r2, #7
  5a:   b510        push    {r4, lr}
  5c:   4b04        ldr r3, [pc, #16]   ; (70 <centry+0x18>)
  5e:   2007        movs    r0, #7
  60:   601a        str r2, [r3, #0]
  62:   f7ff ffec   bl  3e <bounce>
  66:   2000        movs    r0, #0
  68:   bc10        pop {r4}
  6a:   bc02        pop {r1}
  6c:   4708        bx  r1
  6e:   46c0        nop         ; (mov r8, r8)
  70:   20000008    andcs   r0, r0, r8

Disassembly of section .data:

20000000 <c>:
20000000:   00000005    andeq   r0, r0, r5

20000004 <b>:
20000004:   00000004    andeq   r0, r0, r4

Disassembly of section .bss:

20000008 <a>:
20000008:   00000000    andeq   r0, r0, r0

हम वहाँ रुक सकते हैं या जा सकते हैं। यदि हम लिंकर स्क्रिप्ट के समान क्रम में इनिशियलाइज़ करते हैं तो ठीक है यदि हम अगली चीज़ में चले जाते हैं क्योंकि हमने अभी तक वहाँ नहीं प्राप्त किया है। और stm / ldm केवल आवश्यक हैं / शब्द संरेखित पते का उपयोग करना चाहते हैं, इसलिए यदि आप इसे बदलते हैं:

    ldr r0,blen
    cmp r0,#0
    beq bss_zero_done
    ldr r1,bstart
    mov r2,#0
    mov r3,#0
    mov r4,#0
    mov r5,#0
bss_zero:
    stmia r1!,{r2,r3,r4,r5}
    sub r0,#16
    ble bss_zero
bss_zero_done:

लिंकर स्क्रिप्ट में पहले bss के साथ, और हाँ आप ब्लो ब्लो नहीं चाहते हैं।

Disassembly of section .text:

00000000 <_start>:
   0:   20000800    andcs   r0, r0, r0, lsl #16
   4:   00000015    andeq   r0, r0, r5, lsl r0
   8:   00000043    andeq   r0, r0, r3, asr #32
   c:   00000043    andeq   r0, r0, r3, asr #32
  10:   00000043    andeq   r0, r0, r3, asr #32

00000014 <reset>:
  14:   480d        ldr r0, [pc, #52]   ; (4c <blen>)
  16:   2800        cmp r0, #0
  18:   d007        beq.n   2a <bss_zero_done>
  1a:   490b        ldr r1, [pc, #44]   ; (48 <bstart>)
  1c:   2200        movs    r2, #0
  1e:   2300        movs    r3, #0
  20:   2400        movs    r4, #0
  22:   2500        movs    r5, #0

00000024 <bss_zero>:
  24:   c13c        stmia   r1!, {r2, r3, r4, r5}
  26:   3804        subs    r0, #4
  28:   ddfc        ble.n   24 <bss_zero>

0000002a <bss_zero_done>:
  2a:   480b        ldr r0, [pc, #44]   ; (58 <dlen>)
  2c:   2800        cmp r0, #0
  2e:   d005        beq.n   3c <data_copy_done>
  30:   4907        ldr r1, [pc, #28]   ; (50 <rstart>)
  32:   4a08        ldr r2, [pc, #32]   ; (54 <dstart>)

00000034 <data_copy>:
  34:   c978        ldmia   r1!, {r3, r4, r5, r6}
  36:   c278        stmia   r2!, {r3, r4, r5, r6}
  38:   3810        subs    r0, #16
  3a:   ddfb        ble.n   34 <data_copy>

0000003c <data_copy_done>:
  3c:   f000 f80e   bl  5c <centry>
  40:   e7ff        b.n 42 <done>

00000042 <done>:
  42:   e7fe        b.n 42 <done>

00000044 <bounce>:
  44:   46c0        nop         ; (mov r8, r8)
  46:   4770        bx  lr

00000048 <bstart>:
  48:   20000000    andcs   r0, r0, r0

0000004c <blen>:
  4c:   00000004    andeq   r0, r0, r4

00000050 <rstart>:
  50:   20000004    andcs   r0, r0, r4

00000054 <dstart>:
  54:   20000004    andcs   r0, r0, r4

00000058 <dlen>:
  58:   00000008    andeq   r0, r0, r8

0000005c <centry>:
  5c:   2207        movs    r2, #7
  5e:   b510        push    {r4, lr}
  60:   4b04        ldr r3, [pc, #16]   ; (74 <centry+0x18>)
  62:   2007        movs    r0, #7
  64:   601a        str r2, [r3, #0]
  66:   f7ff ffed   bl  44 <bounce>
  6a:   2000        movs    r0, #0
  6c:   bc10        pop {r4}
  6e:   bc02        pop {r1}
  70:   4708        bx  r1
  72:   46c0        nop         ; (mov r8, r8)
  74:   20000000    andcs   r0, r0, r0

Disassembly of section .bss:

20000000 <a>:
20000000:   00000000    andeq   r0, r0, r0

Disassembly of section .data:

20000004 <c>:
20000004:   00000005    andeq   r0, r0, r5

20000008 <b>:
20000008:   00000004    andeq   r0, r0, r4

उन छोरों तेजी से जाना जाएगा। अब मैं नहीं जानता कि अगर आह की बस्स 64 बिट्स चौड़ी हो सकती है या नहीं, लेकिन एक पूर्ण आकार के हाथ के लिए आप इन चीजों को 64 बिट सीमाओं पर संरेखित करना चाहेंगे। एक 32 बिट सीमा पर चार रजिस्टर ldm / stm, लेकिन 64 बिट सीमा तीन अलग-अलग बस लेनदेन नहीं बनती है, जहाँ 64 बिट सीमा पर संरेखित एक एकल लेनदेन है जो प्रत्येक निर्देश के अनुसार कई घड़ियों को बचाता है।

चूँकि हम नंगे पैर कर रहे हैं और हम पूरी तरह से हर उस चीज़ के लिए ज़िम्मेदार हैं, जिसे हम पहले bss कह सकते हैं, फिर डेटा अगर हम ढेर करते हैं, तो ढेर ऊपर से नीचे बढ़ता है, इसलिए यदि हम शून्य bss और कुछ देर तक फैलते हैं जब तक हम शुरू करते हैं वह सही जगह जो हम अभी तक उस मेमोरी का उपयोग नहीं कर रहे हैं। उसके बाद हम .data की नकल करते हैं और ढेर में ठीक कर सकते हैं, ठीक है, ढेर है या नहीं, स्टैक के लिए बहुत जगह है इसलिए हम किसी को भी कुछ भी नहीं कर रहे हैं / (इसलिए जब तक हम लिंकर स्क्रिप्ट में सुनिश्चित करते हैं कि हम ऐसा करते हैं। अगर कोई चिंता है तो ALIGN () को बड़ा बनाइए ताकि हम हमेशा इन भरने के लिए अपने स्पेस में रहें।

तो मेरा सरल उपाय है, इसे ले लो या इसे छोड़ दो। किसी भी कीड़े को ठीक करने के लिए आपका स्वागत है, मैंने इसे हार्डवेयर पर नहीं चलाया और न ही मेरे सिम्युलेटर ...

MEMORY
{
    bob : ORIGIN = 0x00000000, LENGTH = 0x1000
    ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > bob

    .rodata : { *(.rodata*) } > bob

   . = ALIGN(8);
   .bss  : {
   __bss_start__ = .;
   *(.bss*)
   } > ted
   . = ALIGN(4);
   __bss_end__ = .;
   __bss_size__ = __bss_end__ - __bss_start__;

   . = ALIGN(8);
   __data_rom_start__ = .;
   .data : {
    __data_start__ = .;
    *(.data*)
   } > ted AT > bob
   . = ALIGN(4);
   __data_end__ = .;
   __data_size__ = __data_end__ - __data_start__;

}



.thumb

.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word reset
.word done
.word done
.word done

.thumb_func
reset:

    ldr r0,blen
    cmp r0,#0
    beq bss_zero_done
    ldr r1,bstart
    mov r2,#0
    mov r3,#0
    mov r4,#0
    mov r5,#0
bss_zero:
    stmia r1!,{r2,r3,r4,r5}
    sub r0,#16
    ble bss_zero
bss_zero_done:

    ldr r0,dlen
    cmp r0,#0
    beq data_copy_done
    ldr r1,rstart
    ldr r2,dstart
data_copy:
    ldmia r1!,{r3,r4,r5,r6}
    stmia r2!,{r3,r4,r5,r6}
    sub r0,#16
    ble data_copy
data_copy_done:

    bl centry
    b done

.thumb_func
done:   b .

.thumb_func
.globl bounce
bounce:
    nop
    bx lr

.align
bstart: .word __bss_start__
blen:   .word __bss_size__
rstart: .word __data_rom_start__
dstart: .word __data_start__
dlen:   .word __data_size__


void bounce ( unsigned int );

unsigned int a;

unsigned int b=4;
unsigned char c=5;

int centry ( void )
{
    a = 7;
    bounce(a);
    return(0);
}

arm-none-eabi-as --warn --fatal-warnings flash.s -o flash.o
arm-none-eabi-ld -o hello.elf -T flash.ld flash.o centry.o
arm-none-eabi-objdump -D hello.elf > hello.list
arm-none-eabi-objcopy hello.elf hello.bin -O binary

यह सब एक साथ रखो और तुम जाओ:

Disassembly of section .text:

00000000 <_start>:
   0:   20000800    andcs   r0, r0, r0, lsl #16
   4:   00000015    andeq   r0, r0, r5, lsl r0
   8:   00000043    andeq   r0, r0, r3, asr #32
   c:   00000043    andeq   r0, r0, r3, asr #32
  10:   00000043    andeq   r0, r0, r3, asr #32

00000014 <reset>:
  14:   480d        ldr r0, [pc, #52]   ; (4c <blen>)
  16:   2800        cmp r0, #0
  18:   d007        beq.n   2a <bss_zero_done>
  1a:   490b        ldr r1, [pc, #44]   ; (48 <bstart>)
  1c:   2200        movs    r2, #0
  1e:   2300        movs    r3, #0
  20:   2400        movs    r4, #0
  22:   2500        movs    r5, #0

00000024 <bss_zero>:
  24:   c13c        stmia   r1!, {r2, r3, r4, r5}
  26:   3810        subs    r0, #16
  28:   ddfc        ble.n   24 <bss_zero>

0000002a <bss_zero_done>:
  2a:   480b        ldr r0, [pc, #44]   ; (58 <dlen>)
  2c:   2800        cmp r0, #0
  2e:   d005        beq.n   3c <data_copy_done>
  30:   4907        ldr r1, [pc, #28]   ; (50 <rstart>)
  32:   4a08        ldr r2, [pc, #32]   ; (54 <dstart>)

00000034 <data_copy>:
  34:   c978        ldmia   r1!, {r3, r4, r5, r6}
  36:   c278        stmia   r2!, {r3, r4, r5, r6}
  38:   3810        subs    r0, #16
  3a:   ddfb        ble.n   34 <data_copy>

0000003c <data_copy_done>:
  3c:   f000 f80e   bl  5c <centry>
  40:   e7ff        b.n 42 <done>

00000042 <done>:
  42:   e7fe        b.n 42 <done>

00000044 <bounce>:
  44:   46c0        nop         ; (mov r8, r8)
  46:   4770        bx  lr

00000048 <bstart>:
  48:   20000000    andcs   r0, r0, r0

0000004c <blen>:
  4c:   00000004    andeq   r0, r0, r4

00000050 <rstart>:
  50:   20000008    andcs   r0, r0, r8

00000054 <dstart>:
  54:   20000004    andcs   r0, r0, r4

00000058 <dlen>:
  58:   00000008    andeq   r0, r0, r8

0000005c <centry>:
  5c:   2207        movs    r2, #7
  5e:   b510        push    {r4, lr}
  60:   4b04        ldr r3, [pc, #16]   ; (74 <centry+0x18>)
  62:   2007        movs    r0, #7
  64:   601a        str r2, [r3, #0]
  66:   f7ff ffed   bl  44 <bounce>
  6a:   2000        movs    r0, #0
  6c:   bc10        pop {r4}
  6e:   bc02        pop {r1}
  70:   4708        bx  r1
  72:   46c0        nop         ; (mov r8, r8)
  74:   20000000    andcs   r0, r0, r0

Disassembly of section .bss:

20000000 <a>:
20000000:   00000000    andeq   r0, r0, r0

Disassembly of section .data:

20000004 <c>:
20000004:   00000005    andeq   r0, r0, r5

20000008 <b>:
20000008:   00000004    andeq   r0, r0, r4

ध्यान दें कि यह आर्म-नो-ईबीआई और आर्म-लिनेक्स-ग्नूएबी और अन्य वेरिएंट के साथ काम करता है क्योंकि घी व्हिज़ सामान का उपयोग नहीं किया गया था।

आप पाएंगे जब आप चारों ओर देखते हैं कि लोग अपने लिंकर लिपियों में घी व्हिज़ सामान के साथ पागल हो जाएंगे, विशाल राक्षसी रसोई सिंक चीजें। बेहतर यह जानने के लिए कि यह कैसे करना है (या बेहतर कैसे उपकरण को मास्टर करें ताकि आप नियंत्रित कर सकें कि क्या चल रहा है) किसी पर भरोसा करने के बजाय सामान को छोड़ दें और यह न जानें कि यह कहां टूटने वाला है क्योंकि आप समझ नहीं पाते हैं और / या शोध करना चाहते हैं। यह।

एक सामान्य नियम के रूप में एक भाषा को एक ही भाषा के साथ बूटस्ट्रैप नहीं किया जाता है (इस अर्थ में बूटस्ट्रैप का अर्थ है कि एक ही संकलक के साथ एक संकलक नहीं चल रहा कोड) आप बूटस्ट्रैप के कम के साथ एक सरल भाषा का उपयोग करना चाहते हैं। यही कारण है कि सी असेंबली में किया जाता है, इसमें बूटस्ट्रैप की कोई आवश्यकता नहीं है जिसे आप रीसेट के बाद पहले निर्देश से शुरू करते हैं। JAVA, सुनिश्चित करें कि आप J को C और बूटस्ट्रैप में लिख सकते हैं कि C asm के साथ है तो JAVA को बूटस्ट्रैप करें यदि आप C के साथ होंगे लेकिन JAVA को C में भी निष्पादित करेंगे।

क्योंकि हम इन नकल छोरों पर मान्यताओं को नियंत्रित करते हैं, वे हाथ तंग मेमसी / मेमसेट की तुलना में परिभाषा तंग और क्लीनर द्वारा हैं।

ध्यान दें कि आपकी अन्य समस्या यह थी:

unsigned int * bss_start_p = &_BSS_START; 
unsigned int * bss_end_p = &_BSS_END;

यदि ये स्थानीय ठीक हैं, तो कोई बात नहीं, अगर ये वैश्विक हैं तो आपको काम करने के लिए पहले .data की आवश्यकता है और यदि आप उस चाल को .data करने की कोशिश करते हैं तो आप असफल होंगे। स्थानीय चर, ठीक है जो काम करेगा। यदि आप किसी कारण से स्थैतिक स्थानीय बनाने का निर्णय लेते हैं (स्थानीय ग्लोबल्स जिन्हें मैं उन्हें कॉल करना पसंद करता हूं) तो आप फिर से परेशानी में हैं। हर बार जब आप एक घोषणा में एक असाइनमेंट करते हैं, हालांकि आपको इसके बारे में सोचना चाहिए, यह कैसे लागू किया जाता है और क्या यह सुरक्षित है / समझदार है। हर बार जब आप मान लेते हैं कि अघोषित रूप से एक चर शून्य है, तो एक ही सौदा, यदि एक स्थानीय चर इसकी शून्य नहीं माना जाता है, यदि वैश्विक है तो यह है। यदि आप उन्हें कभी शून्य नहीं मानते हैं तो आपको कभी भी परेशान होने की आवश्यकता नहीं है।


कमाल है, यह दूसरी बार है जब मैंने एक उत्तर में अधिकतम वर्ण संख्या को पार कर लिया है ....
old_timer

यह सवाल स्टैकओवरफ्लो पर है न कि इलेक्ट्रिकल इंजीनियरिंग पर।
old_timer

इसके अलावा आपके प्रश्न में बाहरी लिंक पर निर्भर करना अच्छा रूप नहीं है, यदि लिंक प्रश्न से पहले चला जाता है, तो प्रश्न समझ में नहीं आता है।
old_timer

इस मामले में आपका शीर्षक और सामग्री यह जानने के लिए पर्याप्त है कि आप किसी विशेष माइक्रोकंट्रोलर पर C को बूटस्ट्रैप करने की कोशिश कर रहे हैं और .bs और .Data इनिशियलाइज़ेशन में भटक रहे हैं
old_timer

लेकिन इस मामले में एक अन्यथा बहुत जानकारीपूर्ण वेबसाइट द्वारा गुमराह किया गया है।
old_timer
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.