실행 파일을 실행하려면 OS 커널이 필요합니까?


53

C ++과 같은 소스 코드가 컴파일 될 때 컴파일러의 출력은 머신 코드 (실행 가능)이며 CPU에 대한 지침이라고 생각했습니다. 최근에 커널을 읽고 있었고 프로그램이 하드웨어에 직접 액세스 할 수는 없지만 커널을 거쳐야한다는 것을 알았습니다.

따라서 printf()함수를 사용 하여 간단한 소스 코드를 컴파일하고 컴파일하면 실행 가능한 머신 코드가 생성됩니다.이 머신 코드의 각 명령은 메모리에서 직접 실행되거나 (코드가 OS에 의해 메모리에로드되면) 머신 코드의 각 명령을 실행하려면 여전히 OS (커널)를 거쳐야합니까?

나는 비슷한 질문 을 읽었습니다 . 컴파일 후 생성 된 머신 코드가 CPU에 대한 직접 지시인지 CPU에 대한 올바른 지시를 작성하기 위해 커널을 다시 거쳐야하는지 여부는 설명하지 않았습니다. 즉, 머신 코드가 메모리에로드 된 후 어떻게됩니까? 커널을 거치거나 프로세서와 직접 대화합니까?


29
Arduino 용 코드를 작성하는 경우 OS가 필요하지 않습니다.
stib

12
printf좋은 예가 아닙니다. C 스펙에서는 명시 적으로 "호스트 된"구현에서만 사용할 수있는 기능으로 정의됩니다 ( "독립형"이 아닌 커널에서 실행되는 것을 의미 함). 그리고 대부분의 플랫폼 에서 귀하를 대신하여 많은 printf기능을 수행하는 기능입니다 libc(결국 stdout으로 인쇄하는 syscall 포함). 그것은 호출에서 정말 다를 바 없다 libvlc_media_list_add_media또는 PyObject_GetAttr어떤 것을 제외하고, printf구현 여분의 표준이 아닌 추가하지 않고 연결 가능한 보장 -l들.
abarnert

1
이것은 존재합니다! (아무런 관계가없는, 그냥 멋지다라고 생각) erikyyy.de/invaders
Nonny 무스

9
이는 실제로 "실행 가능", "커널", "실행", "필요", "대화"및 "통과"라는 용어의 정확한 정의에 달려 있습니다. 이러한 용어를 정확하게 정의하지 않으면 질문에 대답 할 수 없습니다.
Jörg W Mittag

3
@ JörgWMittag-만약 당신이 pedantic이라면, 왜 당신은 단지 그 용어들과이 질문만을 면밀히 조사하고 있습니까? 정의해야 할 중요한 용어는 "운영 체제"로, MS-DOS (및 유사한 단일 작업 런타임 환경)에 의심의 여지없이 적용됩니다. PC BIOS가 OS 라고 생각하는 (잘못된 정보를 가진) 소수의 사람들 이 있다면 , 모든 것이 준비되어 있습니까? 나는 그렇게 생각하지 않는다. OP는 합리적 (비 영어 원어민 인 경우) 또는 비 기술적 인 상황에서 해당 단어를 사용합니다.
톱밥

답변:


86

OS없이 실행되는 프로그램을 작성한 사람으로서 나는 확실한 대답을 제공합니다.

실행 파일을 실행하려면 OS 커널이 필요합니까?

그것은 그 프로그램이 어떻게 작성되고 구축되었는지에 달려 있습니다.
OS가 전혀 필요하지 않은 프로그램을 작성할 수 있습니다 (지식이 있다고 가정).
이러한 프로그램은 독립형 으로 설명됩니다 .
부트 로더와 진단 프로그램은 일반적으로 독립형 프로그램에 사용됩니다.

그러나 일부 호스트 OS 환경에서 작성되고 작성된 일반적인 프로그램은 기본적으로 동일한 호스트 OS 환경에서 실행됩니다.
독립형 프로그램을 작성하고 구축하려면 매우 명확한 결정과 조치가 필요합니다.


... 컴파일러의 출력은 머신 코드 (실행 파일)이며 CPU에 대한 지시 사항이라고 생각했습니다.

옳은.

최근에 커널을 읽고 있었고 프로그램이 하드웨어에 직접 액세스 할 수는 없지만 커널을 거쳐야한다는 것을 알았습니다.

이것은 OS가 프로그램을 실행하기 위해 사용하는 CPU 모드에 의해 부과되는 제한이며 컴파일러 및 라이브러리와 같은 특정 빌드 도구에 의해 촉진됩니다.
지금까지 작성된 모든 프로그램에 대한 본질적인 제한은 아닙니다.


