본문 바로가기
3. 개발 관련/임베디드 :: 괴발개발주절주절이야기보따리

3. OS가 뭐냐고? (2)

by kyuho.choi 2011. 9. 7.
728x90
반응형
언제나 모든 이야기의 이어짐이 그렇듯,

오늘도 역시 먹다 남은 거 주어먹듯 다시 시작함미다.

=====================================================================
Root Filesystem
=====================================================================
                                                           kernel area (1Gbytes ~ 3Gbytes)

Systemcall Interface
---------------------------------------------------------------
Virtual Filesystem
---------------------------------------------------------------
FileSystem    DeviceDriver    NetworkProtocol  Process MemoryManagement

=====================================================================
Bootloader
                           ===================================================================== 

어떤 것을 되새길 것이냐면, 물론 지난번에 살펴보지 않은 것들이 되겠지요. :)
Virtual Filesystem과 SystemCall Interface 가 남아있습니다.

Virtual Filesystem 과 SystemCall 은 서로 긴밀한 관계를 갖고 있는데,
이는 먼저 리눅스(또는 UNIX like 한 OS)에 대해 먼저 생각해보아야합니다.

컴퓨터공학을 전공하시거나 아니거나!

리눅스라고하는 운영체제는 추상화를 잘 이루고 있다고하더랍니다.
원론적이면서도 중요한 부분인데요.
추상화?라는 것은 무엇이냐면
"물리적이나 개념적으로 존재하는 녀석들을 인식할 수 있는 형태로 표현해주는 것을 의미합니다"
아 물론 당연히 믿거나 말거나 저 만의 정의입미다.

여기에서 물리적이나 개념적으로 존재하는 것, 이라고 하는 부분은 바로 시스템 리소스가 됩니다.

시스템 리소스?는 물리적으로 존재하는 하드디스크나 CPU, 메모리처럼 HW와 관련된 녀석들이 되겠지요.
그럼 여기에서 개념적으로 존재하는 것?은 위 하드디스크를 어떤 알고리즘으로 Input/Output 처리르 할 것이냐에
대한 DISK I/O정책, CPU를 어떻게 사용할 것이냐에 대한 Scheduler, CPU를 사용하는 녀석에 해당하는 process/task 같은 녀석들이 이에 해당합니다.

그럼 인식할 수 있는 형태?는 무척이나 간단하고 또 우리에게 친숙합미다.
눈치 빠른 친구는 알겠지요?!(저의 고등학교 화학 선생님의 단골멘트라 아직도 기억함미다) 네 바로 FILE입지요!!
F.I.L.E, 파일 FAIL 말고 FILE!!! 

리눅스에서 이 FILE은 무척이나 재미있게 표현 및 사용됩니다.

앞서 물리적으로 존재하는 리소스 중 하드 디스크를 언급했는데요.
일반적으로, 파일 이라고하면 하드 디스크와 같은 스토리지 내부에 특정 포맷으로 저장되어 있는 데이터를 의미합니다. 물론, 맞는 말이고 실제로 리눅스던 윈도우던 뭐던간에 그렇게 사용되지요...

재미있게 사용된다는 점은 무엇이냐?면 바로 스토리지에 실제로 존재하지 않는 데이터들도 파일로 표현한다는 점입니다. 무슨말이냐?라고 하면 예를 들어 설명하는 것이 편하겠네요. :)

우선 아래를 보시면 말입니다.
제가 사용하고 있는 리눅스 머신의 /proc 이라는 디렉토리와 /sys, /dev 라는  디렉토리의 내용을  ls 커맨드를 이용하여 리스트업해봤슴미다.

