===============================================================
Á¦¸ñ     : 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 <linux/unistd.h>
#include <linux/errno.h>
#include <linux/sched.h>

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 <stdio.h>
#include <linux/unistd.h>

_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 <linux/kernel.h>
#include <linux/module.h>
// À§ µÎ°³´Â ¸ðµâ ÇÁ·Î±×·¥¿¡ ±âº»ÀûÀ¸·Î Ãß°¡µÇ´Â -_-;; Çì´õÆÄÀÏÀÌÁÒ.
#include <sys/syscall.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

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 ¼öÁ¤ ¹× º¸¿Ï
========================================================================