그래서 우리가 printf () 함수로 간단한 소스 코드를 컴파일하고 컴파일하면 실행 가능한 머신 코드가 생성됩니다.이 머신 코드의 각 명령은 메모리에서 직접 실행됩니다 (코드가 OS에 의해 메모리에로드되면 ) 또는 머신 코드의 각 명령을 계속 실행하려면 OS (커널)를 거쳐야합니까?

모든 명령어는 CPU에 의해 실행됩니다.
지원되지 않거나 잘못된 명령 (예 : 프로세스에 권한이 충분하지 않은 명령)은 즉시 예외를 발생시키고 대신 CPU는이 비정상적인 조건을 처리하기 위해 루틴을 실행합니다.

의 printf () 함수의 예로서 사용되어서는 안된다 "간단한 소스 코드" .
객체 지향 고급 프로그래밍 언어에서 기계 코드로의 변환은 암시하는 것처럼 사소하지 않을 수 있습니다.
그런 다음 데이터 변환 I / O 를 수행하는 런타임 라이브러리에서 가장 복잡한 기능 중 하나를 선택합니다 .

귀하의 질문에 OS (및 런타임 라이브러리)가있는 환경이 명시되어 있습니다.
시스템이 부팅되고 OS에 컴퓨터가 제어되면 프로그램이 수행 할 수있는 작업에 제한이 적용됩니다 (예 : OS에서 I / O를 수행해야 함).
독립형 프로그램 (OS없이)을 실행하려면 OS를 실행하기 위해 컴퓨터를 부팅하지 않아야합니다.


... 머신 코드가 메모리에로드 된 후 어떻게됩니까?

환경에 따라 다릅니다.

독립형 프로그램의 경우 프로그램의 시작 주소로 점프하여 제어권을 넘겨 실행할 수 있습니다.

OS가로드 한 프로그램의 경우 프로그램이 종속 된 공유 라이브러리와 동적으로 링크되어야합니다. OS는 프로그램을 실행할 프로세스를위한 실행 공간을 만들어야합니다.

커널을 거치거나 프로세서와 직접 대화합니까?

머신 코드는 CPU에 의해 실행 됩니다.
그것들은 "커널을 통과 하지 " 않고 " 프로세서와 통신" 하지도 않습니다 .
기계 코드 (op 코드와 피연산자로 구성됨)는 디코딩 된 CPU에 대한 명령이며 작업이 수행됩니다.

아마도 다음 주제는 CPU 모드 일 것 입니다.


2
"독립형 프로그램 (OS없이)을 실행하려면 OS를 실행하기 위해 컴퓨터를 부팅해서는 안됩니다." 완전히 정확하지 않습니다. DOS 이후에 많은 DOS 프로그램이로드 된 후 DOS 서비스를 완전히 무시했습니다 (직접 비트 뱅킹 또는 BIOS 직접 호출). Win3.x는 흥미로운 코너 사례를 제외하고 DOS가 있음을 무시한 훌륭한 예입니다. Win95 / 98 / Me도이 작업을 수행했습니다. 8 비트 / 16 비트 시대의 독립형 프로그램을 지원하는 OS의 예가 많이 있습니다.
Eric Towers

8
@EricTowers- "DOS"는 아마도 MS-DOS를 의미하는 것 같습니다 (MS 또는 Intel과 관련이없는 DOS를 사용했기 때문에)? OS 개념과 디자인에 관한 1970 년대 대학 교과서의 기준과 일치하지 않는 "OS"를 인용하고 있습니다. MS-DOS의 기원은 시애틀 컴퓨터 제품을 통해 CP / M으로 거슬러 올라갑니다. CP / M은 저작자 게리 킬다 (Gary Kildall)가 명시 적으로 OS라고 부르지 않습니다. 프로그램이 시스템을 인계 할 수있는 OS에 시스템 자원 관리의 기본 기능이 실패했습니다. "독립형 프로그램을 지원하는 OS의 많은 예가 있습니다" - "지원" 또는 방지 할 수 없습니까?
톱밥

5
... 또는 ProDOS 또는 PC-DOS 또는 DR-DOS 또는 CBM DOS 또는 TRS DOS 또는 FLEX ...
Eric Towers

3
저는 GCC의 "자립형"용어를 좋아합니다. 영어 단어는 OS없이 실행되는 코드에 대한 올바른 의미를 가지고 있으며, 아마도 "독립형"보다 좋습니다. 예를 들어 gcc -O2 -ffreestanding my_kernel.c special_sauce.S, 일반적인 라이브러리 나 OS가없는 것으로 가정하는 실행 파일을 만들기 위해 컴파일 할 수 있습니다. (물론 부트 로더가로드 할 파일 형식으로 유용하게 링크하려면 링커 스크립트가 필요합니다!)
Peter Cordes

