'Embedded Lab'에 해당되는 글 116건

  1. 2013.08.04 [grub 배경화면 변경]
  2. 2013.06.28 [FTL 기술흐름]
  3. 2013.04.14 [리눅스에서 itoa는 사용 불가]
  4. 2013.04.13 [gz 또는 bz2 압축하기/풀기]
  5. 2013.04.08 [blktrace 포맷을 disksim 포맷으로]
  6. 2013.04.08 [blktrace 설치법]
  7. 2013.04.08 [blktrace 사용법]
  8. 2013.04.08 [blktrace2]
  9. 2013.04.08 [blktrace1]
  10. 2013.04.08 [printk 로그 레벨]

grub2_1.png
grub2_1.png [ 749.84 KiB | 5133 번 봄 ] 

우분투 10.4부터는 Grub2 배경화면 설치가 좀더 쉬워졌습니다.
어차피 이전 팁과 거의 같지만 가급적 쉽고 빠르게 다시 정리했습니다.

우선 배경으로 이용할 사진을 준비합니다.

터미널에서 sudo apt-get install grub2-splashimages 를 입력하면 Grub2용 배경그림이
/usr/share/images/grub에 설치됩니다.
이것을 이용하셔도 되고 개인적으로 좋아하는 그림이 있으시면 아무거나 사용가능합니다.

그림은 png, tga 포멧이어야 하며 해상도는 640x480, 800x600, 1024x768정도가 적당합니다.
1280x1024도 가능하지만 폰트가 작게 보여서 불편합니다.

개인 사진을 넣고 싶으시다면 gimp를 이용해서 크기를 맞추고 png포멧으로 저장해 주면 됩니다.
예제로 800x600 해상도의 첨부파일 Oak_800.png를 이용해 보겠습니다.

배경그림이 결정되었다면 그림 파일을 /boot/grub 디렉토리로 옮겨줍니다.
(그림 파일을 꼭 옮길 필요는 없지만 한 곳에 모아 두어야 관리가 편합니다.)
옭길 때 관리자 모드여야 하기 때문에 Alt + F2 누르고 gksu nautilus를 실행하면 편하실 겁니다.


지금부터는 Grub2 설정입니다.

Grub2가 되면서 기존의 menu.lst 설정 파일이 사라지고 대신 여러개의 파일로 나누어졌습니다.
간략히 설명드리자면 다음 2개의 파일을 수정하고 마지막에 sudo update-grub을 실행해 주면 됩니다.


    /etc/default/grub
    /etc/grub.d/05_debian_theme


우선 Alt + F2를 누르고 gksu gedit /etc/default/grub을 입력합니다.


    # If you change this file, run 'update-grub' afterwards to update
    # /boot/grub/grub.cfg.

    GRUB_DEFAULT=0
    #GRUB_HIDDEN_TIMEOUT=0
    GRUB_HIDDEN_TIMEOUT_QUIET=true
    GRUB_TIMEOUT=5
    GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
    GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
    GRUB_CMDLINE_LINUX=""

    # Uncomment to disable graphical terminal (grub-pc only)
    #GRUB_TERMINAL=console

    # The resolution used on graphical terminal
    # note that you can use only modes which your graphic card supports via VBE
    # you can see them in real GRUB with the command `vbeinfo'
    GRUB_GFXMODE=800x600


관리자 모드로 파일이 열리면 붉은색 부분을 수정해 줍니다.

GRUB_DEFAULT은 기본으로 선택할 항목을 설정하는 것으로 제일 위 부분이 0부터 시작합니다.
    => MS Windows와 멀티부팅을 하고 자주 Windows로 부팅한다면 이부분을 수정해 줍니다.
GRUB_TIMEOUT=5는 5초후에 자동으로 선택 항목으로 부팅한다는 말입니다.
GRUB_GFXMODE=800x600은 배경그림의 해상도를 설정하는 부분입니다.
    => grub2-splashimages를 이용하시는 분들은 640x480으로 설정하면 됩니다.

설정이 끝나면 저장한 다음 다시 Alt + F2를 누르고 gksu gedit /etc/grub.d/05_debian_theme 을 입력합니다.


    #!/bin/bash -e

    source /usr/lib/grub/grub-mkconfig_lib

    # this allows desktop-base to override our settings
    f=/usr/share/desktop-base/grub_background.sh
    if test -e ${f} ; then
    source ${f}
    else
    WALLPAPER="/boot/grub/Oak_800.png"
    COLOR_NORMAL="white/black"
    COLOR_HIGHLIGHT="blue/white"
    fi


파일이 열리고 위와 같은 스크립트가 나타나는데 10번 째 줄 붉은색 부분이 배경으로 쓰일 파일이름입니다.
기존의 moreblue-orbit-grub을 지우고 원하는 그림 파일의 경로를 정확히 적어 넣으시면 됩니다.

11번째 줄 COLOR_NORMAL은 메뉴폰트의 전경색/배경색이고 다음 줄 COLOR_HIGHLIGHT는 선택항목의 전경색/배경색입니다.
단 배경색이 black일 경우는 투명으로 나타나니 유의해 주시고 아래표를 참고해서 색깔은 선택해 주면 됩니다.

Attachment:
grub2_2.png
grub2_2.png [ 16.23 KiB | 5133 번 봄 ] 

메뉴폰트의 배경색은 black(투명)으로 설정하고 배경그림이 밝은 경우 전경색을 어둡게하고 배경그림이 어두우면
전경색을 밝게 하는 것이 눈에 잘 띄고 보기 좋습니다.

설정이 모두 끝나면 파일을 저장하고 나옵니다.

다시 터미널을 열고 sudo update-grub 을 입력해 Grub2 설정을 시스템에 적용합니다.
그러면 /boot/grub/grub.cfg 파일이 새로 생성되는데 부팅시 Grub2가 이 파일을 직접 읽어들입니다.

만약 Grub 메뉴의 위아래 순서를 바꾸고 싶다면 Alt+F2 누르고 gksu gedit /boot/grub/grub.cfg 한 후 
menuentry 'ubuntu ... ... ' { ... ... ... } 부위를 잘라내고 윈하는 위치에 붙여넣기 해 주면 됩니다. 

설정이 모두 끝났으니 이제 다시 재부팅합니다.
멋진 Grub이 보이세요 !

테마의 통일감을 주기 위해 바탕화면 배경그림을 줄여서 Grub 배경으로 사용해도 좋습니다.
마지막으로 Oak의 원본 이미지에 링크 겁니다. 데스크탑 배경으로 괸찮습니다.


'Embedded Lab > linux, x86' 카테고리의 다른 글

