centos 에서 하듯이, 새로 설치한 우분투(10.04.2 LTS) 에서 shutdown now 를 했는데..
종료 GUI가 멈추는 현상이 발생했다.  이유는 못찾았고, shutdown -h 0 이라는 명령을 사용하라는
권고만을 찾았다.

--- 이하 --
출처: http://onjo.tistory.com/1862

우분투(Ubuntu 8.04) 리눅스 종료 방법

1. 종료
sudo shutdown -h 0
sudo init 0
sudo poweroff


2. 재부팅
shutdown -r now

* 우분투에서 (알수 없는 이유로) GUI 를 통한 종료시
  종료가 안되고 멈춰있는 현상이 발생한다.

   따라서 shutdown -h 0 을 통해 종료하는게 안전하다.


출처 : kldp.org

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

출처 : http://suban.tistory.com/463

우선 CDRW가 잘 설정되어있는지부터 보면..
CD라이터는 EIDE장치라도 리눅스에서는 죄다 SCSI장비로 인식되더군요. 이게 제대로 설정되려면 부트로더를 좀 수정합니다.

리로를 쓴다면;

append="hdc=ide-scsi"

를 추가하고 그럽을 쓴다면;

title Red Hat Linux (2.4.9-34SGI_XFS_1.1custom)
root (hd1,0)
kernel /boot/vmlinuz-2.4.9-34SGI_XFS_1.1custom ro root=/dev/hdb1 hdc=ide-scsi

처럼 끝에 hdc=ide-scsi를 추가하면됩니다.
(물론 이 ODD장비가 hdc자리에 물려있다는 가정하에서.)

그리고 재부팅하면 /etc/fstab를 자동으로 업데이트하면서 원래;

$ ls -l /dev/cdrom
lrwxr-xr-x 1 root root 9 9월 28 14:58 /dev/cdrom -> /dev/hdc

이던것이;

$ ls -l /dev/cdrom
lrwxr-xr-x 1 root root 9 9월 28 14:58 /dev/cdrom -> /dev/scd0

0. 장치명 알아내기

1) 공시디를 넣고 다음 명령을 입력한다.

2) wodim --devices

or

cdrecord -devices

1. 하드의 파일을 iso파일로 만들기

# mkisofs -o 생성될파일.iso -R -V CD타이틀명 원본파일경로
1) -o 생성될파일.iso
생성될 ISO파일명을 지정하는 옵션

2) -R
Rock Ridge의 약자로 윈도우의 졸리엣처럼 긴파일명을 지원해주기 위한 옵션

3) -J
Rock Ridge의 약자로 윈도우의 졸리엣처럼 긴파일명을 지원해주기 위한 옵션

4) -V CD타이틀명
CD의 타이틀명을 지정하기위한 옵션. 띄어쓰기가 있을 경우 " " (따옴표)로 묶으면 된다.

5) 원본파일경로
CD로 제작할 파일이 들어있는 디렉토리를 지정하면 된다.
자동으로 용량을 제한하지는 않으므로 디렉토리에 알맞은 크기로 복사해놓아야 한다.

2. iso파일을 CD로 굽기

# cdrecord -v -eject speed=배속 dev=장치ID 원본파일.iso
1) -scanbus
CD레코더 장치가 있는지 있으면 어디로 연결되어 있는지 확인하는 옵션

2) -v
상세한 레코딩정보를 보여주는 옵션

3) -eject
레코딩이 완료된 경우 자동으로 CD를 꺼내는 옵션

4) -dummy
실제 레코딩을 하지 않고 정상적으로 레코딩이 되는지 확인하는 옵션

5) speed=배속
레코딩속도를 지정하는 옵션. 나의 경우는 안전한 CD굽기를 위해 16정도로 지정해준다.

6) dev=장치ID
CD레코더 장치의 고유ID를 의미하며, dev=0,0,0 과 같이 지정하는 것이 보통이며, -scanbus로 확인할 때 장치가 ATA로 표시되어 있다면, dev=ATA:0,0,0 으로 지정하면 된다. ATAPI로 장치가 표시되는 경우는 마찬가지로 ATA대신에 ATAPI로 쓰면 된다.

7) 원본파일.iso
레코딩할 원본파일의 경로를 적어준다.

3. ISO파일을 생성하지 않고 바로 CD로 만들기

# mkisofs -R -V CD타이틀명 원본파일경로 | cdrecord -v -eject speed=배속 dev=장치ID -
모든 옵션은 위에 있는 것과 동일하며 주의할 사항은 마지막에 ' - '를 꼭 붙여주어야 한다는 점이다.
이 경우 ISO파일을 생성하지 않는 것이라기보다는 파이프라인(unnamed pipe)이란 것을 이용하여 cdrecord로 ISO파일 내용을 넘겨주며 CD레코딩이 이루어진다.
그래서 ISO파일은 남지 않게 된다. 용량을 절약할 수 있으며, iso파일이 필요없다면 시간도 훨씬 절약할 수 있다.


4. CD를 iso파일로 이미지뜨기

# dd if=/dev/cdrom of=이미지.iso
1) if=원본이미지파일|원본장치
읽어들일려는 원본장치나 원본이미지파일을 지정하는 속성
CD의 경우 부팅시디도 부팅이미지로 읽을 수 있다.

2) of=복사이미지파일|복사장치
복사될 장치나 생성될 이미지파일을 지정하는 속성
이미지를 뜨는데 뿐만 아니라 하드백업할 때도 사용할 수 있다.
# cat /dev/cdrom > 이미지.iso
위의 명령과 같은 결과를 낳는다.
/dev/cdrom원본장치가 되고, 이미지.iso복사되서 생성될 이미지 파일명이 된다.



WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,
출처 : http://croky.tistory.com/15


LIDS Internals

글쓴이 : 채효철


*INDEX*

1. 소개
2. 중요한 소스 분석
3. 예제
4. 결론

-----------------------------
1. 소개

LIDS 는 Linux Intrusion Detection System 의 약자로서 리눅스 기반의 IDS 이다.
중국의 해커 Huagang Xie 로 부터 시작되어
최고의 보안 도구로 각광 받고 있다. 아직 국내에는 까다라온 사용법 때문에 실제로
적용된 사례가 잘 없지만 외국에는 널리 쓰이고 있다고 한다.
하지만 이름과는 다르게 IDS 의 뜻과는 달리 리눅스의 보안 강화로 요즘 유행하는
Secure OS 을 지향하고 있다.

-현재 시스템의 문제는 무엇일까?
 
  * 현재 파일 시스템은 보호되지 못한다
  * 프로세스도 보호되지 못한다
  * Access Control 모델이 부족하다
  * root 권한이 너무 막강하다.

-모듈 방식 보다 좋은점은 무엇일까?

모듈 방식은 한계가 있는것으로 알려져 있다. 유지보수가 쉬운 이유로
모듈로 작성되고 있지만 모듈 만으로 커널의 모든 자료구조를 접근할수가
없다. 물론 커널을 컴파일 할 당시에 커널에서 쓰이는 자료구조나 변수들을
export 시킨다면 가능은 하겠지만 일반적으로 필요한 것만 export 시키기 때문에
그것은 논외로 하겠다.

- 중요한 기능들

LIDS 에 어떤 중요한 기능이 있는지 살펴보기 위해 커널에 패치된 파일과 새로
생성된 파일들을 살펴보겠다. 우리의 목적은 LIDS 의 내부를 살펴보는 것이기 때문에
사용하는 방법엔 관심이 별로 없다.(물론, 분석을 할려면 어느정도는 알아야 된다)

-패치된 파일

init/main.c       /* 시작 루틴이 있음 */

kernel/fork.c     /* 프로세스 생성하는 부분 */
kernel/ksym.c
kernel/signal.c   /* 프로세스 보호 */
kernel/exit.c

fs/buffer.c
fs/dcache.c
fs/exec.c
fs/namei.c
fs/namespace.c
fs/readdir.c
fs/super.c
fs/open.c