4
@PeterCordes "독립형"은 IMO가 다소 권위있는 것으로 간주 될 수있는 C 표준에서 사용되는 용어입니다. 또는 좋은 용어는 "호스팅되지 않은"것입니다 (OS에서 호스팅하는 것과 동일)
Jan Dorniak

38

커널은 더 많은 코드 일뿐입니다. 그 코드는 시스템의 가장 낮은 부분과 실제 하드웨어 사이에 존재하는 계층이라는 것입니다.

모든 것이 CPU에서 직접 실행되므로 레이어를 통해 전환하여 무엇이든 할 수 있습니다.

프로그램 printf은 처음에 명령 을 사용하기 위해 표준 C 라이브러리가 필요한 것과 같은 방식으로 커널을 "필요"합니다 .

프로그램의 실제 코드는 CPU에서 실행하지만, 코드가 화면에 뭔가가 C에 대한 코드를 통과 인쇄 할 수 있습니다 가지 printf자신의 처리를 할 각각의 다양한 시스템과 통역을 통해, 기능, 그냥 작동하는 방법 hello world! 실제로 화면에 인쇄됩니다.

데스크탑 창 관리자에서 실행되고 터미널 하드웨어에서 실행되는 터미널 프로그램을 실행하는 터미널 프로그램이 있다고 가정하십시오.

더 많은 것들이 있지만 간단하게 유지할 수 있습니다 ...

  1. 터미널 프로그램에서 프로그램을 실행하여 인쇄 hello world!
  2. 터미널은 프로그램이 (C 출력 루틴 hello world!을 통해) 콘솔에 작성되었음을 확인합니다
  3. 터미널 프로그램은 말을 바탕 화면 창 관리자까지 간다 "내가 가진 hello world!나를 작성, 당신은 위치에 넣어 수 있습니다 x, y제발?"
  4. 데스크톱 창 관리자는 "내 프로그램 중 하나가 그래픽 장치가이 위치에 텍스트를 넣기를 원합니다."
  5. 커널은 그래픽 카드를 이해할 수있는 방식으로 요청을 그래픽 장치 드라이버로 전달합니다.
  6. 그래픽 카드의 연결 방법에 따라 PCIe와 같은 물리적 장치 버스에서 데이터를 내보내고 올바른 장치가 선택되어 있는지 확인하고 데이터가 관련 브리지를 통과 할 수 있도록 다른 커널 장치 드라이버를 호출해야합니다. 변환기
  7. 하드웨어가 물건을 표시합니다.

이것은 설명을 위해서만 지나치게 단순화 된 것입니다. 여기에 용들이 있습니다.

당신이 하드웨어 액세스를 필요로 그렇게 효과적으로 모든 것을, 즉 것처럼, 파일 또는 아무것도의 메모리 블록, 비트를 표시 할 수 있다 정확하게 해결하기 위해 커널에서 일부 장치 드라이버를 통해 이동하는 방법 관련 장치에 얘기. PCIe 브리지 장치 위에있는 SATA 하드 디스크 컨트롤러 드라이버 위에있는 파일 시스템 드라이버입니다.

커널은 이러한 모든 장치를 함께 묶는 방법을 알고 있으며, 이러한 모든 작업을 스스로 수행하는 방법에 대해 알 필요없이 프로그램이 작업을 수행하는 비교적 간단한 인터페이스를 제공합니다.

데스크톱 창 관리자는 계층을 제공하므로 프로그램은 창을 그리는 방법을 알 필요가 없으며 동시에 다른 프로그램을 표시하려고 시도하는 다른 프로그램과도 잘 어울립니다.

마지막으로 터미널 프로그램은 프로그램이 창을 그리는 방법이나 커널 그래픽 카드 드라이버와 대화하는 방법을 알 필요가 없으며 화면 버퍼 및 디스플레이 타이밍을 처리하고 실제로 디스플레이에 데이터 라인.

모든 코드 레이어에서 레이어로 처리됩니다.


하드웨어 액세스 뿐만 아니라 프로그램 간의 대부분의 통신 도 커널을 통과합니다. 일반적으로 커널과 관련이없는 것은보다 직접적인 채널을 설정하는 것입니다. 그러나 질문의 ​​목적을 위해 모든 코드를 단일 프로그램으로 압축하는 것이 훨씬 간단한 경우도 가능합니다.
Chris Stratton

실제로 터미널 프로그램을 작성하는 프로그램과 동일한 컴퓨터에서 실행하지 않아도됩니다.
jamesqf

