최소 Linux 커널 환경에서 프로세스를 시작하는 방법은 무엇입니까?

AndreaB

베어 리눅스 커널 위에서 일반 C 프로그램을 실행할 수 있습니까?

Qemu와 함께 가상화 된 Linux 최소 시스템을 사용하고 있는데 여기에서 사용자 지정 커널과 루트 파일 시스템을로드하지만 사용자 공간 hello world 프로그램을 실행할 수없는 것 같습니다.

편집 1 : 질문을 더 자세하게 업데이트했습니다. 내가 따라온 단계는 다음과 같습니다.

1] 호스트 컴퓨터에서 다음 명령을 사용하여 hello_world 프로그램을 컴파일했습니다.

gcc hello_world.c -o hello_world

소스 코드는 다음과 같습니다.

#include <stdio.h>

int main(int argc, char const *argv[]) {
  printf("Hello world!\n");
  return 0;
}

내 호스트 컴퓨터에서 프로그램을 실행하면 제대로 작동합니다. @nexus가 프로그램이 빌드 된 라이브러리를 제안한대로 확인했으며 다음과 같습니다.

    $ ldd hello_world
    linux-vdso.so.1 =>  (0x00007ffc0dfc8000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007efd90658000)
    /lib64/ld-linux-x86-64.so.2 (0x000055a57447f000)

2] Ciro Santilli의 linux-kernel-module-cheat 에서 기본적으로 제공되는 buildroot를 실행하여 루트 파일 시스템을 구축했습니다 . 나는 리눅스 커널을 컴파일하고 해당 bzImage를 얻었습니다.

3] 다음과 같이 루트 파일 시스템을 마운트하고 그 안에 컴파일 된 프로그램을 복사했습니다.

sudo mount -t ext2 rootfs.ext2 /home/andreww/Desktop/mountfile/
sudo cp hello_world /home/andreww/Desktop/mountfile/
sudo umount /home/andreww/Desktop/mountfile/

이것은 잘못된 느낌입니다. 게스트 머신에서 직접 C 프로그램을 컴파일하는 방법을 찾지 못했기 때문에 그렇게했습니다. 게스트 컴퓨터에는 gcc가 없습니다. 실제로 호출하려고하면 다음과 같이 표시됩니다.

 # -sh: gcc: not found

4] 명령으로 에뮬레이트 된 시스템을 시작했습니다.

qemu-system-x86_64 \
    -M pc \
    -append 'root=/dev/vda $extra_append' \
    -drive file=${images_dir}/rootfs.ext2,if=virtio,format=raw \
    -kernel ${images_dir}/bzImage \
    -m 256M \
    -net nic,model=virtio \
    -net user \
    -enable-kvm \
    -cpu host \
    -smp threads=4

Ciro Santilli의 linux-kernel-module-cheat 에서 가져 왔습니다 . rootfs.ext2는 시스템이 시작되는 루트 파일 시스템이고 bzImage는 게스트 머신을 시작할 커널 이미지입니다.

5] 게스트 시스템은 셸 내에서 에뮬레이션됩니다. 이것은 전체 운영 체제 이미지가 아닌 베어 커널 만 가상화하기 때문에 예상했던 것입니다.

buildroot 로그인이 표시되고 root로 로그인하고 다음 명령을 실행합니다.

가상화 된 게스트

hello 프로그램을 실행하려고하면 다음 메시지가 표시됩니다.

-sh: ./hello_world: not found

내 프로그램이 시스템에 elf 파일로로드 된 것을 디버깅하여 본 적이 있어도 내 프로그램이 실행되지 않는다고 가정합니다.

존재하지 않는 임의의 명령을 입력하면 동일한 오류가 발생합니다.

목표는 hello_world 프로그램이 커널 위에있는 사용자 공간에서 실행되도록하는 것입니다. 저는 그것이 커널의 일부가되기를 원하지 않습니다.

나는 너희들과 동의한다. 나는 아마도 도서관이나 기본적인 것을 놓치고있을 것이다. 그러나 나는 무엇을 해야할지 모르겠다.

연결점

기본적으로 init 대신 프로세스를 실행할 수 있습니다. 시스템 초기화 애플리케이션 대신 프로세스를 실행하려면 원래 init를 바꾸거나 init = / path / to / you / application 을 커널 매개 변수로 VM에 전달할 수 있습니다.

그러나 명심해야 할 몇 가지 사항이 있습니다.

모든 라이브러리는 애플리케이션을 빌드 한 시스템과 동일한 위치에있는 VM에 있어야합니다. 여기에는 빌드 된 기본 c 라이브러리도 포함됩니다. 다음을 사용하여 모든 라이브러리 목록을 얻을 수 있습니다.

ldd hello_world

예를 들어 다음 프로그램을 컴파일하면

#include <stdio.h>

int main(int argc, char** argv) {
  printf("hello world!\n");
  return 0;
}