[커널스택]  (0) 2013.08.13
[커널 예전 버전 받기]  (0) 2013.08.06
[리눅스에서 itoa는 사용 불가]  (0) 2013.04.14
[gz 또는 bz2 압축하기/풀기]  (0) 2013.04.13
[blktrace 포맷을 disksim 포맷으로]  (0) 2013.04.08
Posted by cyj4369
,

요즘 FTL에 대한 연구를 하고 있는데 그동안 연구되었던 FTL의 기술 발전 흐름을 정리해 보았습니다. 


  • NAND flash의 단점과 FTL의 등장

    NAND flash는 비 휘발성 메모리 저장장치로 사용하기에 적합하다. 그 이유는 용량대비 가격이 저렴하기 때문이고, 대용량 device를 만들기 용이하기 때문이다. 하지만, NAND flash는 태생적인 단점이 몇 가지 있다.

    • Byte 단위의 접근을 허용하지 않는다. Page단위의 Read/Write 만 가능하다. (XIP 불가능)
    • 덮어쓰기가 되지 않는다. Write를 하기 위해서는 Erase후 program해야 한다.
    • Program과 Erase의 단위가 다르다. Program 하는 단위보다 Erase하는 단위가 월등히 크다
    • Program/Erase 할 수 있는 횟수(P/E cycle)가 무한하지 않다.

       

    이러한 문제 때문에 H/W적으로는 NAND interface protocol 이 S/W적으로는 FTL (Flash Translation Layer)이 필요하게 되었다. FTL 논문을 중심으로 FTL기술이 어떻게 발전해 왔는지 알아보기로 한다.

       

       

  • BAST (2002)

    NAND에서 덮어쓰기 동작을 구현하는 가장 간단한 방법은 쓰기 동작시 마다 해당 page가 속한 Block을 통째로 지우고 다시 쓰는 방법을 사용하는 것이다. 하지만, 이 방법은 한 Block내에 속한 page가 update될 때마다 erase되어야 하고 나머지 page들을 copy해 주어야 하기 때문에 성능면이나 NAND의 수명 측면에서 문제가 되었다. 그래서 등장한 것이 Mapping이라는 개념이고 Write cache(log block)라는 개념이다.

       

    031810_0437_FTL1.png

    BAST 는 log block이라는 cache block을 할당하여 write operation을 수행하는 방법을 사용하였다. Log block은 1:1로 연관되는 Data block이 있으며, 해당 Block에 속한 page들을 write한다. In place order로 program해야 하는 Data block과 달리 Log Block은 Out of place order로 write하고 page map을 관리하는 방법을 사용하였다. Log block은 Data block에 비해 매우 작은 숫자이기 때문에 비어 있는 free block이 필요하면 이전에 사용된 Log block의 데이터를 Data block으로 전송하고 erase하는 방법을 사용하였다. 이를 Merge, Migration, Compaction 또는 Garbage collection이라고 한다.

    파일시스템의 write 패턴에 따라 log block이 data block으로 migration되는 방법이 다르다.

    031810_0437_FTL2.png

    유효한 데이터가 Data block과 Log block에 모두 있는 경우에는 Free block에 data block과 Log block에 있는 데이터를 copy한 뒤 Data block과 log block을 erase하여 Free block으로 만든다.(Full merge) 이 때는 2번의 erase, 1Block copy가 발생한다. 유효한 데이터가 Log block에만 있는 경우 Free block에 Log block의 내용을 copy하고 Log block을 erase한다.(Partial merge) 이 때는 1번의 erase와 1 block copy가 일어난다. 마지막으로 log block의 내용이 모두 유효하면서 in place order로 적혔을 때이다. 이 경우는 Log block을 그대로 Data block으로 mapping만 바꿔주면 된다. 이 때는 erase한번만 일어난다.

    Free block을 얻는 목적은 같은데, 시나리오에 따라서 merge하는 비용은 다른 것을 알 수 있다.

    BAST 는 적용이 간단하고 Sequential data의 비중이 많은 응용에서는 높은 성능을 발휘할 수 있어, card나 USB스토리지에서 널리 사용되었다. 하지만, random 패턴에서는 낮은 성능이 문제가 되었다. 또한, page와 Block의 크기가 커지면서 Switch merge의 비중이 줄고 Full merge가 늘면서 복잡한 응용에서의 FTL로는 부족한 점이 많았다.

    하지만, 적은 리소스로 큰 용량의 NAND를 관리할 수 있다는 점과, 초창기 NAND의 한계를 극복할 수 있다는 가능성을 제시한 의미있는 논문이다.

       

  • FAST, Superblock (2006)

    BAST이후 이 분야에 대한 연구도 활발해 졌다. FAST와 Superblock은 BAST를 기본으로 하면서 BAST 의 단점인 Full merge의 비율을 줄이는데 초점을 두었다.

    031810_0437_FTL3.png

    BAST-위 그림의 (a)의 특징은 Update(log) block과 Data block이 1:1로 대응된다는 점이다. 만약 파일시스템의 Write 패턴이 random이면서 그 범위가 다양하다면(여러 Block boundary를 넘나든다면) I/O의 크기에 비해 많은 수의 log block이 필요로 하게 된다. 이는 log block이 다 차기도 전에 migration하는 결과를 가져와 빈번한 merge로 인해 성능효율성이나 write한 용량대비 많은 erase횟수 유발하게 된다. 게다가 이 때 merge는 full merge나 partial merge이 된다.

       

    FAST는 Update block과 Data block 의 연관 관계를 1:1 에서 1:N으로 확장하여 한 Update block에 여러 Data block이 연관 될 수 있게 하였다. 이렇게 되면 한 Update block에 여러 data block의 data를 담을 수 있어 넓은 범위의 random write가 발생하는 경우 BAST 보다는 Update block에 최대한 많은 양의 data를 write할 수 있었다.(공간 이용도가 높아진다). 하지만, N이 커지면 커질 수록 Migration하는 비용이 커지고, mapping 데이터 양이 커지는 단점이 있다. 즉, migration하는 횟수는 줄었지만, 반대로 비용은 커진 것이다.

       

    Superblock 은 FAST의 연장선에서, FAST의 1:N을 유지하면서도 인접한 Data block을 Group으로 묶어 Superblock이라 칭하고 Superblock내에서는 out of place로 관리하여 Migration 비용을 줄이고자 하였다. 장점은 BAST에 비해 Update block의 활용이 많고, superblock내에서는 out of place로 관리하기 때문에 partial merge를 switch merge로 대신할 수 있다는 장점이 있다. 하지만, superblock도 merge를 해야 하기 때문에 full merge시 비용이 큰 단점이 있다. 또한, out of place map을 유지하는 비용도 추가로 필요하다.

       

  • SAST (2007)

    BAST 와 FAST 는 각각 장.단점이 있다. BAST 는 메모리사용량이 적은 반면, random 패턴의 write시 log block활용도가 낮아 잦은 merge가 일어나고, FAST는 Disk 공간 사용도가 높은 반면 garbage collection의 비용이 큰 단점이 있다. 이를 적절하게 조절할 수 있는 N:N+K mapping 알고리즘이 제안되었다.

    031810_0437_FTL4.png

    SAST 는 Log block과 Log block에 연관되는 Data block의 개수를 조절하여 log block의 공간 활용도를 높이면서 log block에 연관되는 data block의 개수를 제한하여 merge 비용을 줄이려고 하였다.

       

  • LAST (2009)

    Data의 write 패턴은 Random 과 Sequential, Hot과 Cold로 구분 할 수 있다. 이러한 패턴을 고려한 mapping방법이 제안되었다.

    031810_0437_FTL5.png

       

    LAST는 기본적으로 FAST를 계승하는 알고리즘이다. Random과 Sequential을 구별하여 Log block을 할당하였고, Random log block중에서도 Hot과 Cold를 구별하였다. LAST 는 Random 패턴을 구별하기 위해 Write 요청 단위(4KB)를 사용하였다. Hot과 Cold는 최초 write요청은 cold로 지정하고 같은 주소의 요청이 반복되면 hot으로 변경한다. hot random write를 따로 관리하기 때문에 merge 횟수를 줄일 수 있다.

       

  • A-SAST, KAST (2009)

    SAST 이후 이 알고리즘들을 보완하거나 FAST, Superblock의 장점을 융합, 발전시키는 알고리즘들이 등장하였다.

    A-SAST는 기본적으로 SAST의 N:K mapping방법을 사용하지만, N과 K를 runtime시 변경할 수 없었던 SAST 를 개량하여 write 패턴에 따라 동적으로 변경하는 방법을 사용하였다.

    031810_0437_FTL6.png

    A-SAST 는 Log block의 공간 활용도가 떨어질 때는, log block과 연관된 Data block을 늘려 공간활용도를 높이고, 반면 log block의 공간 활용도가 증가하면 log block과 data block의 개수를 줄여 merge 횟 수와 비용을 동시에 줄이는 방법을 제안하였다.

    KAST는 FAST를 바탕으로 하되, 하나의 Log block에 N개의 Data block이 연관되었던 것을 최대 K 개로 제한하였다.

    031810_0437_FTL7.png

    또한, Random log block(RLB)과 Sequential log block(SLB)을 구분하여 data의 패턴에 따라 상호 변환이 가능하게 하였다.

    031810_0437_FTL8.png

    조건에 따라 RLB 를 확장하거나 SLB로 전환하는 방법이 제안되었다. 이 방법의 특징은 data padding을 사용하여 RLB를 SLB로 전환하는 알고리즘이다. Log block에서 대부분 in place order로 write될 수 있는 건인데 조금 틀어진 경우도 swap merge를 유도 할 수 있다.

       

  • 결론

    FTL은 BAST 를 시작으로 KAST에 이르기 까지 서로의 장.단점을 계승 보완하여 발전하였다.FTL이 발전되온 과정을 살펴보면 "Merge 횟수 및 비용 최소화"라는 공통적인 목표를 발견할 수 있다. 이 목표는 성능 뿐 아니라 NAND의 수명에도 영향을 미치기 때문에 중요한 요소이다. Merge 횟수와 비용을 줄이려는 노력은 아래와 같은 방법으로 구체화 되었다.

       

    • Log block의 공간 활용도 증대
    • Write 패턴에 최적화된 Log block 운용 (Random / Sequential, Hot / Cold)
    • Log block와 Data block의 연관 관계 다변화 (1:N, N:K)
    • Block mapping 바탕의 부분적인 Page mapping 운용

       

    SSD의 등장으로 고비용 고사양 device의 시대가 열렸다. 또한, NAND의 Block 및 page의 크기가 계속해서 증가할 것이므로 Block mapping에는 한계가 있다. 따라서 Block mapping의 일부분을 Page mapping으로 보완하려는 시도가 좀 더 발전 할 것으로 예상된다.

    또한, 평균 merge비용 뿐 아니라 순간 최고 merge 비용에 대한 연구, NAND의 공정이 미세화 될 수록 점점 특성이 나빠지는 현상을 고려한 연구도 필요할 것으로 생각된다.