이 질문에 명시 적으로 언급해야 할 수도 있기 때문에-서로 "대화하는"프로그램에 대해 이야기 할 때 은유 적입니다.
user253751

21

환경에 따라 다릅니다. IBM 1401과 같은 많은 구형 컴퓨터에서는 대답이 "아니오"입니다. 컴파일러와 링커는 운영 체제없이 실행되는 독립형 "이진"을 생성했습니다. 프로그램 실행이 중지되면 다른 프로그램을로드했는데 OS없이 실행되었습니다.

한 번에 하나의 프로그램 만 실행하지 않기 때문에 최신 환경에서는 운영 체제가 필요합니다. 여러 프로그램에서 CPU 코어, RAM, 대용량 저장 장치, 키보드, 마우스 및 디스플레이를 한 번에 공유하려면 조정이 필요합니다. OS가 제공합니다. 따라서 현대 환경에서 프로그램은 디스크 또는 SSD를 읽고 쓸 수 없으며 OS를 대신하여 요청해야합니다. OS는 저장 장치에 액세스하려는 모든 프로그램에서 이러한 요청을 가져오고 액세스 제어 (일반 사용자가 OS 파일에 쓸 수 없음)와 같은 사항을 구현하고 장치에 큐에 넣은 다음 반환 된 정보를 정렬합니다. 올바른 프로그램 (프로세스).

또한 최신 컴퓨터 (예 : 1401과 달리)는 IBM이 이전에 판매 한 장치뿐만 아니라 매우 다양한 I / O 장치의 연결을 지원합니다. 컴파일러와 링커는 모든 가능성에 대해 알 수 없습니다. 예를 들어 키보드는 PS / 2 또는 USB를 통해 인터페이스 될 수 있습니다. OS를 사용하면 해당 장치와 통신하는 방법을 알고 있지만 장치 클래스에 대한 공통 인터페이스를 OS에 제공하는 장치 별 "장치 드라이버"를 설치할 수 있습니다. 따라서 프로그램 및 OS조차도 USB 대 PS / 2 키보드에서 키 입력을 얻거나 로컬 SATA 디스크 대 USB 저장 장치 대 스토리지에 액세스하기 위해 다른 작업을 수행 할 필요가 없습니다. NAS 또는 SAN에서. 이러한 세부 사항은 다양한 장치 컨트롤러의 장치 드라이버에 의해 처리됩니다.

대용량 저장 장치의 경우 OS는 저장소가 구현되는 위치와 방법에 관계없이 디렉토리 및 파일에 동일한 인터페이스를 제공하는 파일 시스템 드라이버를 제공합니다. 그리고 다시, OS는 액세스 제어 및 직렬화에 대해 걱정합니다. 일반적으로, 예를 들어, 일부 파일을 건너 뛰지 않고 한 번에 둘 이상의 프로그램에서 같은 파일을 열어서 열지 않아야합니다 (그러나 동시 읽기는 일반적으로 괜찮습니다).

현대의 범용 환경에서는 그렇습니다. 실제로 OS가 필요합니다. 그러나 오늘날에도 실시간 컨트롤러와 같은 컴퓨터가 필요로하기에는 복잡하지 않습니다.

예를 들어 Arduino 환경에는 실제로 OS가 없습니다. 물론, 빌드 환경이 빌드하는 모든 "이진"에 통합되는 라이브러리 코드가 많이 있습니다. 그러나 한 프로그램에서 다음 프로그램으로 해당 코드의 지속성이 없으므로 OS가 아닙니다.


10

많은 답변이 질문을 오해하고 있다고 생각합니다.

컴파일러는 머신 코드를 출력합니다. 이 머신 코드는 CPU에 의해 직접 실행됩니까, 아니면 커널에 의해 "해석"됩니까?

