프로그래밍 농장

임베디드 및 설계 이론 본문

Linux

임베디드 및 설계 이론

Tennessee201 2021. 11. 3.
728x90

Virtual Memory

-> 하드디스크들에 있던것들도 실행되면 메모리에 올라가며 프로세스가 실행된다.

-> 프로그램이 시스템상에서 항상 동시에 돌아가는것이 아니다 :  시간별로 수행하는 프로그램을 나누어보았을떄, 생각보다 많지않을것이다. 

-> 전체프로그램보다는 적은 메모리를 가지고있지만, 그떄그떄 필요한 메모리만 올리면 되기에 램(메모리) 자체의 크기가 클필요가 없다.

-> 위와 같이 메모리에 올려주는것을 커널이 하며, 이를 메모리 메니지먼트라고하며, 이부분이 'Virtual Memory' 라고한다.


- 초기의 프로세싱 방법 ( 비효율적 . . )


- Batch 프로세싱 ( 한번에 프로그램들을 묶어서 작업 ) [ 커널모드 / 유저모드 ]

 

이떄까지는 컴퓨터가 얼마의 용량(메모리)인지를 알고 그에 맞춰서 프로그래밍을 했어야한다. 

OS가 없다? -> 프로그램을 짜는 사람이 직접 모든 과정을 수행해야한다(하드웨어<->소프트웨어) PC에 대한 모든과정.

-> 이떄까지는 사용자가 시작하는 프로그램이 메모리의 0번지로 바로 들어갈수있었다. 

-> 하지만, 이후로 나오는 멀티프로세싱에서는 physical(물리적인) 주소에서 어디로 들어가야할지가 고민.


- 멀티 프로세싱 ( 프로그램끼리 context switch 등을 이용하여 메인메모리에 프로그램들을 여러개를 올려놓고 필요한 수행기능들을 그떄마다 수행한다. )

 Memory Protection : 여러개의 프로그램이 올라갔을떄 서로의 영역을 침범하지않도록 조정해주는것 


 Memory Protection

-> BaseLimit로 구성된다. 

-> 각 프로세스를 수행하려고하면, base를 가지고 메모리의 영역을 먼저 확인한다. 

trap / false / segment false : -> 다른 메모리가 있는 영역에 침범하려고 했다고 알려주는 메시지 

항상 메모리 위치를 조사해서 메모리위치가 나한테 허용된 공간안에서 작동하는지를 확인하는 로직 


Processing of a Program 

1. 컴파일(compiling) : 사람이 알아듣는언어에서 pc가 이해할수있는 기계어로 변경 (어셈블러 . .)

컴퓨터가 이해할수있도록 된 파일 : 오브젝트 파일

2. 링킹(Linking) : 실제 실행가능한(excutable)파일로 변환해주는 과정 

3. 로딩(Loading) : 프로그램을 실제로 쓸수있게 메모리에 올려서 '프로세스'로서 사용하게해주는 과정 


- Logical address vs Physical address

프로세스에서 언급되었던 모든 주소들은 Logical address (논리주소) 이다. 

-> 다른 프로그램들을 고려했으면 : Physical address

-> 다른 프로그램들을 고려하지않았으면 : Logical address

 

Logical address - > Physical address로 변환해주는 과정을 Binding(바인딩) 한다고 한다. 


Types of Address Binding  ( 아래 3경우에서 일어날수있다 )

Compile time : 과거에 os가 없을떄 직접한것 (프로그램을 만드는순간 address binding을 결정해버리는것)

Load time : 프로그램을 실행할떄, 메모리에서의 위치와 mapping 시켜주는 것 ( binding 해주는것 )

                   relocatable 코드 / 상대적인 위치를 매핑 ( 로드할떄 주소가 계산되는것 )

Execution time(현재 대부분 사용) : 명령어를 수행할떄 그떄그떄 명령어의 메모리상 위치를 매번 정해줌 

메모리에서의 위치가 실시간으로 바뀜 : 물리주소(physical address)는 프로세스 전, 실시간으로 정해짐 -> 더 효율적이지만, 더 복잡한 하드웨어의 원인이 됨. 

 

-> Load time과 Execution time의 차이점? : Load time은 한번 프로그램이 올라오면 정해진 메모리위치에 고정. but, 현대 메모리(Execution time)은, 메모리에서의 위치가 실시간으로 바뀜 : 물리주소(physical address)는 프로세스 전, 실시간으로 정해짐 -> 더 효율적이지만, 더 복잡한 하드웨어의 원인이 됨. 


위와 같은 작업들을 수행해주는것을 Memory-management unit(MMU)라고 한다. (중요)

위와같이 물리적인 변환해주는 과정을 뜻함