==============================================================================================
root@chlrbgh0:~# ls /proc/
1      1351   20865  20898  20931  23045  339   6252  6412  9656           modules
1033   1352   20866  20899  20932  23046  34    6255  6415  acpi           mounts
10791  13669  20867  20900  21     23047  340   6260  6417  asound         mtrr
1091   13670  20868  20901  21787  23050  3426  6265  6422  buddyinfo      net
1129   1381   20869  20902  22014  23051  3428  6271  6431  bus            pagetypeinfo
1130   14050  20870  20903  22353  23052  35    6279  6434  cgroups        partitions
1131   1436   20871  20904  22354  23053  3692  6281  6698  cmdline        sched_debug
1136   14527  20872  20905  22355  23054  373   6283  6818  cpuinfo        schedstat
114    1461   20873  20906  22356  23055  374   6290  6901  crypto         scsi
1140   1531   20874  20907  22357  23056  3775  6291  7098  devices        self
1146   1532   20875  20908  22358  23057  378   6292  7101  diskstats      slabinfo
1147   15618  20876  20909  22359  23825  4     6293  7102  dma            softirqs
115    15982  20877  20910  22360  23913  41    6334  7174  driver         stat
1156   1608   20878  20911  22361  23915  4159  6336  7178  execdomains    swaps
1169   1617   20879  20912  22362  26355  4166  6344  7179  fb             sys
121    1650   20880  20913  22363  26360  424   6346  721   filesystems    sysrq-trigger
122    16628  20881  20914  22367  26366  429   6354  7251  fs             sysvipc
123    1669   20882  20915  23027  26369  47    6356  731   interrupts     timer_list
1241   16711  20883  20916  23028  27     48    6358  7322  iomem          timer_stats
1251   1691   20884  20917  23030  28     49    6362  7346  ioports        tty
1264   1745   20885  20918  23032  29     5     6367  7369  irq            uptime
12654  17917  20886  20919  23033  3      50    6368  7440  kallsyms       version
1272   1828   20887  20920  23034  30     51    6369  785   kcore          version_signature
12737  18565  20888  20921  23035  30288  57    6372  83    key-users      vmallocinfo
129    1911   20889  20922  23036  31     58    6374  84    kmsg           vmstat
1313   1919   20890  20923  23037  31639  59    6381  85    kpagecount     zoneinfo
1318   1983   20891  20924  23038  31686  6104  6391  86    kpageflags
1324   1984   20892  20925  23039  31905  6189  6393  880   latency_stats
1325   1990   20893  20926  23040  321    6193  6395  92    loadavg
1327   2      20894  20927  23041  33     6213  6397  93    locks
1330   2068   20895  20928  23042  332    6243  6406  9460  mdstat
1334   20863  20896  20929  23043  333    6246  6408  9479  meminfo
1335   20864  20897  20930  23044  334    6247  6410  9573  misc
root@chlrbgh0:~# 
root@chlrbgh0:~# 
root@chlrbgh0:~# ls /sys/
block  bus  class  dev  devices  firmware  fs  hypervisor  kernel  module  power
root@chlrbgh0:~# 
root@chlrbgh0:/dev# ls   
autofs           loop0               psaux   rtc0  shm       tty22  tty43  tty7     vcs6
block            loop1               ptmx    scd0  snapshot  tty23  tty44  tty8     vcs63
bsg              loop2               pts     sda   snd       tty24  tty45  tty9     vcs7
btrfs-control    loop3               ram0    sda1  sr0       tty25  tty46  ttyS0    vcs8
bus              loop4               ram1    sda2  stderr    tty26  tty47  ttyS1    vcsa
cdrom1           loop5               ram10   sda5  stdin     tty27  tty48  ttyS2    vcsa1
cdrw1            loop6               ram11   sdb   stdout    tty28  tty49  ttyS3    vcsa2
char             loop7               ram12   sdb1  tty       tty29  tty5   uinput   vcsa3
console          lp0                 ram13   sdb2  tty0      tty3   tty50  urandom  vcsa4
core             mapper              ram14   sdb5  tty1      tty30  tty51  usbmon0  vcsa5
cpu              mcelog              ram15   sdc   tty10     tty31  tty52  usbmon1  vcsa6
cpu_dma_latency  mem                 ram2    sdd   tty11     tty32  tty53  usbmon2  vcsa63
disk             net                 ram3    sde   tty12     tty33  tty54  usbmon3  vcsa7
dvd1             network_latency     ram4    sdf   tty13     tty34  tty55  usbmon4  vcsa8
dvdrw1           network_throughput  ram5    sdg   tty14     tty35  tty56  usbmon5  vga_arbiter
ecryptfs         null                ram6    sg0   tty15     tty36  tty57  usbmon6  zero
fd               nvidia0             ram7    sg1   tty16     tty37  tty58  usbmon7
full             nvidiactl           ram8    sg2   tty17     tty38  tty59  vcs
fuse             oldmem              ram9    sg3   tty18     tty39  tty6   vcs1
hpet             parport0            random  sg4   tty19     tty4   tty60  vcs2
input            pktcdvd             rfkill  sg5   tty2      tty40  tty61  vcs3
kmsg             port                root    sg6   tty20     tty41  tty62  vcs4
log              ppp                 rtc     sg7   tty21     tty42  tty63  vcs5
root@chlrbgh0:/dev# 
 ==============================================================================================