ldd의 결과로 이와 같은 것을 얻을 수 있습니다.

$ ldd test
    linux-vdso.so.1 =>  (0x00007ffdba6ba000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8559f50000)
    /lib64/ld-linux-x86-64.so.2 (0x000055fc58ece000)

init 프로세스를 교체하는 경우 콘솔 인터럽트를 처리하고 적절히 처리해야합니다. 그렇지 않으면 정말 나쁜 시스템 충돌의 위험이 있습니다. 결과적으로, 당신이 무엇을하고 있는지 정말로 모른다면 init 프로세스를 유지하고 그 프로세스가 당신의 애플리케이션을 시작하도록하는 것이 좋은 생각입니다.

나는 과거에 당신의 명령의 출력을 보았다. 애플리케이션을 시작하기 위해 셸 스크립트를 사용하고 있습니까? 그렇다면 현재 가상 환경에서 일부 라이브러리가 누락되었음을 나타낼 수 있습니다.

편집하다:

대신 모든 라이브러리를 동일한 파일로 컴파일하는 정적으로 연결된 애플리케이션을 만들 수 있습니다. gcc에서는 해당 -static 스위치를 사용할 수 있습니다 . 차이점보기 :

$ gcc -o test test.c
$ ldd test
    linux-vdso.so.1 =>  (0x00007ffcd1f22000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f088d43a000)
    /lib64/ld-linux-x86-64.so.2 (0x00005580f8a2b000)
$ gcc -static -o test test.c
$ ldd test
    not a dynamic executable

이미 언급했듯이 ldd를 사용하여 필요한 라이브러리를 찾을 수 있습니다. 일반적으로 사용하는 또 다른 옵션 은 출력이 더 자세하므로 objdump 입니다.

따라서 내 응용 프로그램의 경우 다음과 같은 의미가 있습니다 (출력을 관련 섹션으로 줄였습니다).

$ objdump -p test

test:     file format elf64-x86-64

[...]

Dynamic Section:
  NEEDED               libc.so.6
  INIT                 0x00000000004003c8
  FINI                 0x00000000004005c4
  INIT_ARRAY           0x0000000000600e10
  INIT_ARRAYSZ         0x0000000000000008
  FINI_ARRAY           0x0000000000600e18
  FINI_ARRAYSZ         0x0000000000000008
[...]

그래서 내 경우에는, 그게 내가 복사해야 libc.so.6으로입니다 /lib/x86_64-linux-gnu/libc.so.6 내 호스트에 /lib/x86_64-linux-gnu/libc.so.6은 가상 머신 내에서.

도움이되기를 바랍니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

커널 소스 코드에서 최소 부팅 가능한 Linux (터미널 만 사용)를 만드는 방법은 무엇입니까?

분류에서Dev

Linux 커널 관리자의 개발 지점에서 최신 Linux 커널의 코드를 다운로드하는 방법은 무엇입니까?

분류에서Dev

Ubuntu를 실행하는 데 필요한 최소 호환 Linux 커널 버전은 무엇입니까?

분류에서Dev

Ubuntu를 실행하는 데 필요한 최소 호환 Linux 커널 버전은 무엇입니까?

분류에서Dev

Arch Linux를 LTS 커널로 전환하는 방법은 무엇입니까?

분류에서Dev

커널 로그에 커널 코드의 최신 커밋 ID를 인쇄하는 방법은 무엇입니까?

분류에서Dev

Linux 터미널에서 프로세스를 다시 여는 방법은 무엇입니까?

분류에서Dev

Linux 터미널에서 프로세스를 다시 여는 방법은 무엇입니까?

분류에서Dev

Linux에서 시작시 프로세스를 시작하는 방법은 무엇입니까?

분류에서Dev

내 PC에서 정상적으로 작동하는 Linux 커널을 찾는 방법은 무엇입니까?

분류에서Dev

Linux 커널에서 Unix 파일 시스템 지원을 활성화하는 방법은 무엇입니까?

분류에서Dev

Linux 커널 4.x에서 내 시스템 호출을 구현하는 방법은 무엇입니까?

분류에서Dev

Linux 커널에서 udp 소스 포트를 선택하는 데 사용되는 기준은 무엇입니까?

분류에서Dev

Windows 10 작업 관리자에서 커널 시간 및 관리자 프로세스를 표시하는 방법은 무엇입니까?

분류에서Dev

내 프로세서 용 Debian Linux 커널에서 사용하는 드라이버를 업데이트하는 방법은 무엇입니까?

분류에서Dev

커널 소스에서 시간을 인쇄하는 방법은 무엇입니까?

분류에서Dev

Linux 커널에서 CPU 코어의 에너지 소비량을 얻는 방법은 무엇입니까?

분류에서Dev

커널 모듈 (x86-64) 내에서 물리적 주소를 커널 페이지 구조로 변환하는 방법은 무엇입니까?

분류에서Dev