'Embedded Lab > FLASH MEMORY' 카테고리의 다른 글

[NAND 플래시의 종류]  (0) 2012.10.17
[SSD에서 FTL 관리 기법 - BPLRU]  (0) 2012.09.09
[SSD 개론]  (0) 2012.09.06
Posted by cyj4369
,

aoti()와는 달리 itoa()는 별도의 library를 사용하지 않는 한, linux에서는 존재하지 않는 함수이다.


보통 비슷한 용도로 sprintf()를 사용한다.


sprintf( str, "%d", 1234 );


그 다음에 


printf("%s\n", str);

'Embedded Lab > linux, x86' 카테고리의 다른 글

[커널 예전 버전 받기]  (0) 2013.08.06
[grub 배경화면 변경]  (0) 2013.08.04
[gz 또는 bz2 압축하기/풀기]  (0) 2013.04.13
[blktrace 포맷을 disksim 포맷으로]  (0) 2013.04.08
[blktrace 설치법]  (0) 2013.04.08
Posted by cyj4369
,

gzip

압축하기 gzip cvs.pdf
압축풀기 gzip -d cvs.pdf.gz 또는 gunzip cvs.pdf.gz



bzip2

압축하기 bzip2   cvs.pdf
압축풀기 bzip2   -d   cvs.pdf.bz2    또는   bunzip2 cvs.pdf.bz2

 

tar로 묶어서 gzip으로 압축된 파일 풀기

가장 많이 사용되는 형식이다. 이렇게 압축된 파일은 tar.gz 또는 tgz 과 같은 확장자 형식을 지니며 아래와 같이 간편하게 풀 수 있다.

tar  xvfz  test.tar.gz

tar로 묶고 bzip2로 압축된 파일은 tar.bz2 와 같은 확장자 형식을 가지며 다음과 같이하여 푼다.

tar  xvfj   test.tar.bz2

 


출처 : http://ssulsamo.egloos.com/3050850



*압축하기
tar [옵션] [압축 파일 이름] [압축하고자 하는 파일 or 디렉토리]
tar cvf test.tar test

*압축풀기
tar [옵션] [압축 파일 이름]
tar xvf test.tar



