2015.03.13 17:16



모듈과 커널 버전

모듈은 커널 버전과 관련이 많습니다. 커널 버전에 맞춰서 모듈이 빌드되며, 커널의 버전과 모듈의 버전이 일치해야만 이용할 수 있습니다. 커널 소스에서 커널의 버전은 include /linux/version.h에서 확인할 수 있습니다.

#define UTS_RELEASE "2.6.14.6"
#define LINUX_VERSION_CODE 132622
#define KERNEL_VERSION(a,b,c) (((a) << 16 ) + ((b) <<8)  +  (c))

따라서, 특정 버전 이상에서만 동작하는 모듈이라던가, 커널 버전에 따라 다르게 동작하는 모듈을 작성하고 싶다면 이를 활용해서 다음과 같은 코드를 작성할 수 있습니다.

#if LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 10)
MODULE_PARM( user_name, "charp");
#else
MODUILE_PARM( user_name, "s");
#elseif

MODULE_PARM()의 의미나 사용법은 나중에 설명을 한다. 여기서는 VERSION_CODE와 KERNEL_VERSION()사용한 방식만 이해하면 됩니다. KERNEL_VERSION()은 커널 버전 번호를 받아서 정수값으로 만들어 줍니다.  해당하는 커널 버전을 미리 정수 값으로 만들어둔 것이 LINUX_VERSION_CODE이고, 이것은 모든 커널에 선언되어 있습니다.

모듈과 static 선언

모듈 안에서만 사용되는 변수나 함수에는 static 키워드가 선언되어 있습니다. static은 메모리 내에 정적으로 위치하게 만드는 할을 하기 때문에 해당 소스 코드 내에서 전역으로 사용될 수 있습니다. 변수에 사용되면 전역변수가 되며, 함수에 사용되면 전역 함수가 되겟지요. 실제로 .c 코드 안에서 사용되는 모든 C 함수나 함수 바깥에 선언된 변수는 어디서나 상ㅇ할 수 있기 때문에 어떤 의미로는 항상 전역이라고 할 수 있습니다. 함수나 전역 변수에 사용된 static 의 다른 의미는 다른 .c소스 코드에서 접근할 수 없게하는 범위 지정자 입니다.

리눅스 커널은 커널 전체가 하나의 프로그램입니다. 그러니까 같은 이름을 가진 변수나 함수를 만들 수 없습니다. 누군가 A라는 모듈에서 hello()함수를 작성해서 커널 영역에 로드했다면, 또 다른 hello() 함수를 가진 모듈 B는 로드 할 수 없게 됩니다. 이 함수가 모듈 안에서만 사용되고, 다른 커널에서 참조할 필요가 전혀 없다면 이런 파일들은 커널 영역에서 보이지 않게 해야 합니다. 때문에 static을 사용합니다. init_module()과 cleanup_module()함수는 다소 예외적인 경우로는 이 함수는 static을 사용하지 않아도 커널 영역에 공개 되지 않습니다. 실제로, 이들 함수는 __init_module_inline()과 __exit_module() 함수는 다소 예외적인 경우로 이 함수는 static을 사용하지 않아도 커널 영역에 공개 되지 않습니다.  실제로 이들 함수는 __init_module_inline()과 __exit_module_inline() 같은 인라인 함수로 대체되어 실행되고, 이들 함수는 모두 static으로 선언되어 있기 때문에 커널 영역에서 공개되지 않습니다. 커널 영역에 공개된 함수는 /proc/ksyms(2.4커널) 이나 /proc/kallsysms(2.6커널)에서 확인 할 수 있습니다.

typedef int (*__init_module_fun_t)(void)
                            └ init_module()의 원형
