ㅎㅇ헬로
유저영역이랑 커널영역에 대하여 아십니까?
그게 뭔데 씹덕아? 라는 나쁜말은 하지 말아주세요.
바로 오늘의 주제는 유저영역과 커널영역에 대하여 알아보기 입니다 ㅋㅅㅋ
사실 커널의 개념만 알면 쉬운 주제입니다. 커널의 약간 확장 개념이라고 보시면 될 것 같습니다.
반대로 커널에 대해 모르면 이해하기 힘들 수도 있습니다!
바로 ㄱㄱ싱 하시죠.
유저영역과 커널영역
유저영역과 커널영역은 운영체제에서 정말로 중요한 개념이랍니다?
대체 뭐길래 그러는걸까요...
바로 시스템 자원(메모리, 프로세서, 장치 등)의 접근 권한을 설정하기 위해 나눈 개념입니다.
각 영역은 무슨 역할을 하고, 왜 나눈 것일까요?
●커널영역
커널영역은 프로세스의 주소공간을 제외한 나머지 영역을 칭합니다.
커널영역에는 커널이 위치하고 있습니다. 때문에 모든 시스템 자원에 대한 권한이 있습니다.
여기서 권한에 대한 예시를 들자면, 파일을 읽어오거나, 쓰는 작업, 혹은 저장하는 등의 하드웨어적인 부분에 대한 접근 권한이라 할 수 있겠습니다.
시스템 자원에 대한 처리 및 메모리 할당과 해제를 해주고, 외에 CPU스케줄링 등을 해주는 영역입니다.
시스템 자원에 대하여 직접적으로 접근할 수 있어 속도가 빠릅니다.
●유저영역
유저영역은 프로세스의 주소공간인 스택, 힙, 코드, 데이터 영역을 칭합니다.
유저영역은 시스템 자원에 직접적으로 접근할 수 없습니다.
일반적으로 소프트웨어 개발자가 애플리케이션 로직, 사용자 인터페이스, 데이터 처리 및 관련 기능을 구현하는 영역입니다.
시스템 자원에 대한 접근을 하려면 시스템 호출을 통해 접근해야 하기 때문에 속도가 느립니다.
● 유저영역과 커널영역간의 전환, System Call
앞서 유저영역과 커널영역에 대해 간략히 말씀을 드렸는데요? 한 가지 궁금증이 생겨버립니다.
우리가 개발하는 환경은 유저영역인데, 유저영역은 시스템 자원에 접근할 수 없습니다. 그럼 시스템 자원은 못쓰는 것일까요? 사실 그럴리가 없죠. 위에서 이미 설명도 했답니다?
유저영역에서 시스템 자원에 접근하려면 커널영역에 요청을 해야합니다. 이 때 커널영역에 접근을 해야하는데, 이 과정을 시스템 호출(System Call)이라고 합니다.
시스템 호출은 매우 중요한 개념입니다. 성능과 관련이 매우 밀접하기 때문이죠. 왜 성능과 관련이 있을까요?
시스템 호출(System Call)은 유저영역에서 커널영역으로 전환하는 과정을 거칩니다. 이 때 운영체제는 장치문맥을 교환(Context Switching)하게 되는데요, 이 비용이 상당합니다.
+++ 추가로 커널객체에 대하여 간단하게
특정 시스템 자원에 접근할 수 있는 객체를 커널객체라 하는데, 이 객체를 유저영역에서 직접 쓸 순 없고, Handle이라는 개체로 유저영역에 넘겨주게 됩니다. 유저영역에선 Handle을 통해 커널에게 해당 객체의 특정요청을 보낼 수 있습니다.
(당연하게도 커널객체는 커널영역에 할당되는 것이고, Handle은 유저영역에 할당되는 메모리입니다.)
● 유저영역과 커널영역을 왜 나눴을까
유저모드와 커널모드는 분리됨으로써 여러 장점을 취할 수 있습니다.
안정성 : 서로의 영역이 분리됨으로써 어플리케이션에서 심각한 오류가 발생되어도 통상적으로 커널엔 심각한 영향을 끼치지 않는 경우가 많습니다.
보안 : 프로그램이 시스템 자원에 접근할 때 커널을 통해 요청하도록 함으로써, 권한 검사를 수행할 수 있습니다. 이를 통해 악의적인 코드가 시스템 자원을 부적절하게 사용하지 못하게 합니다. (객체지향프로그래밍을 해보신 분이라면 쉽게 이해할 수 있을텐데요, class의 private멤버를 public함수를 통해 특정 접근권한만 주는거랑 비슷하다고 볼 수 있습니다.)
효율성 : 커널은 시스템 자원에 대한 최적화된 접근 방식을 제공하고, 내부적으로 CPU와 메모리 자원을 효율적으로 관리합니다. (하지만 자주 상호작용할 경우 System Call로 인해 오버헤드가 발생할 수 있습니다.)
이번에 유저영역과 커널영역에 대해 다뤄봤습니다만, 컴퓨터 구조라는 것은 눈에 보이지 않기 때문에 추상적으로 느껴질 수 밖에 없다고 생각합니다. 그래서 예시를 한가지 들어보려고 합니다.
저는 개인적으로 유저영역과 커널영역을 개인과 은행의 대출관계와 비슷하다고 생각합니다.
- 개인 : 유저영역
- 은행 : 커널영역
- 현금 : 중요 시스템 자원, 즉 커널 객체
- 통장 : 시스템 자원을 쓰기 위한 수단, 즉 Handle
현금은 우리의 생활에서 상당히 중요한 자원입니다.
우리는 현금이 필요할 때, 은행에게서 현금 대출을 요청(System Call) 하는데요.
이때 은행은 대출조건을 검사하고 적합할 경우 통장을 통해 현금을 빌려주게 됩니다.
이 과정을 간략히 나타내면,
1. 현금을 은행에게 요청 (커널 객체를 커널 영역에서 요청)
2. 은행은 요청을 받고 검사하는데 시간이 걸림 (유저영역 -> 커널영역간의 전환 비용)
3. 검사 결과가 적합할 시 은행은 통장을 통해 현금을 줌 (커널 객체를 Handle 로 반환해줌)
4. 개인은 빌린 대출을 갚아야함 (커널 객체를 Handle을 통해 메모리 해제)
이렇게 나타낼 수 있습니다.
단, 저는 이해를 돕기 위해 예시를 든 것 뿐이지, 완벽한 예시란건 없다고 생각합니다. 알아서 걸러들으시길 ㅇㅅㅇ
또한 유저영역과 커널영역에 대한 상식을 만화로 잘 표현하신 분이 있습니다. 이 게시글을 보는 것도 도움이 될 것 같습니다.
'프로그래밍 > CS' 카테고리의 다른 글
[CS] 인터럽트 (0) | 2024.10.22 |
---|---|
[CS] CPU 스케줄링 (4) | 2024.10.21 |
[CS] CPU의 메모리 계층 구조 (4) | 2024.10.13 |
[CS] 커널(Kernel)과 그 종류에 대해 (0) | 2024.10.13 |
[CS] 프로세스와 스레드 (2) | 2024.10.06 |