*tar.gz
tar는 압축을 하는 툴이 아니다 단지 여러개의 파일을 하나의 파일로 모아주기만 한다.
만약에 압축을 하고 싶으면 옵션에 z를 넣고 파일 이름에 확장자를 tar.gz로 한다. (그냥 tar로 해도 상관은 없다..)
-z옵션은 GNU tar에서만 제공하는 기능이다. (리눅스는 GNU tar를 사용한다)

 - 압축하기
    
tar zcvf test.tar.gz test

 - 압축풀기
    tar zxvf test.tar.gz


'Embedded Lab > linux, x86' 카테고리의 다른 글

[grub 배경화면 변경]  (0) 2013.08.04
[리눅스에서 itoa는 사용 불가]  (0) 2013.04.14
[blktrace 포맷을 disksim 포맷으로]  (0) 2013.04.08
[blktrace 설치법]  (0) 2013.04.08
[blktrace 사용법]  (0) 2013.04.08
Posted by cyj4369
,

- sudo blktrace -d /dev/sda5 -a complete -o - |  blkparse -f "%5T.%9t 0 %8S %9n %3d \n" -i - -o out.txt 로 입력해서 파일로 저장한다

T.t =  I/O들어오는시간, D = Device Number,  S =  Sector Number, n = Sector를 몇개 쓸것인지(record size),  d =Read/Write

① blktrace로 trace를 추출


② trace추출 후 disksim형태로의 변환
    -blktrace에서 I/O들어오는 시간을 ns로 표현하는데
      disksim에서는 ms로 바꿔서 설정해야된다
    - Read = 0, Write = 1로 바꿔준다

윈도우나 리눅스 인스톨은 VirtualBox에서 가상 windows7설치를 실행하는 동안에 blktrace 실행

출처 : http://dmclab.hanyang.ac.kr/tc/younjunsik/entry/20105-10-작업일지

'Embedded Lab > linux, x86' 카테고리의 다른 글

[리눅스에서 itoa는 사용 불가]  (0) 2013.04.14
[gz 또는 bz2 압축하기/풀기]  (0) 2013.04.13
[blktrace 설치법]  (0) 2013.04.08
[blktrace 사용법]  (0) 2013.04.08
[blktrace2]  (0) 2013.04.08
Posted by cyj4369
,

block trace 란 리눅스에서 Disk I/O 가 일어날때,
linux 하위 level 에서 어떻게 Block 단위의 I/O 가 일어났는지 알아낼수 있는 Tool 
DB 접근에서 주로 DB recovery 나 join 시의 DIsk I/O 패턴을 알아내는데 유용하다. 

1. yum install blktrace-1.0.1-3.XX .. 를 인스톨 한다. ( block trace 뜨는 프로그램 )
http://rpm.pbone.net/index.php3/stat/3/srodzaj/1/search/blktrace 


2. seekwatcher 다운로드 ( 생성한 block trace 를 image 로 정리해서 보여줌 ) 
   - 미리 설치할 package : http://sourceforge.net/projects/matplotlib/files/matplotlib/matplotlib-0.99.1/matplotlib-0.99.1.2.tar.gz/download 
 
   - seekwatcher http://oss.oracle.com/~mason/seekwatcher/seekwatcher-0.12.tar.bz2  

3. seekwatcher 압출을 풀면 seekwatcher 란 실행파일이 생성 됨 이 파일을 /usr/bin 에 복사후 사용

blktrace 실행


1. mkdir /trace 
2. blktrace -d /dev/target_device 
3. cd /trace 에 device_name.blktrace 파일이 생성 된다.

seekwatcher 실행


seekwatcher  -t trace파일 


exception


 

/usr/lib/python2.6/site-packages/matplotlib/rcsetup.py:117: UserWarning: rcParams key "numerix" is obsolete and has no effect;
 please delete it from your matplotlibrc file
  warnings.warn('rcParams key "numerix" is obsolete and has no effect;\n'
   

  cd $HOME
  rm .matplotlib/



[root@ljh8324-skku /]# blktrace -d /dev/sdb1
Invalid debug path /sys/kernel/debug: 0/Success 

$ mount -t debugfs debugfs /sys/kernel/debug

'Embedded Lab > linux, x86' 카테고리의 다른 글

[gz 또는 bz2 압축하기/풀기]  (0) 2013.04.13
[blktrace 포맷을 disksim 포맷으로]  (0) 2013.04.08
[blktrace 사용법]  (0) 2013.04.08
[blktrace2]  (0) 2013.04.08
[blktrace1]  (0) 2013.04.08
Posted by cyj4369
,

Usage 1)
blktrace /dev/sda /dev/sdc &
kill -15 pid
blkparse sda sdc > events
less events
 
 
 
Usage 2)
화면에서 실시간 확인시
blktrace [블록장치경로] -a complete -o - | blkparse -f “%d,%S,%n\n” -i -
 
Usage 3)
파일로 저장시
blktrace [블록장치경로] -a complete
blkparse -f “%d,%S,%n\n”-i [tracefile] > test.csv
 
 -f Output format. Customize the output format. The format field
   identifiers are:

%a - Action
%c - CPU ID
%C - Task command (process) name
%d - Direction (r/w)
%D - Device number
%e - Error number
%M - Major
%m - Minor
%N - Number of bytes
%n - Number of sectors
%p - PID
%P - PDU
%s - Sequence number
%S - Sector number
%t - Time (wallclock - nanoseconds)
%T - Time (wallclock - seconds)
%u - Time (processing - microseconds)
%U - Unplug depth
 

Default Output

The standard header (or initial fields displayed) include:

"%D %2c %8s %5T.%9t %5p %2a %3d"

Breaking this down:

%D
Displays the event's device major/minor as: %3d,%-3d.
%2c
CPU ID (2-character field).
%8s
Sequence number
%5T.%9t
5-character field for the seconds portion of the time stamp and a 9-character field for the nanoseconds in the time stamp.
%5p
5-character field for the process ID.
%2a
2-character field for one of the actions.
%3d
3-character field for the RWBS data.

Seeing this in action:

8,0 3 1 0.000000000 697 G W 223490 + 8 [kjournald]

The header is the data in this line up to the 223490 (starting block). The default output for all event types includes this header.

 

 
 
$ blktrace -d /dev/sda -o - | blkparse -i -
/sys/kernel/debug does not apper to be a debug filesyste

위와 같은 에러를 내면서 blktrace가 동작하지 않는다면, 



아래와 같이 해 준다.



$ mount -t debugfs debugfs /sys/kernel/debug

 

To launch automatically,

put this into /etc/fstab

 

debug /sys/kernel/debug debugfs default 0 0



출처 : http://blog.naver.com/PostView.nhn?blogId=go4real&logNo=89718340&redirect=Dlog&widgetTypeCall=true

'Embedded Lab > linux, x86' 카테고리의 다른 글