기본적으로 CPU는 머신 코드를 직접 실행합니다 . 커널이 모든 응용 프로그램을 실행하도록하는 것은 상당히 느릴 것입니다. 그러나 몇 가지주의 사항이 있습니다.

  1. OS가 있으면 응용 프로그램은 일반적으로 특정 명령을 실행하거나 특정 리소스에 액세스 할 수 없습니다. 예를 들어, 응용 프로그램에서 시스템 인터럽트 테이블을 수정하는 명령을 실행하면 CPU는 대신 OS 예외 처리기로 건너 뛰어 문제가있는 응용 프로그램이 종료됩니다. 또한 응용 프로그램은 일반적으로 장치 메모리를 읽고 쓸 수 없습니다. (즉, "하드웨어와의 대화") 이러한 특수 메모리 영역에 액세스하는 것은 OS가 그래픽 카드, 네트워크 인터페이스, 시스템 시계 등과 같은 장치와 통신하는 방식입니다.

  2. OS가 애플리케이션에 적용하는 제한은 권한 모드, 메모리 보호 및 인터럽트와 같은 CPU의 특수 기능에 의해 달성됩니다. 스마트 폰이나 PC에서 찾을 수있는 CPU에는 이러한 기능이 있지만 특정 CPU에는 없습니다. 이러한 CPU에는 실제로 원하는 기능을 달성하기 위해 응용 프로그램 코드를 "해석"하는 특수 커널이 필요합니다. 매우 흥미로운 예는 Gigatron인데 , 34 명령어 컴퓨터를 에뮬레이트하는 칩으로 만들 수있는 8 명령어 컴퓨터입니다.

  3. Java와 같은 일부 언어는 실제로 기계 코드가 아닌 Bytecode라는 언어로 "컴파일"됩니다. 과거에는 프로그램을 실행하는 것으로 해석되었지만 요즘 Just-in-Time 컴파일이라는 것이 일반적으로 사용되므로 CPU에서 기계 코드로 직접 실행됩니다.

  4. Hypervisor 라는 프로그램에서 기계 코드를 "해석"해야하는 가상 컴퓨터에서 소프트웨어를 실행합니다 . VM에 대한 업계의 엄청난 수요로 인해 CPU 제조업체는 게스트 시스템에 대한 대부분의 명령을 CPU에서 직접 실행할 수 있도록 VTx와 같은 기능을 CPU에 추가했습니다. 그러나 가상 시스템에서 호환되지 않는 CPU 용으로 설계된 소프트웨어 (예 : NES 에뮬레이션)를 실행할 때는 시스템 코드를 해석해야합니다.


1
Java의 바이트 코드는 일반적으로 기계 코드가 아니지만 Java 프로세서 는 여전히 존재합니다 .
Ruslan

하이퍼 바이저는 항상 통역사가되지 않았습니다. 가상 머신이 호스트와 호환되지 않는 명령어 세트 인 가상 머신이지만 동일한 아키텍처 실행을 위해 초기 하이퍼 바이저조차도 CPU에서 직접 코드를 실행하는 경우 해석이 필요합니다 (반 가상화 커널이 필요하지 않은 CPU의 경우 필요한 하이퍼 바이저 지원).
Toby Speight

5

코드를 컴파일 할 때 (대부분의 경우) 시스템 라이브러리에 의존하는 소위 "객체"코드를 생성 printf한 다음 특정 운영 체제에서 사용할 수있는 프로그램 로더를 추가하는 링커로 코드를 래핑합니다. (예를 들어 Linux에서 Windows 용으로 컴파일 된 프로그램을 실행할 수없는 이유) 인식하고 코드를 풀고 실행하는 방법을 알고 있습니다. 따라서 프로그램은 샌드위치 내부의 고기이며 전체적으로 번들로만 먹을 수 있습니다.

최근에 커널을 읽고 있었고 프로그램이 하드웨어에 직접 액세스 할 수는 없지만 커널을 거쳐야한다는 것을 알았습니다.

반쯤 사실입니다. 프로그램이 커널 모드 드라이버 인 경우 하드웨어에 "통화"하는 방법을 알고 있다면 실제로 하드웨어에 직접 액세스 할 수 있지만 일반적으로 (특히 문서화되지 않거나 복잡한 하드웨어의 경우) 사람들은 커널 라이브러리 인 드라이버를 사용합니다. 이 방법으로 주소, 레지스터, 타이밍 및 기타 여러 가지를 알 필요없이 거의 사람이 읽을 수있는 방식으로 하드웨어와 통신하는 방법을 알고있는 API 함수를 찾을 수 있습니다.

이 기계어 코드의 각 명령어는 메모리에서 직접 실행되거나 (코드가 OS에 의해 메모리에로드되면) 기계어 코드의 각 명령은 여전히 ​​실행되도록 OS (커널)를 거쳐야합니다

글쎄, 커널은 웨이트리스로서, 당신을 테이블로 안내하고 당신을 섬기는 책임이 있습니다. 그것이 할 수없는 유일한 것은-당신을 위해 먹는 것입니다, 당신은 스스로해야합니다. 커널은 코드와 마찬가지로 프로그램을 메모리에 압축 해제하고 CPU에서 직접 실행하는 머신 코드 인 코드를 시작합니다. 커널은 당신을 감독하기 만하면됩니다. 허용되는 것과 허용되지 않는 것.

컴파일 후 생성 된 머신 코드가 CPU에 대한 명령인지 아니면 CPU에 대한 올바른 명령을 작성하기 위해 커널을 다시 거쳐야하는지 설명하지 않습니까?

