ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • dd
    Linux/development tool 2023. 6. 10. 14:41

    글의 참고


    글의 전제

    - `운영체제 만들기` 파트에서 퍼온 모든 참조 글들과 그림은 반드시 `이 글과 그림을 소스 코드로 어떻게 구현을 해야할까` 라는 생각으로 정말 심도있게 잠시 멈춰서 생각해봐야 실력이 발전한다.


    글의 내용

     

    : dd 유틸리트를 이용하면 간단하게 디스크 드라이브를 이미지를 만들 수 있다.

    dd if=/dev/zero of=./disk.img bs=512 count=1024

    : if는 `input file`의 약자이고, of는 `output file`의 약자이다. 위에 명령어를 통해서 0으로 채워진 0x80000(524288)B 크기의 disk.img 라는 파일이 만들어진다. 이와 같이 입력 파일의 값으로 출력 파일을 만드는게 dd다. 그 사이즈는 bs와 count에 전달된 값을 통해 계산한다. bs는 `Byte Per Sector`, 즉, 섹터 하나의 크기를 의미하며, count는 그 섹터들의 개수를 의미한다. 즉, dd는 `섹터 크기 * 카운트` 만큼의 사이즈를 출력 파일에 만든다.

     

    - 옵션

    : if=FILE

    read from FILE instead of stdin

    " `dd` 명령어가 읽을 입력 파일을 지정한다. `dd`는 대개 텍스트 파일보다는 바이너리 파일 복사용도로 많이 쓰이기 때문에, 여기에는 주로 이미지 파일 같은 것들이 작성된다.

     

    : of=FILE

    write to FILE instead of stdout

    " 입력 파일의 내용을 복사할 출력 파일을 지정한다. `pool.o` 파일의 모든 내용을 `temp.img`에 복사한다. 2개의 파일은 사이즈도 동일하다.

    dd if=pool.o of=temp.img

     

    : bs=BYTES

    read and write up to BYTES bytes at a time (default: 512); overrides ibs and obs

    " 한 번에 얼마나 많은 `바이트`를 읽어야 하는 지를 지정한다. 대개, `count` 옵션과 함께 사용된다. 아래 명령어의 의미는 `kernel.bin` 파일의 내용을 `disk.img` 파일에 복사할 것이다. 그런데, `kernel.bin` 파일 사이즈가 `36864(36*1024)B` 보다 크다면, `disk.img`의 사이즈는 `36864(36*1024)B` 가 된다. 만약에, `kernel.bin` 사이즈가 `36864(36*1024)B` 보다 작다면, `disk.img`의 사이즈는 `kernel.bin` 사이즈가 같다.

    dd if=kernel.bin of=./disk.img bs=36 count=1024

    " `count`는 루프문과 같다. 즉, 위의 명령어는 1024번의 루프를 돌면서 매번 36B를 읽는것이다. 이렇게 말하면 풍기는 뉘앙스로는 이 값이 클 수록 성능이 좋아질 것 같은 느낌이든다. 

     

     

    : ibs=BYTES

    read up to BYTES bytes at a time (default: 512)

    " 입력 파일(`if=`에 명시된 파일)의 `BYTES`만큼 만큼 읽는다. 현재는 `bs`를 사용하면서 거의 사용되지 않는 듯 하다.

     

    : obs=BYTES

    write BYTES bytes at a time (default: 512)

    " 출력 파일(`of=`에 명시된 파일)의 `BYTES`만큼 쓴다. 현재는 `bs`를 사용하면서 거의 사용되지 않는 듯 하다.

     

    : count=N

    copy only N input blocks

    " 이 옵션의 주의점은 파라미터가 `블락`이라는 점이다. 예를 들어, 아래와 같이 실행할 경우 `pool.o` 파일의 `0B ~ 512B` 까지의 내용이 `temp.img`로 복사된다. 즉, `count` 옵션은 `bs` 옵션에 의존한다.

    dd if=pool.o of=temp.img bs=256 count=2

     

    : seek=N

    (or oseek=N) skip N obs-sized output blocks

    " 출력 파일의 시작 바이트를 `N` 번지로 지정한다. 그 앞에는 0으로 채워진다. `pool.o` 파일 사이즈가 `10632B`다. 그렇면, `temp.img` 사이즈는 몇일까? `11656B`가 된다.

    dd if=pool.o of=temp.img seek=2

    " `seek=2`를 통해 `temp.img` 파일의 시작 포인터가 1024B가 된다. 그래서 `pool.o` 파일의 모든 내용은 `disk.img`의 1024B 지점부터 복사된다. `disk.img`의 `0B ~ 1024B` 까지는 0이 되고, 1024B 부터 `pool.o` 파일의 내용을 확인할 수 있다.

     

     

    : skip=N

    (or iseek=N) skip N ibs-sized input blocks

    " 특정 파일의 앞 부분 `0B ~ 512B`를 생략하고 다른 파일로 복사하고 싶다면, 어떻게 해야할까? `skip=1` 옵션을 주면 된다.

    dd if=pool.o of=temp.img skip=1 count=2

    " 위의 내용을 적용할 경우, `pool.o` 파일의 `512B ~ 1536B`의 내용이 `temp.img`로 복사된다. 그래서 `temp.img`의 사이즈가 1024B가 된다.

     

     

    : conv=notrunc 

    do not truncate the output file

    " 아래의 명령어를 실행하면 `temp.img` 파일은 어떻게 될까?

    dd if=kernel.bin of=temp.img
    dd if=kernel32.bin of=temp.img

    " 최초의 명령어를 실행할 때는 `temp.img`는 `kernel.bin`과 동일한 내용과 사이즈로 만들어진다. 그런데, 두 번째 명령어를 실행하고 나면, `temp.img`는 `kernel32.bin`과 동일한 내용과 사이즈로 생성된다. 즉, `temp.img`는 계속 새로 생성된다.

     

    " 사용자가 원하는 내용이 `0B ~ 1024B` 까지는 `kernel.bin` 내용을 넣고, 그 뒤부터는 `kernel32.bin`을 넣고 싶으면 어떻게 해야할까?

    dd if=kernel.bin of=temp.img count=2
    dd if=kernel32.bin of=temp.img seek=2 `conv=notrunc`

    " `conv=notrunc` 옵션은 `of=`에 지정된 파일이 존재할 경우, 삭제하는게 아니라 보존한다. `bs`를 명시하지 않으면, 기본적으로 512가 된다. `count` 옵션은 `block`의 개수를 작성한다. `bs`가 명시되어 있지 않으므로, `count=2`라면, 1024B를 의미한다.

     

    " 그리고, `seek` 옵션은 위에서 말했다시피, `bs`에 지정된 바이트만큼 움직이게 된다. `bs`를 명시하지 않으면, 기본적으로 512가 된다. 그래서 `seek=2`는 1024B를 의미하게 된다.

     

     

    - 16진수 사용하기

    : DD 에서 16진수를 사용하면 다음과 같은 에러가 발생한다.

    dd: warning: ‘0x’ is a zero multiplier; use ‘00x’ if that is intended

    : 간단하다. 16진수를 $(())로 감싸주면 된다.

    dd bs=1 count=$((0x10000)) if=kernel64.bin of=disk.img seek=$((0x50000))

     

    - 패딩 넣기

    : 아래와 같이 dd를 사용하면 `kernel64.bin` 사이즈와 `disk.img` 사이즈가 동일하게 만들어진다.

    dd if=kernel64.bin of=disk.img
    dd if=kernel64.bin of=disk.img bs=1 count=$((0x50000))

    : 위의 2개 모두 `kernel64.bin` 사이즈와 disk.img 사이즈가 동일하게 만들어진다. `truncate`를 사용하면 된다.

     

    truncate -s $((0x50000)) disk.img

    : kernel64.bin은 disk.img 맨 앞쪼 부터 채워지고, 사이즈는 0x50000가 된다. 

     

    - 뒤에 붙히기(Append)

    : disk1.img 뒤에 kernel64.bin 파일의 내용을 붙힌다.

    dd if=kernel64.bin >> disk1.img

     

    - 중간에 삽입하기

    : `skip`과 `seek`을 사용하면 된다. 

    'Linux > development tool' 카테고리의 다른 글

    [GIT] - git diff를 통한 patch 파일 생성 및 적용  (0) 2023.08.03
    Shell script  (0) 2023.07.10
    [개발 도구] objdump  (0) 2023.06.10
    [개발도구] - inline assembly  (0) 2023.06.07
    [개발도구] - Linker  (0) 2023.06.04
Designed by Tistory.