[blktrace 포맷을 disksim 포맷으로]  (0) 2013.04.08
[blktrace 설치법]  (0) 2013.04.08
[blktrace2]  (0) 2013.04.08
[blktrace1]  (0) 2013.04.08
[printk 로그 레벨]  (0) 2013.04.08
Posted by cyj4369
,

이전 글 보기:


지금까지 상위 (filesystem) 계층에서 요청된 I/O 연산이 bio를 거쳐 request로 만들어지는 과정을
살펴보았다. 이제 이렇게 생성된 request가 I/O 스케줄러 단에서 처리되는 방식을 알아볼 것이다.

앞서 살펴보았듯이 생성된 request는 대부분 (per-task) plugging 기능이 적용된 상태일 것이므로
(직접적인 read/write의 경우는 물론 read-ahead, writeback의 경우도 이에 해당한다)
I/O 스케줄러에게 전달되기에 앞서 plugged list에 잠시 보관된다.

plugging 기능을 사용하려면 해당 함수의 스택에 blk_plug 구조체를 할당하고
먼저 blk_start_plug() 함수를 호출한 후에 I/O 연산을 발생시키고
마지막으로 blk_finish_plug() 함수를 호출하면 된다.

blk_start_plug() 함수는 주어진 blk_plug 구조체를 적절히 초기화한 후에
현재 태스크의 plug 필드에 저장하는데, 만약 blk_start_plug() 함수가 중첩된 실행 경로 상에서
여러 번 호출되었다면 제일 첫 번째로 호출된 경우에만 plug 필드를 저장한다.
이는 plugging 로직이 가장 상위 수준에서 처리될 수 있도록 보장해 준다.

blk_finish_plug() 함수는 태스크의 plug 필드와 인자로 주어진 blk_plug 구조체가 일치하는 경우에만
동작하며, 대응하는 start 함수와 현재 finish 함수 사이에서 발생한 I/O 연산 (request)들을 모두
I/O 스케줄러에게 전달하고 (insert) 실제로 드라이버가 I/O를 실행하도록 한다.
request를 I/O 스케줄러에게 전달하는 방식은 request의 종류 및 상황에 따라 몇 가지 정책이 적용된다.

만약 plugged list에 request가 존재하는 상황에서 어떠한 이유로 인해 현재 태스크가 더 이상
실행되지 못하고 (자발적으로!) sleep 해야한다면 kblockd 스레드가 대신 plugged list를 넘겨받아
I/O 스케줄러에게 전달한 뒤에 I/O 연산을 실행한다.

plugged list 내의 request들이 I/O 스케줄러에게 전달되는 순간 다시 한번 merge가 가능한지
검사하게 되는데 이는 여러 태스크들이 동시에 디스크 상의 비슷한 위치에 접근하는 경우 각각의 태스크들은
자신의 plugged list에 포함되어 다른 태스크들은 접근하지 못하던 request들이 이제 공유되므로
새로이 merge될 가능성이 있기 때문이다. 이러한 정책은 ELEVATOR_INSERT_SORT_MERGE로 나타내며,
plugging 기법을 이용하지 않을 시에는 이러한 merge 시도를 할 필요가 없으므로
ELEVATOR_INSERT_SORT 정책이 사용된다.

I/O 스케줄러는 주어진 request들을 디스크 상의 위치에 따라 배열하여 seek time을 최소화하기 위해
노력하는데, 이 때 기본적으로 디스크의 헤드가 한 쪽 방향으로만 일정하게 움직이도록 하므로
이를 엘리베이터 (elevator)라고도 부른다. (물론 세부 동작은 각 I/O 스케줄러마다 다르다)

이를 위해서는 I/O 스케줄러 내부에 request들을 (잘 정렬하여) 보관할 자료구조가 필요한데
여기서는 rb tree (red-black tree)가 사용되며, 앞서 살펴보았듯이 (merge를 위해)
정렬된 rb tree 내의 특정 request를 빨리 찾아내기 위해 별도의 해시 테이블을 가지고 있다.
이렇게 rb tree 내에 보관된 request들은 REQ_SORTED라는 플래그를 추가하여 표시한다.

하지만 FLUSH/FUA request에 대해서는 약간 다른 ELEVATOR_INSERT_FLUSH 정책을 취하게 되는데
이러한 request들은 해당 디스크의 특성에 따라 다르게 처리될 수 있으며 또한 일반적인 merge를
지원하는 대신 중첩된 flush 요청을 한꺼번에 처리하는 기법을 사용하기 때문이다.

앞서 살펴보았듯이 FLUSH는 디스크 내부의 write-back 캐시의 내용을 실제 디스크에 저장하라는 의미이며
FUA는 write-back 캐시가 없는 것처럼 현재 데이터를 디스크에 직접 기록하라는 의미이다.
따라서 디스크가 내부 캐시를 가지지 않는 경우라면 FLUSH/FUA는 아무런 의미가 없다.
또한 캐시를 가진 디스크라고 하더라도 FUA 지원 여부는 선택적이므로 지원하지 않는 디스크의 경우
FUA request가 들어오면 이를 다시 FLUSH로 변경하여 처리하게 된다.

특히 FUA request의 경우 write할 데이터와 함께 요청되므로 최악(?)의 경우
하나의 (FLUSH & FUA) request는 다음과 같이 세 단계로 나누어 처리되어야 한다.

 (pre) FLUSH + WRITE + (post) FLUSH

따라서 FLUSH/FUA request는 REQ_FLUSH_SEQ 플래그를 추가하여 이러한 과정을 거치고 있음을 나타내며
이에 대한 추가적인 정보를 request 구조체 내의 flush (구조체) 필드에 저장하고 있다.

또한 이러한 request를 여러 태스크가 동시에 요청하는 경우 FLUSH 연산이 여러 차례 실행될 수 있으나
그 사이 데이터가 write 되지 않았다면 실질적으로 의미가 없으므로 (캐시 내의 모든 데이터가 이미 저장되었다)
이러한 중첩된 FLUSH 연산을 한 번만 수행해도 동일한 효과를 얻을 수 있게 될 것이다.

따라서 이러한 FLUSH/FUA request를 효율적으로 처리하기 위해 별도의 queue를 유지하며
총 2개의 리스트를 통해 하나의 FLUSH 요청이 실행되는 동안 발생된 FLUSH request들은 다른 리스트에
대기시키는 double buffering 방식을 이용하여 중첩된 request들을 한꺼번에 완료시키게 된다.

이렇게 I/O 스케줄러에게 전달된 request는 최종적으로 dispatch queue로 전달된다.
이렇게 전달된 request는 더 이상 merge될 수 없으므로 해시 테이블에서 제거되며 dispatch queue 내에서
디스크 섹터 번호를 기준으로 정렬된다 (단, 이미 처리 중이거나 REQ_SOFTBARRIER 플래그가 설정된
request들은 더 이상 정렬할 수 없으므로 그 이후의 request들만을 고려하게 된다).