실행 결과를 보시면 각 디렉토리에 여러 파일이나 디렉토리 들이 있구나...라는 것을 보실 수 있습니다.
그러면, 요녀석들은 실제로 하드디스크에 존재하는 녀석들이냐!?라고 하면 없습니다.
백날 눈씻고 훝어봐도 없습니다!?

요녀석들은 특수한 파일 시스템으로 RAM, 즉 메모리를 통해서 그 FILE 정보를 관리하는 녀석들입니다.
우선은 그런게 있구나...라고 기억만하고 넘어가시면 됩니다. :)

이 중, /dev 디렉토리의 디렉토리 내부의 내용은 조금 특이합니다. RAM을 이용하여 표현되는 녀석들도 있고,
하드디스크 내부에 포함되어 있는 녀석도 있습니다. 특징이라면, 디렉토리의 이름답게 dev, 즉 device 와 관련된 정보가 이 디렉토리에 존재합니다. 앞서 언급한 것과 엮어서?정의해보면, 시스템 리소스 중 HW에 해당하는 녀석들을
File로 추상화하고 있는 녀석이 바로 이 /dev 디렉토리입니다.

그럼, Virtual Filesystem 은 뭘하는 놈이냐?를 살펴보기엔 아직 이릅니다...ㅠㅠ
살펴봐야할 것들이 몇몇개가 더 있습지요!

그럼 무엇을 살펴봐야 하느냐!?라고 하면 바로 SystemCall Interface임미다.
System Call?은 어플리케이션 동작시에 libc 라이브러리에서 제공하는 함수가 실행될 때, 이에 대응해서 OS에서 실행되는 소프트웨어 인터럽트입니다. 그냥 OS안에 포함되어있는 래퍼함수라고 이해하시면 됨미다.
(libc는 Glibc/Blibc/bionic libc 등 다양한 종류가 있으나 System Call Interface를 동작시킨다는 관점에서는 모두 동일함미다.)

그럼 System Call 이라는 녀석은 뭘하는고 하니, 요녀석 또한 제 이름 그대로 시스템을 컨트롤하는 인터페이스랍니다. 그.러.면! 시스템을 어떻게? 컨트롤하느냐?라는 부분에 있어서, 바로 오늘 주절주절거리고 있는 저 FILE들을 이용하여 시스템을 컨트롤해줍니다.

앞서 어플리케이션에서 libc 함수를 호출하면 System Call이 그에 대응해서 실행된다고 했는데,
예를 들자면 다음과 같습니다.

Application A 에서 다음과 같은 작업을 수행한다고 가정할 떄,

int main(...)
{
    int fd;
    fd = open("/dev/abstracted_device_file",O_RDWR) 
    return 0; 
}

위에서 처럼 open() 이라는 함수를 호출하는 경우!!!
바로 이 open() 이라는 함수가 libc 라이브러이에 있는 함수임미다.
요 녀석이 호출되면 OS 에서는 소프트웨어 인터럽트가 발생했구나!!!???라고 인지하고 
해당 소프트웨어 인터럽트를 처리하도록 그에 맞는 OS 내부의 함수를 실행시켜주지요.