fs/proc/base.c    /* 프로세스 감추기 */
fs/proc/root.c

-추가된 파일
kernel/lids.c     /* lids 의 핵심적 소스, 파일을 ACL 에 연결시키는등 */
kernel/klids.c          /* lids thread 이다. 초기화시 kernel_thread() 를 통해서
실행됨 */
kernel/lids_mail_script.c /* 경고를 메일로 보낸다 */
kernel/lids_syslog_script.c
kernel/lids_net.c                   /* 네트워크 관련 보호루틴 */
kernel/lids_logs.c                  /* 로그 남기는 루틴 */

소스 파일명을 보면 알수있듯이

파일 시스템 보안과 프로세스 보안으로 나눌수 있다.
proc/ 파일 아래의 소스들은 프로세스를 보호하고
fs/ 디렉토리의 소스들은 파일 시스템이 ACL 에 의해 보호되는지
체크하고 실패하면 경고를 낸다.  kernel/ 디렉토리에서 새로 생성된 파일들은 관리자에게
메일로 경고를 하거나 로그를 남긴다.


종합해 보자면 LIDS 의 특징은 다음과 같다.

보호(Protection). LIDS는 여러분의 하드 디스크에 있는 중요한 파일을 보호할 수 있다.
이때 파일시스템의 타입은 문제가 되지 않는다. 루트를 포함한 누구든지 지정된 파일을
변경할 수 없게 된다. LIDS는 또한 중요한 프로세스에 대해 kill 되어지는 것을 방지할 수
있다. LIDS는 인증되지 않은 프로그램으로부터의 RAW IO operation을 보호할 수 있다.
여러분의 하드디스크를 포함하여 MBR까지 보호할 수 있다.

탐지(Detection). 누군가 여러분의 호스트를 스캔했을 때 LIDS가 그것을 탐지하여 관리자
에게 알려줄 수 있다. LIDS는 또한 규정을 어긴 시스템상의 행동을 알아 챌 수도 있다.

응답(Response). LIDS에 의해 보호되고 있는 시스템 상에서 누군가 시스템상의 규정을
어겼을 때(주로 해킹을 위해) LIDS는 그 규정을 어긴 행동에 대해 자세한 메세지를 시스템
로그 파일로 기록한다. LIDS는 또한 여러분의 메일박스로 로그 메세지를 보낼 수도 있다.
이런 경우 LIDS는 즉시 유저 세션을 셧다운 시킬 수 있다.

2. 중요한 소스 분석

이번 절에서는 LIDS 소스에서 핵심적인 부분 몇가지를 분석하겠습니다.

- (1) 예) sys_ioperm