dispatch queue 내의 request들은 순서대로 드라이버에 의해 처리되며
이렇게 request의 처리를 실제로 시작하는 것을 dispatch 혹은 issue라고 부른다.
dispatch된 request들은 REQ_STARTED 플래그를 추가로 설정하며 queue에서 제거되며
디스크 오류로 인해 request가 오랫동안 완료되지 못하는 경우를 방지하기 위해 타이머를 설정한다.

dispatch queue가 비게되면 드라이버는 I/O 스케줄러에게 새로운 request를 queue에 추가하도록 요청한다.
request가 더이상 존재하지 않거나 I/O 스케줄러가 dispatch queue로 전달하지 않으면 처리는 종료된다.

지금껏 블록 장치 I/O 연산이 전달되는 과정을 간략히 살펴보았는데
리눅스 커널의 블록 서브시스템 관리자이기도 한 Jens Axboe님이 만든 blktrace 도구를 이용하면
현재 시스템 내의 디스크 장치의 I/O 과정을 한 눈에 알아볼 수 있는 방법을 제공한다.

만일 기본적인 출력 내용을 터미널 상에서 확인하고 싶다면 단순히 btrace라는 스크립트를 이용할 수 있다.
그 외의 자세한 옵션은 blktrace 및 blkparse의 man 페이지를 참조하기 바란다.
아래는 내 시스템에서의 출력 내용 중 일부이다.

# btrace /dev/sda
  ...
  8,0    0       60    10.168088873   178  A  WS 353925552 + 8 <- (8,5) 46516656
  8,0    0       61    10.168089576   178  Q  WS 353925552 + 8 [jbd2/sda5-8]
  8,0    0       62    10.168097323   178  G  WS 353925552 + 8 [jbd2/sda5-8]
  8,0    0       63    10.168098432   178  P   N [jbd2/sda5-8]
  8,0    0       64    10.168100785   178  A  WS 353925560 + 8 <- (8,5) 46516664
  8,0    0       65    10.168101033   178  Q  WS 353925560 + 8 [jbd2/sda5-8]
  8,0    0       66    10.168102298   178  M  WS 353925560 + 8 [jbd2/sda5-8]
  8,0    0       67    10.168104627   178  A  WS 353925568 + 8 <- (8,5) 46516672
  8,0    0       68    10.168104843   178  Q  WS 353925568 + 8 [jbd2/sda5-8]
  8,0    0       69    10.168105513   178  M  WS 353925568 + 8 [jbd2/sda5-8]
  8,0    0       70    10.168106517   178  A  WS 353925576 + 8 <- (8,5) 46516680
  8,0    0       71    10.168106744   178  Q  WS 353925576 + 8 [jbd2/sda5-8]
  8,0    0       72    10.168107411   178  M  WS 353925576 + 8 [jbd2/sda5-8]
  8,0    0       73    10.168109205   178  A  WS 353925584 + 8 <- (8,5) 46516688
  8,0    0       74    10.168109435   178  Q  WS 353925584 + 8 [jbd2/sda5-8]
  8,0    0       75    10.168110081   178  M  WS 353925584 + 8 [jbd2/sda5-8]
  8,0    0       76    10.168111110   178  A  WS 353925592 + 8 <- (8,5) 46516696
  8,0    0       77    10.168111328   178  Q  WS 353925592 + 8 [jbd2/sda5-8]
  8,0    0       78    10.168111953   178  M  WS 353925592 + 8 [jbd2/sda5-8]
  8,0    0       79    10.168112970   178  A  WS 353925600 + 8 <- (8,5) 46516704
  8,0    0       80    10.168113266   178  Q  WS 353925600 + 8 [jbd2/sda5-8]
  8,0    0       81    10.168113923   178  M  WS 353925600 + 8 [jbd2/sda5-8]
  8,0    0       82    10.168115804   178  A  WS 353925608 + 8 <- (8,5) 46516712
  8,0    0       83    10.168116019   178  Q  WS 353925608 + 8 [jbd2/sda5-8]
  8,0    0       84    10.168116656   178  M  WS 353925608 + 8 [jbd2/sda5-8]
  8,0    0       85    10.168118495   178  A  WS 353925616 + 8 <- (8,5) 46516720
  8,0    0       86    10.168118722   178  Q  WS 353925616 + 8 [jbd2/sda5-8]
  8,0    0       87    10.168119371   178  M  WS 353925616 + 8 [jbd2/sda5-8]
  8,0    0       88    10.168121449   178  A  WS 353925624 + 8 <- (8,5) 46516728
  8,0    0       89    10.168121665   178  Q  WS 353925624 + 8 [jbd2/sda5-8]
  8,0    0       90    10.168122304   178  M  WS 353925624 + 8 [jbd2/sda5-8]
  8,0    0       91    10.168123327   178  A  WS 353925632 + 8 <- (8,5) 46516736
  8,0    0       92    10.168123554   178  Q  WS 353925632 + 8 [jbd2/sda5-8]
  8,0    0       93    10.168124212   178  M  WS 353925632 + 8 [jbd2/sda5-8]
  8,0    0       94    10.168125241   178  A  WS 353925640 + 8 <- (8,5) 46516744
  8,0    0       95    10.168125462   178  Q  WS 353925640 + 8 [jbd2/sda5-8]
  8,0    0       96    10.168126087   178  M  WS 353925640 + 8 [jbd2/sda5-8]
  8,0    0       97    10.168128954   178  I  WS 353925552 + 96 [jbd2/sda5-8]
  8,0    0        0    10.168131125     0  m   N cfq178 insert_request
  8,0    0        0    10.168131926     0  m   N cfq178 add_to_rr
  8,0    0       98    10.168133660   178  U   N [jbd2/sda5-8] 1
  8,0    0        0    10.168135051     0  m   N cfq workload slice:100
  8,0    0        0    10.168136148     0  m   N cfq178 set_active wl_prio:0 wl_type:1
  8,0    0        0    10.168136908     0  m   N cfq178 Not idling. st->count:1
  8,0    0        0    10.168138014     0  m   N cfq178 fifo=          (null)
  8,0    0        0    10.168138615     0  m   N cfq178 dispatch_insert
  8,0    0        0    10.168139739     0  m   N cfq178 dispatched a request
  8,0    0        0    10.168140355     0  m   N cfq178 activate rq, drv=1
  8,0    0       99    10.168140588   178  D  WS 353925552 + 96 [jbd2/sda5-8]
  8,0    0      100    10.168534375     0  C  WS 353925552 + 96 [0]
  8,0    0        0    10.168554570     0  m   N cfq178 complete rqnoidle 1
  8,0    0        0    10.168555455     0  m   N cfq178 set_slice=120
  8,0    0        0    10.168556271     0  m   N cfq178 Not idling. st->count:1
  8,0    0        0    10.168556774     0  m   N cfq schedule dispatch
  ...