`apt-get`을 사용하는 최신 버전이 아닌 다른 커널 버전에 대한 linux-headers- *를 얻는 방법은 무엇입니까?

분류에서Dev

Linux 커널 모듈에서 문자 장치의 모드를 설정하는 방법은 무엇입니까?

분류에서Dev

Linux 커널 모듈에서 메모리 안전 오류를 감지하는 방법은 무엇입니까?

분류에서Dev

최대 카디널리티 이분 일치를 최소 경로 커버로 줄이는 방법은 무엇입니까?

분류에서Dev

마젠타 커널에서 프로세스가 만드는 컨텍스트 전환 수를 확인하는 방법은 무엇입니까?

분류에서Dev

마젠타 커널에서 프로세스가 만드는 컨텍스트 전환 수를 확인하는 방법은 무엇입니까?

분류에서Dev

Linux 커널 모듈의 sysfs에 어레이를 저장하는 방법은 무엇입니까?

분류에서Dev

Linux 커널 3.4를 제거하는 방법은 무엇입니까?

분류에서Dev

Linux 커널 3.4를 제거하는 방법은 무엇입니까?

분류에서Dev

이전 Linux 커널을 GRUB에 추가하는 방법은 무엇입니까?

분류에서Dev

도커 터미널 시작 스크립트를 변경하는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    커널 소스 코드에서 최소 부팅 가능한 Linux (터미널 만 사용)를 만드는 방법은 무엇입니까?

  2. 2

    Linux 커널 관리자의 개발 지점에서 최신 Linux 커널의 코드를 다운로드하는 방법은 무엇입니까?

  3. 3

    Ubuntu를 실행하는 데 필요한 최소 호환 Linux 커널 버전은 무엇입니까?

  4. 4

    Ubuntu를 실행하는 데 필요한 최소 호환 Linux 커널 버전은 무엇입니까?

  5. 5

    Arch Linux를 LTS 커널로 전환하는 방법은 무엇입니까?

  6. 6

    커널 로그에 커널 코드의 최신 커밋 ID를 인쇄하는 방법은 무엇입니까?

  7. 7

    Linux 터미널에서 프로세스를 다시 여는 방법은 무엇입니까?

  8. 8

    Linux 터미널에서 프로세스를 다시 여는 방법은 무엇입니까?

  9. 9

    Linux에서 시작시 프로세스를 시작하는 방법은 무엇입니까?

  10. 10

    내 PC에서 정상적으로 작동하는 Linux 커널을 찾는 방법은 무엇입니까?

  11. 11

    Linux 커널에서 Unix 파일 시스템 지원을 활성화하는 방법은 무엇입니까?

  12. 12

    Linux 커널 4.x에서 내 시스템 호출을 구현하는 방법은 무엇입니까?

  13. 13

    Linux 커널에서 udp 소스 포트를 선택하는 데 사용되는 기준은 무엇입니까?

  14. 14

    Windows 10 작업 관리자에서 커널 시간 및 관리자 프로세스를 표시하는 방법은 무엇입니까?

  15. 15

    내 프로세서 용 Debian Linux 커널에서 사용하는 드라이버를 업데이트하는 방법은 무엇입니까?

  16. 16

    커널 소스에서 시간을 인쇄하는 방법은 무엇입니까?

  17. 17

    Linux 커널에서 CPU 코어의 에너지 소비량을 얻는 방법은 무엇입니까?

  18. 18

    커널 모듈 (x86-64) 내에서 물리적 주소를 커널 페이지 구조로 변환하는 방법은 무엇입니까?

  19. 19

    `apt-get`을 사용하는 최신 버전이 아닌 다른 커널 버전에 대한 linux-headers- *를 얻는 방법은 무엇입니까?

  20. 20

    Linux 커널 모듈에서 문자 장치의 모드를 설정하는 방법은 무엇입니까?

  21. 21

    Linux 커널 모듈에서 메모리 안전 오류를 감지하는 방법은 무엇입니까?

  22. 22

    최대 카디널리티 이분 일치를 최소 경로 커버로 줄이는 방법은 무엇입니까?

  23. 23

    마젠타 커널에서 프로세스가 만드는 컨텍스트 전환 수를 확인하는 방법은 무엇입니까?

  24. 24

    마젠타 커널에서 프로세스가 만드는 컨텍스트 전환 수를 확인하는 방법은 무엇입니까?

  25. 25

    Linux 커널 모듈의 sysfs에 어레이를 저장하는 방법은 무엇입니까?

  26. 26

    Linux 커널 3.4를 제거하는 방법은 무엇입니까?

  27. 27

    Linux 커널 3.4를 제거하는 방법은 무엇입니까?

  28. 28

    이전 Linux 커널을 GRUB에 추가하는 방법은 무엇입니까?

  29. 29

    도커 터미널 시작 스크립트를 변경하는 방법은 무엇입니까?

뜨겁다태그

보관