#title XIP »ìÆ캸±â '''''eXecute In Place (XIP) »ìÆ캸±â''''' ÀúÀÚ: Phil Wilshire [[BR]] ¹ø¿ª: ±è³²Çü [[TableOfContents]] == XIP (eXecute In Place) == XIP ´Â uClinux »ó¿¡¼­ È°¿ëÇÒ ¼ö ÀÖ´Â À¯¿ëÇÑ ¿É¼Ç ÁßÀÇ ÇϳªÀÌ´Ù. XIP ÀÇ ÀåÁ¡Àº µ¿ÀÏÇÑ ÇÁ·Î±×·¥À» ¿©·¯¹ø ½ÇÇàÇÒ ¶§ ÅؽºÆ® ¼¼±×¸ÕÆ®¸¦ º¹»çÇÒ ÇÊ¿ä°¡ ¾ø´Ù´Â °ÍÀÌ´Ù. ½ÇÁ¦·Î ÅؽºÆ® ¼¼±×¸ÕÆ®´Â Ç÷¡½Ã ¸Þ¸ð¸® »ó¿¡ Á¸ÀçÇÒ ¼ö Àֱ⠶§¹®¿¡ ½Ã½ºÅÛÀÇ RAM ¿¡ º¹»çµÉ ÇÊ¿ä°¡ ÀüÇô ¾ø´Ù. ÀÌ°ÍÀº Ä¿´Ù¶õ ÄÚµå ¿µ¿ªÀ» °¡Áö´Â ÇÁ·Î±×·¥ÀÌ ½Ã½ºÅÛ »ó¿¡ ¿©·¯ °³ÀÇ ÀνºÅϽº·Î ½ÇÇàµÇ´Â ŽºÅ©¿¡¼­ À¯¿ëÇÏ´Ù. ÀÌ °æ¿ì °¢°¢ÀÇ ÇÁ·Î¼¼½º¿¡ ´ëÇؼ­ ¿ÀÁ÷ ½ºÅÃ, BSS, µ¥ÀÌÅÍ ¼¼±×¸ÕÆ®¸¸ÀÌ »õ·Î »ý¼ºµÉ ÇÊ¿ä°¡ ÀÖ´Ù. ±×¸®°í ÅؽºÆ® ¼¼±×¸ÕÆ® ¿µ¿ªÀº Ç÷¡½Ã ¸Þ¸ð¸®¿¡ Á¸ÀçÇϰųª, ¼º´ÉÀÌ ¹®Á¦°¡ µÇ´Â °æ¿ì ÆÄÀÏ ½Ã½ºÅÛÀÇ ³»¿ëÀ» RAM ¿¡ º¹»çÇÑ ÈÄ¿¡ ·¥ µð½ºÅ©·Î ¸¶¿îÆ®µÉ ¼ö ÀÖ´Ù. ¸¸¾à ÆÄÀÏ ½Ã½ºÅÛ ³»ÀÇ ½ÇÇà ÆÄÀÏÀÌ XIP ¸¦ Áö¿øÇϵµ·Ï ÄÄÆÄÀÏ µÇ¾ú°í Çì´õ ÆÄÀÏ¿¡¼­ XIP Ç÷¡±×¸¦ ¼³Á¤ÇÏ¿´À¸¸é ¿ÀÁ÷ ÇϳªÀÇ ÅؽºÆ® ¼¼±×¸ÕÆ®¸¸ÀÌ ·ÎµåµÇ¾î ½ÇÇàµÈ´Ù. == XIP ¿Í Ä¿³Î == Ä¿³ÎÀº Ç×»ó "XIP" ·Î µ¿ÀÛÇÑ´Ù. ¿©±â¼­ °¡Áú ¼ö ÀÖ´Â ´Ü ÇÑ°¡Áö Àǹ®Á¡Àº ¸¸¾à Ä¿³ÎÀÌ ½ÇÇàµÇ±â Àü¿¡ RAM À¸·Î º¹»çµÇ´Â °æ¿ì¿¡ ´ëÇÑ °ÍÀÌ´Ù. ÀÌ°ÍÀº ´ÙÀ½°ú °°Àº ¿©·¯°¡Áö Àϵ鿡 ÀÇÁ¸ÇÑ´Ù: * Ä¿³ÎÀÌ ÅؽºÆ® ¼½¼Ç¿¡ ÀÖ´Â º¯¼ö¸¦ »ç¿ëÇϴ°¡? * Ä¿³Î ¸µÅ© ¸ÊÀÌ ROM ³»ÀÇ Ä¿³ÎÀÇ º£À̽º·Î Á¤ÀǵǾî Àִ°¡? * Ä¿³Î ½ºÅ¸Æ® ¾÷ ÄÚµå (Ä¿³Î ¼Ò½º Æ®¸® ³»ÀÇ `head.S` ȤÀº `crt0.s` ÆÄÀÏ) °¡ Ä¿³ÎÀ» RAM À¸·Î Àç¹èÄ¡ (relocate) Çϵµ·Ï ¿ä±¸Çϴ°¡? Àϼ³¿¡ µû¸£¸é ARM Ä¿³ÎÀÇ ¾î¶² º¯¼ö°¡ ÅؽºÆ® ¼¼±×¸ÕÆ® ³»¿¡ Àֱ⠶§¹®¿¡ ARM Ä¿³ÎÀ» ROM ¿¡¼­ ½ÇÇà½ÃÅ°±â ¾î·Æ´Ù°í ÇÑ´Ù. (TODO: ½Ã¹Ä·¹ÀÌÅ͸¦ ÅëÇØ È®ÀÎÇØ º¼ °Í!) 68K (Dragonball) ¿Í Coldfire Ä¿³ÎÀº ROM ¿¡¼­ ½ÇÇàµÉ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ¸ðµç ÃʱâÈ­ ÄÚµå´Â ³ªÁß¿¡ ¿©±â¿¡ »ç¿ëµÈ ¸Þ¸ð¸®¸¦ ´Ù½Ã »ç¿ëÇÒ ¼ö ÀÖ°Ô Çϱâ À§Çؼ­ RAM »ó¿¡ Á¸ÀçÇϵµ·Ï ÇØ¾ß ÇÑ´Ù (¾Æ´Ï¸é ¸Þ¸ð¸®¸¦ ÇØÁ¦ÇÏÁö ¾Êµµ·Ï ÇÑ´Ù). == XIP ¿Í »ç¿ëÀÚ Å½ºÅ© == »ç¿ëÀÚ Å½ºÅ©µµ XIP ·Î µ¿ÀÛÇϵµ·Ï Á¤ÀÇÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ¿ÀÁ÷ µ¥ÀÌÅÍ, BSS, Àç¹èÄ¡ Á¤º¸¿Í ½ºÅà ¸¸ÀÌ °¢ ŽºÅ© °íÀ¯ÀÇ RAM ¿µ¿ª¿¡ Á¸ÀçÇÑ´Ù. ½ºÅà ¿µ¿ªÀÇ Å©±â°¡ Áõ°¡µÉ ¼ö ¾øÀ½¿¡ ÁÖÀÇÇ϶ó. ÀÌ Å©±â´Â `elf2flt` °¡ µ¿ÀÛÇÒ ¶§ °íÁ¤µÈ´Ù. ÀÌ°ÍÀº `elf2flt` ÇÁ·Î±×·¥À» ´Ù½Ã ½ÇÇàÇϰųª `flthdr` (¾Æ·¡ ÂüÁ¶)¸¦ »ç¿ëÇؼ­ º¯°æÇÒ ¼ö ÀÖ´Ù. /!\ ÁÖÀÇ: ÀÌ Ç÷¡±×?¸¦ ÀÌ¿ëÇؼ­ XIP °¡ ¾Æ´Ñ Äڵ带 XIP ÄÚµå·Î º¯°æÇÒ ¼ö´Â ¾ø´Ù. ÇÏÁö¸¸ XIP Äڵ尡 (¿©·¯ ÀνºÅϽº°¡ ½ÇÇàµÉ ¶§) ÅؽºÆ® ¼½¼ÇÀ» °­Á¦·Î ·ÎµåÇϵµ·Ï ÇÒ ¼ö´Â ÀÖ´Ù. ¸ðµç flat ÆÄÀÏÀ» ·ÎµåÇÏ´Â Ä¿³Î ÄÚµå´Â ¿©±â¿¡ ÀÖ´Ù: '''`linux-2.[04].x/fs/binfmt_flat.c`''' ±× Áß ÇÊ¿äÇÑ RAM ¿µ¿ªÀ» ÇÒ´çÇÏ´Â ºÎºÐÀÇ ÄÚµå´Â ´ÙÀ½°ú °°´Ù. {{{ extra = MAX(bss_len + stack_len, relocs * sizeof(unsigned long)); down_write(&t->mm->mmap_sem); realdatastart = do_mmap(0, 0, data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long), PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0); up_write(&t->mm->mmap_sem); }}} == Flat ÆÄÀÏ Àç¹èÄ¡ == ·Î´õ ÇÁ·Î¼¼½º´Â µ¥ÀÌÅÍ ¼¼±×¸ÕÆ®°¡ ÇÒ´çµÈ ¿µ¿ªÀÌ º¯°æµÊ¿¡ µû¶ó ÇÊ¿äÇÑ ÀÛ¾÷µéÀ» ó¸®ÇØ¾ß ÇÑ´Ù. ÀÌ°ÍÀº MMU °¡ ¾ø±â ¶§¹®¿¡ ¹ß»ýÇÏ´Â ¹®Á¦ÀÌ´Ù. ¿ì¸®´Â ´Ü¼øÈ÷ "ÀûÀýÇÑ °÷¿¡ ¸Þ¸ð¸®°¡ Á¸ÀçÇϵµ·Ï" ÇÒ ¼ö ¾ø´Ù. Àç¹èÄ¡ ¸ñ·ÏÀº elf ÆÄÀÏÀÌ flat ÆÄÀÏ·Î º¯È¯µÉ ¶§ `elf2flt` ÇÁ·Î±×·¥¿¡ ÀÇÇØ Á¤ÇØÁø´Ù. °í·ÁÇØ º¼ ¸¸ÇÑ µÎ°¡Áö Á¾·ùÀÇ Àç¹èÄ¡ ¹æ¹ýÀÌ ÀÖ´Ù. === Global Offset Table (GOT) === ÀÌ°ÍÀº »ç½Ç ÀÌ ¹®¼­¿¡¼­ ´Ù·ê ³»¿ëÀº ¾Æ´ÏÁö¸¸ ¾ð±ÞÇÒ °¡Ä¡°¡ ÀÖÀ¸¹Ç·Î ¾ê±âÇÏ°íÀÚ ÇÑ´Ù. ¸¸ÀÏ ÄÄÆÄÀϽà ¿É¼ÇÀ¸·Î GOT¸¦ È°¼ºÈ­ ½ÃÄ×´Ù¸é µ¥ÀÌÅÍ ¼¼±×¸ÕÆ®´Â GOT ¿µ¿ª¿¡¼­ ½ÃÀÛÇÏ°Ô µÈ´Ù. ÀÌ Å×ÀÌºí¿¡ ÀÖ´Â ÁÖ¼Ò °ªµéÀº µ¥ÀÌÅÍ ¼½¼ÇÀÇ ½ÇÁ¦ ÁÖ¼Ò¸¦ ¹Ý¿µÇÏ¿© Àç¹èÄ¡µÉ ÇÊ¿ä°¡ ÀÖ´Ù. GOT Å×À̺íÀÇ ¸¶Áö¸·Àº (Á¸ÀçÇÏ´Â °æ¿ì) -1 (0xFFFFFFFF) °ªÀ» °¡Áø´Ù. ¾Æ·¡ÀÇ ÄÚµå´Â `binfmt_flat.c` ÀÇ ³»¿ëÀ¸·Î GOT Å×À̺íÀ» ¾÷µ¥ÀÌÆ®ÇÏ´Â ºÎºÐÀÌ´Ù. {{{ if (flags & FLAT_FLAG_GOTPIC) { for (rp = (unsigned long *)datapos; *rp != 0xffffffff;rp++) { unsigned long addr; if (*rp) { addr = calc_reloc(*rp, libinfo, id, 0); if (addr == RELOC_FAILED) return -ENOEXEC; *rp = addr; } } } }}} === ÄÚµå Àç¹èÄ¡ (Code RELOCS) === ÀÌ ¹æ¹ýÀº `elf2flt` ÇÁ·Î¼¼½º¿¡ ÀÇÇØ »ý¼ºµÈ Àç¹èÄ¡ Å×À̺íÀ» »ç¿ëÇÑ´Ù. ÁÖÀÇÇÒ Á¡Àº, ¸¸¾à ÆÄÀÏÀÌ XIP ·Î µ¿ÀÛÇϵµ·Ï µÇ¾î ÀÖ´Ù¸é ¿©·¯ °³ÀÇ ½ÇÇà ÆÄÀÏ¿¡¼­ °øÀ¯µÇ±â À§ÇØ ÅؽºÆ® ¼¼±×¸ÕÆ® ¿µ¿ªÀº ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù´Â °ÍÀÌ´Ù. Å×À̺íÀÇ °¢ ¿£Æ®¸®´Â Àç¹èÄ¡µÉ ÇÊ¿ä°¡ ÀÖ´Â ¿µ¿ªÀÇ ÁÖ¼Ò¸¦ ³ªÅ¸³½´Ù. Àç¹èÄ¡ÇÒ ¿µ¿ª ÀÚü°¡ Àç¹èÄ¡µÇ±â ¶§¹®¿¡ ÀÌ ¿µ¿ªÀÇ ÁÖ¼Ò°¡ ¸ÕÀú ¼öÁ¤µÇ¾î¾ß ÇÑ´Ù. ÀÏ´Ü º¯°æµÈ ÁÖ¼Ò°¡ °è»êµÇ¸é ±× ÁÖ¼Ò°¡ °¡¸®Å°´Â ¿µ¿ªÀÇ ³»¿ëÀº °áÁ¤µÇ¸ç ÇØ´ç ¿µ¿ª¿¡´Â »õ·Î¿î ÁÖ¼Ò°¡ Àû¿ëµÈ´Ù. Áּҵ鰣¿¡ ´Ù¸¥ ¹ÙÀÌÆ® ¿À´õ¸µ Çü½Ä (little/big endian) ÀÌ »ç¿ëµÈ´Ù¸é º¹ÀâÇÑ ¹®Á¦°¡ ¹ß»ýµÇ¸ç Àç¹èÄ¡µÇ´Â ½ÇÁ¦ ÁÖ¼Ò´Â Á¤·ÄµÇÁö ¾ÊÀ» ¼ö ÀÖ´Ù. ´Ù½Ã Çѹø `binfmt_flat.c` ÆÄÀÏÀ» »ìÆì º¸ÀÚ. ¾Æ·¡ÀÇ ÄÚµå´Â Àç¹èÄ¡¸¦ ¼öÇàÇÏ´Â ºÎºÐÀ» ³ªÅ¸³½´Ù. {{{ for (i=0; i < relocs; i++) { unsigned long addr; /* Àç¹èÄ¡µÉ Æ÷ÀÎÅÍÀÇ ÁÖ¼Ò¸¦ ¾ò¾î¿Â´Ù. (¹°·Ð ¸ÕÀú ÀÌ ÁÖ¼Ò¸¦ Àç¹èÄ¡ ÇØ¾ß ÇÑ´Ù) */ rp = (unsigned long *)calc_reloc(ntohl(reloc[i]), libinfo, id, 1); if (rp == (unsigned long *)RELOC_FAILED) return -ENOEXEC; /* Æ÷ÀÎÅÍ°¡ °¡¸®Å°´Â ³»¿ëÀ» °¡Á® ¿Â´Ù. */ addr = get_unaligned (rp); if (addr != 0) { /* * Àç¹èÄ¡¸¦ ¼öÇàÇÑ´Ù. * µ¥ÀÌÅÍ ¼½¼ÇÀÇ PIC Àç¹èÄ¡´Â ÀÌ¹Ì Å¸°ÙÀÇ ¹ÙÀÌÆ® ¿À´õ·Î µÇ¾î ÀÖ´Ù. */ addr = calc_reloc( (flags & FLAT_FLAG_GOTPIC) ? addr : ntohl(addr), libinfo, id, 0); if (addr == RELOC_FAILED) return -ENOEXEC; /* Àç¹èÄ¡µÈ Æ÷ÀÎÅ͸¦ ±â·ÏÇÑ´Ù(write back). */ put_unaligned (addr, rp); } } }}} == ¿¬°á == À§¿¡ »ìÆ캸¾ÒµíÀÌ ÀÌ°ÍÀÌ µ¿ÀÛÇϱâ À§Çؼ­´Â ¿©·¯ ½Ã½ºÅÛµéÀÌ ÇÔ²² ÀûÀýÈ÷ µ¿ÀÛÇØ¾ß ÇÑ´Ù. * `bitfmt_flat.c` ´Â `elf2flt` ÀÇ Ãâ·ÂÀ» ÀÌÇØÇØ¾ß ÇÑ´Ù. * `elf2flt` ´Â (ƯÈ÷) Àç¹èÄ¡ ¿µ¿ª¿¡ ´ëÇÑ ÀûÀýÇÑ Ãâ·ÂÀ» »ý¼ºÇØ¾ß ÇÑ´Ù. * ÄÄÆÄÀÏ·¯´Â ¿Ã¹Ù¸¥ GOT Á¤º¸¿Í PIC Äڵ带 »ý¼ºÇØ¾ß ÇÑ´Ù. * crt0.o °ú °°Àº ¶óÀ̺귯¸® ¿ä¼Ò´Â À§ÀÇ ¸ðµç °Íµé°ú Àß µ¿ÀÛÇØ¾ß ÇÑ´Ù. ÀÌ ¸ðµç ¿ä¼ÒµéÀÌ ÇÔ²² °ü¸®µÇ±â À§ÇØ ¸®ºñÀü ¹øÈ£°¡ »ý¼ºµÇ¾ú´Ù. == Flathdr - flat ÆÄÀÏ ¸Å´ÏÀú == ÀÌ ÇÁ·Î±×·¥Àº `elf2flt` ¿¡ ÀÇÇØ »ý¼ºµÈ flat ÆÄÀÏ ³»ÀÇ flat Çì´õÀÇ ³»¿ëÀ» Á¶»çÇϰųª º¯°æÇϱâ À§ÇØ »ç¿ëµÈ´Ù. »ç¿ë ¹æ¹ýÀº ¾Æ·¡¿Í °°´Ù {{{ /usr/local/bin/flthdr romfs/bin/boa romfs/bin/boa Magic: bFLT Rev: 4 Entry: 0x50 Data Start: 0x11980 Data End: 0x13d40 BSS End: 0x15604 Stack Size: 0x2000 Reloc Start: 0x13d40 Reloc Count: 0x4f Flags: 0x2 ( Has-PIC-GOT )flt. }}} »ç¿ëÇÒ ¼ö ÀÖ´Â ¿É¼ÇÀº ¾Æ·¡¿Í °°´Ù. {{{ -p : print current settings -z : compressed flat file -d : compressed data-only flat file -Z : un-compressed flat file -r : ram load -R : do not RAM load -s size : stack size -o file : output-file (default is to modify input file) }}} ¾Æ·¡´Â `flthdr` À» »ç¿ëÇÏ¿© ¾ÐÃàµÈ flat ÆÄÀÏÀ» »ý¼ºÇÏ´Â ¿¹Á¦ÀÌ´Ù. {{{ /usr/local/bin/flthdr -z romfs/bin/boa -o romfs/bin/boaz ±×¸®°í ±× °á°ú´Â ¾Æ·¡¿Í °°´Ù /usr/local/bin/flthdr -p romfs/bin/boaz romfs/bin/boaz Magic: bFLT Rev: 4 Entry: 0x50 Data Start: 0x11980 Data End: 0x13d40 BSS End: 0x15604 Stack Size: 0x2000 Reloc Start: 0x13d40 Reloc Count: 0x4f Flags: 0x6 ( Has-PIC-GOT Gzip-Compressed ) ls -l romfs/bin/boa* -rwxr--r-- 1 philw philw 81532 Jul 18 04:22 romfs/bin/boa -rw-rw-r-- 1 philw philw 40261 Jul 18 04:16 romfs/bin/boaz }}} load to ram ºñÆ®´Â -r ȤÀº -R ¿É¼Ç¿¡ ÀÇÇØ º¯°æµÉ ¼ö ÀÖ´Ù. {{{ /usr/local/bin/flthdr -r romfs/bin/boa °á°ú´Â ¾Æ·¡¿Í °°´Ù /usr/local/bin/flthdr -p romfs/bin/boa romfs/bin/boa Magic: bFLT Rev: 4 Entry: 0x50 Data Start: 0x11980 Data End: 0x13d40 BSS End: 0x15604 Stack Size: 0x2000 Reloc Start: 0x13d40 Reloc Count: 0x4f Flags: 0x3 ( Load-to-Ram Has-PIC-GOT ) }}} ½ºÅÃÀÇ Å©±â´Â -s ¿É¼ÇÀ» ÀÌ¿ëÇÏ¿© º¯°æÇÒ ¼ö ÀÖ´Ù. {{{ /usr/local/bin/flthdr -s 16384 romfs/bin/boa °á°ú´Â ¾Æ·¡¿Í °°´Ù usr/local/bin/flthdr -p romfs/bin/boa romfs/bin/boa Magic: bFLT Rev: 4 Entry: 0x50 Data Start: 0x11980 Data End: 0x13d40 BSS End: 0x15604 Stack Size: 0x4000 Reloc Start: 0x13d40 Reloc Count: 0x4f Flags: 0x2 ( Has-PIC-GOT ) }}} == ÄÄÆÄÀÏ Ç÷¡±× == ÀÌ ºÎºÐÀÌ ÀÌ ¹®¼­ÀÇ ÇÙ½ÉÀÌ´Ù. °¢°¢ÀÇ ½Ã½ºÅÛ¿¡¼­ XIP ·Î µ¿ÀÛ½ÃÅ°±â À§ÇÑ ÄÄÆÄÀÏ Ç÷¡±×´Â ¹«¾ùÀϱî? ´ÙÀ½ Å×À̺íÀ» »ìÆ캸¸é µµ¿òÀ» ¾òÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù. (TODO: È®ÀÎÇÏ°í Å×ÀÌºí ¿Ï¼ºÇϱâ) GOT ¿É¼ÇÀº..?? || ¾ÆÅ°ÅØó || »ç¿ëÀÚ ÇÁ·Î±×·¥ || Ä¿³Î || || M68K (Dragonball) || `-msep_data` || `-DMAGIC_ROM_PTR` || || Coldfire || `-msep_data` || `-DMAGIC_ROM_PTR` || || ARM || `-D__PIC__ -fpic -msingle-pic-base` || (`-D__PIC__` ´Â ÀӽùæÆíÀÌ´Ù) || || SH3 || ` ` || ` ` || || Mips || `-G 0 -mabicalls -fpic` || `-G0 -mno-abicalls -fno-pic` || || Sparc || ` ` || ` ` || || Etrax (cris) || ` ` || ` ` || == ÀúÀÚ == ÀÌ ¹®¼­ÀÇ ÀúÀÚ´Â Phil Wilshire À̸ç [http://www.sysdcs.com/ System Design & Consulting Services (SDCS)] ÀÇ Æ®·¹ÀÌ´× ÇÁ·Î±×·¥ÀÇ ÀϺηΠ»ç¿ëµÇ¾ú´Ù. ---- Please see: [uClinux] ---- CategoryDevelopment