여기서 주의깊게 봐야할 부분은 알파벳 약자로 이루어진 6번째와 7번째 열 부분이다.
6번째 열이 나타내는 것은 해당 request가 처리되는 과정을 나타내며 (아래에서 설명)
7번째 열이 나타내는 것은 request의 종류로 여기서 WS는 sync write, N은 none에 해당한다.

6번째 열을 자세히 살펴보면 약간의 규칙성을 발견할 수 있는데 (첫번째 request는 제외)
먼저 A는 remap의 약자로 (8,5) 즉 /dev/sda5 파티션에 대한 I/O가
/dev/sda 디스크 전체에 대한 위치로 변환된 것을 뜻한다.
다음은 Q인데 이것은 queue의 약자로 make_request_fn이 실행되어 bio의 처리가 시작되었음을 뜻한다.
다음은 G인데 이것은 get (request)의 약자로 request 구조체가 하나 할당되었음을 뜻한다.
다음은 P인데 이것은 plug의 약자로 request가 plugged list에 포함되었음을 뜻한다.

이후의 요청들은 모두 A -> Q -> M의 과정을 거치는데, A와 Q는 위와 동일하고
M은 merge의 약자로 요청된 bio가 (앞선) request와 통합되었음을 뜻하는 것이며
8번째 열은 해당 bio의 시작 섹터 번호 및 크기임을 고려하면 연속된 요청이란 것을 쉽게 알 수 있다.

그 아래쪽에 I가 보이는데 이것은 insert의 약자로 앞서 생성(되고 merge)된 request가
I/O 스케줄러에게 전달되었음을 뜻한다. 그 바로 아래는 실제 request가 아닌 message를 의미하는
m이 있으며 (이는 CFQ 스케줄러에서 출력한 메시지이다) 지금은 무시하고 넘어가도 좋다.
다음은 U인데 이것은 unplug의 약자로 plugged list 내의 request들을 I/O 스케줄러에게 모두 전달했음을 뜻한다.
다음은 D인데 이것은 dispatch의 약자로 드라이버에게 I/O 연산의 실행을 시작하라고 요청하였음을 뜻한다.
다음은 C인데 이것은 complete의 약자로 dispatch된 request의 처리가 완료되었음을 뜻하는 것이다.

위의 경우 8섹터 (= 4KB) 크기의 bio 12개가 순서대로 요청되어 96섹터 (= 48KB) 크기의 한 request로
merge된 후 한 번에 처리되는 것을 볼 수 있었다.

지금까지 살펴본 과정을 그림으로 나타내면 다음과 같다.



출처 : http://studyfoss.egloos.com/tag/blktrace/page/1

'Embedded Lab > linux, x86' 카테고리의 다른 글

[blktrace 설치법]  (0) 2013.04.08
[blktrace 사용법]  (0) 2013.04.08
[blktrace1]  (0) 2013.04.08
[printk 로그 레벨]  (0) 2013.04.08
[환경변수 삭제]  (0) 2013.04.07
Posted by cyj4369
,

blktrace는 Block I/O Layer 에서 storage (disk, flash 등)로 입출력이 일어나는 과정을 분석해주는 tracing tool 이다.

blktrace가 분석한 내용을 blkparse 가 parsing하여 결과를 눈으로 쉽게 확인할 수 있게 한다.

[그림 1. blktrace architecture]

blktrace 및 blkparse options


blktrace는 여러 옵션을 사용하여 tracing 할 수 있도록 한다. 아래는 일반적인 blktrace 및 blkparse의 사용법이다.

% blktrace -d <dev> -o - | blkparse -i - -o <trace_file>

-d : Use specified device. May also be given last after options

-o : File(s) to send output to
      (위의 사용법에서는  뒤에 '-'가 오는데 이는 stdout 인 텍스트 터미널을 뜻한다.)

-i : Input file containing trace data, or '-' for stdin 
     (위의 사용법에서 blktrace 의 trace data가 stdout으로 지정했으므로, blkparse도 stdin으로 설정한다.)

위의 명령어로 수행하면 <dev>에서의 Block I/O trace결과가 <trace_file>에 저장된다.

이 외에도 많은 옵션들이 있지만, 특별한 경우에 사용되므로 사용해보지 않았다.


iozone를 이용한 blktrace 분석


1. blktrace 를 수행한다.

 blktrace -d /dev/sdb -o - | blkparse -i - -o ./blktrace.sdb.ext4.iozone

 : 현재 dev는 /dev/sbd 이고 분석결과가 저장된 output file은 임의로 blktrace.sdb.ext4.iozone 로 하였다.

2. iozone을 이용하여 mount된 dev에 io를 수행한다.   

 iozone -w -e -s 64k -f ./mnt/iozone.dummy -i 0

 : 64KB 사이즈의 파일(iozone.dummy)을 sequential write pattern으로 write하였다.

  (iozone에 대한 설명은 생략한다.)

3. blktrace 를 종료하고 결과파일을 확인한다.

dev<mjr,mnr>   <cpu>  <seq_num> <time stamp> <pid> <event> <start blk+#of blk>      <process>
 
 8,16           1        1     1.427376394  5529    Q  WS 274432 + 8                [iozone]
  8,16           1        0     1.427383444     0    m   N cfq5529 alloced
  8,16           1        2     1.427384090  5529    G  WS 274432 + 8                [iozone]
  8,16           1        3     1.427385813  5529    P   N [iozone]
  8,16           1        4     1.427386431  5529    I   W 274432 + 8                [iozone]
  8,16           1        0     1.427387153     0    m   N cfq5529 insert_request
  8,16           1        0     1.427387804     0    m   N cfq5529 add_to_rr
  8,16           1        5     1.427390420  5529    Q  WS 274440 + 8                [iozone]
  8,16           1        6     1.427391162  5529    M  WS 274440 + 8                [iozone]
  8,16           1        7     1.427392450  5529    Q  WS 274448 + 8                [iozone]
  8,16           1        8     1.427392667  5529    M  WS 274448 + 8                [iozone]
 ...
  8,16           1       83     1.538002853  5529    U   N [iozone] 1
  8,16           1       84     1.538011856  5529    D   W 274432 + 128              [iozone]
  8,16           1       85     1.591459857     0    C   W 274432 + 128              [0]