컴파일 후에 생성 된 머신 코드는 CPU에 직접 지시합니다. 의심의 여지가 없습니다. 컴파일 된 파일의 모든 코드가 실제 머신 / CPU 코드 인 것은 아닙니다. 링커는 커널 만 해석 할 수있는 메타 데이터로 프로그램을 래핑했습니다.

머신 코드가 메모리에로드 된 후 어떻게됩니까? 커널을 거치거나 프로세서와 직접 대화합니까?

코드가 두 개의 레지스터를 추가하는 것과 같은 단순한 opcode 인 경우 커널 지원없이 CPU에서 직접 실행하지만 라이브러리의 함수를 사용하는 코드 인 경우 이러한 호출은 예를 들어 웨이트리스와 같이 커널에서 지원합니다. 식당에서 식사를하려면 포크, 스푼 (그리고 여전히 자산)과 같은 도구를 제공하지만 무엇을 할 것인지는 "코드"까지 제공합니다.

글에서 화염을 막기 위해 OP가 기본 사항을 이해하는 데 도움이되기를 바랍니다.하지만이 답변을 개선하기위한 좋은 제안은 환영합니다.


3

따라서 간단한 소스 코드를 컴파일 할 때 printf () 함수로 컴파일하면 실행 가능한 머신 코드가 생성됩니다.이 머신 코드의 각 명령은 메모리에서 직접 실행됩니다 (코드가 메모리에로드되면 기계 코드의 각 명령이 여전히 OS (커널)를 거쳐 실행되어야합니까?

기본적으로 시스템 호출 만 커널로 이동합니다. I / O 또는 메모리 할당 / 할당 해제와 관련이있는 경우 일반적으로 시스템 호출이 발생합니다. 일부 명령은 커널 모드에서만 실행될 수 있으며 CPU가 예외를 트리거하게합니다. 예외로 인해 커널 모드로 전환하고 커널 코드로 이동합니다.

커널은 프로그램의 모든 명령어를 처리하지는 않습니다. 단지 시스템 호출을 수행하고 CPU를 공유하기 위해 실행중인 프로그램 사이를 전환합니다.

사용자 모드 (커널없이)에서 메모리 할당을 수행 할 수 없습니다. 액세스 할 수있는 메모리에 액세스 할 수없는 경우 이전에 커널에서 프로그래밍 한 MMU가 CPU 수준 "세그먼트 결함"예외를 통지하고 발생시킵니다. 커널을 트리거하고 커널이 프로그램을 종료합니다.

사용자 모드 (커널없이)에서 I / O를 수행 할 수 없습니다. I / O 포트 또는 장치의 레지스터에 액세스하거나 장치에 연결된 주소 (I / O를 수행하는 데 필요한 하나 또는 둘 다)에 액세스하면 같은 방식으로 예외.


실행 파일을 실행하려면 OS 커널이 필요합니까?

실행 파일 유형에 따라 다릅니다.

커널은 RAM 및 하드웨어에 대한 공유 액세스를 중재 할뿐만 아니라 로더 기능도 수행합니다.

ELF 또는 PE와 같은 많은 "실행 가능 형식"에는 코드 외에 실행 파일에 메타 데이터가 있으며이를 처리하는 로더의 작업입니다. 읽기 마이크로 소프트의 PE 형식에 대한 처참한 세부 사항을 자세한 내용은.

이 실행 파일은 라이브러리 (Windows .dll또는 Linux 공유 객체 .so파일) 도 참조 합니다. 코드가 포함되어 있어야합니다.

컴파일러가 운영 체제 로더에서 처리하도록되어있는 파일을 생성하고 해당 로더가 없으면 해당 파일이 작동하지 않습니다.

  • 로더의 역할을하는 코드를 포함시킬 수 있습니까?

확실한. 메타 데이터를 처리하지 않고 어떻게 든 원시 코드를 실행하도록 OS를 설득해야합니다. 코드가 커널 API를 호출해도 여전히 작동하지 않습니다.

  • 커널 API를 호출하지 않으면 어떻게됩니까?

어떻게 든 운영 체제에서이 실행 파일을로드하더라도 (즉, 원시 코드를로드하고 실행할 수있는 경우) 여전히 사용자 모드에있게됩니다. 할당되지 않은 메모리 또는 I / O 장치 주소 / 레지스터와 같이 커널 모드와 달리 사용자 모드에서 금지 된 항목에 코드가 액세스하는 경우 권한 또는 세그먼트 위반으로 인해 충돌이 발생합니다 (다시 예외는 커널 모드로 이동하여 처리됨) 거기) 여전히 작동하지 않습니다.

  • 커널 모드에서 실행하면 어떻게됩니까?

그런 다음 작동합니다.



