=============================================================== Á¦¸ñ : Linux System Call - ±¸Á¶ ºÐ¼® ¹× °£´ÜÇÑ Syscall ÀÛ¼º ÀÛ¼ºÀÏÀÚ : 2002. 07. 30 ¼öÁ¤ÀÏÀÚ : 2003. 04. 10 ¹®¼­¹öÁ¯ : ver 0.0.5 ¶óÀ̼¾½º : GPL =============================================================== Linux System Call ======================================================= * Áغñ¹° - i386ÀÌ»ó - ¸®´ª½º ¸Ó½Å - ¸®´ª½º source - binutils - glibc.a - nasm * test ȯ°æ - os : redhat linux 6.2 - processor : pentium 2 333mhz - ram : 64mb Àú´Â linux kernel newbie µµ ¸øµÇ¸ç system call À̳ª linux kernel ±¸Á¶¿¡ ´ëÇؼ­µµ Ãʺ¸ ¼öÁØÀÌ´Ï Æ²¸° ³»¿ëÀ̳ª ÀÌ»óÇÑ ³»¿ëÀº ¹Ù·Î ¸ÞÀÏ·Î ¾Ã¾îÁÖ¼¼¿ä. Á¦°¡ °ËÁõ ÈÄ ¹Ù·Î °íÃļ­ ¾÷µ¥ÀÌÆ® ÇÏ°Ú½À´Ï´Ù. ÀÌ ¹®¼­´Â °áÄÚ Á¦ °³ÀÎÀÇ Ã¢ÀÛ¹°À̳ª ±×·±°ÍÀÌ ¾Æ´Ñ ´Ù¸¥ÀÌÀÇ ¹®¼­¸¦ ¹ø¿ª ºÐ¼®ÀÛ¾÷À» ÇßÀ» »ÓÀÔ´Ï´Ù. (¿¹¸¦ µé¸é, linus °¡ linuxÀÇ ±âÃʸ¦ ¼¼¿üÀ¸¸ç, FSF ¿Í °°Àº ÆÀµéÀÌ ÀÌ¹Ì ´ÙÇÑ ÀÛ¾÷µéÀ» ±×Àú °øºÎÇϴ°ÍÀÏ »ÓÀÌÁÒ.) email : osx86@codesum.org ======================================================= 1. Linux Kernel Compile ¿ì¼± system call À» ¸¸µé°í ³ª¸é Ä¿³Î ÄÄÆÄÀÏ¿¡ ´ëÇؼ­ ¾Ë¾Æ¾ß µÇ´Ï±î ´ëÃæ Á¤¸® ÇغýÀ´Ï´Ù. ////////////////////////////////////////////////////////////////////////////////// 1) ½Éº¼¸¯ ¸µÅ© »èÁ¦ rm -rf /usr/src/linux 2) »õ·Î¿î Ä¿³Î ¼Ò½º µð·ºÅ丮¸¦ À§ÇÑ ½Éº¼¸¯ ¸µÅ© »ý¼º mkdir linux-major.minor.patch ls -s linux-major.minor.patch linux 3) Ä¿³Î ¼Ò½º ¾ÐÃàÇ®±â tar xvzf linux-major.minor.patch.tar.gz 4) ¾ÐÃàÀÌ Ç®¸° Ä¿³ÎÀÇ ¹öÁ¯À̸§À¸·Î °æ·Î¸¦ ¹Ù²Ù±â mv linux linux-major.minor.patch 5) »õ·Î¿î Ä¿³ÎÀ» À§ÇÑ ½É¹ú¸¯ ¸µÅ© »ý¼º ¹× È®ÀÎ cd /usr/include rm -rf asm ln -s /usr/src/linux/include/asm-i386 /usr/include/asm ln -s /usr/src/linux/include/linux /usr/include/linux ls -l linux asm lrwxrwxrwx 1 root root 26 1¿ù 17 10:46 asm - /usr/src/linux/include/asm-i386 lrwxrwxrwx 1 root root 28 1¿ù 17 10:45 linux - /usr/src/linux/include/linux 4) ½Éº¼¸¯ ¸µÅ© µð·ºÅ丮¿¡¼­ ±âÁ¸ Ä¿³Î ÀÇÁ¸¼º »èÁ¦ make mrproper 5) Ä¿³Î ¼³Á¤ÀÛ¾÷ make menuconfig or make config 6) Ä¿³Î ¼Ò½º ÆÄÀÏ °£ ÀÇÁ¸¼º°Ë»ç make dep 7) °ú°Å ¿ÀºêÁ§Æ® ÆÄÀÏÀ̳ª ±¸¹öÁ¯ ¼Ò½º ÆÄÀÏ »èÁ¦ make clean 8) Ä¿³Î À̹ÌÁö ¸¸µé±â make zImage (¾ÐÃàÄ¿³ÎÀ» ¸¸µé¶§ ) make bzImage (ÀϹÝÀûÀÎ Ä¿³Î ¸¸µé¶§ ) make bzdisk (Ç÷ÎÇÇ µð½ºÅ©¿¡ ÀúÀåÇÒ Ä¿³Î ) make zlilo (lilo.conf ÀÚµ¿È­ ) ¿Ï¼ºµÈ Ä¿³ÎÀ̹ÌÁöÀÇ À§Ä¡´Â /usr/src/linux/arch/[processor]/boot/bzImage 9. ¸ðµâ ÄÄÆÄÀÏ ¹× ¼³Ä¡ make modules make modules_install 10. lilo ȯ°æ¼³Á¤Çϱâ vi /etc/lilo.conf lineardefault = ±âº»À¸·Î ºÎÆÃÇÒ Ä¿³Î À̹ÌÁö label .... image=/Ä¿³Î PATH/Ä¿³Î À̹ÌÁö À̸§ label = lilo Ä¿¸Çµå·Î ÀνÄÇÒ Ä¿³ÎÀ̸§ read-only root = ·çÆ® ÆÄÀϽýºÅÛ ////////////////////////////////////////////////////////////////////////////////// ( Ä¿³Î ÄÄÆÄÀÏ¿¡ ´ëÇؼ­ ºÎÁ·ÇÏ°Ô ¼³¸íÀÌ µÇ¾îÀÖÀ¸¹Ç·Î, kldp ³ª Ÿ »çÀÌÆ®¿¡¼­ Ä¿³Î ÄÄÆÄÀÏ¿¡ ´ëÇؼ­ ¸ÕÀú ÀÍÇôµÎ¼¼¿ä. ) 2. System Call ±¸ÇöÀ» À§ÇÑ ÇÊ¿ä Áö½Ä 2-1). H/W ÀÎÅÍ·´Æ® - Device -> PIC (ÀÎÅÍ·´Æ® ¹ß»ý) - PIC -> CPU (ÀÎÅÍ·´Æ® ¾Ë¸²) - CPU -> PIC (¾î¶² ÀåÄ¡¿¡¼­ ¹ß»ýÇß´ÂÁö ÁúÀÇ) - PIC -> CPU (ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÑ ÇÉ ³Ñ¹ö¸¦ ¾Ë¸²) - CPU -> Kernel (CPU´Â Çɳѹö°ªÀ» Kernel ¿¡°Ô ¾Ë¸®°í Ä¿³ÎÀº IDT ¿¡¼­ ±×¿Í ¸ÅÇÎµÈ ÀåÄ¡¸¦ ãÀ½) - Kernel -> interrupt function ( ÀÎÅÍ·´Æ® ÇÔ¼ö È£Ãâ ) 2-2). IDT(Interrupt Descriptor Table) ±¸¼º 0x0 ~ 0x1F - Trap Handler 0x20 ~ 0x7F - Interrupt Handler(IRQ) 0x80 - System Call ... 2-3). System Call ±¸ÇöÀ» À§ÇÑ °úÁ¤ ¼³¸íÀÌ ºÎÁ· Çß´ø°Í °°ÁÒ. 2-1) ¿¡ ´ëÇÑ ³»¿ëÀº 8259 PIC(Programmable Interrupt Controller ¿´´ø°¡) Çϴ³𿡠´ëÇؼ­ Á» ã¾Æº¸½Ã¸é ÀÌÇØ°¡ µÉ°Í°°½À´Ï´Ù. ±×¸®°í 2-2) ÀÇ IDT ´Â Intel Architecture Software Developers Manual 3 ¸¦ ÂüÁ¶ÇÏ½Ã¸é µÉ°Í °°±¸¿ä. ¾Æ´Ï¸é i386 ÀÌ»óÀ¸·Î ¾²¿©Áø ½Ã½ºÅÛ °ü·Ã ¼­ÀûÀ̶ó¸é ÀÖÀ»°Ì´Ï´Ù. ¿ì¼± ½Ã½ºÅÛ ÄÝ ÀÛ¼ºÀ» À§Çؼ­´Â ´ÙÀ½°ú °°Àº °úÁ¤À» °ÅĨ´Ï´Ù. System Call Table, Stub À» °íÄ¡°í, ±×¸®°í »õ·Î ¸¸µé System Call ÀÇ À§Ä¡¸¦ Á¤ÇÕ´Ï´Ù. ±× À§Ä¡¿¡ System CallÀ» ±¸ÇöÇÕ´Ï´Ù. ±×¸®°í ³ª¼­ ¸¸µé¾îÁø c ¼Ò½ºÄڵ带 ¹Ì¸®Á¤ÇصР/usr/src/linux/ ÇÏÀ§ µð·ºÅ丮Áß ÇÑ°÷¿¡ ³Ö°í, OBJECT ÆÄÀÏ À̸§À» Á¤ÇØÁÝ´Ï´Ù. ÀÌÁ¦ Ä¿³Î REBUILD¸¦ ÇÏ°í, »õ·Î ¸¸µé¾îÁø Ä¿³Î À̹ÌÁö·Î ºÎÆÃÇÏ°Ô LILO ȤÀº ´Ù¸¥ ºÎÆ®·Î´õ¸¦ ÀÌ¿ëÇØ ¼³Á¤ÇÏ°í, »õ·Î ºÎÆÃÀ» ÇÕ´Ï´Ù. º° ¹®Á¦ ¾øÀÌ ºÎÆÃÀÌ µÇ¾úÀ¸¸é, ±× ½Ã½ºÅÛ ÄÝÀ» ÀÌ¿ëÇÑ ÇÁ·Î±×·¥À» ÀÛ¼ºÇÕ´Ï´Ù. ±×¸®°í ½ÇÇàÇغ¾´Ï´Ù. 3. System Call ±¸Çö ¿ì¼± ¿øÇÏ´Â ¸®´ª½º Ä¿³Î ¼Ò½º(/usr/src/linux)°¡ ÀÖ´Â °÷À¸·Î À̵¿ÇÕ´Ï´Ù. 3-1). System Call Stub System Call Stub ¿¡ »õ·Î »ý¼ºÇÒ ½Ã½ºÅÛ ÄÝ Name°ú Number¸¦ Ãß°¡ÇÕ´Ï´Ù. source: /usr/src/linux/include/asm-[processor]/unistd.h # System Call Stub define ÆÄÀÏ ================================================================================= #ifndef _ASM_I386_UNISTD_H_ #define _ASM_I386_UNISTD_H_ /* * This file contains the system call numbers. */ #define __NR_exit 1 #define __NR_fork 2 #define __NR_read 3 #define __NR_write 4 #define __NR_open 5 #define __NR_close 6 #define __NR_waitpid 7 ... ... #define __NR_sendfile 187 #define __NR_getpmsg 188 /* some people actually want streams */ #define __NR_putpmsg 189 /* some people actually want streams */ #define __NR_vfork 190 // ÀÌ ¾Æ·¡ ÇÑÁÙÀ» Ãß°¡ÇØÁÖ¼¼¿ä #define __NR_mycall 191 ================================================================================= ¸®´ª½º ÇÁ·Î±×·¡¹ÖÀ» Çغ¸¼Ì°Å³ª °ü·Ã ¼­ÀûÀ» º¸¼Ì´ø ºÐµéÀº ¾Ë°Ì´Ï´Ù. Àú´Â -_- ¸ô¶ú½À´Ï´Ù. ÀÌ°Ô ¸Õ°¡... ¿©Æ° ÀÌ ÆÄÀÏ¿¡ stub °ú system call °ü·Ã ÀÎÀÚ¿¡ µû¸¥ ±¸Çö ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ±×·³ stub ¾Æ·§ ºÎºÐÀ» º¼±î¿ä ... ================================================================================= #define _syscall0(type,name) \ type name(void) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name)); \ __syscall_return(type,__res); \ } #define _syscall1(type,name,type1,arg1) \ type name(type1 arg1) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1))); \ __syscall_return(type,__res); \ } #define _syscall2(type,name,type1,arg1,type2,arg2) \ type name(type1 arg1,type2 arg2) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \ __syscall_return(type,__res); \ } #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ type name(type1 arg1,type2 arg2,type3 arg3) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ "d" ((long)(arg3))); \ __syscall_return(type,__res); \ } #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ "d" ((long)(arg3)),"S" ((long)(arg4))); \ __syscall_return(type,__res); \ } #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ type5,arg5) \ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \ __syscall_return(type,__res); \ } ================================================================================= ´ëÃæ ÀÌ·±°ÍµéÀÌ º¸ÀÌÁÒ. Àú·±½ÄÀ¸·Î argument ÀÇ ¼ö¿¡ µû¶ó Àú·± ½ÄÀ¸·Î Á¤ÀÇÇؼ­ ¾´´Ù´Â ÀǹÌÀÔ´Ï´Ù. ¾Æ·¡¿¡ ¶Ç ³ª¿ÃÅ×´Ï ¿ì¼± °£´ÜÈ÷ ¤¾î º¸°í ³Ñ¾î °©½Ã´Ù. Çѳ𸸠Á·Ãĺ¾½Ã´Ù. ================================================================================= #define _syscall2(type,name,type1,arg1,type2,arg2) \ type name(type1 arg1,type2 arg2) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \ __syscall_return(type,__res); \ } ================================================================================= #define _syscall2(type,name,type1,arg1,type2,arg2) \ ¿ì¼± #define À» º¸¸é _syscall2 µÚ¿¡ ¼ýÀÚ 2´Â argument °¡ µÎ°³¶ó´Â ÀÇ¹Ì ÀÔ´Ï´Ù. ±×¸®°í () ¾ÈÀÇ ³»¿ëÀ» Àß º¸½Ã¸é, type Àº system call ÀÇ return data type ÀÔ´Ï´Ù. ±×¸®°í name Àº ¿ì¸®°¡ Á¤ÀÇÇÒ system ÄÝÀÇ À̸§ÀÌ µÇ°ÚÁö¿ä. ¿ì¸®´Â mycall À̶ó°í system call À» ›§À¸´Ï ³ªÁß¿¡ ±¸Çö ÆÄÀÏ¿¡¼­ Àú·±½ÄÀ¸·Î ÇÏ¸é µÈ´Ù´Â ¸»ÀÔ´Ï´Ù. ±×·¸´Ù°í ¿©±â #define ¿¡¼­´Â °íÄ¡½Ã¸é ¾ÈµË´Ï´Ù. ¿©Æ° ±×·¸±¸¿ä. type1 Àº ù¹ø° argumentÀÇ data type ÀÌ µÇ°Ú±¸¿ä. arg1 Àº ù¹ø° argument ÀÇ À̸§ÀÔ´Ï´Ù. ¹¹ ±× µÚ´Â ¼³¸í ¾ÈÇصµ ¾Æ½Ç°Å¶ó ¹Ï±¸¿ä. ÀÌÁ¦ ±× ¹Ø¿¡ ÇÔ¼ö ¾ÈÀ¸·Î µé¾î°¡ º¾½Ã´Ù. long __res; __res ¶ó´Â º¯¼ö¸¦ »ý¼ºÇÏ´Â °Å°ÚÁÒ. __asm__ volatile ("int $0x80" \ ¸Õ°¡ º¹Àⱺ¿ä. ´Ù¸¥°Ç Á¦Ãĵΰí int $0x80 ÀÇ Àǹ̴ IDT TABLE ÀÇ 0x80 ¿µ¿ªÀÇ ¿£Æ®¸®¸¦ ¾´´Ù°í Çϴµ¥ ... °£·«ÇÏ°Ô IDT ¿£Æ®¸®¿¡ ´ëÇØ ¼³¸íÇسí°Ô ÀÖÁÒ. °Å±â º¸½Ã¸é 0x80Àº System Call ÀÔ´Ï´Ù. : "=a" (__res) \ ¸®ÅÏ°ªÀ» __res ¿¡ ÀúÀåÇϱâ À§ÇÔÀÔ´Ï´Ù. : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \ ¿©±â¼­ __NR_##name À̶ó°í ÀÖ½À´Ï´Ù. º¸Åë ½Ã½ºÅÛ ÄÝÀº sys_fork(), sys_exit() ÀÌ·±½ÄÀ¸·Î ±¸Çö µË´Ï´Ù. ÇÏÁö¸¸ »ç¿ë½Ã¿¡´Â fork() ÀÌ·±½ÄÀ¸·Î »ç¿ëÀ» ÇÏÁÒ. ¸Ó ´ëÃæ »ç¼³Àº Á¦Ãĵΰí, __NR_##name Àº À§¿¡ stub ¿¡ Ãß°¡ÇÏ´Â ºÎºÐ¿¡ ¿ì¸®°¡ mycall À̶ó°í ÇßÀ¸´Ï ÀÌ ºÎºÐ°ú ¿¬°èµÇ´Â °ÍÀÔ´Ï´Ù. __NR_mycall À̶õ Àǹ̰¡ µÇ°ÚÁÒ. ¿ä³ðÀÌ eax ·¹Áö½ºÅÍ¿¡ µé¾î°©´Ï´Ù. °á±¹ 191 À̶õ °ªÀÌ eax ¿¡ ÀúÀåÀÌ µÇ´Â°Å°ÚÁÒ. Áõ°Å·Î´Â ÀÌ·±³ðÀÌ Æ÷ÂøµÇ¾ú½À´Ï´Ù. ======================================================= source : glibc -> sysdep.h #define SYS_ify(syscall_name) __NR_##syscall_name #define DO_CALL(args, syscall_name) PUSHARGS_##args DOARGS_##args movl $SYS_ify (syscall_name), %eax; int $0x80 POPARGS_##args ======================================================= DO_CALL Á¤ÀÇ¿¡¼­ µÑ,³Ý.. ³×¹ø° ¶óÀÎÀ» º¸½Ã¸é movl $SYS_ify (syscall_name), %eax; ¿ä·Ð³ðÀÌ º¸À̽ÃÁÒ. syscall_name À» eax¿¡ ÀúÀå -_-;; ±×¸®°í ù¹ø° ÀÎÀÚ´Â ebx, µÎ¹ø° ÀÎÀÚ´Â ecx ¿¡ ÀúÀåÀÌ µË´Ï´Ù. ±×·± ÀǹÌÀÔ´Ï´Ù.(-_-;;; ¶¡»¹»¹) ´ëÃæ stub Àº ÀÌÁ¤µµ·Î ¸¶Ä¡±¸¿ä. ¼³¸íÀÌ ±æ¾ú´Âµ¥ ¿ì¸®°¡ Ãß°¡ÇÑ ³»¿ëÀº ¾Æ·¡ÀÇ ÇÑÁÙ ºÐÀÌÁÒ. #define __NR_mycall 191 3-2). System Call Table ÀÌÁ¦ System Call Table ¿¡ ¿ì¸®°¡ stub ¿¡ Ãß°¡ÇÑ ½Ã½ºÅÛ ÄÝ¿¡ ´ëÇÑ Table Entry ¸¦ ¸¶Âù°¡Áö·Î Ãß°¡ ÇØÁÖ¾î¾ß °ÚÁÒ. source: /usr/src/linux/arch/[processor]/kernel/entry.S # System CallÀ» Table¿¡ µî·Ï ================================================================================= .... ...¾î¼±¸ Àú¼±¸ Àú¿½Ã±¸.... ENTRY(sys_call_table) .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ .long SYMBOL_NAME(sys_exit) .long SYMBOL_NAME(sys_fork) .long SYMBOL_NAME(sys_read) .long SYMBOL_NAME(sys_write) .long SYMBOL_NAME(sys_open) /* 5 */ ... ÀÌ·¯Äô Àú·¯Äô ... .long SYMBOL_NAME(sys_capset) /* 185 */ .long SYMBOL_NAME(sys_sigaltstack) .long SYMBOL_NAME(sys_sendfile) .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ .long SYMBOL_NAME(sys_vfork) /* 190 */ // ¾Æ·¡¿¡ ÀÌ ÇÑÁÙÀ» »ðÀÔÇսôÙ. .long SYMBOL NAME(sys_mycall) /* 191 */ /* * NOTE!! This doesn't have to be exact - we just have * to make sure we have _enough_ of the "sys_ni_syscall" * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ .rept NR_syscalls-190 .long SYMBOL_NAME(sys_ni_syscall) .endr ================================================================================= ¸Ó °¨ÀÌ ¿À½Ã³ª¿ä ... -_-;; ¾È¿Â´Ù¸é ÇÒ¼ö ¾ø±¸¿ä. .long SYMBOL NAME(sys_mycall) /* 191 */ À§¿¡¼­ ÇÏ´ÂÀÏÀÌ ¹«¾ùÀΰ¡ ? ¶ó´Â Áú¹®ÀÌ ½º½º·Î »ý±ä´Ù¸é ¾ÆÁÖ ´ë´ÜÇÑ°Ì´Ï´Ù ¶ó°í ¸»ÇÒÁÙ ¾Ë¾ÒÁÒ... ±×¶§ºÎÅÍ ÇÇ°ïÀÇ ¿¬¼ÓÀÔ´Ï´Ù. ENTRY(sys_call_table) ¿ì¼± ENTRY Àú³ðÀÌ ¾îµð Á¤ÀǵǾî ÀÖ³ª ÇÏ´Ï ... linkage ¶ó´Â ³ð¿¡ Á¤ÀÇ°¡ µÇ¾îÀÖ´õ¶ó±¸¿ä. ===================================== source: include/linux/linkage.h #define SYMBOL_NAME(X) X #define ENTRY(name) \ .globl SYMBOL_NAME(name); \ ALIGN; \ SYMBOL_NAME_LABEL(name) ===================================== ÀÚ¼¼ÇÑ ºÐ¼®Àº ÀÌ ¹®¼­ÀÇ ºÐ¼® 0.0.2 version ¿¡¼­ ÇÏ°Ô µÉ°Ì´Ï´Ù. ´ëÃæ º¸½Ã¸é ENTRY°¡ Àü¿ªÀ¸·Î SYMBOL_NAME(name) À̶õ°É ¼±¾ðÇÏ°í, ¹¹ Àǹ® µ¢¾î¸®ÀÔ´Ï´Ù. ¿ì¼± sys_call_table À̶õ³ðÀ» Àü¿ªº¯¼ö·Î À⳪ºÎ´Ù ÇÏ°í »ý°¢ÇսôÙ. ±×¸®°í ¿ì¸®°¡ »ý¼ºÇÒ ½Ã½ºÅÛ ÄÝ À̸§À» table¿¡ µî·ÏÀ» ÇÕ´Ï´Ù. ¾Æ·¡¿Í °°ÀÌ ... .long SYMBOL NAME(sys_mycall) /* 191 */ ±×¸®°í ENTRY.S ÆÄÀÏÀÇ ¸Ç ¾Æ·¡ ¼¼ÁÙÀ» º¾½Ã´Ù. .rept NR_syscalls-190 .long SYMBOL_NAME(sys_ni_syscall) .endr Àú 190 À̶õ ¼ýÀÚ -_- 191·Î ¹Ù²ã¾ß °ÚÁÒ. ¿©´ãÀÔ´Ï´Ù¸¸ Áß°£Áß°£¿¡ µî·ÏµÈ entry Áß¿¡ sys_ni_syscall À̶ó°í ÀÖ½À´Ï´Ù. Ä¿³Î ´ººñ »çÀÌÆ®¸¦ µÚÁö´Ù º¸´Ï ±¸ÇöÀº ¾ÈµÈ syscall holder ¶ó°í ³ª¿Í ÀÖ´õ±º¿ä. ¾Æ¸¶ Á¦ »ý°¢¿£ ni °¡ not implemented ÀÇ ¾àÀÚ°¡ ¾Æ´Ñ°¡ ÇÏ´Â »ý°¢ÀÌ .. (¾îµð±îÁö³ª Á¦ »ý°¢ÀÏ »ÓÀÔ´Ï´Ù. -_-a) ¹¹ ÀÌÁ¤µµ·Î TABLE¿¡ ¿ì¸®°¡ ¸¸µé System Call ÀÇ µî·ÏÀ» ¸¶ÃƽÀ´Ï´Ù. 3-3) System Call ±¸Çö ¿¹ ¿ì¼± °£´ÜÈ÷ ÀÎÀڵΰ³¸¦ ¹Þ¾Æ ´õÇÏ°í, ±× °ªÀ» ¸®ÅÏÇÏ´Â system callÀ» ÀÛ¼ºÇغ¾½Ã´Ù. (À̳ðÀº ¾ø´Â°Ë´ç -_- ãÁö ¸¶½Ã°í ÀÛ¼ºÇϽñæ...) ============================================ source: /usr/src/linux/kernel/mycall.c #include #include #include asmlinkage int sys_mycall(int x, int y) { return x+y; } ============================================ ±×·³ ¿ì¸®°¡ ÀÛ¼ºÇÑ ½Ã½ºÅÛ ÄÝÀ» Ä¿³Î ÄÄÆÄÀÏÇÒ¶§ °°ÀÌ ÄÄÆÄÀÏ µÇµµ·Ï Makefile À» °íÃľ߰ÚÁÒ. =================================================================== source : /usr/src/linux/kernel/Makefile (¾öÇÑ ´Ù¸¥µ¥ ÀÖ´Â Makefile °íÄ¡Áö ¸¶¼¼¿ä -_-;;) # # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (ie not a .c file). # # Note 2! The CFLAGS definitions are now in the main makefile... .S.s: $(CPP) -traditional $< -o $*.s O_TARGET := kernel.o O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \ module.o exit.o signal.o itimer.o info.o time.o softirq.o \ resource.o sysctl.o mycall.o ifeq ($(CONFIG_MODULES),y) OX_OBJS = ksyms.o endif include $(TOPDIR)/Rules.make sched.o: sched.c $(CC) $(CFLAGS) $(PROFILING) -fno-omit-frame-pointer -c $< =================================================================== O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \ module.o exit.o signal.o itimer.o info.o time.o softirq.o \ resource.o sysctl.o mycall.o À§¿¡ O_OBJS ¶ó°í º¸À̽ÃÁÒ. Á¶±â ¼Â°ÁÙ ³¡¿¡ º¸½Ã¸é mycall.o ¶ó´Â °ÍÀº Á¦°¡ »õ·Î¿î ½Ã½ºÅÛ ÄÝÀ» µî·ÏÇϱâ À§Çؼ­ Ãß°¡ÇÑ ³»¿ëÀÔ´Ï´Ù. ¿©·¯ºÐµµ Ãß°¡ÇϽðí ÀúÀåÇÏ°í ÆÄÀÏÀ» ´Ý½À´Ï´Ù. ±×¸®°í Âü°í·Î 2.4.19 ¹öÁ¯ Ä¿³ÎÀÇ MakefileÀ» º¸´Ï O_OBJS ´Â ¿Âµ¥°£µ¥ ¾ø°í, obj_y ¶ó´Â ³ðÀÌ ÀÖ´õ±º¿ä. 2.4.19 ¹öÁ¯ Ä¿³ÎÀ» ¾²½Ã´Â ºÐµé Âü°í ÇϽñ⠹ٶø´Ï´Ù. (ÀÌÁ¦ ¸ÓÇØ¾ß µÇ´õ¶ó -_-a) ¾Æ Ä¿³Î ¸®ºôµå¸¦ Çؾ߰ÚÁÒ. /usr/src/linux/make bzImage ÀÏÄÉ ÇØÁֽðí, Ä¿ÇÇÇÑÀÜÀ» ÇÏ°í ¿É´Ï´Ù. ¹°·Ð ¿©±â¼­ ¸Õ°¡¸¦ À߸øÇß´Ù¸é ¹®Á¦°¡ »ý±é´Ï´Ù. stub°ú entryÀÇ number°¡ ¸ÂÁö ¾ÊÀ¸¸é ¹®Á¦°¡ »ý±é´Ï´Ù. È®ÀÎÇØÁֽðí, ¶Ç kernel/Makefile ¿¡¼­ O_OBJS ¹Ø¿¡ mycall.c ¶ó°í Àû¾îµÎ½Ã´Â ºÐÀÌ ÀÖ´õ±º¿ä.(Á¢´Ï´Ù ¤Ì.¤Ì) ±×·²°æ¿ì ¾Ë¼ö¾ø´Â ÆÄÀÏ Æ÷¸ËÀ̶ó°í ³ª¿É´Ï´Ù. ÁÖÀÇÇϼ¼¿ä.. ±×¸®°í mycall.c ´Â ¾û¶×Çѵ¥ ÀÛ¼ºÇسõ°í, MakefileÀº kernel/Makefile À» °íÄ¡´Â ºÐµµ °è½Ã´õ±º¿ä. ( À̰͵µ Á¢´Ï´Ù ¤Ì.¤Ì ÇϼöÀÇ ±æÀ̶õ ...) ¸Ó ÀÌÁ¤µµÇßÀ¸¸é º° ÀÌ»ó¾øÀÌ Ä¿ÇǸ¦ ¸¶½Ã°í ¿À½Ã¸é µÉ°Ì´Ï´Ù. ÇÑÂü ±â´Ù¸®¸é ¾î¼±¸ Ä¿³Î À̹ÌÁö°¡ ¿Ï¼ºµÇ¾ú´Ù°í ³ª¿Ã°Ì´Ï´Ù. ¿Ï¼ºµÈ Ä¿³ÎÀ̹ÌÁö´Â /usr/src/linux/arch/[processor]/boot/bzImage ¶ó°í º¸ÀÏ°Ì´Ï´Ù. (À̳ðÀÌ ¾øÀ¸¸é -_-; Àúµµ ¸ð¸§´Ï´Ù ¹º°¡ ¿À·ù°¡ À־ Á¦´ë·Î ¾ÈµÇ¾ú°ÚÁö¿ä.) ÀÌÁ¦ Àú³ðÀ» ¿Å±é½Ã´Ù. Ȥ½Ã ¹®Á¦°¡ »ý±æÁö ¸ð¸£´Ï ¿ø·¡ ÀÖ´ø Ä¿³ÎÀ̹ÌÁö´Â º¸Á¸ÇØµÎ´Â°Ô ÁÁ°ÚÁÒ. mv /usr/src/linux/arch/i386/boot/bzImage /boot/bzImages ¿ì¼± Àú·¸°Ô ¿Å°ÜµÎ°í, lilo.conf ÆÄÀÏÀ» ¼öÁ¤ÇÕ´Ï´Ù. (Àú´Â grupÀ̳ª gag ÀÎÁö ¸ÕÁö ÇÏ´Â°Ç ¾È ½áºÁ¼­ Àß ¸ð¸£°Ú±º¿ä) vi /etc/lilo.conf ÇϽøé liloÀÇ config ÆÄÀÏÀÌ ¿­¸®°ÚÁÒ. ====================================================================== boot=/dev/hda map=/boot/map install=/boot/boot.b prompt timeout=50 linear default=linux image=/boot/vmlinuz-¾î¼±¸ Àú¼±¸ label=linux read-only root=/dev/hda1 // ¾Æ·¡¿¡ ÀÌ·¸°Ô Ãß°¡ÇØÁÖ¼¼¿ä image=/boot/bzImages label=systest read-only root=/dev/hda1 ====================================================================== image=/boot/bzImages <-- À̹ÌÁö ÆÄÀÏÀ̸§°ú path °¡ °°¾Æ¾ßÇÕ´Ï´Ù. label=systest <-- ±×³É alias ÀǹÌÀÇ ¶óº§ÀÔ´Ï´Ù. read-only root=/dev/hda1 ¸®·Î¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº »ý·«Çϵµ·Ï ÇÏ°Ú½À´Ï´Ù. (¿Ö ? Àúµµ Àß ¸ð¸£´Ï±î¿ä ...) ¿©Æ° ÀÌ Á¤µµ·Î Çسõ°í ... ÀÌÁ¦ ÀçºÎÆÃÀ» ÇÕ´Ï´Ù. ºÎÆýà ¸®·Î¿¡ ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÕ´Ï´Ù. lilo : systest Ä¿³Î ¾î¼±¸ Àú¼±¸ Çϸ鼭 ºÎÆÃÀÌ µÇ°ÚÁÒ. ÀÌÁ¦ ºÎÆÃÀÌ ¿Ï·áµÇ¸é ... ¿©±â ±îÁö ¿ì¸®°¡ ÀÛ¼ºÇÑ ½Ã½ºÅÛ ÄÝ Å¾Àç°¡ ³¡³­°ÍÀÔ´Ï´Ù. ÀÌÁ¦ »ç¿ëÀÚ ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ¿©, ½Ã½ºÅÛ ÄÝÀÌ Á¦´ë·Î µ¿ÀÛÇÏ´ÂÁö ¾Ë¾Æº¾½Ã´Ù. ========================================================== # source : /home/ed/test.c #include #include _syscall2(int,mycall,int,x,int,y) int main() { int i; i = mycall(2,3); printf("system call : mycall return -> %d\n",i); return 0; } ========================================================== À§ÀÇ ¼Ò½ºµµ ÀÛ¼ºÇϽô µµÁß¿¡ _syscall2(int,mycall,int,x,int,y) À̳ðÀ» º¸½Ã°í ¾îµð¼­ ¸¹ÀÌ ºÃ´Ù ¶ó°í »ý°¢ÀÌ µå¼Ì´Ù¸é, ¼º°øÀÔ´Ï´Ù. º»¹® ÀúÀ§¸¦ º¸½Ã¸é ... ÀÌ·± ³»¿ëÀÌ ³ª¿ÀÁÒ.. Çѳ𸸠Á·Ãĺ¾½Ã´Ù. ================================================================================= #define _syscall2(type,name,type1,arg1,type2,arg2) \ type name(type1 arg1,type2 arg2) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \ __syscall_return(type,__res); \ } ================================================================================= ¿©±â¼­ _syscall2 À½ ... ÀÌÇØ°¡ °¡½ÃÁÒ. _syscall2(return data type,function name,argument type1,arg1 name,argument type2,arg2 name) À§¿¡¼­ x°¡ ebx ¿¡ y°¡ ecx¿¡ ÀúÀåµÇ´Â°Í ¸¶Á® ÀÌÇØÇÏ¼Ì´Ù¸é ¤Ì.¤Ì Àü ¾ÆÁ÷µµ ÀÌÇØ°¡ Àß ... ±×¸®°í ÇÔ¼öÀÇ Áö¿ªº¯¼ö°¡ __res¿¡ ÀÇÇØ ¸®ÅÏµÈ´Ù´Â°Í ±îÁö ¾Æ¼Ì´Ù¸é ... ¾µµ¥¾ø´Â À̾߱â´Â ±×¸¸ÇÏ°í ÀÌÁ¦ ÄÄÆÄÀÏÇÏ°í ½ÇÇàÀ» ÇغÁ¾ß°ÚÁÒ. ¾Æ ÄÄÆÄÀÏÇϱâÀü¿¡´Â ²À ´ÙÀ½°ú °°ÀÌ ½É¹ú¸¯ ¸µÅ©¸¦ °É¾îÁÖ¼¼¿ä. ¾È±×·¯¸é ¶óÀ̺귯¸®¸¦ ãÀ»¼ö ¾ø´Ù°í ³ª¿Ã°Ì´Ï´Ù. # symbolic link cd /usr/include rm -rf asm ln -s /usr/src/linux/include/asm-i386 /usr/include/asm ln -s /usr/src/linux/include/linux /usr/include/linux ls -l linux asm lrwxrwxrwx 1 root root 26 1¿ù 17 10:46 asm - /usr/src/linux/include/asm-i386 lrwxrwxrwx 1 root root 28 1¿ù 17 10:45 linux - /usr/src/linux/include/linux # compile gcc -o test test.c # execution ./test system call : mycall return -> 5 À§¿Í °°Àº °á°ú¸¦ º¸¼Ì´Ù¸é ¼º°øÇϼ̽À´Ï´Ù. 4. ¹®Á¦Á¡ ³»¿ëÀÌ Âª¾Ò´Âµ¥ ¸ðÀÚ¶õ ºÎºÐµµ ¸¹À» °Å¶ó »ý°¢ÇÕ´Ï´Ù. À¯Àú ÇÁ·Î±×·¥¿¡¼­ ½Ã½ºÅÛ ÄÝÀÇ ÁøÇà°úÁ¤À» Á¤¸®Çغ¸¸é ... ¾Æ·¡¿Í °°ÀÌ µÇ´Â°Í °°½À´Ï´Ù. usertask -> libc.a -> idt -> kernel -> sys_call_table -> real handler ±×¸®°í Á¦°¡ Çغ» ¹Ù·Î´Â entry ¿Í unistd ¿¡ ½Ã½ºÅÛ ÄÝÀÇ °³¼ö°¡ ´Ù¸¥°æ¿ì°¡ ÀÖ´õ±º¿ä. entry.s ¿¡´Â 190°³°¡ Àִµ¥ unistd¿¡ 197 °³°¡ Àֱ淡 °ú°¨È÷ 7°³¸¦ ÁÖ¼®Ã³¸®ÇÏ°í µ¹·ÁºÃ½À´Ï´Ù. Àß µÇ´õ±º¿ä. ÀÌ·± Àú·± ¹æ¹ýÀ¸·Î µ¹·Áº¸½Ã±â ¹Ù¶ø´Ï´Ù. end of [ver 0.0.1] [ver 0.0.2] 5. system call À» ¸ðµâ·Î ÀÛ¼ºÇϱâ 5-1) system call ¸ðµâ ÀÛ¼º ¸®´ª½º¿¡´Â ¸ðµâÀ» kernel space ¿¡ ÀûÀçÇÏ´Â ÁÁÀº ±â´ÉÀÌ ÀÖÁö ¾Ê¾Ò´Â°¡ ? ±×°É ÀÌ¿ëÇØ °£´ÜÇÑ ½Ã½ºÅÛ È£Ãâ ¸ðµâÀ» ÀÛ¼ºÇغ¸ÀÚ. ================================================================= filename : wrapper.c (¼Ò½º¿¡ ÀÌÁÙÀ» Ä¡½Ã´Â ºÐÀÌ ÀÖÀ»±î?) #include #include // À§ µÎ°³´Â ¸ðµâ ÇÁ·Î±×·¥¿¡ ±âº»ÀûÀ¸·Î Ãß°¡µÇ´Â -_-;; Çì´õÆÄÀÏÀÌÁÒ. #include #include #include #include extern void *sys_call_table[]; asmlinkage int(*original_call)(const char *, int, int); asmlinkage int(*getuid_call)(); asmlinkage int sys_our_open(char *fname, int flags, int mode) { printk("%s file is opened by %d\n", fname, getuid_call()); return(original_call(fname, flags, mode)); } int init_module() { // ÇÔ¼ö Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇØ ¿À¸®Áö³¯ sys_open ÀúÀå original_call = sys_call_table[__NR_open]; // ±×¸®°í sys_open ÀÇ ÀÚ¸®¿¡ sys_our_open À¸·Î ´ëÄ¡ sys_call_table[__NR_open] = sys_our_open; // user id °®°í ¿À±â getuid_call = sys_call_table[__NR_getuid]; printk("Module Init!!\n"); return 0; } void cleanup_module() { sys_call_table[__NR_open] = original_call; } //¼Ò½ºÂüÁ¶ : Ä¿³Î ÇÁ·Î±×·¡¹Ö ¼­Àû ================================================================== À§ ÄÚµå´Â sys_call_table ¿¡ µî·ÏµÈ sys_open À» sys_our_open À¸·Î ´ëÄ¡ÇÏ´Â ÇÁ·Î±×·¥ÀÌ´Ù. ¹°·Ð ´Ù¸¥ ½Ã½ºÅÛ Äݵ鵵 °¡´ÉÇÏ´Ù. # compile : wrapper.c gcc -D__KERNEL__ -D_LINUX -DMODULE -O2 -c wrapper.c ÄÄÆÄÀÏÀÌ ¿Ï·áµÇ¸é ÀÌÁ¦ wrapper.o ¶ó´Â ÆÄÀÏÀÌ ÀÛ¼ºµÉ°ÍÀÌ´Ù. ¿©±â¼­ºÎÅÍ´Â ¸ðµâ¿¡ °ü·ÃµÈ ³»¿ëÀ̹ǷΠ¹®¼­Áß¿¡ "Linux Module Programming ±âÃÊ" Àΰ¡ ¸Õ°¡ÇÏ´Â ¹®¼­°¡ -_- ÀÌ È¨ÆäÀÌÁö ¾îµò°¡¿¡ ÀÖÀ»°ÍÀÌ´Ù. ÀÐ°í ¿À±â¹Ù¶õ´Ù. À½³É ¿©Æ° ÀÌÁ¦ ¸ðµâÀ» ¿Ã·Áº¸ÀÚ. # insert module insmod wrapper.o ÀÌ·¸°Ô kernel space¿¡ ¸ðµâÀ» ¿Ã¸®°Ô µÇ¸é, init_module ÀÌ ½ÇÇàµÇ°í, ±× ÀÌÈÄ ¾î¶² ÆÄÀÏÀ» ¿­°ÔµÇ¸é, ±× ÆÄÀÏ À̸§ÀÌ ¹«¾ùÀ̸ç, ÆÄÀÏÀ» ¿¬ user id °¡ »Ñ·ÁÁö°Ô µÉ°ÍÀÌ´Ù. ¾Æ¸¶µµ root °¡ ½ÇÇàÀ» Çß´Ù¸é, ´ÙÀ½°ú °°ÀÌ ... ¸»ÀÌ´Ù. Module Init!! /etc/localtime file is opened by 0 ... ... ... ÀÌ·¸°Ô ºñ½ÁÇÏ°Ô ³ª¿Â´Ù¸é Á¤»óÀûÀ¸·Î system call ¾÷¾îÄ¡±â¿¡ ¼º°øÇÑ°ÍÀÌ´Ù. ÀÌÁ¦ ¸ðµâÀÌ ¿Ã¶ó°¬´ÂÁö È®ÀÎÀÌ µÇ¾úÁö¸¸ ±×·¡µµ Çѹø È®ÀÎÇغ¸ÀÚ # list module lsmod ¶ó°í ¿£ÅÍÄ¡´Â ¼ø°£ -_-;; ¸ðµâ ¸®½ºÆ®¸¦ º¸¿©ÁÖ±âÀ§ÇØ Ä¿³ÎÀÌ ¾î¶² ÆÄÀÏÀ̵ç system call ÀÎ sys_open À» È£ÃâÇϸé sys_our_open À¸·Î ¸ÕÀú È£ÃâµÇ¾î ¶ß°Ô µÉ°ÍÀÌ´Ù. À§¿¡¼­ insmod ÇßÀ»¶§ ó·³ ÆÄÀϸíÀ» ¾î¶² uid¸¦ °¡Áø »ç¶÷ÀÌ ¿­¾ú´ÂÁö °¡¸¸È÷ ³öµÖµµ ½Ã½ºÅÛÀº ¾î¶² ÆÄÀϵéÀ» ¿­±âÀ§ÇØ sys_open À» sys_call_table ¿¡¼­ È£ÃâÇÏ°Ô µÇÁö¸¸, °á±¹ sys_our_open À» ¼± È£ÃâÇÑÈÄ¿¡ sys_open À» È£ÃâÇÏ°Ô µÇ´Â°ÍÀÌ´Ù. ½ÉÁö¾î ls ¶ó´Â ¸í·ÉÀ» ¼öÇàÇصµ ¹«½¼ ÆÄÀÏÀ» ¿©´ÂÁö Æ¢¾î ³ª¿Â´Ù. °è¼Óº¸´Ù°¡´Â -_-;;; ¾îÁö·´´Ù. ±×³É ÀÌÁ¦ ¸ðµâÀ» kernel space¿¡¼­ ³»¸®ÀÚ ... # release module rmmod wrapper ³¡³ª¸é¼­µµ ¸¶Áö¸·À¸·Î ¹ß¾ÇÀ» ÇÏ´Â sys_our_open À» º¼¼ö ÀÖÀ»°ÍÀÌ´Ù. ÀÌÁ¦ºÎÅÍ´Â sys_our_open ÀÌ sys_open ÀÇ ¾Õ±æÀ» ¸·´ÂÀÏÀº ¾øÀ»°ÍÀÌ´Ù. Á¤»óÀûÀ¸·Î sys_open ¸¸ÀÌ È£ÃâµÇ°Ô µÈ´Ù. 6. ¾î¼Àºí¸® ¾ð¾î·Î ½Ã½ºÅÛ ÄÝ È£ÃâÇϱâ ÀÌ ³»¿ëÀº ÀÌ ¹®¼­ 2-2 ¿¡ ³ª¿À´Â ÀÎÅÍ·´Æ® µð½ºÅ©¸³ÅÍ Å×À̺í(IDT)¿¡ ³ª¿Â ³»¿ëÀ» ½ÇÁ¦·Î ¾î¼Àºí¸® ¾ð¾î¸¦ »ç¿ëÇؼ­ ÀÎÅÍ·´Æ® È£ÃâÇÏ¿© ¹®ÀÚ¸¦ Ãâ·ÂÇÏ´Â ÇÔ¼ö¸¦ ÀÛ¼ºÇÏ°í, ¹®ÀÚ¿­À» Á¤ÀÇÇÏ´Â ÇϳªÀÇ c ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿©, µÑÀ» µ¿½Ã¿¡ ¸µÅ©ÇÏ¿© ¾î¼Àºí¸® ¾ð¾î·Î ¾î¶»°Ô ½Ã½ºÅÛ ÄÝÀ» »ç¿ëÇϴ°¡¿¡ ´ëÇÑ ³»¿ëÀÔ´Ï´Ù. 6-1. ¶óÀ̺귯¸® µ¶¸³ÀûÀÎ Hello World ÇÁ·Î±×·¥ ÀÛ¼ºÇϱ⠴ëºÎºÐÀÇ C ÇÁ·Î±×·¡¸ÓµéÀº ¹®ÀÚ¿­ Ãâ·ÂÀ» À§Çؼ­ printf ³ª fprintf ¸¦ »ç¿ëÇÕ´Ï´Ù. ¹°·Ð, À̵éÀº GNU libc ¿¡ ÀÇÇØ Á¦°øµÇ´Â Ç¥ÁØ ¶óÀ̺귯¸® ÇÔ¼ö ÀÔ´Ï´Ù. ¾î¼Àºí¸® ¾ð¾î¿¡¼­ ÀÌ·± Ãâ·Â ·çƾÀ» Áö¿øÇÏ°Ô Çϱâ À§Çؼ­ xputchar() ¶ó´Â ÇÔ¼ö¸¦ »ý¼ºÇß½À´Ï´Ù. xputchar.asm (write ½Ã½ºÅÛ ÄÝÀ» »ç¿ëÇØ ¹®ÀÚ¿­À» Ãâ·ÂÇÏ´Â ÄÚµå) ====================================================================== ; N A M E : x p u t c h a r . a s m ; ; D E S C : putchar() by assembly ; ; A U T H : Wataru Nishida, M.D., Ph.D. ; wnishida@skyfree.org ; http://www.skyfree.org ; ; M A K E : nasm -f elf xputchar.asm ; ; V E R S : 1.0 ; ; D A T E : Dec. 17, 2000 ; bits 32 ; 32bit ¸ðµå »ç¿ë ; ¿©±â¼­ºÎÅÍ code ½ÃÀÛ section .text ; GCC ÀÇ .text ¼½¼Ç¿¡¼­ Äڵ尡 ½ÃÀÛ global xputchar ; Àü¿ª ÇÔ¼öó·³ xputchar() ¼±¾ð ; ; x p u t c h a r ; ; int xputchar (unsigned int ch) ; ; --- return one (success) or -1 (error) ; ; Dec. 17, 2000 xputchar: push ebp ; EBP ¸¦ ½ºÅÿ¡ PUSH mov ebp, esp ; xputchar ÀÚü ½ºÅà ÇÁ·¹ÀÓÀÇ Áغñ ; [ebp] °¡ ÀúÀåµÈ EBP ¸¦ °¡¸®Å°°Ô ÇÏ°í, ; [ebp+4] °¡ º¹±Í ÁÖ¼Ò¸¦ °¡¸®Å°°Ô ÇÔ ; EAX,ECX,EDX ¸¦ Á¦¿ÜÇÑ ·¹Áö½ºÅ͸¦ º¸Á¸ push ebx ; Save EBX. ; 1 ¹ø° ¾Æ±Ô¸ÕÆ®´Â [ebp+8]¿¡ 2¹ø° ¾Æ±Ô¸ÕÆ®´Â [ebp+12] ¿¡ ... mov eax, [ ebp + 8 ]; ¹®ÀÚÄÚµå ¾ò¾î¿À±â mov [ msgbuf ], al ; ÀúÀåÇϱâ mov edx, 1 ; ¹®ÀÚÄ«¿îÆ® ¼³Á¤ mov ecx, msgbuf ; ¹öÆÛ Æ÷ÀÎÅÍ ¼³Á¤ mov ebx, 1 ; Ç¥ÁØ Ãâ·Â(STDOUT) ¼³Á¤ mov eax, 4 ; sys_write ½Ã½ºÅÛ ÄÝ È£Ãâ int 0x80 ; IDT ÀÇ 0x80( ½Ã½ºÅÛ ÄÝ È£ÃâÀ» À§ÇÑ ÀÎÅÍ·´Æ®) pop ebx ; EBX º¹±¸ ½ÃÅ°±â leave ; ESP¿Í EBP ¸¦ °°°Ô ÇÏ°í, ½ºÅÿ¡¼­ pop Çؼ­ EBP·Î ret ; º¯¼ö½ÃÀÛÀ» À§ÇÑ ÀúÀå °ø°£Àº ¿©±â¼­ ºÎÅÍ ... section .data ; GCC ÀÇ .data ¼½¼Ç¿¡ º¯¼öÀûÀç msgbuf db 0 ; ¸Þ½ÃÁö ¹öÆÛ ====================================================================== xputchar() ÇÔ¼ö´Â ¾Æ±Ô¸ÕÆ® 3°³¸¦ »ç¿ëÇÏ´Â "write" ½Ã½ºÅÛ ÄÝ(ÇÔ¼ö ¹øÈ£ 4¹ø)À» ½ÇÇà½ÃŲ´Ù. write ÀÇ Ã¹¹ø° ¾Æ±Ô¸ÕÆ®´Â ÆÄÀÏ µð½ºÅ©¸³Å͸¦, µÎ¹ø°´Â ½ºÆ®¸µ ¹öÆÛ Æ÷ÀÎÅ͸¦ ¸¶Áö¸·Àº ¹®ÀÚ¿­ÀÇ ±æÀ̸¦ ³ªÅ¸³½´Ù. ÀÌ ÇÁ·Î±×·¥¿¡¼­´Â STDOUT(Ç¥ÁØ Ãâ·Â)À» ÇϳªÀÇ ÆÄÀÏ µð½ºÅ©¸³ÅÍ Ã³·³ »ç¿ëÇÑ´Ù. Àӽà ¹öÆÛ¸¦ À§ÇØ static º¯¼öÀÎ msgbuf ¸¦ .data ¼½¼Ç¿¡ Á¤ÀÇÇÏ°í, ¹®ÀÚ¿­ Ãâ·ÂÀ» ¿øÇÑ´Ù¸é, strlen ÇÔ¼ö¸¦ »ý¼ºÇؾ߸¸ ÇÑ´Ù. À§ÀÇ Äڵ带 Àߺ¸½Ã¸é Á¦°¡ 3Àå 3-1Àý¿¡¼­ ¼³¸íÇß´ø ³»¿ë°ú À¯»çÇÏÁÒ. xputchar ¼Ò½ºÄÚµå Çϴܺθ¦ º¸½Ã¸é mov edx, 1 mov ecx, msgbuf mov ebx, 1 mov eax, 4 int 0x80 °¡ º¸À̽ÃÁÒ. mov eax, 4 °¡ ½Ã½ºÅÛ ÄÝ ½ºÅÓÀÇ ¹øÈ£¸¦ °¡¸®Åµ´Ï´Ù. µû¶ó¼­ 4¹ø ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇÏ°Ú´Ù´Â À̾߱Ⱑ µË´Ï´Ù. ±×¸®°í ±× ¹Ù·Î À§¿¡ mov ebx, 1 ÀÌ º¸À̽ÃÁÒ. ebx ¿¡´Â eax °¡ °¡¸®Å°´Â ÇØ´ç ½Ã½ºÅÛ ÄÝÀÇ Ã¹¹ø° ¾Æ±Ô¸ÕÆ®¸¦ ÀúÀåÇÏ°Ô µÈ´Ù°í Çß¾úÁÒ. ebx ¿¡ 1À» ³Ñ°ÜÁÖ¾úÀ¸´Ï ÆÄÀÏ µð½ºÅ©¸³Åʹ ǥÁØÃâ·ÂÀÌ µË´Ï´Ù. ( ¾Æ¸¶µµ stdin ÀÌ 0 stderr ÀÌ 2 ·Î ±â¾ïµË´Ï´Ù¸¸ Çѹø Å×½ºÆ® Çغ¸¼¼¿ä.) ecx ¿¡´Â eax °¡ °¡¸®Å°´Â ½Ã½ºÅÛ ÄÝÀÇ µÎ¹ø° ¾Æ±Ô¸ÕÆ®¸¦ ÀúÀåÇÏÁÒ. ecx ¿¡ ¹®ÀÚ¿­ ¹öÆÛ Æ÷ÀÎÅ͸¦ ³Ñ°ÜÁÖ¾ú°í, edx ¿¡´Â ¼¼¹ø° ¾Æ±Ô¸ÕÆ®¸¦ ÀúÀåÇϴµ¥ ¸¶Áö¸·Àº ¹®ÀÚ¿­ÀÇ ±æÀÌÁÒ. ±×¸®°í ¸¶Áö¸·À¸·Î int 0x80 ÀÎÅÍ·´Æ® È£ÃâÀ» ÇÏ°Ô µÇ´Âµ¥, IDT ¿¡ Á¤ÀÇµÈ ½Ã½ºÅÛ ÄÝ ÀÎÅÍ·´Æ® È£ÃâÀÔ´Ï´Ù. ÀÌ·¸°Ô ÀüüÀûÀ¸·Î ÀÛ¼ºµÈ Äڵ带 global xputchar ·Î Á¤ÀÇÇÏ¿© c ¿¡¼­ ºÒ·¯ ¾µ¼ö ÀÖ°Ô Àü¿ªÇÔ¼ö·Î ¸¸µì´Ï´Ù. ±Ùµ¥ main ÇÔ¼ö Á¾·á¸¦ À§ÇÑ Äڵ嵵 ÀÛ¼ºÇØ¾ß °ÚÁÒ. xexit.asm ============================================ bits 32 section .text global xexit xexit : mov ebp, esp mov ebx, [ebp+4] mov eax, 1 int 0x80 ============================================ ÀÌ È£ÃâÀº c ·Î ÀÛ¼ºÇÒ ÇÁ·Î±×·¥ÀÇ Á¾·á¸¦ À§ÇÑ ½Ã½ºÅÛ ÄÝ sys_exit¸¦ È£ÃâÇÏ¿©, ÇÁ·Î±×·¥À» Á¾·á½ÃÅ°´Â ÇÁ·Î±×·¥ ÀÔ´Ï´Ù. ¿ø¸®´Â À§ÀÇ xputchar¿Í °°ÁÒ. hello.c ============================================ extern int xputchar(unsigned int); extern int xexit(int); main(){ char msg[]="Hello World!\n"; char *ptr; int res; ptr = msg; while (*ptr) res = xputchar(*ptr++); xexit(128); } ============================================ ÀÌ ÇÁ·Î±×·¥¿¡¼­ ¿ì¸®°¡ ¾î¼Àºí¸® ¾ð¾î¸¦ »ç¿ëÇÏ¿©, write ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇÏ°Ô ÀÛ¼ºÇÑ xputchar ¸¦ »ç¿ëÇØ "Hello World!" ¸¦ Ãâ·ÂÇÏ°Ô µË´Ï´Ù. ÀÌ c ÇÁ·Î±×·¥Àº ´Ü¼øÇÏ´Ï Çѹø ÀÛ¼ºÇغ¸¼¼¿ä. 6-2. build ÀÛ¾÷°ú ÇÁ·Î±×·¥ ½ÇÇàÇϱâ # xputchar.asm , xexit ÀÇ make $ nasm -f elf xputchar.asm (elf Æ÷¸ËÀ» °®´Â xputchar.o ÆÄÀÏ »ý¼ºµÊ) $ nasm -f elf xexit.asm (elf Æ÷¸ËÀ» °®´Â xexit.o ÆÄÀÏ »ý¼ºµÊ) # hello.c ÀÇ compile $ gcc -c hello.c (hello.o ¶ó´Â ¸ñÀûÄÚµå »ý¼ºµÊ) # À§ÀÇ ÄÄÆÄÀÏÀ» ÅëÇØ »ý¼ºµÈ hello.o ÆÄÀÏ°ú xputchar.o ÆÄÀÏÀ» ÀÌ¿ëÇØ ¸µÅ©Çϱâ $ ld -s -e main -o hello hello.o xputchar.o xexit.o (hello.o xputchar.o xexit.o ÆÄÀÏÀ» »ç¿ëÇØ hello ¶ó´Â ½ÇÇà ÄÚµå·Î ¸µÅ©ÇϵÇ, ¿£Æ®¸® Æ÷ÀÎÆ®(-e)´Â main ÇÔ¼ö¿¡¼­ ½ÃÀÛÇÏ°Ô ÇÏ°í, -s ¿É¼ÇÀ» ÁÖ¾î ºÒÇÊ¿äÇÑ ¼½¼Ç ½É¹ú Å×À̺í Á¦°Å) # ºÒÇÊ¿äÇÑ ¼½¼Çµé Á¦°ÅÇϱâ $ strip --remove-section=.comment --remove-section=.note hello (hello ÆÄÀÏÀÇ comment ¼½¼Ç°ú note ¼½¼Ç Á¦°Å ) # °øÀ¯ ¶óÀ̺귯¸® ÀÇÁ¸¼º Ãâ·ÂÇؼ­ È®ÀÎ $ ldd hello statically linked (ELF) ¶Ç´Â not a dynamic executable # »ý¼ºµÈ ÆÄÀϵé ======================================================================= $ ls -l total 25 drwxr-sr-x 2 root src 208 Jan 6 22:03 . drwxr-sr-x 4 root src 96 Jan 6 21:57 .. -rwxr-xr-x 1 root src 676 Jan 6 22:03 hello -rw------- 1 root src 196 Jan 6 22:02 hello.c -rw-r--r-- 1 root src 1040 Jan 6 22:02 hello.o -rw------- 1 root src 1360 Jan 6 21:31 xexit.asm -rw-r--r-- 1 root src 512 Jan 6 21:31 xexit.o -rw------- 1 root src 1360 Jan 5 18:49 xputchar.asm -rw-r--r-- 1 root src 704 Jan 5 18:49 xputchar.o ======================================================================= # ÇÁ·Î±×·¥ÀÇ ½ÇÇà $ ./hello ; echo $? Hello World! 128 À§ÀÇ ld ¿¡¼­ -s ¿É¼ÇÀº ÀÚµ¿ÀûÀ¸·Î ½É¹ú Å×ÀÌºí ¼½¼ÇÀ» Á¦°ÅÇÏ°Ô ÇÕ´Ï´Ù. ¿Ï¼ºµÈ ÇÁ·Î±×·¥Àº ¶óÀ̺귯¸® µ¶¸³ÀûÀ̸ç, ±× Å©±âµµ 676 ¹ÙÀÌÆ®°¡ µË´Ï´Ù. °á±¹, Ç¥ÁØ È¯°æÀÇ µµ¿ò¾øÀÌ ¸®´ª½º Ä¿³ÎÀ» ¿ÏÀüÈ÷ ÄÁÆ®·Ñ ÇÏ°Ô µÇ¾úÁÒ. (À§ÀÇ build ½Ã ¿É¼ÇµéÀÌ ÇÏ´Â ÀÏÀÌ ¹«¾ùÀÎÁö Á»´õ ÀÚ¼¼È÷ ¾Ë°í ½ÍÀ¸½Ã´Ù¸é, C Calling Convention ¹®¼­¿Í elf Æ÷¸Ë¹®¼­¸¦ ÂüÁ¶Çϼż­ Àо½Ã¸é µÉ°Í °°³×¿ä.) ÃàÇÏÇÕ´Ï´Ù. ÇÏÁö¸¸ ÀÌ°Ç ½ÃÀÛÀÏ »ÓÀÌÁÒ. ^^ 7. Á¤¸® Ä¿³Î ¸®ºôµå´Â ½Ã°£ÀÌ Á¶±Ý °É¸³´Ï´Ù. ¸ðµâ ÇÁ·Î±×·¡¹ÖÀ¸·Î Å×½ºÆ® Çغ»ÈÄ ÃÖÁ¾ÀûÀ¸·Î Ä¿³Î ¸®ºôµå¸¦ ÇÏ´Â°Ô ÁÁ°Ú´Ù´Â \n´ÔÀÇ ÀÇ°ß¿¡ µû¶ó ÀÌ·¸°Ô ¹®¼­¸¦ ¾÷µ¥ÀÌÆ® Çß½À´Ï´Ù. À§ÀÇ ½Ã½ºÅÛÄÝ µ¤¾îÄ¡±â ¿Ü¿¡ Çϳª¸¦ ´õ Ãß°¡ÀûÀ¸·Î Àç¹Ì·Î ¸¸µé¾îºÁµµ µÇ°Ú½À´Ï´Ù. ½Ã°£ÀÌ ³¯¶§... ¿À·£¸¸¿¡ ¿Ã¸®´Â ÀÚ·á¶ó ÁöÁ®ºÐÇÑ ¸éÀÌ ¸¹±º¿ä... ¾Æ¹«ÂÉ·Ï ÀÌÇØÇØÁֽñ⠹ٶø´Ï´Ù. ¿©Æ° ÀоîÁּż­ °¨»çµå¸³´Ï´Ù. _(__)_ ======================================================================== * Change Log (bout Documentation) - v 0.0.5 (2003.04.10) : ¾î¼Àºí¸® ¾ð¾î¸¦ ÀÌ¿ëÇÏ¿© C ÇÁ·Î±×·¥°ú ÇÔ²² ¸µÅ©ÇÏ¿© ½Ã½ºÅÛÄÝÀ» ¾î¶»°Ô ¾î¼Àºí¸® ¾ð¾î¸¦ »ç¿ëÇØ Á¦¾îÇÏ´ÂÁö¿¡ ´ëÇÑ ³»¿ë (ÂüÁ¶ : http://www.skyfree.org/linux/assembly/section6.html) - v 0.0.4 : ½Ã½ºÅÛ ÄÝÀ» ¸ðµâ·Î ÀÛ¼ºÇÏ¿© »ç¿ëÇÏ´Â ¹æ¹ý - v 0.0.3 : Ä¿³Î ÄÄÆÄÀϺκРerrata ¼öÁ¤ ¹× º¸¿Ï ========================================================================