결과파일에서 pid=5529 를 가지는 iozone process가 실제로 write 작업을 수행하고 있는 과정을 확인할 수 있다.

실제로 block i/o 동작을 간단히 살펴보자. 

a. seq_num=5 에서 Q event 가 수행된다. Q는 Queue의 약어로, make_request_fn가 수행되어 bio처리가 시작되었음을 나타낸다. 

b. seq_num=6 에서 event 가 수행된다. M은 Merge의 약어로, 앞선 bio request 와 통합되었음(plugged)을 나타낸다. 

c. Q->M 동작이 128 sector (64KB) 까지 반복된다. 이는 현재 iozone이 sequential write를 수행하기 때문에 모든 bio request들이 하나로 통합(merge)됨을 알 수 있다.

d. seq_num=83 에서 event 가 수행된다. U는 unflugged의 약어로, plugged list 내의 request를 I/O scheduler에게 전달했음을 나타낸다. 

e. seq_num=84 에서 D event 가 수행된다. D는 dispatch의 약어로, I/O scheduler가 block device driver에게 수행하라고 요청한 것이다.

f. seq_num=85 에서 event 가 수행된다. C는 complete의 약어로, dispatch된 request의 I/O동작이 완료되었음을 나타낸다.


<event> field 뒤에는 RWBS field로 다음과 같이 정리된다. 

RWBS DESCRIPTION

       This is a small string containing at least one character ('R' for read, 'W'  for  write,  or  'D'  for block discard
       operation), and optionally either  a  'B'  (for  barrier  operations)  or  'S'  (for   synchronous operations).


위 과정을 보면, iozone에서 실제 128KB의 sequential write 요청에 대한 Block I/O 동작을 확인할 수 있다. blktrace는 Block I/O뿐만 아니라 I/O scheduler의 동작까지도 확인할 수 있다. 

아래는 blkparse 결과파일에서 확인할 수 있는 모든 event에 대해 정리한 것이다.


(출처 : http://linux.die.net/man/1/blkparse)


Trace Actions

The following trace actions are recognised:
C -- complete
A previously issued request has been completed. The output will detail the sector and size of that request, as well as the success or failure of it.
D -- issued
A request that previously resided on the block layer queue or in the i/o scheduler has been sent to the driver.
I -- inserted
A request is being sent to the i/o scheduler for addition to the internal queue and later service by the driver. The request is fully formed at this time.
Q -- queued
This notes intent to queue i/o at the given location. No real requests exists yet.
B -- bounced
The data pages attached to this bio are not reachable by the hardware and must be bounced to a lower memory location. This causes a big slowdown in i/o performance, since the data must be copied to/from kernel buffers. Usually this can be fixed with using better hardware -- either a better i/o controller, or a platform with an IOMMU.
M -- back merge
A previously inserted request exists that ends on the boundary of where this i/o begins, so the i/o scheduler can merge them together.
F -- front merge
Same as the back merge, except this i/o ends where a previously inserted requests starts.
M --front or back merge

One of the above

M -- front or back merge
One of the above.
G -- get request
To send any type of request to a block device, a struct request container must be allocated first.
S -- sleep
No available request structures were available, so the issuer has to wait for one to be freed.
P -- plug
When i/o is queued to a previously empty block device queue, Linux will plug the queue in anticipation of future ios being added before this data is needed.
U -- unplug
Some request data already queued in the device, start sending requests to the driver. This may happen automatically if a timeout period has passed (see next entry) or if a number of requests have been added to the queue.
T -- unplug due to timer
If nobody requests the i/o that was queued after plugging the queue, Linux will automatically unplug it after a defined period has passed.
X -- split
On raid or device mapper setups, an incoming i/o may straddle a device or internal zone and needs to be chopped up into smaller pieces for service. This may indicate a performance problem due to a bad setup of that raid/dm device, but may also just be part of normal boundary conditions. dm is notably bad at this and will clone lots of i/o.
A -- remap
For stacked devices, incoming i/o is remapped to device below it in the i/o stack. The remap action details what exactly is being remapped to what.


출처 : http://ji007.tistory.com/archive/20120426

'Embedded Lab > linux, x86' 카테고리의 다른 글

[blktrace 사용법]  (0) 2013.04.08
[blktrace2]  (0) 2013.04.08
[printk 로그 레벨]  (0) 2013.04.08
[환경변수 삭제]  (0) 2013.04.07
[간단한 블록 디바이스 드라이버 모듈(램디스크)]  (0) 2013.04.07
Posted by cyj4369
,

커널 함수에서 사용되는 출력 함수이다.

printf와의 차이는 메시지 기록관리를 위한 로그레벨을 지정할 수 있다는 것이다.

로그레벨                        명령어 의미

  "<0>"     KERN_EMERG         시스템이 동작하지 않는다.

  "<1>"     KERN_ALERT         항상 출력

  "<2>"     KERN_CRIT         치명적인 정보

  "<3>"      KERN_ERR        오류 정보

  "<4>"     KERN_WARNING 경고 정보 

  "<5>"     KERN_NOTICE         정상적인 정보 

  "<6>"     KERN_INFO         시스템 정보 

  "<7>"     KERN_DEBUG        디버깅 정보


위처럼 로그레벨을 지정하는 이유는 kernel source 내에서 원하는 정보만 출력할 수 있게 함이다.


사용법은 다음과 같다


 printk(KERN_ERR"This is KERN_ERR option\n");


다음 명령을 실행해보면 현재의 로그레벨을 확인 할 수 있다.


 $cat /proc/sys/kernel/prink 

      7     4     1     7


[7] : 현재 로그레벨

       이 레벨보다 높은 메시지(숫자가 작은 수)만 출력을 해준다.

[4] : 기본 로그레벨

       printk()함수를 입력하면서 별도로 로그레벨을 입력하지 않을 경우

[1] : 최소 로그레벨

       부여할 수 있는 최소 로그레벨이다.

       이 값이 1이라면 우리가 printk 함수를 입력하면서 0을 부여할 수 없다.

[7] : 부팅시 로그레벨

        부팅시 출력될 레벨을 지정해주는 것이다.


출력되지 않았을 경우 다음과 같은 명령어로 로그버퍼에 기록된 내용을 볼 수 있다. (출력되지 않은 메시지도 볼 수 있음)

dmesg

# cat /proc/kmsg

'Embedded Lab > linux, x86' 카테고리의 다른 글

[blktrace2]  (0) 2013.04.08
[blktrace1]  (0) 2013.04.08
[환경변수 삭제]  (0) 2013.04.07
[간단한 블록 디바이스 드라이버 모듈(램디스크)]  (0) 2013.04.07
[환경변수 삭제]  (0) 2013.03.29
Posted by cyj4369
,