이것은 완전히 정확하지 않습니다. 하드웨어 액세스 커널을 통과 요구 사항은, 심지어이 있다고 커널, 오늘날 많은 시스템에 긍정 만든 디자인 결정이지만, 많은 간단한 시스템 (심지어이 일에) 부정적으로했다.
Chris Stratton

A) 커널이 있고 B) 사용자 / 감독자 모드와 MMU를 사용하여 CPU에서 코드를 실행하는 경우 상황이 어떻게 진행되는지 설명하고 있습니다. 예, MMU 또는 사용자 / 감독자 모드가없는 CPU 및 마이크로 컨트롤러가 있으며 일부 시스템은 전체 사용자 / 감독자 인프라를 사용하지 않고 실행됩니다. Microsoft의 첫 번째 Xbox는 사용자 / 감독자 모드가있는 표준 x86 CPU가 커널 모드를 떠나지 않았다는 점에서 이렇습니다.로드 된 게임은 원하는 작업을 수행 할 수 있습니다.
LawrenceC

1
MacOS X 이전의 Macintosh 시스템 은 메모리 보호를 사용하지 않은 수십 년 동안 메모리 보호를 지원하는 범용 CPU (68000 제품군, PowerPC)에서 실행되는 범용 컴퓨터 의 OS였습니다. : 모든 프로그램이 메모리의 모든 항목에 액세스 할 수 있습니다.
curiousguy

3

TL; DR 번호

Arduino 개발은 OS가없는 현재 환경으로 떠 오릅니다. 이 아기들 중 하나에서 당신은 운영 체제를위한 공간이 없습니다.

마찬가지로, Sega Genesis 게임에는 Sega가 제공하는 OS가 없었습니다. 방금 베어 메탈에 직접 쓰는 68K 어셈블러로 게임을 만들었습니다.

또는 내가 이빨을 자르고 인텔 8051에 내장 된 작업을 수행하는 경우. 2k * 8 크기의 2716 eprom이면 운영 체제를위한 공간이 없습니다.

물론 이것은 단어 응용 프로그램이 매우 광범위하게 사용된다고 가정합니다. 수사 학적 질문으로 Arduino 스케치가 실제로 적용 가능한지 자문 해 보는 것이 좋습니다.


3

다른 답변이 그 자체로 옳지 않다는 것을 암시하고 싶지는 않지만 너무 두려워서 여전히 당신에게 매우 모호한 세부 사항을 너무 많이 제공합니다.

기본적인 대답은 코드가 프로세서에서 직접 실행된다는 것입니다. 그리고 기계 코드는 다른 사람과 "대화"하지 않습니다. 프로세서는 활성 구성 요소이며 컴퓨터에서 수행하는 모든 작업은 해당 프로세서에 의해 수행됩니다 (여기서 작업을 단순화하고 있지만 지금은 괜찮습니다). 프로세서는 코드를 읽고 실행하여 결과를 뱉어냅니다. 머신 코드는 단지 프로세서를위한 음식입니다.

혼동은 하드웨어라는 단어의 사용에서 비롯됩니다. 부서가 예전만큼 명확하지는 않지만 단순히 모든 하드웨어를 호출하는 것보다 주변 장치의 관점에서 생각하는 것이 좋습니다. 따라서 컴퓨터에 운영 체제 또는 이와 유사한 것이있는 경우 프로그램은 주변 장치에 액세스하기 위해 해당 서비스를 사용해야하지만 프로세서 자체는 주변 장치가 아니며 프로그램이 직접 실행되는 기본 처리 장치입니다.

커널, 운영 체제 및 유사한 중간 계층은 일반적으로 여러 프로그램이 실행될 것으로 예상되고 시스템에서 이러한 프로그램이 컴퓨터 주변 장치를 어떻게 사용할 수 있는지 관리해야하는 대규모 시스템에서만 사용됩니다. 같은 시간). 이러한 경우, 실행중인 프로그램은 시스템을 사용하여 이러한 주변 장치에만 액세스 할 수 있으며 시스템을 공유하는 방법을 결정하고 충돌이 없는지 확인합니다. 경쟁 프로그램간에 관리가 필요없는 소규모 시스템으로, 기본 시스템이 전혀없고, 종종 기본 시스템이없고, 이러한 시스템에서 정상적으로 실행되는 단일 프로그램은 주변 장치로 원하는 것을 자유롭게 수행 할 수 있습니다.


2

전원을 켤 때 컴퓨터에서 실행되는 BIOS는 ROM에 저장된 실행 코드입니다. 기계 명령어와 데이터로 구성됩니다. 소스 코드에서이 BIOS를 어셈블하는 컴파일러 (또는 어셈블러)가 있습니다. 이것은 특별한 경우입니다.

