
밑에 하드웨어가 있고요 위는 미드웨어라고 하는 소프트웨어 레이어가 있을 수 있고, 아니면 펌웨어라고 부르는 소프트웨어 레이어가 있습니다. 그 위에 운영체제가 올라갈 거고요
그위에 우리가 관심 있는 시스템 라이브러리, 마지막으로 다양한 어플리케이션들이 있을 수 있습니다.
스크립트 랭귀지라는 것은 요즘 많이 쓰는 파이썬 같은걸 얘기를 하는데요, 컴파일이 없습니다. 그래서 스크립트
랭기지라고 부르고요, 호스트 랭기지가 뭐냐면 C, JAVA같이 컴파일 해야하는 랭기지를 얘기합니다.
각각 장단점이 있을 텐데, 스크립트 랭기지는 사용하기 편하죠 당연히 컴파일을 안하니까 로딩같은거 신경 안써도 되고요, 호스트 랭귀지는 번거로워요. 코드 짠거 빌딩도 해야되고 코드 관리도 해야되고, 또 컴파일, 로딩 등 신경 쓸게 많아요. 그럼에도 불구하고 빠릅니다. 왜 빠르냐면 컴파일 해서 나오는게 컴퓨터 하드웨어가 알아먹을 수 있는 인스트럭션 레벨까지 다 내려와요. 그래서 컴퓨터 입장에서는 당연히 호스트랭기지가 더 빠릅니다. 그리고 시스템 라이브러리는 C아님 C++가 대부분이에요 거의 90%이상이 C아님 C++에요.
OS, 우리는 리눅스 유닉스를 집중할 건데 C를 사용합니다. 가끔 요즘 붙어있는 디바이스 드라이버 같은 경우에는 C++가 사용되는 경우도 있고요. 밑에는 뭐냐 미드웨어 펌웨어, 이게 약간 특이한 소프트웨어들 인데요, 기본적으로 호스트 랭기지로 쓰여져 있고요, 가끔은 어셈블리로 쓰여져 있는 경우도 있습니다. 그 이유는 펌웨어 같은 경우에는 주로 어떤 경우에 펌웨어 소프트웨어를 구현하냐면 자주 재사용할 때, 예를 들어서 셀폰은 평소에 꺼져있죠. 근데 사용하고 싶을 때 화면을 두드리면 화면이 딱 들어오죠, 이런 동작을 소프트웨어로 구현할 때 여러가지 인스트럭션들을 하드웨어 한테 집어 넣어줘야지 화면이 켜질거에요. 근데 어떤 상황에서 두드리든 언제두드리든 동작이 바뀌지 않죠. 완전히 동일한 거를 계속 반복해서 사용합니다. 유저와의 인터렉션에 상관없이 그런 종류의 소프트웨어는 펌웨어라는 타입으로 구현을 해요. 그래서 제일 낮은 레벨의 랭기지로 구현을 해서하드웨어를 바꿔놓으면 나중에 이제 그 입력이 들어왔을 때마다 계속해서 반복 수행을 하게 됩니다.
미들웨어는 이름이 약간 어느정도 설명을 하고 있는데, 여기 위에있는 애랑 밑에있는 애랑 사이에 있다에요. 운영체제라는 소프트웨어와 시스템이라는 하드웨어 사이에있다 해서 미들웨어에요. 그게 무슨 소리냐면 어떤 하드웨어가 와도, OS가 뭐가와도 약간 좀 제너럴 하게 동작을 해주는 소프트웨어들을 미들웨어라고 해요. 그런데 이제 미들웨어라는 이름자체가 약간 어느 한쪽에 분리하기 어려운 소프트웨어라고 생각하시면 됩니다. 예를들어 이제 이거는 논란의 여지가 많은데 부트로더라고 하는 소프트웨어가 있는데 원래는 하드웨어 스펙시틱합니다. 본인이 무슨 하드웨어를 쓰는지 알고 부트로더라는 소프트웨어를 작성을 해야하는데 시스템들이 요즘엔 규격에 맞춰서 나오다 보니까 비슷해졌어요. 그래서 특이한 기능들은 나중에 세팅을 해주더라도 기본기능은 다 초기화가 된다. 이런 개념을 미들웨어로 하고 있습니다.
그래서 우리가 집중해서 볼것은 미들웨어 펌웨어, OS고요 지금까지 우리가 배울 것들이 어떤 내용인지 잘 살펴봤습니다.
그다음 옆에 그림을 보시면 비슷한 그림이 있어요. 가운데 커널이라고 하는게 있습니다. 유닉스 커널이나 리눅스커널 말하는게 맞아요 그위에 시스템 콜이라는 레이어가 있습니다. 시스템 콜 위에 시스템 라이브러리라는 애가 있고요. 마지막에 어플리케이션들이 있을겁니다.
커널은 운영체제에서 가장 기초적인 기능, 즉 컴퓨터를 운영하는데 필요한 것들, 메모리를 사용하고, Cpu에 인스트럭션들을 돌리고 디스크에서 데이터를 가져오고 이런 아주 기초적인 기능을 구현하는 걸 커널이라고 합니다. 리눅스 커널은 C로 사용되어 있습니다.
커널은 그 위의 레이어들, 즉 시스템 라이브러리나 어떤 시스템 소프트웨어들이 어떤 하드웨어 기능을 직접 사용할 수 있도록 api라고 하는것을 만들어줍니다. 그래서 위에있는 레이어들을 시스템 소프트웨어로 구현할 때 우리가 이 함수를 호출하면 하드웨어에 이런 기능이 수행되는구나, 이런 인터페이스를 시스템 콜이라고 합니다. 그래서 시스템 콜은 어떤 운영체제를 사용하느냐에 따라 다르고 우리는 유닉스 기반의 운영체제를 집중해서 볼겁니다. 따라서 유닉스 기반의 운영체제의 시스템 콜을 볼겁니다. 그리고 그 인터페이스를 사용해서 시스템 소프트웨어로 구현해줍니다. 아주 대표적인 시스템 라이브러리가 gmo 라이브러리라는 건데요,malloc 사용해본적 있죠 메모리 얼로케이션 function인데요, 수업자료 다음 장을 보시면 말록이라고 있습니다.
static void*
_int_malloc(mstate av, size_t bytes)
{
INTERNAL_SIZE_T nb; /* normalized rquest size */
unsigned int idx; /* associated bin index */
mbinptr bin; /* associated bin */
mchunkptr victim; /* inspected/selected chunk */
INTERNAL_SIZE_T size;
int victim_index;
mchunkptr remainder; /* 분할되고 남은 청크 */
unsigned long remainder_size;
unsigned int block; /* bit map traverser */
unsigned int bit; /* bit map traverser */
unsigned int map; /* current word of binmap */
mchunkptr fwd; /* misc temp for linking */
mchunkptr bck; /* misc temp for linking */
#if USE_TCACHE
size_t tcache_unsorted_count; /* count of unsorted chunks processed */
#endif
checked_request2size(bytes, nb); //실제 할당받는 크기로 변환
/*사용가능한 아레나가 없는 경우 sysmalloc으로 할당받는다. mmap 사용*/
if (__glibc_unlikely(av == NULL))
{
void* p = sysmalloc(nb, av);
if (p != NULL)
alloc_perturb(p, bytes);
return p;
}
...
이 소스 코드는 지금보면 glibc의 malloc에 malloc function중에 있는 코드고요 밑에 부분에 kmalloc을 호출합니다. kmalloc은 kernel malloc이라고 해서 운영체제 안에서 커널이 메모리를 allocated할 때 사용됩니다. 그래서 이 malloc 소스코드를 보면 우리가 이제 오늘이나 내일 다음주 까지해서 배울시에 기본적인 기능들이 다 들어가 있어요. 실제 제가 이제 강의를 하면서 이번학기에 실제 예제들을 최대한 많이 보여드릴 텐데요 실제로 이제 최근에 나외있는 버전들의 실제 시스템 소프트웨어들을 보여드릴 거에요 이거같이. 여긴 안나와 있지만, malloc 코드가 어떻게 구현돼 있냐면, 기본적으로 하는게 시스템에 있는 메모리를 할당받아서 그 주소를 유저한테 주는 함수죠. 이게 안에 구현할 때 mmap이라는 시스템 콜을 사용합니다. mmap은, 약간 운영체제의 개념인데요 피지컬 메모리 스페이스를 특정 사이즈 단위로 쪼개서 관리를 합니다. 그 특정 사이즈를 블록, 페이지라고 하고요 그 페이지를 사실은 페이지를 쪼개놨는데 여러가지 이유에 의해서 이렇게 continious하게 사용하지 않으면 여기있었다가 저기있었다가 사이즈가 다 다를거고요. 그러니까 사용자가 요청한 사이즈만큼 여기저기서 모아다가 logically continious한 스페이스를 만들어서 올려줍니다. 그 함수가 mmap입니다.
mmap이 그래서 메모리를 직접 관리하는 시스템 콜이고요 malloc은 malloc입장에서 보면 여기는 유저레벨이에요. 운영체제 밑에서 무슨일이 벌어지는지 모르겠는데 나는 이만큼의 메모리가 필요해요, 그러니까 주세요, 하고 mmap한테 요청하면 mmap이 따로 줘요. 그러면 malloc 입장에서는 내가 요청한 만큼의 이런 연속적인 메모리 스페이스를 받은거에요 그럼 이제 거기다가 유저는 C 프로그래밍 짜가지고 넣고싶은거 넣겠죠.
여기까지 시스템 라이브러리고요 우리는 프로그래밍을 하는 걸 배우고싶은 타입이에요. 이제 그래서 그 다음장에 보시면 우리는 이번 한주 동안 시스템 프로그래밍에 필요한 C언어에대해 집중해서 배울 겁니다.
이번 시간에 여기 나와있는 일단 데이터를 C에서 어떻게 처리하는지 살펴볼거고요, 메모리 스페이스 헨들링과 포인터에대해 볼겁니다.
그리고 약간 이제 연결돼 있는 운영체제에서 필요한 내용들도 살짝 살짝 배울 거고요, 유저레벨 디바이스라고 지금 아까 잠깐 설명을 했는데요 커널은 자기만의 메모리 스페이스를 가지고 있어요 부팅타임에 모든 운영체제는 메모리를 초기화하고 메모리를 커널만 사용할 수 있는 영역을 확보합니다. 그래서 그 부분을 커널 스페이스라고 부르고요. 근데 커널이 다 쓰면 어플리케이션이 이것을 볼 수가 없으니까 다른 어플리케이션들도 써라 하고 남겨준 부분이 있는데 그게 user-level device 라고 생각하시면 돼요.