이 시스템콜은 I/O Port 를 접근하기 위해 커널에 허가를 요청 합니다.
커널 내부에서 이 요청이 허가된 사용자 - 루트인지 - 를 체크하기 위해

  62     if (turn_on && !capable(CAP_SYS_RAWIO)) {
  63 #ifdef CONFIG_LIDS
  64             lids_security_alert("CAP_SYS_RAWIO violation: attempted to g
  65 #endif
  66         return -EPERM;
  67     }

capable 함수는 인라인 함수로써 내부에 아래의 소스로 치환된다.

  if(cap_raised(current->cap_effective,cap))
  {
          current->flags != PF_SUPERPRIV;
        return 1;
  }

  이 함수는 current 즉 현재 프로세스의 cap_effective 라는 디스크립터를 검사해서
  CAP_SYS_RAWIO - 로우레벨 I/O 작업의 권환이 있는지 - 를 검사해서
  있다면 현재 프로세스의 PF_SUPERPRIV 플래그를 할당한다.

다시 돌아가서, 만약 허가되지 않은 사용자가 io_perm 을 호출했다면 lids_security_alert 가 실행된다.
이 함수는 lids_log 라는 함수를 호출해서 아래와 같은 동작을 한다.

  1. 현재 프로세스의 매핑된 영역중 executable 한 영역을 찾아
     매핑된 파일의 directory entry 를 얻는다.
  2. 현재 프로세스의 tty 이름을 얻는다.
  3. directory entry 와 tty 이름과 pid uid 등의 정보를 모아 프린트를 한다.

이 함수는 관리자에게 경고를 보내는 것이다.

LIDS 의 설계 목표중 하나가 Linux kernel 의 capability 지원을 강화하기 위한 것이다.
capability 에는 아래와 같은 속성이 있다.

CAP_CHOWN : 파일과 그룹의 허가권의 변경제한을 무시한다.
CAP_DAC_OVERRIDE : 파일 접속 퍼미션을 무시한다.
CAP_DAC_READ_SEARCH : 파일과 디렉토리의 읽기와 검색 허가를 무시한다.
CAP_FOWNER : 파일 허가권을 무시한다.
CAP_FSETID : setuid 와 setgid 플래그의 제한을 무시한다.
CAP_KILL : 시그널 보낼때의 제한을 무시한다.
CAP_SETGID : setgid 플래그 조작을 허용한다.
CAP_SETUID : setuid 플래그 조작을 허용한다.
CAP_SETPCAP : 다른 프로세스 에게 허가된 능력(capabilities) 의 부여한다.
CAP_LINUX_IMMUTABLE : 추가 전용파일이나 일정한 파일의 변경을 허용한다.
CAP_NET_BIND_SERVICE : TCP/IP socket 을 1024 번 이하로의 바인딩을 허용한다.
CAP_NET_BROADCAST : 네트워크 브로드캐스팅과 멀티캐스트를 듣는것을 허용한다.
CAP_NET_ADMIN : 일반적인 네트워킹 관리를 허용한다.
CAP_NET_RAW : RAW/PACKET socket 의 사용을 허용한다.
CAP_IPC_LOCK : 페이지나 메모리 세그먼트의 잠금을 허용한다.
CAP_IPC_OWNER : IPC 의 소유권 검사를 생략한다.
CAP_SYS_MODULE : 커널 모듈을 삽입/삭제 를 허용한다.
CAP_SYS_RAWIO : ioperm 과 iopl 을 이용해 I/O 포트에 접근을 허용한다.
CAP_SYS_CHROOT : chroot() 를 허용한다.
CAP_SYS_PTRACE : 어떤 프로세스에서나 ptrace() 를 허용한다.
CAP_SYS_PACCT : 프로세스 계정의 설정의 허용한다.
CAP_SYS_ADMIN : 일반적인 시스템 관리를 허용한다.
CAP_SYS_BOOT : reboot() 를 허용한다.
CAP_SYS_NICE : nice() 의 제한을 무시한다.
CAP_SYS_RESOURCE : 여러 자원 사용의 제한을 무시한다.
CAP_SYS_TIME : 시스템 시간과 실시간 시간의 조작을 허용한다.
CAP_SYS_TTY_CONFIG : tty 장치의 설정을 허용한다.
CAP_HIDDEN : 이 기능은 LIDS 에서 추가되는 것으로 프로세스를 숨기는 것이다.
CAP_KILL_PROTECTED : 이 함수 역시 LIDS 에서 추가되는 것으로 프로세스를 보호한다.
CAP_PROTECTED : 위와 유사

예를들어 nice 시스템 콜이 해당 프로세스가 요청을 할 권한이 있는지 검사하기 위해
capable(CAP_SYS_NICE) 로 검사하면 된다.


- (2) 프로세스 감추기

이 기능은 LIDS 패치에 의해 추가된 기능이다.
유닉스의 전형적인 명령어인 ps 를 실행하면 아래와 같이 프로세스가 출력된다.

root         1  0.0  0.1  1368  420 ?        S    Sep05   0:06 init
root         2  0.0  0.0     0    0 ?        SW   Sep05   0:00 [keventd]
root         3  0.0  0.0     0    0 ?        SW   Sep05   0:00 [kapmd]
root         4  0.0  0.0     0    0 ?        SWN  Sep05   0:00 [ksoftirqd_CPU0]
root         5  0.0  0.0     0    0 ?        SW   Sep05   0:00 [kswapd]
root         6  0.0  0.0     0    0 ?        SW   Sep05   0:00 [bdflush]
root         7  0.0  0.0     0    0 ?        SW   Sep05   0:00 [kupdated]
root         8  0.0  0.0     0    0 ?        SW   Sep05   0:00 [mdrecoveryd]
root        12  0.0  0.0     0    0 ?        SW   Sep05   0:00 [kjournald]
chc       1624  0.0  3.4 22844 8904 ?        S    Sep05   0:00 kdeinit: kwrited
chc       1632  0.0  3.5 21808 9044 ?        S    Sep05   0:00 korgac --miniicon
chc       1643  0.0  3.2 21776 8368 ?        S    Sep05   0:00 kalarmd --login
chc       1681  1.5 11.0 66376 28320 ?       S    Sep05   2:05 /usr/lib/mozilla/

잠깐 왜 우리가 프로세스를 잠궈야 할까? 그것은 해커가 루트를 획득한후 프로세스들을 제거하여
웹 서비스 같은것을 중단시킬수 있기 때문인데 예를들어 kill -9 4 를 하면
kswapd 가 죽지 않고 Zombie 상태가 될것이다. 그렇게 되면 우리가 예상한것 보다
큰 문제가 발생할 것이다.

ps 를 하게되면 내부적으로 아래와 같을 것이다.

1. execve("/bin/ps");
2. proc 라이브러리 열기
3. /proc 안에 있는 디렉토리들을 차례대로 열어서 프로세스들의 정보를 얻어낸다.
4. 만약 open("/proc/1624") 를 한다면, proc 가상 파일시스템을 거쳐서 proc_pid_lookup
  함수까지 가게된다.
  이 함수는 ls /proc 명령을 치게 되면 pid 가 디렉토리 목록으로 나올것이다.

아래 소스는 proc_pid_lookup 함수중 프로세스를 하이드 하는 부분이다.

1021 #ifdef CONFIG_LIDS
1022     if (cap_raised(task->lids_cap,CAP_HIDDEN) && lids_load && lids_local_load)
1023         inode=NULL;
1024     else
1025 #endif

자세한 설명을 하자면, task 프로세스의 lids_cap 에서 현재 capability 가 hidden 라면
얻어낸 inode 를 NULL 로 저장하여 보이지 않게 한다.

그런데 LIDS 가 패치된 커널 소스 안에는 프로세스를 숨기는 코드가 보이질 않는데
이것은 lids-adm 이라는 유저레벨 관리툴이 있어서 그 관리 프로그램으로
커널과 통신하여 관리할수 있다.

- (3) 파일 보호

보통 리눅스에서 파일에 접근 하려면 -rwxrwxrwx 이러한 권한만 가지고 접근여부를
결정한다. 하지만 이런것에 헛점이 있을수 있다. 그래서 LIDS 자체에서
강력한 파일시스템 보안을 제공한다.

커널 소스에서 파일에 접근하기 전에 반드시 lids_check_base 라는 함수를 호출한다.
이 함수는 dentry 와 플래그를 입력 받는다.

이 함수의 동작의 예를 들어보면
어떤 시스템콜을 통해서 /etc/apache 디렉토리에 접근하려고 한다.
그리고 현재 /etc 에는 ACL(Access Control List)에 기반하여 보호가 된다고 가정하자.

잠깐 우선 어떻게 관리할 파일(아이노드)이 기술되는지 살펴보겠다.
LIDS 에서 사용되는 자료구조는

struct lids_acl {
      struct lids_acl *next;
      unsigned long int ino;
      kdev_t  dev;
      int     type;                  
};

위와 같으며

next 는 다음 acl 을 가리키고
ino 는 관리될 파일(아이노드)를 가리키며
dev 는 디바이스 타입을 가리킨다.
type 는 읽기전용,쓰기전용,추가전용,접근불가 이렇게 나뉘며
특히 추가전용 같은 경우 로그파일 같은곳에 유용하다.

다시 돌아가서..
lids_check_base 의 동작 방법을 알아본다면,

while(dentry)
{
        만약 현재 프로세스가 도메인을 체크한다면
                lids_check_acl(base,flag);
        dentry = dentry->d_parent;        
}

이 소스는 parent dentry 로 가면서 dentry 가 LIDS 시스템에 의해 보호되고 있는지
체크를 하는 부분이다.

lids_check_acl 함수의 동작부분을 요약해보면 아래와 같다.

acl = current->lids_sys_acl->lids_domain;

while(acl != NULL)
{
        if(acl->ino == inode->i_ino)
                return 보호되고 있다;
}

그 다음부분은 lids_data 라는 자료구조에 들어가 있는 아이노드와 비교하여
리턴한다.

- (4) 그 외

지금까지 LIDS 에서 가장 많은 비중을 차지한 함수들을 분석하였다.
그 외에는 LIDS 관리 프로그램인 lids-adm 과 통신을 하기 위한 코드들이다.

3. 예제

이해를 돕기 위해 예제를 들어 보겠다.

유저모드에서 아래와 같은 문장을 실행하게 되면 lids.conf 에 2번과 같은 문장이
추가 될 것이다.

1) lidsadm -A -r /sbin/
2) 0:0::1:0:80483:770:/sbin:0-0
  각 필드들은 타입,아이노드,디바이스번호,파일명 등이다.

그리고 리부팅을 해서 커널의 처음 시작 루틴에서 lids_load 를 1로 설정한다.
초기에 lids_init() 를 호출하면 아래와 같은 루틴이 작동한다.

filp = filp_open(LIDS_CONF_FILE,O_RDONLY,O_RDONLY);

즉 /etc/lids.conf 을 연다.

filp->f_op->read(filp,buffer,1024,&filp->f_pos);

설정 파일에서 1024 바이트만 읽는다. 물론 이 연산은 유저모드에서 커널모드로
복사해 오는것이기 때문에 더 복잡하다.

한줄씩 읽으면서 #으로 시작하면 넘어가고 아니면 lids_init_add_file 을 호출해서
한줄에 읽은 문자열을 넘겨줘서 분석을 하고 각 필드들을 메모리에 넣고
나머지 아이노드,타입,파일명 필드는 lids_get_info 함수에서 처리한다.
그런후에 얻어진 inode 번호등을 이용해 lids_add_acl 함수로 acl list 에 추가하게
되는 것이다. 그리고 앞에서 보았듯이 디렉토리에 접근 할때는 acl list 를
검사한다.

'Linux' 카테고리의 다른 글

우분투 종료방법 (ubuntu shutdown)  (1) 2011.03.04
리눅스에서 CD 굽기기  (0) 2011.03.04
__attribute__ __context__ sparse  (0) 2011.02.15
#define 활용, macro, preprocess (DEBUG, printf)  (0) 2010.12.07
linux directory dirent.h  (0) 2010.12.05

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,
커널 코드를보다가.. lock과 관련해서
__attribute__(__context__()) 과같은 구문을 보게 되었다.
리누즈 토발즈가 만든 Sparse라는 정적분석 도구에 관련된 내용이었다.
자세한 내용은
http://en.wikipedia.org/wiki/Sparse#cite_note-3
를 참조하면된다.

Sparse는 gcc의 __attribute__ 를 이용해서 '문제의 소지가있고 주의깊게 관찰해야할 특정부분의' 소스코드내에 __context__()와 같은 코드를 껴넣음으로써, 컴파일 타임에 개발자에게 '포인터가 어떤 어드레스 스페이스에 속하는지' 혹은 '함수가 어떤 lock을 얻고 반환했는지' 에대한 정보를 제공한다.

.

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

출처 : http://blog.naver.com/PostView.nhn?blogId=dolicom&logNo=10096312448


보통 리눅스 커널을 디버깅 하려면 쉽게 log 메세지를 이용할 수 있다. 이럴 때는 printk 함수를 사용하면 되는데 디버깅이 끝나면 제거 하면 된다.