다른 특별한 경우로는 커널과 커널 자체를로드하는 부트 스트랩 프로그램이 있습니다. 이러한 특수 사례는 일반적으로 C ++ 이외의 언어로 코딩됩니다.

일반적으로 컴파일러가 커널이나 라이브러리 루틴이 제공하는 시스템 서비스를 호출하는 일부 명령어를 생성하도록하는 것이 훨씬 더 실용적입니다. 컴파일러를 훨씬 가볍게 만듭니다. 또한 컴파일 된 코드를 더 가볍게 만듭니다.

스펙트럼의 다른 쪽 끝은 Java입니다. Java에서는 컴파일러가 소스 코드를 기계 명령어로 변환하지 않습니다.이 용어는 일반적으로 이해되기 때문입니다. 대신 소스 코드는 가상 머신 (Java Virtual Machine)의 "기계 명령어"로 변환됩니다. Java 프로그램을 실행하려면 먼저 Java Virtual Machine에 대한 인터프리터가 포함 된 Java 런타임과 결합해야합니다.


2

예전에는 프로그램을 직접 실행하거나 다른 사람이 프로그램에 작성한 라이브러리 코드를 추가하여 프로그램을 실행하는 동안 수행해야하는 모든 작업을 수행해야했습니다. 컴퓨터에서 그 옆에있는 유일한 것은 운이 좋으면 컴파일 된 프로그램에서 읽을 수있는 코드였습니다. 일부 컴퓨터에는 스위치를 통해 코드를 입력해야했지만 더 많은 작업을 수행하려면 (원래의 "부트 스트랩"프로세스), 심지어 전체 프로그램도 이런 방식으로 입력했습니다.

프로그램을로드하고 실행할 수있는 코드를 실행하는 것이 좋았습니다. 나중에 컴퓨터는 특히 하드웨어가 도움이 될 수있는 경우 CPU간에 스위치를 전환하여 여러 프로그램을 동시에 실행하도록 지원할 수있을만큼 강력하지만, 프로그램의 복잡성이 증가함에 따라 서로의 발끝을 밟지 않습니다 (예 : , 프린터로 데이터를 한 번에 보내려는 여러 프로그램을 처리하는 방법은 무엇입니까?).

이 모든 결과는 사용자 프로그램에서 헬퍼 코드를 호출하는 표준화 된 방법으로 대량의 헬퍼 코드가 개별 프로그램에서 "운영 체제"로 이동되었습니다.

그리고 그것은 우리가 오늘있는 곳입니다. 프로그램은 최고 속도로 실행되지만 운영 체제에서 관리하는 것이 필요할 때마다 운영 체제에서 제공하는 도우미 루틴을 호출하며 해당 코드는 필요하지 않으며 사용자 프로그램 자체에는 없습니다. 여기에는 디스플레이에 쓰기, 파일 저장, 네트워크 액세스 등이 포함됩니다.

전체 운영 체제없이 특정 프로그램을 실행하는 데 필요한 것을 제공하는 마이크로 커널이 작성되었습니다. 이것은 숙련 된 사용자에게는 몇 가지 장점이 있지만 다른 대부분은 제공하지 않습니다. 자세한 내용을 보려면 Wikipedia 페이지 ( https://en.wikipedia.org/wiki/Microkernel)를 참조하십시오 .

Java Virtual Machine을 실행할 수있는 Microkernel을 실험했지만 나중에 그 점이 Docker라는 것을 알았습니다.


1

일반적인 데스크탑 OS에서 커널 자체 는 실행 파일입니다. (Windows에는 ntoskrnl.exe; Linux에는 vmlinux등이 있습니다.) 실행 파일을 실행하기 위해 커널이 필요한 경우 해당 OS가 존재하지 않을 수 있습니다.

커널이 필요한 것은 커널이하는 일을하는 것입니다. 여러 실행 파일을 한 번에 실행하고, 그 사이에 심판을 지정하고, 하드웨어를 추상화하는 등의 작업을 수행 할 수 있습니다. 대부분의 프로그램은 자체적으로 유능한 작업을 수행 할 수 없으므로 가능하더라도 원치 않을 것입니다. 운영 체제 자체라고 할 수없는 DOS 시대에 게임은 종종 로더처럼 OS를 사용하고 커널처럼 하드웨어에 직접 액세스했습니다. 그러나 게임을 구입하기 전에 컴퓨터에 어떤 브랜드와 하드웨어 모델이 있는지 알고 있어야했습니다. 많은 게임이 특정 비디오 및 사운드 카드 제품군 만 지원했으며 경쟁 브랜드에서 전혀 효과가 없었던 경우 매우 열악했습니다. 그'

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.