sys_open() 이라는 함수가 그 것입니다...sys_ 라고 하는 것이 바로 System Call 을 의미하고 있음을 아시겠지요?

System Call 또한 libc 함수에서 인자로 주고 실행한 `/dev/abstracted_device_file`이라고 하는 놈에 대하여 동작을 해야 하는 데, 여기에서 의문이 발생하게 됨미다.

sys_open()이라고 하는 System Call은 `/dev/abstracted_device_file`라는 파일이 실제로 어디에 존재하는 녀석인지?와 어떤 시스템 리소스를 추상화하고 있는 녀석인지?에 대한 정보가 없지요. 또한 어떤 인터페이스를 이용하여 그 파일을 접근할 것이지 등의 정보도 없고요.

그냥 파일의 이름과 경로만 알 뿐임미다. 이 것을 도와주는 녀석이 바로 가상파일시스템!!이라는 말입지요.
실제 파일이 어디에 위치하고 있는 녀석인지, 그 파일이 시스템 리소스 중에 어떤 것과 연결되어 있는 녀석인지,
파일의 타입은 무엇인지 등을 복잡한 미로에서 길을 찾듯이 찾아 내 주는 녀석이 바로 Virtual Filesystem 이라는 녀석이 됩니다.

원론적인 이야기를 다시 해보면 위에서처럼 하드웨어 제어하고 싶은 어플리케이션이 있는 데,
그 어플리케이션을 내가 어떻게 만들어야 하드웨어를 제어하느냐?의 이야기입지요.

어플리케이션을 만들면서 하드웨어를 어떻게 제어할 것인지, 그 하드웨어가 어떤 방식(I2C, SPI, SDIO, I2S ... ...)으로 CPU와 통신하며 동작하는 지, 하드웨어가 아닌 파일 시스템이라면 그 파일 시스템이 어떤 포맷(FAT,NTFS, EXT2, EXT3, EXT4, YAFFS2,UBIFS ... ...)인지 알아야 하느냐의 문제임미다.

물론 알면 좋지만, 어플리케이션을 작성하는 사람이 이를 모두 알고 어플리케이션을 만들기란 어렵지요...매우! 무척이나 어렵슴미다...일단 저는 못함미다 희희
그래서 이를 대신해주는 것이 바로 VFS(Virtual Filesystem) 임미다. 어플리케이션이 System Call 인터페이스를 구동시킬 때, "동일한" 방식으로 시스템을 제어하도록 돕는 도구가 바로 System Call 과 VFS 에 해당하는 녀석들입지요.

원리는 간단함미다.

시스템에 존재하는 리소스 들을 하나하나 파일로 표현하면 어플리케이션에서는 libc 를 이용해서 `동일한` 방식으로
open()하고 `동일한` 방식으로 read()하며, `동일한` 방식으로 write() 등을 수행하게 되는 검미다. 그러면 시스템이 제어가 되지요. 어플리케이션에서는 단순히 파일에 억세스 하는 것이지만, 그 파일이 시스템 리소스와 연결되어 있는 녀석들이니까요. :)

혹, 시스템 프로그래밍 관련 강좌를 들어보시거나 다루어 보신 분이라면,
FILE 에 대하여 상당한 이해를 요구하는 것을 경험해보셨을 겁니다. 또는 FILE 을 잘 다루어야함미다.
그 이유가 물론 앞서 언급한 부분들에 해당되는 것이죠. FILE이라는 것이 단순히 하드디스크안에 저장되어 있는 놈들만 해당되는 게 아니라 시스템 리소스들도 다 FILE 로 다루기 때문에 그렇다고함미다.

FILE 과 System Call에 대하여 얼렁뚱땅 스물스물 설명하고 넘어가는 것 같지만,
다음에 보다 쉽게 요 두녀석을 다시 살펴보도록 하겠슴미다.
728x90
반응형

댓글