#ifdef DEBUG

#define DPRINTF(fmt,args,...) printk(##args)

#else

 #define DPRINTF

#endif


이렇게 하면

DPRINTF을 골라서 쉽게 제거할 수 있다.


예를 들어 특정 부분만을 디버깅 할 때만 printf 한다면


#include <stdio.h>


#define DEBUG

#ifdef DEBUG
#define DPRINTF(fmt,args,...) printf( "%s:%s:%d: " fmt, __FILE__,  __FUNCTION__, __LINE__, ##args)
#else
#define DPRINTF   - 코드내의 이 함수를 제거 하여 출력하지 않는다.
#endif


int main( int argc, char *argv[])
{
   int i = 0;

   if (argc < 2) {
      DPRINTF( "argc=%d\n", argc);
   } else {
      DPRINTF( "argc=%d,argv1=%s\n", argc, argv[1]);
   }

   printf("파일이름: %s\n", __FILE__);
   printf("현재 라인번호 : %d\n", __LINE__);
   printf("현재 출력되는 함수 : %s\n", __FUNCTION__);
   printf("컴파일 날짜 : %s\n", __DATE__);
   printf("컴파일 시간 : %s\n", __TIME__);

   return 0;
}


실행 :

C:\defexam\defexam\defexam.cpp:main:23: argc=1
파일이름: c:\defexam\defexam\defexam.cpp
현재 라인번호 : 29

현재 출력되는 함수 : main
컴파일 날짜 : Nov 14 2010
컴파일 시간 : 21:55:14




#와 ##


#   : 스트링화 한다.

## : 토큰을 연결하여 하나의 토큰으로 만든다.



Token


프로그램을 구성하고 있는 문법적으로 의미 있는 최소 단위

          

if (i<100) sum+=i;
===> if, (, i, <, 100, ), sum, +=, i, ;

10개의 토큰으로 이루어 진다.



토큰의 예

  • 키워드 : int, while, if, else, auto, char, for…
  • 식별자 : main, printf, scanf, i, j…
  • 연산자 : +, -, *, /, =, <. >=…
  • 수치상수 : 124, 12.35, 7E9 등과 같은 수
  • 문자상수 : 단일 인용 부호(' ')내의 단일 문자나 문자열
  • 특수문자 : (, ), ;와 같이 구분자로 사용되는 문자
  • 주해 : /*와 */사이에 있는 임의의 문자열, 컴파일러에 의해 번역되지 않는다.

#예 :

#define QUOTEME(x) #x
printf("%s\n", QUOTEME(1+2));
===>
printf("%s\n", "1+2");


Token concatenation


#define CATTOK(x,y)  x##y


  int manage;

   manage = 10;

   printf("%d\n", CATTOK(man,age));

===>

   printf("%d\n", manage );



 

 

예 1 :


#define FORMAT_(type) FORMAT_##type
#define FORMAT_int    "%d"
#define FORMAT_double "%g"


 