-> 유일하게 MMU만이 physical address의 위치를 알수있다. (구성되는지를 안다) 

-> CPU는 정작 실제 물리주소가 어떻게 구성되는지를 모른다. 

Relocation Register / Memory Protection with Relocation Register이 존재


Relocation Register 

: 프로세스마다 할당이 되어있어서, logical address + relocation register -> physical address 

 


Memory Protection with Relocation Register 

만약 깜빡하고 p1을 넣고 p2를 메모리에 넣었는데, 메모리가 상대적인 위치라 타 메모리에 침범할수있는 것을 막는다. 

 

-> 메모리의 어떤부분에 올릴까?

Memory allocation : 메모리의 특정부분에 할당하는것 

Contiguos memory allocation : 연속적으로 메모리에 올리는 방식 (가장 기본적, 단순) -> but, 메모리에 hole이 생김 

이후 process10을 사용하고 싶을떄 어떠 hole에 넣어야할지 ~~  -> 아래에 3가지 전략이 존재한다. 


 

First-fit :  그냥 들어갈수있는 공간에 할당하면됌 /  빨리할당가능 / 'simple'(장점일수도 ..?) 

Best-fit :  -> 들어갈 프로세스와 가장 크기가 비슷한 메모리부분에 할당해 주는것 ex) 메모리 낭비가 가장 덜한곳에 .. 

( 총 용량의 차가 가장적은 부분. Hole에 할당가능 )  / 시간이 많이걸림( 모든hole을 확인해야함) 

Worst-fit :  들어갈수있는 공간중 가장 큰곳에 할당 (낭비최대)  : 시간이 많이걸림( 모든hole을 확인해야함) 


- 외부단편화 ( External Fragmentataion ) : (파편화문제)

-> 총 용량은 남아있지만, 중간에 10mb가 껴있으면, 남는 용량이 있어도 못 할당하는것 


First-Fit example

공간은 충분한데, 연속성문제떄문에 외부단편화 문제발생 ! 


Best-Fit example

마찬가지로 외부단편화문제 발생

given memory partitions&nbsp;


Worst-Fit example

worst-fit을 사용시 그만큼 외부단편화문제를 줄일수있다 ! ( 연속적으로 공간을 확보할떄 사용 . .)

-> Hole을 크게 남겨주면 오히려 남은공간이 크기떄문에 다른 프로세스가 들어가기 좋다 

( 외부단편화문제를 해결하는 가장 좋은 방법 ) 


 Compaction(압축) : 위와 같은 외부단편화를 없애기위한 가장 쉬운방법

 압축을 사용하면 어떤 fit이든 외부단편화문제를 해결할수있다. -> but, 만만한 작업이 아니다. (실제쓴다기보다는, 이런 대안도있다 ~)


위와 같은 문제가 발생하는 이유 : Contigous memory allocation을 전제로 하고있기떄문.

-> 프로세스를 할당할떄, 하나의 프로세스가 하나의 Hole에 들어가야한다고 가정하고있기떄문 . .


위와 같은 가정을 안한다면? -> 'Paging Scheme'

: 프로세스를 페이지단위로 전부 나눔 -> 이후에 페이지별로 메모리를 전부 할당해줌 (불연속적으로 할당) 

: 보통 4kb 크기로 나누어져서 메모리에 할당된다. 

but, 처음부터 이 paging을 안 쓴 이유? -> '복잡해서' : not simple 

연속적일경우 : 시작과 끝주소만 알면 Memory Protection를 지킬수있었다.

but, 페이징으로 쪼개져서 비연속적이어질경우, 어렵다. 

-> mmu가 paging에서 큰 작업을 해주어야한다. 


Paging table 

-> 페이징을 하여 전부 흩어놓으면, 이것들을 어디에 흩어놓았는지 저장해놓는것이 필요하다. 

-> 매번 접근할떄마다 logical address의 실제 위치한 physical address를 알려주어야한다. 

-> 매 address마다 테이블을 만들자니, 너무 커져서 답이없음 .. -> logical address 전체를 전부 다 physical address로 만드는것이 아니라, 4kb로 나누어서 이를 메모  리에 넣을떄, 적어도 같은 page내에서는 같은 주소를 할당하기로 함

사용자 입장에서 보는것 : page 

physical한 메모리가 보는 입장에서 : frame 


모든 address를 physical address로 바꾸는데 동참시키는것이 아니라, 아래처럼 우측(page offset)은, 페이지 내부의 주소영역이다(논리적 = 물리적주소 동일) .  또한 좌측(page number)은, 페이지자체를 가르키는 주소영역을 별도로 분리


  - 페이징 예제  [매우 중요]

-> 위 조건과 같이, physical 메모리는 32byte(실제 pc가 꽂혀있는 용량)이며, logical 메모리는 16byte (프로그래머가 쓸수있다고 생각하는 용량)