typedef void (*__cleanup_module_func_t)(void);
#define module_init(x) \              └ cleanup_module()의 원형
   int init_module(void) __attribute__(alias(#3))); \
   static inline _init_module_func_t __init_module_inline(void) \
    └  커널 영역에 고액되지 않는 지역 함수로 선언됩니다.
   {  return x; }

#define module_exit (x) \
  void cleanup_module(void) __attribute__((alias(#x))); \

  static inline __cleanup_module_func_t__cleanup_module_inline(void) \
    └  커널 영역에 고액되지 않는 지역 함수로 선언됩니다.
  { return x; }
static으로 선언되어 있으면, 외부 C 소스 코드에서 extern 선언으로 참조할 수 없습ㄴ디ㅏ. 2.5 커널에서는 모듈 내에서 static 없이 선언된 함수는 커널 영역에 공개되었지만 2.6에서는 공개되지 않았습니다.

모듈과 커널 심볼

모듈은 커널 영역에서 실행되기 때문에 표준 C 함수들은 사용할 수 없습니다. 대신에, 커널 영역에서 사용할 수 있는 함수나 자료 구조의 목록을 커널에서 제공합니다. 이 목록은 2.4 커널에서는 /proc/ksyms, 2.6 커널에서는 /proc/kallsyms를 통해 제공합니다. printk()함수도 커널 심볼 파일에서 확인할 수 있습니다.

2.6 커널의 심볼

# grep printk /proc/kallsyms
.........     ┌ 심폴의 타입 정보
c011d6b0  T printk
c011d6b0  T vprintk
c011d6b0  T __printk_ratelimit
........                               ┌ 심폴의 타입 정보
c011d6b0  U printk        [vmhgfs]
c011d6b0  U printk        [vmxnet]
      |            └ 심볼 이름
                 └ 심볼 이름

심볼 타입

설명

A

절대 주소로 변경되지 않음

B

bss 영역의 심볼

C

공용 심볼로 초기화되지 않은 변수를 의미

D

data 영역의 심볼로 초기화된 변수를 의미

R

rdata 영역, 즉 읽기 전용변수를 의미

T

text 영역의 심볼로 함수를 의미

U

해당 모듈에서 정의하지 않은 (undefined) 심폴을 의미

I

다른 심볼에 대한 간접(Indirect) 참조를 의미하는 GNU 확장

N

디버깅 심볼

- 심볼의 타입 -

printk() 함수를 사용하는 모듈이 있으면 printk()함수를 이용하는 모듈 이름과 함께 printk()에 대한 심볼 타입이 "U"로 나타납니다. 직접 작성한 모듈에서 printk() 함수를 정의한 것이 아니기 떄문에 그렇습니다. 심볼 타입이 대문자로 사용되면 전역 심볼을 의미하고, 소문자로 되어 있으면 지역 심볼을 의미합니다.


심볼 : 2.4와 2.6의 차이

2.4 커널에서는 모듈 안에서 static으로 선언되지 않은 함수들이 모두 커널 심볼로 공개되어 있습니다. 2.6커널에서는 static으로 선언되지 않은 함수여도, 커널 심볼로 등록 하지 않으면 공개되지 않게 변경되었습니다.

커널 심볼로 공개시키는 방법은 EXPORT_SYMBL()이나 EXPORT_SYMBOL_GPL()과 같은 매크로를 사용해서 공개할 심볼을 지정하기만 하면 됩니다. printk() 함수의 경우 kernel/printk.c 에서 다음과 같은 부분을 확인할 수 있습니다.

kernel/printk.c

EXPORT_SYMBOL(printk);

이와 같이 정의되어 있기 때문에 외부 심볼로 공개되어 있으며, 커널이나 모듈 내에서 자유롭게 사용할 수 있습니다.

2.4 커널의 심볼
[/usr/src/linux-2.4.x.x #] grep printk /proc/ksyms

       ┌ 커널 내 심볼의 시작 주소
c0114aa0 printk_R1b7d4074
                       
└ 커널 버전과 심볼의 CRC 정보를 합한 값

2.6 커널의 /proc/kallsyms에서는 버전 정보를 제공하지 않습니다.
심볼과 관련된 매크로는 include/linux/module.h에 정의되어 있으며 알아야 될 것은 다음과 같습니다.

종류

설명

EXPORT_SYMBOL(var)

심볼을 공개합니다.

EXPORT_SYMBOL_NOVERS(var)

심볼을 버전정보 없이 공개합니다.

EXPORT_SYMBOL_GPL(var)

EXPORT_SYMBOL과 동일 하지만 GPL과 호환되는 라이선스로 등록한 모듈에서만 심볼을 볼 수 있습니다.

EXPORT_NO_SYMBOLS

모듈 내에서 어떤 심볼도 공개하지 않음을 정의합니다.

 - 심볼 매크로  -

EXPORT_NO_SYMBOLS는 모듀 내의 어디서나 한 줄만 넣어주면 되며, 해당 모듈에서 어떤 심볼도 공개하지 않음을 의미합니다. EXPORT_SYMBOL_GPL()은 MODULE_LICENSE()과 관련이 깊습니다.

모듈의 라이선스

리눅스 커널은 GPL라이선스를 따릅니다. 그리고 GPL 라이선스가 적용된 소스 코드를 수정한 경우 수정된 소스 코드를 공개해야 합니다. 일부 업체들은 오픈 소스를 이용해서 제품을 개발하지만 수정된 소스 코드를 공개해야 합니다. 일부 업체들은 오픈 소스를 이용해서 제품을 개발하지만 수정된 소스 코드를 공개하지 않아 물의를 사기도 했습니다. 매년 라이선스와 관련된 분쟁이 증가하고 있습니다. 때문에 모듈에서도 제작자가 원하는 라이선스를 지정하도록 했으면, 이 라이선스를 지정하지 않으면, 오픈소스인 커널에 상업적인 코드가 추가될 수 있고, 이는 커널의 오픈 소스를 위배할 수 있다는 경고를 보여줍니다.

module license 'unspecified' taints kernel.

현재 까지는 MODULE_LICENSE()를 통해 라이선스를 명시하지 않아도 문제는 없지만, 이런 라이선스 논쟁 이후 EXPORT_SYMBOL_GPL()이 추가 되었습니다. 이는, GPL과 호환되는 라이선스를 지정하지 않은 모듈에서는 커널의 기능을 사용할 수 없게 하는 정책을 추가하기 위한 것으로, 현재 이와 관련된 불이익은 없지만, 필요한 경우 GPL 호환 라이선스를 따르지 않는 상업적 코드들은 GPL코드를 이용할 수 없게 하기 위한 조치를 반영한것입니다.

MODULE_LICENSE()를 통해 지저앟ㄹ 수 있는 라이선스는 다음과 같다.

라이선스 종류

의미

GPL

GNU Public License v2 또는 이상

GPL v2

GNU Public License v2

GPL and additional rights

GNU Public License v2 right and more

Dual BSD/GPL

GNU Public License v2 또는 BSD 라이선스 선택

DUAL MPL/GPL

GPL v2 또는 모질라 라이선스 선택

Proprietary

비자유 소프트웨어



출처 : 리눅스 커널 프로그래밍  저 한동훈,원일용, 하홍준  / 한빛 미디어

신고

'Programming > Linux/Unix' 카테고리의 다른 글

디바이스 트리 작성법 (2편)  (1) 2015.03.24
디바이스 트리 작성법 (1편)  (0) 2015.03.24
[Linux] Module 관련  (0) 2015.03.13
[Makefile] Kbuild 와 Module Compile  (0) 2015.03.09
[Makefile] Device Driver  (0) 2015.03.09
Makefile 문법 및 관련 내용  (0) 2015.03.09


Posted by injunech
2015.03.09 17:38


Document/kbuild/makefile.txt 및 Document/kbuild/modules.txt 문서를 번역편집한 문서정리

출처좌표 : http://deepbluedawn.wordpress.com/2009/07/31/169/ 



이 문서는 리눅스 커널 2.6.x에 사용되는 kbuild System의 module build과정에 대해 설명하기 위한 문서입니다.Linux Kernel소스의 Documents/kbuild/makefiles.txt 및 Documents/kbuild/modules.txt문서를 번역및 편집한 것입니다. 따라서 상당부분이 난해하기도 하고 직역을 한 부분이 있으니 이해해 주셨으면 합니다. 번역이 매끄럽지 못한 부분은 반드시 원문을 읽어 영어 단어의 뜻을 파악하시기 바랍니다.

1.Kbuild system?

일반적인 리눅스 Application 개발자라 하더라도 커널 Makefile이 어떻게 동작하는지 아는 것이 좋은 경우가 많다. 단순히 새로운 커널을 컴파일해 설치해 사용하는 사용자가 아니고 시스템을 아우르는 어플리케이션 개발자라면 커널이 어떻게 만들어지는 알고 있는 것이 도움이 될 때가 많기 때문이다. 예를 들어 현재 설정에 의해 어떤 모듈이 어떤 파일로 이루어져 있는지 알수 있으면 그 파일들을 조사해 수정하거나 하는 일이 가능하다.

kbuild system은 리눅스 버젼 2.6.x대에 도입된 새로운 kernel build system이다.  kbuild는 kernel source tree 내부의 모듈들과 kernel source tree 외부의 모듈들에 대한 build를 지원한다.(후자의 경우 외부 혹은 “out-of-tree” 모듈이라고 불리우며 현재 개발 중이거나, 혹은 Kernel의 source tree에 포함되지  않는 module을 가리킬때 사용된다.)

외부 모듈 개발자들은 모든 복잡성을 숨길수 있는 간단한 하나의 makefile을 제공해야 하며, 이 makefile을 사용, 누구나  make 명령어를 통하여 module을 build할 수 있어야 한다.

1.1 Goal 정의

Goal 정의는 kbuild Makefile의 가장 중요한 부분이다. Goal은 Build과정을 통하여 최종적으로 만들어져할 것, 특별한 컴파일 옵션, 사용되야할 하위디렉토리를 정의한다. 가장 간단한 kbuild makefile은 다음과 같은 한 줄을 갖는다.

예:

obj-y += foo.o


이 예가 말하는 것은 이 디렉토리 내에 foo.o(foo.c나 foo.S로부터 만들어질)란 이름의 한개의 오브젝트가 있다는 것이다. 만약 foo.o가 모듈로 만들어진다면 obj-m이란 변수가 사용된다. 그래서 다음과 같은 예처럼 된다.

예:

obj-$(CONFIG_FOO) += foo.o


$(CONFIG_FOO)는 y(built-in을 의미)나 m(모듈을 의미)의 값을 갖는다. 만약 CONFIG_FOO가 y나 m의 값을 갖지 않는다면 이 파일은 컴파일되거나 링크되지 않는다.


1.2 Built-in 오브젝트 Goal (obj-y)

kbuild Makefile은 $(obj-y) 리스트 내에 vmlinux에 필요한 오브젝트 파일을 지정해 놓는다. kbuild는 모든 $(obj-y) 파일을 컴파일한다. 그리고 이런 모든 파일을 하나의 build-in.o로 만들기 위해 “$(LD) -r”을 부른다.

$(obj-y)에 기록된 파일의 순서는 매우 중요하다. 중복되서 나열되는 것도 허용되지만 첫번째로 나오는 것이 built-in.o에 링크되고 그 이후의 것은 무시된다. 어떤 기능 들은(예를 들어 module_init()나 __initcall) 부팅하는 동안 나타나는 순서대로 불려지기 때문에 링크 순서도 중요하다. 그래서 순서를 바꾸게되면 디스크 등의 드라이버가 사용되는 순서가 바뀌는 등의 일 때문에 디스크의 번호도 바뀔수 있다.

예:

#drivers/isdn/i4l/Makefile

# Makefile for the kernel ISDN subsystem and device drivers.

# Each configuration option enables a list of files.

obj-$(CONFIG_ISDN) += isdn.o

obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o


1.3. Loadable module goals(obj-m)

$(obj-m)은 적재 가능한 모듈을 만들 때 사용된다.

모듈은 하나의 소스 코드나 여러 개의 소스 코드에서 만들어질 수 있다. 하나의 소스 코드로 만들어지는 경우엔 그냥 $(obj-m)에 더하기만 하면 된다.

예:

#drivers/isdn/i4l/Makefile

obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o


Note: 이 예에서 $(CONFIG_ISDN_PPP_BSDCOMP)는 ‘m’을 나타낸다.


만약에 커널 모듈이 여러 개의 소스 파일로부터 만들어지면 위에 나온 것과 같은 방식으로 지정하면된다. kbuild는 만들고자하는 모듈이 어느 부분에서 오는지를 알면되고 $(<module_name>-objs)에 지정해 주면 된다.

예:

#drivers/isdn/i4l/Makefile

obj-$(CONFIG_ISDN) += isdn.o

isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o


이 예에서 모듈 이름은 isdn.o이고 kbuild는 $(isdn-objs)안에 있는 오브젝트를 컴파일 한 후에 “$(LD) -r”을 실행해 isdn.o를 만들어낸다. kbuild는 오브젝트를 접미사 -objs와 -y에 의해 만들어지는 복합 오브젝트로 인식할 수 있다. 만약 오브젝트가 복합 오브젝트의 일부라면 Makefile이 CONFIG_ 값을 사용하도록 할 수 있다.

예:

#fs/ext2/Makefile

obj-$(CONFIG_EXT2_FS) += ext2.o

ext2-y := balloc.o bitmap.o

ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o

이 예에선 xattr.o는 $(CONFIG_EXT2_FS_XATTR)이 ‘y’인 경우에만 복합 오브젝트인 ext2.o의 일부 뿐이다. Note: 물론 커널 안에 모듈을 포함하는 경우에도 위와 같은 문법은 그대로 적용된다. 그래서 CONFIG_EXT2_FS=y인 경우 kbuild는 ext2.o 파일을 만들어 built-in.o에 링크하게된다.


2.외부 모듈을 build하는 방법


kbuild를 사용하여 외부 모듈을 build하기 위해서는 다음의 두 가지 사항이 구비 되어 있어야 한다.

Full source tree와 이를 사용하여 build된 kernel image가 있어야 한다.

Kernel을 build 할때 사용된 target들의 일부 부분이 module build를 위하여 사용 가능하여야 한다.


2.1 외부 modules을 build하는 방법

외부 module을 build하는 일반적인 3가지 방법에 대해서 알아보자.


일반적인 module build 방법

make -C <path-to-kernel> M=’pwd’

현재 동작중인 kernel을 참조하여 module을 build하는 경우.

make -C /lib/modules/’uname -r’/build M=’pwd’

Build된 kernel을 install하는 경우

make -C <path-to-kernel> M=’pwd’ modules_install

여기에서 간단히 짚고 넘어가야 할 부분은 세가지 정도이다. 먼저 make에서 -C option은 뒤의 parameter로 directory를 변경하라는 의미이고 uname -r 은 현재 운영중인 커널의 릴리즈 버젼 정보를 출력해 주는 명령어이다.

M과 modules_install등은 추후 설명할 build target 들이다.


2.2 외부 modules을 build하는 방법


make -C <path-to-kernel> M=’pwd’: pwd로 지정되어 있는 현재 directory의 모듈을 build하며, build과정에서 생성된 모든 출력 파일은 같은 directory에 저장된다. kernel source에 대한 갱신은 이루어지지 않으며, 반드시 적어도 한번은 kernel source가 성공적으로 build되어 있어야 한다.

make -C <path-to-kernel> M=’pwd’ module: 위의 방법에서 명시적으로 “module” 이라고 하는 target을 선언한 것이며 동작은 위의 서술과 동일하다.

make -C <path-to-kernel> M=’pwd’ modules_install: Build된 module을 설치한다. 설치되는 기본 directory는 /lib/modules/<kernel-version>/extra 이지만, prefix INSTALL_MOD_PATH를 통하여 설치되는 경로를 지정할 수 있다.

make -C <path-to-kernel> M=’pwd’ clean: 모듈 build과정에서 생성된 모든 file들을 삭제하며, kernel source directory는 변경되지 않는다.

make -C <path-to-kernel> M=’pwd’ help: 외부 모듈을 build하는데 필요한 build target들을 설명하는 명령이다.

2.3 사용가능한 option


make -C <path-to-kernel> M=’pwd’ M= 옵션은 kbuild에게 “외부 모듈”이 build되고 있다라는 사실을 알리는 옵션이며 SUBDIRS= 의 backward compatibility도 지원한다.


2.4 모듈 build를 위한 kernel tree 준비하기


외부 모듈을 build하기 위한 정보를 생성하기 위하여 kernel build target인 modules_prepare가 반드시 사용되어야 한다. (CONFIG_MODVERSIONS가 설정되어 있는 경우에도 modules_prepare target은 Module.symvers를 생성하지는 않는다. 조심할 것)


2.5 모듈의 파일 하나씩 build하기


kbuild는 하나의 모듈을 구성하는 각각의 파일들을 따로 build 할 수 있다.

(예)


make -C <path-to-kernel> M=’pwd’ bar.lst

make -C <path-to-kernel> M=’pwd’ bar.o

make -C <path-to-kernel> M=’pwd’ foo.ko

make -C <path-to-kernel> M=’pwd’ /


3. Kbuild/Makefile을 사용한 예제


kbuild system은 linux kernel을 효과적으로 build하기 위한 framework이다. Linux kernel과 밀접한 관련이 있는 kernel module은 다음과 같은 이유때문에 kbuild system을 사용하여야 한다.


전체 build system의 변경사항에 대하여 compatible하기 위하여

gcc등 compilation에 필요한 tool들과 해당 옵션들에 대하여 kernel build와 동일한 규칙을 적용하기 위하여

아래의 file들로 구성되어진 모듈을 compile하기 위하여 Makefile 하나를 생성해 보도록 하자.


8123_if.c

8123_if.h

8123_pci.c

8123_bin.o_shipped <- binary blob


3.1 모듈과 Kernel을 위한 공유 Makefile


외부 모듈은 항상 argument없이 단순한 ‘make’명령만으로 해당 module을 build할수 있는 wrapper Makefile을 포함하여야 한다.

Example 1:

–> filename: Makefile

ifneq ($(KERNELRELEASE),)

# kbuild part of makefile

obj-m  := 8123.o

8123-y := 8123_if.o 8123_pci.o 8123_bin.o

else

# Normal Makefile


KERNELDIR := /lib/modules/`uname -r`/build

all::

$(MAKE) -C $(KERNELDIR) M=`pwd` $@


# Module specific targets

genbin:

echo “X” > 8123_bin.o_shipped

endif


위의 예제에서 KERNELRELEASE 변수는 하나의 Makefile을 두 부분으로 나누는 역할을 수행한다. 위의 예제에서 make utility는 kbuild를 위한 두줄의 선언문만 인식을 못함에 비해 kbuild system은 두 라인의 선언문만 인식할 수 있다. 최근 version의 kernel에서 kbuild system은 먼저 Kbuild를 찾고 두번째 옵션으로 Makefile을 찾도록 되어 있다. Kbuild 파일을 사용하여 위의 예제에서 제공된 Makefile은 아래의 두가지 파일로 분리할 수 있다.


Example 2:

–> filename: Kbuild

obj-m  := 8123.o

8123-y := 8123_if.o 8123_pci.o 8123_bin.o

–> filename: Makefile

KERNELDIR := /lib/modules/`uname -r`/build

all::

$(MAKE) -C $(KERNELDIR) M=`pwd` $@

# Module specific targets

genbin:

echo “X” > 8123_bin.o_shipped


위의 예제에서는 상당히 작은 2개의 파일을 얻을 수 있었다. 그러나, 이렇게 작은 경우의 파일에 대해서 이러한 분리가 과현 실효성이 있는가에 대한 의문을 가질수 있으나, 매우 큰 Makefile의 경우, 이렇게 분리하는 것이 실효성을 가질수도 있다라는 점에 주목하자.

신고

'Programming > Linux/Unix' 카테고리의 다른 글

디바이스 트리 작성법 (2편)  (1) 2015.03.24
디바이스 트리 작성법 (1편)  (0) 2015.03.24
[Linux] Module 관련  (0) 2015.03.13
[Makefile] Kbuild 와 Module Compile  (0) 2015.03.09
[Makefile] Device Driver  (0) 2015.03.09
Makefile 문법 및 관련 내용  (0) 2015.03.09


Posted by injunech
2015.03.09 16:40



원본 : http://korea.gnu.org/manual/4check/make-3.77/ko/make_toc.html


GNU Make

재컴파일을 지휘하는 프로그램(A Program for Directing Recompilation)

GNU make Version 3.77.

May 1998

번역시작: March 2000

최종 갱신: May 9th, 2000

Richard M. Stallman 그리고 Roland McGrath
역자: 선정필



아래 GNU 사이트 참조

http://korea.gnu.org/



신고

'Programming > Linux/Unix' 카테고리의 다른 글

디바이스 트리 작성법 (2편)  (1) 2015.03.24
디바이스 트리 작성법 (1편)  (0) 2015.03.24
[Linux] Module 관련  (0) 2015.03.13
[Makefile] Kbuild 와 Module Compile  (0) 2015.03.09
[Makefile] Device Driver  (0) 2015.03.09
Makefile 문법 및 관련 내용  (0) 2015.03.09


Posted by injunech
2015.03.06 11:54


이 문서는 vi 에디터의 이름은 들어 보았으나, 사용법을 잘 모르는 사용자를 위한 것입니다. 자세한 설명서는 http://www.vim.org 에서 찾아 보시기 바랍니다.

  

1. vi 실행 방법

 

커맨드 라인에서 다음과 같이 입력하면, 인자로 입력한 이름의 파일을 편집할 수 있습니다.

 

$ vi 파일_이름...

 

파일의 이름에는 다수의 파일 이름을 넣을 수 있으며, vi 내에서 :n 명령으로 다음 파일로 넘어 갈 수 있습니다.

 

 

2. vi 실행 모드


vi 에디터는 크게 명령 모드와 입력 모드로 나눌 수 있고, 명령 모드에는 vi 명령 모드와 ex 명령 모드가 있습니다. vi 시작시, vi 명령 모드로 시작하며, 특정 키를 눌러, 입력 모드 및 ex 명령 모드로 전환할 수 있습니다. vi 명령 모드로 돌아오기 위해서는, Esc(Escape)키를 누르면 됩니다.

 

아래에, 입력 모드 및 명령 모드에서, 자주 사용되는 명령어를 적어 보았습니다(이것은 제가 선호하는 명령들로, 실제로는 훨씬 다양한 명령들이 있습니다).

 

실질적으로 vi 에디터를 이용하여 편집 작업을 하기 전에, 아래의 명령들을 전부 다 사용해 보시기 바랍니다. 어떤 명령들은 너무 강력해서 수습하기 어려운 경우도 있으니, 각각의 명령들의 특성을 미리 알아 두는 것이 필요합니다.

 

 

1) 입력 모드 전환 키 : 실질적으로 문서에 글자를 입력하기 위해서는 명령 모드에서 입력 모드로 모드 전환이 이루어져야 합니다. 이 때 사용할 수 있는 키가 여러 가지가 있는데, 여기서는 그것들에 대해 설명하겠습니다. 단순 입력 작업이 끝나고, 커서 이동이나 편집 작업 등을 하려고 할 때는 Esc키를 눌러서 입력 모드에서 빠져 나와야 합니다.

 

i : 현재 커서 위치에 글자 삽입이 가능해 짐, i 키를 누르고 난 이후에 쓰는 글은 커서 위치에 쓰여지게 됨
I : 현재 줄 처음에 삽입
a : 현재 커서 다음 위치에 추가
A : 현재 줄 마지막에 추가
o : 아랫 줄에 추가
O : 윗 줄에 추가
s : 현재 커서 글자 지우고 입력 모드로 전환
r : 현재 커서 글자 지우고 한 글자 입력 받아 명령 모드로 돌아감
Esc : 입력 모드 또는 ex 명령 모드에서 vi 명령 모드로 전환, vi 명령 모드에서 Esc키를 누르면 삑 소리가 남

 

 

2) vi 명령 모드 키: Esc키를 눌러서 들어 올 수 있는 모드입니다. vi 에디터 시작할 때의 초기 모드이기도 합니다. 키 앞에 숫자를 입력하면 그 명령이 숫자 만큼 반복됩니다. 입력 모드에서 입력 작업 완료 후, 커서 이동이나 삭제, 복사, 붙여 넣기 등의 편집 작업 등을 할 때는 Esc키를 눌러 vi 명령 모드로 전환시킨 후에 해야 합니다.

 

[ 커서 이동 ]

h : 한 문자 왼쪽으로 커서 이동(도스용이나 윈도우즈용 vi 에디터의 경우는 대부분, 커서 이동에 방향키를 사용할 수 있으나, 방향키가 없는 터미널 키보드에서 vi 에디터를 사용하기 위해서는 여기서 설명하는 키들을 알아둘 필요가 있습니다)
j : 한 줄 아래쪽으로 커서 이동
k : 한 줄 위쪽으로 커서 이동
l : 한 문자 오른쪽으로 커서 이동
w : 다음 단어 첫 문자로 커서 이동
b : 이전 단어 첫 문자로 커서 이동
Ctrl+f : 한 페이지 아래로 커서 이동
Ctrl+b : 한 페이지 위로 커서 이동
G : 마지막 줄로 커서 이동, 숫자G로 눌렀을 때, 숫자에 해당되는 줄로 커서 이동
^ : 공백 문자가 아닌, 현재 줄의 첫 문자로 커서 이동
0 : 공백 문자를 포함한, 현재 줄 첫 문자로 커서 이동
$ : 현재 줄 마지막 문자로 커서 이동

 

[ 삭제 ] : 삭제된 것은 버퍼에 저장되므로 p나 P 명령으로 붙여 넣기가 가능함

x : 현재 커서 위치 문자 삭제
X : 현재 커서 위치 이전 문자 삭제
dw : 현재 커서 위치 단어 삭제, 숫자dw로 쓰면 숫자만큼의 단어가 삭제됨, 다른 삭제 명령도 마찬가지로 숫자 입력 방식이 적용됨
db : 현재 커서 위치 이전 단어 삭제
dd : 현재 커서 위치 줄 삭제, 숫자dd로 쓰면 숫자만큼의 줄이 삭제됨
d^ : 현재 줄에서 현재 커서 위치 이전 문자열 삭제
d$ : 현재 줄에서 현재 커서 위치 이후 문자열 삭제
D : d$와 같음

 

[ 복사, 붙여 넣기 ] : 여기서의 복사란, 버퍼로의 복사를 말함, 실제로 붙여 넣기를 하려면 p나 P키를 눌러야 함

yw : 현재 커서 이후 단어 복사, 숫자yw로 쓰면 숫자만큼의 단어가 복사됨, 다른 복사 명령에도 이와 같은 숫자 입력 방식이 적용됨
yb : 현재 커서 이전 단어 복사
yy : 현재 줄 복사, 숫자yy로 쓰면 숫자만큼의 줄이 복사됨
p : 복사된 항목을 현재 커서 위치 이후에 붙여 넣기, 삭제된 항목도 붙여 넣기 가능
P : 복사된 항목을 현재 커서 위치 이전에 붙여 넣기, 삭제된 항목도 붙여 넣기 가능

 

[ 검색 ]

/검색어 : 전진 검색
?검색어 : 후진 검색
n : 검색 반복

N : 반대 방향 검색 반복

 

[ 되돌리기(undo) ]

u : 되돌리기(undo). u키를 계속 치게되면, undo 버퍼가 빌 때까지 계속 되돌리기할 수 있음. 유용함
U : 라인 되돌리기. 한 줄에 대해서 모든 편집을 없던 것으로 하고 원상태로 되돌림

Ctrl+r : Redo(undo undo)

 

[ 기타 ]

J : 커서 위치 아랫줄을 현재 줄에 붙임. 커서 이동의 j와 혼동될 수가 있으므로, 대소문자 구별에 유의해야 함

. : 이전 실행 명령 반복. 같은 명령을 빠르게 반복하고자 할 때 유용함. 참고로, 문자열 입력 후, 명령 모드로 돌아와서 .을 입력하면 입력된 문자열이 커서 위치에 삽입됨

ZZ : 현재 문서 저장하고, 종료하기

 


3) ex 명령 모드 : ex 라인 에디터의 명령어를 사용할 수 있습니다. vi 명령 모드 상태에서, : 키를 눌러서 들어가고, Esc키를 눌러서 다시 vi 명령 모드로 나옵니다. 아래에 제가 자주 사용하는 명령들을 적어 봅니다. 각각의 명령을 입력한 후, 실행을 하기 위해서는 엔터키를 누르면 됩니다.

 

시작줄번호,끝줄번호d : 시작줄번호에서 끝줄번호까지의 줄을 지움, 붙여 넣기 가능, 문서의 처음 줄은 1, 현재 줄은 . , 마지막 줄은 $로 지정 가능, 줄번호 입력없이 d만 입력했을 경우에는, 현재 줄을 지움

 

시작줄번호,끝줄번호y : 시작줄번호에서 끝줄번호까지의 줄을 복사

 

시작줄번호,끝줄번호s/찾을문자열/바꿀문자열/g : 시작줄번호에서 끝줄번호까지 '찾을문자열'을 찾아 '바꿀문자열'로 바꿈, g를 사용하지 않으면, 한 줄에 '찾을문자열'이 여러 개 있더라도, 그 줄에 대해서는 한 번만 바꿔짐. 유닉스 정규 표현식을 써서 강력한 검색 및 치환이 가능함

 

se nu : 줄 번호 표시

 

n : 다음 파일 편집, vi 실행시 인자로 입력한 파일이 여러 개일 경우에 해당

 

r 파일이름 : '파일이름'의 파일을 읽어 와서 현재 커서 아랫줄에 삽입

 

sh : 쉘로 잠깐 빠져 나가기, 쉘에서 exit 치면, 다시 vi로 돌아옴. vi를 백그라운드로 돌려서(Ctrl+z), 쉘로 나가 다른 작업을 한 후, fg로 돌아오는 방법도 있음

! 명령 : 밖으로 빠져 나가지 않고 바로 '명령'을 실행시킴

 

w : 저장하기, w!로 쓰면, 강제로 저장하기
w 파일이름 : '파일이름'으로 저장하기
q : vi 종료하기, q!로 쓰면 강제로 종료하기
wq : 저장하고, 종료하기. wq!로 쓰면 강제로 저장하고 종료하기


 

 

이상이 vi 에디터에서 제가 자주 사용하는 명령들입니다. 이 정도만 익숙하게 쓰실 수 있으면, 웬만한 편집 작업은 문제없이 할 수 있습니다. 이 외에도, 아주 많은 명령들이 있습니다. 그런 명령들을 잘 사용하시면 vi 에디터를 아주 편리하게 사용하실 수 있을 것 같습니다. 특히, 최근의 vi 에디터들은 기능이 다양해져서 Syntax highlighting 기능 등을 비롯하여 여러 가지 기능들을 지원하는 것 같습니다. 그 설정 방법을 찾아서 공부하시면 매우 유용하게 사용할 수 있을 것 같습니다.

 

이 문서를 읽고, 연습도 했는데, 잘 모르겠다 싶은 분은, Cygwin에서 vimtutor라는 명령을 내리세요. 하나 하나 따라 하면서 연습할 수 있습니다.

 

 

 

--------------------------------------------------------------------------------------


VI 사용하기

 

Vi 시작하기

  • $ vi : vi 시작하기
  • $ vi aaa.txt : aaa.txt 파일을 편집하면서 vi 시작
  • $ vi -R aaa.txt : 읽기 전용으로 열기

 Esc : 또는 / 
편집상태→ 
명령대기상태
(Esc모드)
→ 
명령줄상태
 삽입명령어
i,a,A,I,o,O
 Esc 또는 Enter 

  • 명령대기상태 → 편집상태 : 삽입명령어 (아래참조.)
  • 편집상태 → 명령대기상태 : Esc글쇠.
  • 명령대기상태 → 명령줄纘?: : 또는 / (아래참조)
  • 명령줄상태 → 명령대기상태 : Esc 또는 Enter (아래참조)

  

커서의 이동

  • hljk : 왼쪽(←, Back space), 오른쪽(→, space), 위(↑), 아래(↓)
  • bw : 이전 단어의 첫 글자로 / 다음 단어의 첫 글자로 이동.
  • BW : 이전 단어의 첫 글자로 / 다음 단어의 첫 글자로 이동. (문장부호 무시)
  • e : 다음 단어의 끝 글자로 이동.
  • E : 다음 단어의 끝 글자로 이동. (문장부호 무시)
  • HML : 화면의 맨 위/ 중간 / 맨 아래로
  • 0 : 그 줄의 맨 처음으로 (숫자 0이다.)
  • $ : 그 줄의 맨 끝으로
  • + : 다음 줄의 처음으로
  • - : 윗 줄의 처음으로
  • 3| : 현재 줄의 3번째 열로
  • 4H : 화면 상의 처음 줄부터 4줄 밑으로
  • 4L : 화면 상의 마지막 줄부터 4줄 위로
  • () : 이전 문장의 시작으로 / 다음 문장의 시작으로
  • {} : 이전 문단의 시작으로 / 다음 문단의 시작으로
  • [[]] : 이전 섹션의 시작으로 / 다음 섹션의 시작으로

편집 버퍼를 통한 이동

  • ^F^B : 한 화면 앞으로 / 뒤로 (^는 Ctrl글쇠를 의미.)
  • ^D^U : 반 화면 앞으로 / 뒤로
  • 4^B : 4화면 위로 이동
  • 4^F : 4화면 아래로 이동
  • 7^U : 7줄 위로 이동
  • 7^D : 7줄 아래로 이동
  • ^Y : 커서는 현재 위치 그대로 화면만 한 줄씩 아래로 이동
  • ^E : 커서는 현재 위치 그대로 화면만 한 줄씩 위로 이동

행 단위 이동

  • :0 : 파일의 첫 번째 행으로 가기 (숫자 0)
  • :10 : 10번째 행으로 가기
  • :$ : 파일의 마지막 행으로 가기
  • G : 파일의 마지막 행으로 가기
  • 10G : 10번째 행으로 가기

삽입명령어

  • i : 커서 위치부터 삽입 시작
  • a : 커서 위치 오른쪽부터 삽입 시작
  • A : 현재 줄의 맨 끝 부터 삽입 시작
  • I : 현재 줄의 맨 처음 부터 삽입 시작
  • o : 커서 아래에 행 삽입
  • O : 커서 위에 행 삽입

삭제명령

  • x : 현재 커서위치의 한 문자 삭제
  • X : 현재 커서 왼쪽의 한 문자 삭제
  • dd : 한 줄 지우기
  • 4dd : 4 줄 지우기
  • dw : 한 단어 지우기
  • d2w : 2 단어 지우기
  • D : 커서 오른쪽 행 삭제
  • :5 d : 5 째 행 삭제
  • :5,10 d : 5-10 째 행 삭제

파일의 저장 및 종료

  • :wq : 저장 후 vi 종료
  • :w : 저장 (종료는 하지 않고 계속 편집)
  • :q! : 저장하지 않고 vi 빠져나가기
  • :w filename : filename으로 저장 후 계속 편집
  • ZZ : 변경사항 저장 후 vi 종료

내용의 복사 및 이동

  • yy : 현재의 행 복사
  • 5yy : 현재의 행 위치부터 5행 복사
  • p : 아래(오른쪽)에 붙여넣기
  • P : 위(왼쪽)에 붙여넣기
  • f4yy : 현재의 행 위치부터 4행을 'f'라는 이름의 버퍼에 복사
  • fp : 'f'라는 이름의 버퍼에 복사된 내 용을 현재 행 위치에 붙여넣기
  • :3 co 7 : 3 행을 7행 다음으로 복사
  • :1,3 co 7 : 1-3 행을 7행 다음으로 복사
  • :3 m 7 : 3 행을 7행 다음으로 이동
  • :1,3 m 7 : 1-3 행을 7행 다음으로 이동

내용 고치기

  • J : 현재 행과 아래 행 결합
  • 3J : 3줄 합치기
  • u : 이전 명령 취소
  • cw : 단어 변경
  • cc : 행 변경
  • C : 커서 오른쪽의 행 변경
  • s : 커서가 위치한 문자열 대체
  • r : 한 글자만 변경 (입력 모드로 바뀌지 않음)
  • R : 입력하는 대로 겹쳐써서 변경
  • xp : 커서 위치 문자와 오른쪽 문자 교환
  • - : 문자형(대,소문자) 변경
  • U : 행 변경사항 취소
  • :u : 이전의 최종행 취소

명령 취소 및 반복

  • . : 마지막 명령 반복
  • 2. : 마지막 명령 2회 반복
  • u : 마지막 명령 취소
  • U : 현재 줄을 저장

행 번호 설정 및 화면표시

  • :set nu : 행 번호 표시
  • :set nonu : 행 번호 숨기기
  • := : 현재 줄번호 보여주기
  • :/pattern/ = : pattern이 위치한 줄번호 보여주기

시스템이 다운된 후에 파일 되살리기

  • vi -r : 되살릴 수 있는 모든 파일 이름 보여주기
  • vi -r file.txt : vi를 시작하여 지정한 파일 되살리기

다른 파일을 파일 내로 삽입

  • :r filename : 커서 다음에 파일 삽입
  • :20 r filename : 파일을 20번째 행 다음에 삽입

새로운 파일 편집하기

  • :e fine.txt : file.txt 편집하기
  • :e! : 현재의 편집중인 내용 무시하고 가장 최근에 편집한 내용 다시 편집하기

다중 편집하기

    % vi file1 file2 file3
    혹은
    :e file1 file2 file3
    했을 때,
  • :args : 편집 중인 파일목록 보여주기
  • :n[ext] : 다음 파일로 넘어가기
  • :prev[ious] : 이전 파일로 넘어가기 (단 편집 중인 파일이 저장되지 않으면 다음 파일로 넘어갈 수 없다.)

문자열 탐색

  • /aaa : 'aaa' 찾기 (현재 위치부터 뒤로)
  • ?aaa : 'aaa' 역방향 찾기 (현재 위치부터 앞으로)
  • : 가장 최근에 검색한 문자열 다시 검색
  • : 가장 최근에 검색한 문자열 다시 역방향 검색
  • :set noh : 문자열 검색 후 문자열 강조 끄기

치환

vi에서 치환은 정규표현식 이 이용된다. (실제로 이 상태에서 실행하는 명령어는 ed나 ex라는 프로그램이 처리하게 된다. 그래서 보통 이 상태를 "ed-모드"라고 한다.) 문서에서 원하는 패턴을 찾으려면 바로 위에 '문자열 탐색'에서 설명된 바와 같이 /문자열 이나 ?문자열 을 사용한다. 문자치환 명령은 다음과 같다.

[형식] :범위s/변경전/변경후/수정자  

'범위'는 명령이 실행될 범위(예: 10,20 이면 10행 부터 20행 까지)를 나타낸다. 's'는 치환(substitute)의 약자이며 '수정자'는 치환 명령의 세부사항을 결정한다. 필요한 것만 뒤에 적어주면 된다. (중복 가능)

  • (global) - 한 줄에서 일치하는 부분을 여러개 찾았을 때 전부 치환한다. 이것을 사용하지 않으면 처음 것만 치환.
  • (confirm) - 만족하는 정규표현식을 찾았을 때 치환하기 전에 확인한다.
  • (ignore-case) - 대소문자를 구별하지 않는다.

"변경전"과 "변경후"에 치환할 내용을 입력한다. "변경전"에 정규표현식을 적는다. 정규표현식으로 ., *, ^, $, [], \(...\), \<...\>, POSIX.2 단축 표현을 사용할 수 있다. 여기서 여러 문자를 묶여서 단위를 만들고 찾은 내용을 기억하는 특수문자가 \(, \)임을 주의해야 한다. 반대로 (, )가 일반문자이다. vim(VI iMproved)에서는 vi에 추가로 |, +, (?와 같은) =, {n,m}을 사용할 수 있지만, 앞에 를 붙여야 한다. 또, vim에는 \i, \k, \p, \s 등의 단축 표현들이 있다.

"변경후"에 \n 과 를 사용할 수 있다. \n 는 "변경전"에서 n번째 \(...\) 에 대응하는 부분이고, 는 "변경전"에 만족한 전체를 나타낸다. 예를 들어, 
:%s/\([0-9][0-9]*\) \([Cc]hapter\)/\2 \1/ 
는 문서에서 12 Chapter같은 부분을 Chapter 12와 같이 치환하고, 
:%s/F[1-9][12]*/&/g 
는 HTML 문서에서 "F1" ~ "F12"란 단어 모두를 굵은 체로 바꿉니다. (주의! &는 정규표현식의 특수문자는 아니지만 vi의 특수문자이므로, 문자그대로의 &를 사용하려면 대신 \& 를 사용해야 한다.) 이외에도 (뒤를 모두 대문자로) \u 나 (뒤를 모두 소문자로) \l 같은 기능이 있다.

    :%s/aaa/bbb/g - 파일 전체(g)에서 'aaa'을 'bbb' 로 치환 
    :%s/^M//g - 파일 전체(g)에서 ^M 을 삭제. ^M은 Ctrl+V+Enter로 입력한다. 
    :s/aaa/bbb/ - 현재 행에서 'aaa'을 'bbb' 로 치환 
    :1,10 s/aaa/bbb/ - 1행부터 10행 까지 'aaa'을 'bbb' 로 치환 
    :1,. s/str/rep/ - 1부터 현재행까지 'aaa'를 'bbb' 로 전부 바꾸기 
    :g/감자/s//바위/gc - 각 발생 확인 후 대체 

주의할 점은 치환명령어가 / 문자로 각 부분을 구분하기때문에 "변경전"이나 "변경후"에 / 문자를 사용하려면 \/ 같이 써야한다. 
필요하다면 / 대신 다른 문자를 사용해도 된다. 예를 들어, 
:%s/\/usr\/local\/bin\//\/usr\/bin\//g 
대신 
:%s#/usr/local/bin/#/usr/bin/#g 
가 알아보기 더 쉽다.

신고


Posted by injunech
2015.03.05 16:54


Samba 설치 및 설정


- Samba Package 설치

sudo apt-get install samba smbfs


- Samba 아이디, 암호 추가 설정

sudo smbpasswd -a 아이디

sudo vim /etc/samba/smbusers

#파일에 추가
아이디 = "network username"


- Samba 아이디 삭제

sudo smbpasswd -x 아이디


- Samba Server 설정

sudo vim /etc/samba/smb.conf (Samba 설정 파일 편집)

#기본 설정
workgroup = WORKGROUP
encrypt passwords = yes

#접근을 허락할 아이피 범위
hosts allow = 192.168.

#문자 인코딩 설정, 우분투는 utf-8을 기본적으로 사용하고 이것이 윈도우즈에서도 한글이 잘 깨지지 않는다.
unix charset=utf-8
dos charset=utf-8

#공유시 보여질 이름 (여러개 만들 수 있음)
[ShareDirectory]
comment = 공유폴더
path = /home/testuser/shareDir
read only = no
browsable = yes


- Samba 공유 폴더 확인

sudo testparm


- Samba 재시작

sudo /etc/init.d/samba restart


- Samba 읽기 전용으로 폴더 공유하기

sudo vim /etc/samba/smb.conf (Samba 설정 파일 편집)

#아래 내용을 찾아
security = user

#아래 처럼 바꾼다.
security = user
username map = /etc/samba/smbusers

#아래 내용의 주석을 제거한다.
;[homes]
;comment = Home Directories
;browseable = no
;valid users = %S
;writable = yes

#설정 확인
sudo testparm

#재시작
sudo /etc/init.d/samba restart


- 읽기/쓰기 권한으로 공유

sudo vim /etc/samba/smb.conf (Samba 설정 파일 편집)

writable = yes


- 읽기 전용 권한으로 공유

sudo chmod 777 /home/testuser/shareDir

sudo vim /etc/samba/smb.conf (Samba 설정 파일 편집)

security = user
username map = /etc/samba/smbusers

[ShareDirectory]
comment = 공유폴더
path = /home/testuser/shareDir
public = yes
writable = no
valid users = 아이디1 아이디2
create mask = 0700
directory mask = 0700
force user = nobody
force group = nogroup


- 읽기/쓰기 권한으로 공유

sudo vim /etc/samba/smb.conf (Samba 설정 파일 편집)

[ShareDirectory]
comment = 공유폴더
path = /home/testuser/shareDir
public = yes
writable = yes
valid users = 아이디1 아이디2
create mask = 0700
directory mask = 0700
force user = nobody
force group = nogroup


- 공개 폴더 읽기 전용 권한으로 공유

sudo vim /etc/samba/smb.conf (Samba 설정 파일 편집)

[global]
security = share

[public]
comment = Public Folder
path = /home/public
public = yes
writable = no
create mask = 0777
directory mask = 0777
force user = nobody
force group = nogroup

#nobody 계정 생성
sudo smbpasswd nobody


- 공개 폴더를 읽기/쓰기 권한으로 공유

sudo vim /etc/samba/smb.conf (Samba 설정 파일 편집)

[global]
security = share

[public]
comment = Public Folder
path = /home/public
public = yes
writable = yes
create mask = 0777
directory mask = 0777
force user = nobody
force group = nogroup


- 네트워크 프린터에서 인쇄하기

sudo vim /etc/samba/smb.conf (Samba 설정 파일 편집)

printing = cups
printcap name = cups

#프린터 관리 서비스 재시작
sudo /etc/init.d/cupsys restart


- 웹을 통해 삼바 설정 관리 (SWAT : Samba Web Administration Tool)

-- INETD과 SWAT 를 설치
sudo apt-get install netkit-inetd
sudo apt-get install swat

-- inetd daemon 설정
sudo vim /etc/inetd.conf (inetd daemon 설정 파일 편집)

#아래 내용 찾아서
<#off#> swat stream tcp nowait.400 root /usr/sbin/tcpd /usr/sbin/swat

#아래처럼 변경
swat stream tcp nowait.400 root /usr/sbin/swat swat

-- 대몬 재시작
sudo /etc/init.d/inetd restart

-- root 암호 설정
sudo passwd root

-- 웹 접속
http://localhost:901


신고


Posted by injunech
2015.02.23 11:32


[Linux/Unix] Vim (Vi) 작업 취소 단축키


작업 취소


현재 편집중이라면 키보드의 Esc키를 눌러 명령 모드로 들어가서,

소문자 u 를 누르면 방금 했던 작업이 취소됩니다.

다시 편집을 계속하기 위해서는 i 키를 누릅니다.



현재 줄에서 수정한 내용만 취소


현재 편집중이라면 키보드의 Esc키를 눌러 명령 모드로 들어가서,

대문자 U 를 누르면, 현재 커서가 위치하고 있는 줄에서 했던 모든 작업만 취소됩니다. 현재 줄에서 아무리 복잡한 작업을 해도 원상태로 쉽게 돌아갑니다.



취소를 취소하기 (Redo)


위의 u 키로 취소했지만 마음이 바뀌어서, 취소하기 전으로 돌아가고 싶을 때는

Ctrl+R 키를 누릅니다.

뭔가를 취소(Undo)했을 때에만 Redo가 작동합니다. 취소한 적이 한번도 없다면, 취소에 대한 취소도 작동하지 않습니다.


신고


Posted by injunech