void print_star(const starStruct *const star) {
  /* FORMAT_(type) will be replaced with FORMAT_int or FORMAT_double */
  #define EXPAND_STAR_MEMBER(member, type) \
    printf("%s: " FORMAT_(type) "\n", #member, star->member);
  EXPAND_STAR
  #undef EXPAND_STAR_MEMBER
  }

 

예 2 :

 

#define MYCASE(item,id) \
case id: \
  item##_##id = id;\
break

switch(x) {
    MYCASE(widget,23);
}

===>

case 23:
  widget_23 = 23;
break;

 


예 3 :


#define     CONCAT(a, b)     a##b


// main 함수

int main(void)

{

          int arr〔2〕= { 100, 200 };


          printf("%d \n", CONCAT(2, 4));

          printf("%d %d \n", CONCAT(arr, 〔0〕), CONCAT(arr, 〔1〕));


          return 0;

}



printf 사용시 방법 몇가지


 

#define print_int(val)    printf("%d", val)
#define print_double(val) printf("%g", val




#define DPRINTF(a,args...) fprintf( stderr, "%s:%d:"#a"\n", __FUNCTION__, __LINE__, ##args)


예:


#define DPRINTF(fmt,args,...) printf( "%s:%d:" fmt, __FUNCTION__, __LINE__, ##args)


int main( int argc, char *argv[])
{
   int i = 0;


   if (argc < 2) {

      DPRINTF( "argc=%d", argc);

   }


   printf("End of program\n");
   return 0;
}


#define CHECK1(x,format,args) if(x) {printf(format,args);}


#define fcntl( fd, command, ... ) \
wpurple_fcntl( fd, command, ##__VA_ARGS__ )

#define gprintk(fmt, x... ) printk( "%s: " fmt, __FUNCTION__ , ## x)

 

다른 예


#define a /*
#<?php echo "\\010Hello, world!\\n"// 2> /dev/null > /dev/null \\
;
// 2> /dev/null; x=a;
$x=5 // 2> /dev/null \\
;
if (($x))
// 2> /dev/null; then
return 0;
// 2> /dev/null; fi
#define e ?>
#define b */
#include
#define main() int main()
#define printf printf(
#define true )
#define function
function main()
{
printf "Hello, world!\\n"true/* 2> /dev/null | grep -v true*/;
return 0;
}
#define c /*
main
#*/


예 :


#define printf(fmt, args...)    test_print(fmt, ##args)


int ttyS1_fd;


void test_print(char *fmt, ...)
{
   write(ttyS1_fd, fmt, strlen(fmt));
}

int main(void)
{
   if ( (ttyS1_fd = open("/dev/ttyS1", O_RDWR|O_NOCTTY)) < 0 ) {
       printf(" /dev/ttyS1" open failed\n");
       return 1;
   }

   while (1) {
      printf("abcde %d\n", 1);
      sleep(1)
   }

  return 0;
}

 

#define sum(x,y)  (x+y)


#define LEN 100

#define WIDTH 100

   char array[LEN][WIDTH];

#undef LEN

#undef WIDTH




printk 사용


참고로 printk 함수는

printk()는 카널의 메시지를 콘솔이나 dmesg, syslog 데몬에게 넘겨주는 일을 한다.



1. printk

 

 include/linux/kernel.h


일반적인 프로그램을 작성할때도 로그정책은 매우 중요하다. 보통 레벨 1은 가장 낮은 수준의 디버그 메시지 레벨 3은 모든 디버그 메시지를 모두 남기는 식으로 정하는데 priorities를 이용해서 발생되는 로그에 레벨을 부여해 줄 수 있다.

priority 는 다음과 같이 커널에 정의되어 있다.

#define KERN_EMERG    "<0>"  /* system is unusable               */ 
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */

2. printk 사용

 

KERN_INFO의 동일한 표현

printk(KERN_INFO "system ok\n");

printk("<6>" "system ok\n");

printk("<6>system ok\n");


기타 예 :

printk(KERN_INFO "i = %u\n", i);

printk("<0> %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);

레벨에 대한 표시를 하지 않는다면 default 레벨은 "KERN_WARNING" 이다.

 

3. 커널 메시지 관리 데몬

- klogd : 커널에서 발생하는 메시지를 기록하고 관리한다.

- syslogd : 커널에서 발생한느 메시지와 응용 프로그램에서 요청한 시스템 정보를 기록하고 관리한다.

- /var/log/messages 파일에 모든 커널메시지가 저장된다.

 

4. 로그 정보보기

- dmesg

- cat /proc/kmsg : 커널 메시지가 발생할 때 즉시 출력.



Windows CE에서 사용법


보통 디버깅 시 정의하는 것을 바꿀 필요가 생긴다. 지금 WindowsCE의 메세지를 PC WIN32 MFC로 바꾸려면 RETAILMSG과 TRACE의 정의가 틀리다. 따라서 이것을 조정하기 위한 정의 이다.


RETAILMSG 함수의 첫번째 인수 n을 제거하는 것이다.


#define RETAILMSG(n, args...) TRACE(##args)   ---> ##다음 부터는 그대로



RETAILMSG(1, (TEXT("Invalid parameter to ReadChunk()\r\n")));

===> TRACE( (TEXT("Invalid parameter to ReadChunk()\r\n")));


RETAILMSG(1, (TEXT("Error opening %s. Error code = 0x%08x\n"), pszFilename, GetLastError()));

===> TRACE( (TEXT("Error opening %s. Error code = 0x%08x\n"), pszFilename, GetLastError()));


'Linux' 카테고리의 다른 글

LIDS 내부구조(리눅스 파일 보안)  (0) 2011.02.16
__attribute__ __context__ sparse  (0) 2011.02.15
linux directory dirent.h  (0) 2010.12.05
insmod,rmmod,lsmod,modprobe,depmod,modinfo  (0) 2010.12.05
[MTD] NAND: nandsim page-wise allocation  (0) 2010.12.05

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

linux directory dirent.h

Linux 2010. 12. 5. 23:53
출처 : http://marnitto.edogawa.kr/category/?page=1

C 언어에서 파일을 다루기 위해서는 OS에서 제공하는 API, 이를테면 Windows에서의 CreateFile 등의 함수를 사용해도 됩니다만, 일반적으로 간단한 파일 입출력을 위해서는 FILE * 을 이용합니다. 마찬가지로 디렉토리를 다루기 위해서 C 언어에서는 DIR *과 struct dirent를 사용합니다. 이는 기본적으로 다음 헤더 참조를 통해 사용할 수 있습니다.
#include <dirent.h>

디렉토리를 여는 방법부터 알아보도록 하겠습니다. 디렉토리 열기는 opendir()라는 함수를 통해서 사용 가능합니다.
DIR * opendir(char const *path);
path 안에는 경로를 넣으면 됩니다. 리턴값은 에러가 발생했다면 NULL, 그렇지 않으면 DIR * 포인터를 리턴합니다. 파일에서의 fopen과 비슷한 대신에 뒤에 읽기/쓰기 등의 지정이 없다고 생각하시면 됩니다.

디렉토리 안의 파일들을 하나하나 살펴보려면 간단히 readdir라는 함수를 사용하면 됩니다.
struct dirent * readdir(DIR *dp);
dp 에는 opendir를 통해서 열었던 DIR *를 그대로 넘겨주시면 됩니다. 이 함수가 맨 처음 호출되면 디렉토리의 맨 처음에 있는 파일에 관한 정보를 struct dirent 에 담아 리턴합니다. 한 번 더 호출되면 그 다음의 파일에 관한 정보를 읽습니다. 이 작업이 반복되다가 더 이상 읽을 파일이 없다고 판단되면 NULL을 리턴합니다.
struct dirent는 디렉토리 내의 파일에 관한 아주 간단한 정보를 담고 있습니다. struct dirent는 dirent.h에 다음과 같이 정의되어 있습니다(MinGW 기준).
struct dirent
{
long d_ino; /* Always zero. */
unsigned short d_reclen; /* Always zero. */
unsigned short d_namlen; /* Length of name in d_name. */
char d_name[FILENAME_MAX]; /* File name. */
}
일반적으로 d_in나 d_reclen의 경우는 잘 쓰이지 않고, 주로 d_name이 쓰입니다.

디렉토리 내의 파일에 관한 정보를 처음부터 다시 읽고 싶다면 rewinddir 함수를 사용하면 됩니다.
void rewinddir(DIR *dp);
디렉토리가 몇 번째 파일까지 탐색했는지를 알고 싶으면 telldir 함수를 사용하면 됩니다. 이 함수는 디렉토리를 어느 정도까지 읽었는지 그 인덱스를 리턴합니다.
long telldir(DIR *dp);
디렉토리의 탐색 위치를 임의로 변경하고 싶으면 seekdir 함수를 사용하면 됩니다.
void seekdir(DIR *dp, long index);

디렉토리에 대해서 더 이상 작업할 게 없으면 closedir를 통해 정리하면 됩니다.
int closedir(DIR *dp);
이 함수는 성공하면 0, 실패하면 1을 리턴합니다.


간단한 예제로, 현재 디렉토리에 있는 모든 파일을 탐색하는 프로그램을 작성했습니다.
#include <dirent.h>
#include <stdio.h>

int main()
{
DIR *dp;
struct dirent *f;

dp = opendir(".");
if (!dp) return 0;

while (1)
{
f = readdir(dp);
if (!f) break;

printf("[%d] %s\n", telldir(dp), f->d_name);
}

closedir(dp);
return 0;
}



WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,
출처 : http://blog.daum.net/yong0319/7895693

▣ 커널관리 파일

- insmod
: 모듈 추가. 커널 디렉토리를 찾아서 해당 모듈을 추가한다.
■ 형식 : insmod [옵션] [오브젝트파일]
■ 옵션
  -k : autoclean 을 사용하여 적재

- rmmod
: 모듈 삭제
■ 형식 : rmmod [옵션] [모듈]
■ 옵션
  -r : 의존관계에 있는 모듈을 한번에 삭제

- lsmod
: 추가된 모듈 출력(/proc/modules 를 참조한다)
■ 형식 : lsmod [옵션]
■ 옵션
  -V : lsmod 버전 출력

- modprobe
: 모듈 추가. depmod에 의해 갱신된 modules.dep에서 찾아 추가한다. insmod와 달리 해당 커널 디렉토리로 갈 필요없이 아무위치에서나 모듈을 추가할수 있다. 또한 의존성이 필요한 모듈이나 먼저 실행되어야 할 모듈이 있다면 그 모듈부터 추가하고 해당 모듈을 추가한다
■ 형식 : modprobe [옵션] [오브젝트파일]
■ 옵션
  -k : autoclean 을 사용하여 추가
  -r : 모듈 삭제

- depmod
: 의존성 검사를 한뒤 modules.dep 파일을 갱신한다. kernald나 modprobe를 실행하기 전엔 꼭 depmod -a를 사용하는 습관을 들인다
■ 형식 : depmod [옵션]
■ 옵션

- modinfo
: 모듈 정보 확인
■ 형식 : modinfo [모듈명]

※ autoclean
autoclean라는 플레그를 사용하면 커널 데몬(kerneld)에 의해 일정시간 사용하지 않는 모듈을 삭제한다. 단 커널 컴파일시 kerneld 지원 여부를 물을때 Y를 해야 사용 가능


※ 참고사항
insmod는 '/lib/modules/커널버전' 디렉토리를 뒤져 해당 모듈이 있으면 메모리에 올려준다.
modprobe는 depmod에 의해 생성된 modules.dep에서 모듈을 찾아 올린다. 그리고 해당 모듈에 의존성이 있거나 해당모듈보다 선행되어야 하는 모듈이 있으면 그 모듈도 같이 올려준다.
이 부분이 insmod와 가장 큰 차이점이다.
예를 들어 vfat란 모듈을 올리기 위해서는 fat란 모듈을 먼저 올려야 하는데, fat 모듈이 메모리에 올라가 있지 않은 상태에서
# insmod vfat 하면 fat에 대한 symbol을 찾지못해 vfat 모듈을 올리지 못하지만
# modprobe vfat 을 실행하면 자동으로 먼저 fat 모듈을 올리고, 그 다음으로 vfat 모듈을 올린다
(커널 컴파일시 fat, vfat을 모듈로 설정했다고 가정)
modprobe로 해당 모듈을 찾지 못하는 경우 modules.dep에 없을 가능성이 크므로
#depmod -a 해서 모듈 의존 관계를 새롭게 갱신시킬 필요가 있다.

참고로 의존 관계에 있는 모듈들을 한꺼번에 내리려면 rmmod -r 옵션을 하면 된다.

'Linux' 카테고리의 다른 글

#define 활용, macro, preprocess (DEBUG, printf)  (0) 2010.12.07
linux directory dirent.h  (0) 2010.12.05
[MTD] NAND: nandsim page-wise allocation  (0) 2010.12.05
여러 가지 커널 팁 #2  (0) 2010.12.04
여러 가지 커널 팁 #1  (0) 2010.12.04

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

출처 : http://www.mail-archive.com/git-commits-head@vger.kernel.org/msg03785.html

[MTD] NAND: nandsim page-wise allocation (1/2)

This patch removes code that does chip mapping. The chip mapping code
is no longer used.

Signed-off-by: Vijay Kumar <[EMAIL PROTECTED]>
Signed-off-by: David Woodhouse <[EMAIL PROTECTED]>

---
drivers/mtd/nand/nandsim.c | 22 ----------------------
1 files changed, 0 insertions(+), 22 deletions(-)

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 545ff25..5dd3c4e 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -37,10 +37,6 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/delay.h>
-#ifdef CONFIG_NS_ABS_POS
-#include <asm/io.h>
-#endif
-

/* Default simulator parameters values */
#if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \
@@ -440,14 +436,6 @@ init_nandsim(struct mtd_info *mtd)
printk("options: %#x\n", ns->options);

/* Map / allocate and initialize the flash image */
-#ifdef CONFIG_NS_ABS_POS
- ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob);
- if (!ns->mem.byte) {
- NS_ERR("init_nandsim: failed to map the NAND flash image at
address %p\n",
- (void *)CONFIG_NS_ABS_POS);
- return -ENOMEM;
- }
-#else
ns->mem.byte = vmalloc(ns->geom.totszoob);
if (!ns->mem.byte) {
NS_ERR("init_nandsim: unable to allocate %u bytes for flash
image\n",
@@ -455,7 +443,6 @@ init_nandsim(struct mtd_info *mtd)
return -ENOMEM;
}
memset(ns->mem.byte, 0xFF, ns->geom.totszoob);
-#endif

/* Allocate / initialize the internal buffer */
ns->buf.byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
@@ -474,11 +461,7 @@ init_nandsim(struct mtd_info *mtd)
return 0;

error:
-#ifdef CONFIG_NS_ABS_POS
- iounmap(ns->mem.byte);
-#else
vfree(ns->mem.byte);
-#endif

return -ENOMEM;
}
@@ -490,12 +473,7 @@ static void
free_nandsim(struct nandsim *ns)
{
kfree(ns->buf.byte);
-
-#ifdef CONFIG_NS_ABS_POS
- iounmap(ns->mem.byte);
-#else
vfree(ns->mem.byte);
-#endif

return;
}
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html




[MTD] NAND: nandsim page-wise allocation (2/2)

For page wise allocation, an array of flash page pointers is allocated
during initialization. The flash pages are themselves allocated when a
write occurs to the page. The flash pages are deallocated when they
are erased.

Signed-off-by: Vijay Kumar <[EMAIL PROTECTED]>
Signed-off-by: David Woodhouse <[EMAIL PROTECTED]>

---
drivers/mtd/nand/nandsim.c | 162 +++++++++++++++++++++++++++++++++++++-------
1 files changed, 138 insertions(+), 24 deletions(-)

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 5dd3c4e..f00e195 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -227,6 +227,14 @@ MODULE_PARM_DESC(dbg, "Output debug information
if not zero");
#define NS_MAX_PREVSTATES 1

/*
+ * A union to represent flash memory contents and flash buffer.
+ */
+union ns_mem {
+ u_char *byte; /* for byte access */
+ uint16_t *word; /* for 16-bit word access */
+};
+
+/*
* The structure which describes all the internal simulator data.
*/
struct nandsim {
@@ -243,17 +251,11 @@ struct nandsim {
uint16_t npstates; /* number of previous states saved */
uint16_t stateidx; /* current state index */

- /* The simulated NAND flash image */
- union flash_media {
- u_char *byte;
- uint16_t *word;
- } mem;
+ /* The simulated NAND flash pages array */
+ union ns_mem *pages;

/* Internal buffer of page + OOB size bytes */
- union internal_buffer {
- u_char *byte; /* for byte access */
- uint16_t *word; /* for 16-bit word access */
- } buf;
+ union ns_mem buf;

/* NAND flash "geometry" */
struct nandsin_geometry {
@@ -342,6 +344,46 @@ static struct mtd_info *nsmtd;
static u_char ns_verify_buf[NS_LARGEST_PAGE_SIZE];

/*
+ * Allocate array of page pointers and initialize the array to NULL
+ * pointers.
+ *
+ * RETURNS: 0 if success, -ENOMEM if memory alloc fails.
+ */
+static int
+alloc_device(struct nandsim *ns)
+{
+ int i;
+
+ ns->pages = vmalloc(ns->geom.pgnum * sizeof(union ns_mem));
+ if (!ns->pages) {
+ NS_ERR("alloc_map: unable to allocate page array\n");
+ return -ENOMEM;
+ }
+ for (i = 0; i < ns->geom.pgnum; i++) {
+ ns->pages[i].byte = NULL;
+ }
+
+ return 0;
+}
+
+/*
+ * Free any allocated pages, and free the array of page pointers.
+ */
+static void
+free_device(struct nandsim *ns)
+{
+ int i;
+
+ if (ns->pages) {
+ for (i = 0; i < ns->geom.pgnum; i++) {
+ if (ns->pages[i].byte)
+ kfree(ns->pages[i].byte);
+ }
+ vfree(ns->pages);
+ }
+}
+
+/*
* Initialize the nandsim structure.
*
* RETURNS: 0 if success, -ERRNO if failure.
@@ -435,14 +477,8 @@ init_nandsim(struct mtd_info *mtd)
printk("sector address bytes: %u\n", ns->geom.secaddrbytes);
printk("options: %#x\n", ns->options);

- /* Map / allocate and initialize the flash image */
- ns->mem.byte = vmalloc(ns->geom.totszoob);
- if (!ns->mem.byte) {
- NS_ERR("init_nandsim: unable to allocate %u bytes for flash
image\n",
- ns->geom.totszoob);
- return -ENOMEM;
- }
- memset(ns->mem.byte, 0xFF, ns->geom.totszoob);
+ if (alloc_device(ns) != 0)
+ goto error;

/* Allocate / initialize the internal buffer */
ns->buf.byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
@@ -461,7 +497,7 @@ init_nandsim(struct mtd_info *mtd)
return 0;

error:
- vfree(ns->mem.byte);
+ free_device(ns);

return -ENOMEM;
}
@@ -473,7 +509,7 @@ static void
free_nandsim(struct nandsim *ns)
{
kfree(ns->buf.byte);
- vfree(ns->mem.byte);
+ free_device(ns);

return;
}
@@ -769,6 +805,84 @@ find_operation(struct nandsim *ns, uint32_t flag)
}

/*
+ * Returns a pointer to the current page.
+ */
+static inline union ns_mem *NS_GET_PAGE(struct nandsim *ns)
+{
+ return &(ns->pages[ns->regs.row]);
+}
+
+/*
+ * Retuns a pointer to the current byte, within the current page.
+ */
+static inline u_char *NS_PAGE_BYTE_OFF(struct nandsim *ns)
+{
+ return NS_GET_PAGE(ns)->byte + ns->regs.column + ns->regs.off;
+}
+
+/*
+ * Fill the NAND buffer with data read from the specified page.
+ */
+static void read_page(struct nandsim *ns, int num)
+{
+ union ns_mem *mypage;
+
+ mypage = NS_GET_PAGE(ns);
+ if (mypage->byte == NULL) {
+ NS_DBG("read_page: page %d not allocated\n", ns->regs.row);
+ memset(ns->buf.byte, 0xFF, num);
+ } else {
+ NS_DBG("read_page: page %d allocated, reading from %d\n",
+ ns->regs.row, ns->regs.column + ns->regs.off);
+ memcpy(ns->buf.byte, NS_PAGE_BYTE_OFF(ns), num);
+ }
+}
+
+/*
+ * Erase all pages in the specified sector.
+ */
+static void erase_sector(struct nandsim *ns)
+{
+ union ns_mem *mypage;
+ int i;
+
+ mypage = NS_GET_PAGE(ns);
+ for (i = 0; i < ns->geom.pgsec; i++) {
+ if (mypage->byte != NULL) {
+ NS_DBG("erase_sector: freeing page %d\n",
ns->regs.row+i);
+ kfree(mypage->byte);
+ mypage->byte = NULL;
+ }
+ mypage++;
+ }
+}
+
+/*
+ * Program the specified page with the contents from the NAND buffer.
+ */
+static int prog_page(struct nandsim *ns, int num)
+{
+ union ns_mem *mypage;
+ u_char *pg_off;
+
+ mypage = NS_GET_PAGE(ns);
+ if (mypage->byte == NULL) {
+ NS_DBG("prog_page: allocating page %d\n", ns->regs.row);
+ mypage->byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
+ if (mypage->byte == NULL) {
+ NS_ERR("prog_page: error allocating memory for page
%d\n", ns->regs.row);
+ return -1;
+ }
+ memset(mypage->byte, 0xFF, ns->geom.pgszoob);
+ }
+
+ pg_off = NS_PAGE_BYTE_OFF(ns);
+ memcpy(pg_off, ns->buf.byte, num);
+
+ return 0;
+}
+
+/*
* If state has any action bit, perform this action.
*
* RETURNS: 0 if success, -1 if error.
@@ -776,7 +890,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
static int
do_state_action(struct nandsim *ns, uint32_t action)
{
- int i, num;
+ int num;
int busdiv = ns->busw == 8 ? 1 : 2;

action &= ACTION_MASK;
@@ -800,7 +914,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
break;
}
num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
- memcpy(ns->buf.byte, ns->mem.byte + NS_RAW_OFFSET(ns) +
ns->regs.off, num);
+ read_page(ns, num);

NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int
buf, raw offset %d\n",
num, NS_RAW_OFFSET(ns) + ns->regs.off);
@@ -841,7 +955,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
ns->regs.row, NS_RAW_OFFSET(ns));
NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift
- ns->geom.pgshift));

- memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF,
ns->geom.secszoob);
+ erase_sector(ns);

NS_MDELAY(erase_delay);

@@ -864,8 +978,8 @@ do_state_action(struct nandsim *ns, uint32_t action)
return -1;
}

- for (i = 0; i < num; i++)
- ns->mem.byte[NS_RAW_OFFSET(ns) + ns->regs.off + i] &=
ns->buf.byte[i];
+ if (prog_page(ns, num) == -1)
+ return -1;

NS_DBG("do_state_action: copy %d bytes from int buf to (%#x,
%#x), raw off = %d\n",
num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) +
ns->regs.off);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html

'Linux' 카테고리의 다른 글

linux directory dirent.h  (0) 2010.12.05
insmod,rmmod,lsmod,modprobe,depmod,modinfo  (0) 2010.12.05
여러 가지 커널 팁 #2  (0) 2010.12.04
여러 가지 커널 팁 #1  (0) 2010.12.04
vm_struct vs vm_area_struct  (0) 2010.11.27

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

여러 가지 커널 팁 #2

Linux 2010. 12. 4. 23:19
글쓴이: Dave Jones (dave@ext2.net)
옮긴이: 임종균 (hermes44@secsm.org)
원문: http://ext2.linuxberg.com/99/07/kernel/070699-kernel1.shtml

내가 받은 편지로 판단해 볼 때, System.map 파일은 여전히 사람들에게는 어려운 것 같다. 그래서 커널 메일링 리스트에서 그 파일에 대한 긴나긴 토론들을 읽어보았다.

  • Q. 그것은 어떤 용도로 사용됩니까?
    A. 만약 커널 oops가 발생하면, 화면에 여러 가지 레지스터들과 그 16진수 내용에 대한 한 페이지의 정보가 출력될 것입니다. 만약 System.map이 있다면, klogd는 16진수 주소를 그 주소가 나타내는 함수 이름으로 변환할 것입니다. 이 정보로부터 정확히 어느 위치에서 커널이 문제를 일으켰는지 판단할 수 있습니다. System.map이 없다면, 완전히 쓸모없는 16진수 주소들만을 떠맡게 될 것입니다. 이 값들은 각 기계마다 다르고, 커널 설정마다 다르기 때문입니다.

  • Q. 그렇다면 그 파일 없이도 살 수 있습니까?
    A. 리눅스는 System.map 없이 부팅할 것입니다. 그러나 시스템에 문제가 발생할 때, 주어지는 정보는 당신에게나 커널 개발자에게도 무엇이 문제인지에 대한 어떠한 단서도 주지 못 할 것이라는 경고를 합니다. System.map은 몇 백 Kb밖에 안 되고, 일단 설치한 후에는 완전히 잊어버리고 있어도 됩니다.

  • Q. 심볼릭 링크를 만들고 하는 모든 작업들이 너무 혼란스럽습니다.
    A. Jeff Garzik께서 x86에서 사용자는 'make install' 할 수 있는다는 언급을 하신 편지를 보내주셨습니다. 이는 vmlinuz-VERSION과 System.map-VERSION을 /boot로 복사하고 lilo를 실행합니다. 미리 /etc/lilo.conf가 변경되어 있어야 합니다. (그리고 klogd의 시작 스크립트에서 'klogd -k /boot/System.map-`uname -r`'을 사용해야 합니다.)

또 몇몇 사람들은 명령행에 '-j n'을 추가하는 것에 (즉 `make -j 32 bzImage`) 대한 메세지를 보고 편지를 보냈다. 어떤 사람들은 단일 프로세서 시스템에서 그것의 유효성에 대해 질문했다.

난 64MB RAM의 K6-233 시스템에서 테스트를 했다. 작업의 수를 바꿔가면서 커널을 컴파일을 하였다. 동시 빌드의 수를 늘리면 커널 빌드는 더 빨라진다. 한계는 -j 32로 보인다. (빌드 시간을 거의 1분 정도 줄였다.) 이 이상은 거의 향상이 없는 것 같다. SMP 시스템에서 더 많은 이득을 볼 수 있는 것이 맞지만, 테스트는 단일 프로세서 시스템에서도 역시 -j는 유효한 팁이란 것을 보여준다.

Liviu Sas은 'nice --20 make bzImage' 또한 컴파일 속도를 높이는 유용한 팁이라는 제안을 보내주었다.

John Slee는 lilo.conf 자동 생성기를 보내주었다. 이 작은 스크립트는 /boot에서 모든 안정 커널을 찾아서 lilo.conf를 만든다. 가장 높은 버전의 커널을 기본값으로 잡는다.

기본으로 필요한 작업은 모든 lilo.conf에 포함될 옵션들을 가지고 있는 /etc/lilo.conf.static 파일을 만드는 것이다. 그 후, 아무 인자없이 스크립트를 실행하기만 하면 된다. lilo.conf를 만들고 새 부트로더를 설치한다.

내가 보기에 한 가지 단점은 부트 항목별로 옵션을 넣을 수 없다는 것이다.

#!/bin/bash

umask 772
kernel_dir=/boot

# lilo assumes the default image is the first one in lilo.conf, so
# we sort the kernel images backwards, hence the highest-version'd kernel
# will be the default.
images=`cd $kernel_dir && ls -1 vmlinuz-* \
| egrep "vmlinuz-([0-9]+).([0-9]+).([0-9]+)[^-]*$" \
| sort -rn`

cp -f /etc/lilo.conf.static /tmp/lilo.conf

# three lines per entry, 3 x 19 images = 57
( for img in $images ; do
label=`echo $img | sed 's/vmlinuz/linux/ ; s/-//g ; s/\.//g'`
echo "image=$kernel_dir/$img"
echo "label=$label"
echo ""
done ) | head -57 >> /tmp/lilo.conf

if /sbin/lilo -C /tmp/lilo.conf ; then
mv -f /etc/lilo.conf /etc/lilo.conf.last
cp -f /tmp/lilo.conf /etc/lilo.conf
echo successfully installed new bootloader.
rm -f /tmp/lilo.conf
exit 0
else
echo eek, lilo barfed
rm -f /tmp/lilo.conf
exit 1
fi

내가 받았던 편지에서 또 다른 흔한 주제는 커널 패치에 대한 기사에 관련된 것이다. 특히, 많은 사람들이 옛날 커널을 위해 작성된 패치를 새 커널에 적용하려는 데서 문제를 겪고 있다. 대부분의 경우, 패치 과정중에 어떤 경고 메세지를 받았고 패치가 어떻게 동작하는지 완전히 이해하지 못 한다면, 그 패치의 관리자에게 연락을 해서, 문제점에 대해 말해주어야 한다.
만약 'offset 31 lines'나 이 비슷한 메세지가 나왔다면, 이는 문제가 아니다. 파일에서 패치하려하는 루틴의 코드가 약간 변경되어지만, 목표 루틴은 발견되어 패치되었다는 것을 의미한다.


WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

여러 가지 커널 팁 #1

Linux 2010. 12. 4. 23:18

여러 가지 커널 팁 #1

글쓴이: Dave Jones (dave@ext2.net)
옮긴이: 임종균 (hermes44@secsm.org)
원문: http://ext2.linuxberg.com/99/05/kernel/052999-kernel3.shtml

내게는 커널을 빌드(build)하는 것에 익숙치 못한 친구들이 몇 있다. 비록 커널에 포함되어 모아져 있는 정보가 있기는 하지만, 여전히 같은 질문들이 올라오는 것을 보게 된다.

여기에 일반적으로 알아야 하지만, 내가 많은 질문을 받았던 것으로 볼 때 그렇지 못한 몇몇 가지의 팁들이 있다.

커널 팁에 관한 기사가 정규적으로 나오기를 희망한다.
다른 커널-빌더와 공유하고 싶은 것 있다면, 내게 편지를 보내거나 포럼에 써라.

  • Q. 스크롤되는 것이 너무 빠릅니다. 그것 모두에 대해서 알아야 할 필요가 있나요?
    A. 아니요! 다음과 같이, 출력되는 메세지를 안 보이게 할 수 있습니다.
    	make -s zImage
    또는
    	make -s bzImage
    이렇게 하면 경과/에러 메세지만 보일 것입니다.

  • Q. 제 시스템에서는 커널 컴파일이 오래 걸립니다. 빠르게 하는 방법이 없나요?
    A. 물론 있습니다! 동시에 여러 개의 파일을 컴파일 하기 위해서 리눅스의 멀티태스킹 능력을 이용할 수 있습니다. make 명령에 -j <숫자>를 추가하면 됩니다. <숫자>는 동시에 빌드 작업을 하는 작업의 수를 나타냅니다.
    	make -j 32 bzImage
    이는 동시에 32개의 파일을 빌드하여 bzImage를 만듭니다. 만약 충분한 램이 없다면, 이는 역효과를 가져올 수 있음에 주의하세요. 더 자주 스왑 영역을 필요하게 되어, 결국 성능을 저하시키기 때문입니다. 사용자의 시스템에 맞는 숫자를 알아내기 위해서는 다른 숫자로 실험을 해보시기 바랍니다. 어떤 숫자 이상에서는 CPU가 컴파일을 하는데 최대로 사용되고 있기 때문에, 작업의 숫자를 늘리는 것이 더 이상의 성능 향상을 가져오지 않습니다.
    각주를 보세요.

  • Q. 지금 빌드하는 작업의 숫자가 더 빠른지, 어떻게 알아낼 수 있나요?
    A. 'time' 명령을 사용하세요.
    	time make -j 32 bzImage


  • Q: 모듈를 빌드한 후, 'make modules_install'을 했는데 재대로 동작하지 않습니다. 무엇 때문인가요? /lib/modules/2.x.x 디렉토리안에 modules.dep 파일을 발견했는데, 그 파일을 복사/편집/해킹을 해야하나요?
    A: 아니요! make modules_install을 한 후, 'depmod -a 2.2.x'를 하세요. modules.dep가 자동으로 만들어질 것 입니다.

  • Q: 시스템에 여러 개의 커널을 가지고 있는데, 부팅할 때 잘못된 System.map이라는 메세지가 뜹니다. 어떻게 각 커널에 맞는 올바른 System.map을 로딩할 수 있을까요?
    A: 전에는 Lilo의 map 옵션을 사용하라고 말했습니다. 여러 사람이 제게 지적을 했듯이 그것은 틀립니다. 이 문제에 대한 두 가지 가능성 있는 방법이 있습니다. System.map 파일을 /boot/에 하나, /usr/src/linux/에 다른 하나를 둡니다. 그러나 이는 최대 두 개의 커널 이미지만을 허용합니다. 또 다른 방법은 klogd를 시작하는 스크립트를 다시 작성하는 것입니다. 커널 버전을 확인하여(uname -r), 'System.map' 뒤에 붙인 후, 그 파일명을 -k 옵션으로 klogd로 넘기는 것입니다. RedHat 6.0에서, /etc/rc.d/init.d/syslog 파일을 고쳐야 합니다. 'daemon klogd' 줄을 다음과 같이 고칩니다:
    	daemon klogd -k /boot/System.map-`uname -r`
    커널을 빌드한 후, 다음 명령을 수행합니다:
    	mv /usr/src/linux/System.map /boot/System.map-`uname -r`
    만약 선택한 배포본에서 스크립트를 위와 같은 동작을 하도록 바꾸려는 분이 있다면, 제게 어떤 변경을 해야하는 지 알려주세요. 그것들은 한데 모아 다음에 커널-팁 기사를 쓸 때 알려드리겠습니다.

  • Q: 제 시스템에는 여러 개의 커널이 있습니다. 매번 lilo.conf를 고쳐야 하는 문제가 있습니다. 더 쉬운 방법은 없나요?
    A: 가장 쉬운 방법은 lilo.conf에 vmlinuz와 vmlinuz.old를 다 가지고 있는 겁니다. (map= 항목으로 System.map과 System.map.old를 지정하고)
    (다음 예에서, 우리는 2.2.5를 돌리고 있고, 2.2.4를 백업으로 가지고 있으며, 2.2.6을 설치하려고 합니다.)

    rm -f vmlinuz vmlinuz.old system.map system.map #심볼릭 링크 없애기
    rm -f vmlinuz-2.2.4 System.map-2.2.4 #예전 커널 없애기
    ln -s vmlinuz-2.2.5 vmlinuz.old #백업 링크 설정
    ln -s vmlinuz-2.2.6 vmlinuz #새로운 커널 링크 설정
    ln -s System.map-2.2.5 System.map.old #백업 map 링크 설정
    ln -s System.map-2.2.6 System.map #새로운 map 링크 설정
    /sbin/lilo
    한 번에 두개 이상의 커널을 가지고 있다면, 이 작업은 더 길어질 것입니다. 그래서 일반적으로 새로운 lilo 항목을 추가하는 것이 더 쉽습니다.
정정:
한 독자가 내게 컴파일은 매우 CPU 의존적인 작업이기 때문에 단일 프로세서 시스템에서 make의 -j는 큰 차이는 없을 것이라는 내용의 편지를 보냈다. SMP 박스에서 보다 이득은 크지 않겠지만 내 시스템에서는 빌드가 더 빨라진 듯하다. 예로, 커널 2.2.3ac1을 -j 1로 98% CPU 사용율로 8m 44s에 컴파일했다. -j 32로 증가할 때, 99% CPU 사용율에 시간이 8m 1s로 줄었다. 실험해 보아라. 그 이득은 서로 다를 것이다.

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,