-> 위는 둘다 4byte라는 page를 가진다.  ( 1페이지 = 4byte ) ( 페이지 내부만을 가르키려면 4 = 2의2승 -> 2bit 필요 )

위 조건을 가정하고 계산할시, logical memory는 16바이트를 페이지(4바이트)로 나누면 총 4페이지이다.

physical memory의 경우, 32바이트를 페이지(4바이트)로 나누면 8프레임이다. ( physical한 부분의 페이지 = 프레임 )


LA 0 ('a') maps to PA 20 ->  LA(logical address) 0번을 넣으면 PA(physical address) 20번으로 매핑되야한다는 소리

LA 5 ('f') maps to PA 25 ->  LA(logical address) 5번을 넣으면 PA(physical address) 25번으로 매핑되야한다는 소리

 

위 계산에서 논리주소 -> 물리주소 매핑과정에서 2진수로 변환을 하여 확인해본다면 특정 규칙이 반복되는것을 알수있다. 

아래와 같이 논리주소(LA) : 5 라고한다면, 2진수는 0101이며, 마지막 두자리는 아래와 같이 물리주소의 어떤 FRAME에 들어가더라도 변하지않는 값이다. 이는 논리주소에서의 2진수값이기떄문이다. 

그래서 이와 같이 바뀌지않는값을 page offset이라고하며 page table에 굳이 넣을 필요가 있을지에 대한 의문이 생긴다. (왜? -> 절대 바뀌지않는다는것이 보장되기떄문 ) 바뀌는 부분만을 page number라고한다. 

ex) 

0 , 1 두칸이 있을떄, 어디에 저장되었는지(썼는지) 그 위치를 기록하려면 1비트가 있으면된다.

0, 1, 2, 3 4칸이 있을떄, 2비트가 있으면된다. 

0, 1, 2 .. 7 8칸이 있을떄, 3비트가 있으면된다. 

=> 공식추론가능 : Address가 M이라고하면, 이 Address를 관리하기위해 필요한 비트는 log2M 개면 된다. 

=> 1024 를 2진수로 -> 1111111111(10개) -> 1024짜리 메모리를 관리하기위해서는 10메모리 비트가 필요하다.

 

위와 같은 paging 기법을 쓰면 Internal Fragmentation(내부 단편화) 문제가 생긴다. 

페이지 내부에서 앞의 2byte는 쓰는데 뒤의 2byte는 안쓰게 되는것을 뜻한다. 

만약, Logical size가 13byte을 경우 페이징을했을떄 address는 4byte 페이지이기에, 

마지막 1byte는 마지막 3byte는 낭비이다. -> Internal Fragmentation 


-> Logical address는 64페이지가 있는데 ,이것이 1024개의 word이며, physical memory는 32 frame이다. 

: ( word는 4byte이다. -> page 하나당 4kb이다   /  1kbyte = 1024byte

 

: logical address는 64페이지가 있는데 페이지 하나당 4kb -> 총 256kb 

: 전체 logical address의 영역 = 256kb = 2의 18승 Byte  ( 2의 18승 = 262144byte = 256kb )

http://convertwizard.com/256-kilobytes-to-bytes

-> 256kb를 쓰려면 메모리를 가르키는 주소가 18 bit는 되야한다는 뜻이다.

 

- 그렇다면, physical address의 사이즈는 어떻게 될까 ?

page와 frame은 크기가 같다 . :  frame도 결국 4kbyte라는 뜻이다. 

32 * 1024 * 4 bytes = 128 * 1024bytes = 128kb = 2의 17승 byte

-> mmu를 거치면 최종적으로 17bits가 필요함


예제 2

: 1 페이지가 1kb (1024byte)이고,  -> 1024byte는 2의10승 -> page offset : 10bit 가 필요하다. 

문제의 요점 : page number(address thread에 참여) 와 page offset (참여 x) 

: 주소가 들어오면 page number와 page offset으로 구분하라는 뜻이다. 

3085 를 2진수로 변환시 12bit 짜리로 나오지만, 위처럼 offset은 10bit 이전과 이후로 나뉜다. 

--> 3085의 2진수 : 1100 0000 1101  여기 12자리에서 10자리 bit 까지는 변하지않는 offset : 13이고,

10자리 bit 이후  11은 page number로서, 3이다. 


그렇다면, 42095의 page number와 page offset은 어떻게될까 ?

42095의 2진수는 1010 0100 0110 1111 이다.

16자리 bit에서 10자리 bit 까지 계산하면page offset : 15 + 32 + 64 = 111 

16자리 bit에서 10자리 bit 부터 계산하면 page number : 1+ 8 + 32 = 41

 

728x90