1. 다운로드





2. C: 밑에 "dev"라는 폴더를 생성 후 압축풀기


3. java 설치 후, jdk폴더를 dev에 복붙




4. eclipse.ini


-startup

plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar

--launcher.library

plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.300.v20150602-1417

-product

org.eclipse.epp.package.jee.product

--launcher.defaultAction

openFile

--launcher.XXMaxPermSize

256M

-showsplash

org.eclipse.platform

--launcher.XXMaxPermSize

256m

--launcher.defaultAction

openFile

--launcher.appendVmargs

-vm

C:\dev\jdk1.8.0_60\bin\javaw.exe    // JDK 설정 , vmargs 보다 위에

-vmargs

-Dosgi.requiredJavaVersion=1.7        // 해당 버전이 1.7이면 1.7로 설정하면 속도가 더 빨라짐... 찾는 범위를 한정지어서 그런건가

-Xms1024m                                    // 메모리 힙 최소

-Xmx2048m                                    // 메모리 힙 최대 (컴터 메모리가 8GB이상일때만 2048정도로 해줭




# 이클립스 플러그인으로 설치

- Spring

- SVN

- Maven

- MyBatis


- MSSQL은 바로 메이블 플러그인이 바로 없어서 따로 메이븐 레파지토리쪽으로 설치해준 후에 매핑시켜주면 됨




'Development > Web' 카테고리의 다른 글

MVC 1  (0) 2015.08.30
서블릿  (0) 2015.08.30
[JQuery] plug-in top 100  (0) 2015.05.27
[웹서비스] 기초 4 - QnA, Web Client  (0) 2015.05.01
[웹서비스] 기초 3- 웹 서비스 구현  (0) 2015.04.29

요즘 밖에서 맛있는 쿠키를 사먹어도 역시 집에서 만든 맛이 절대 안남

요즘 자꾸 바삭하고 고소한 쿠키가 먹고싶음


물론 만드는 재료랑 방법에 따라서 완전 천차만별이겠지만..


너무너무 귀찮은데 수제쿠키가 먹고싶을때,

반죽 5분, 굽는데 15분 걸리는 초간단 대왕 쿠키가.. 딱


걍 정말 파는맛인데 기호에따라서 난 좀 담백하게

특히 요런 덩어리 쿠키만들때 무리한 견과류 첨가는 자칫 바삭이아닌 푸석이 될 수 있으므로.. 뭐든 적당히 적당히..~~


마시따마시따마시따 




'취미 ㅋㅋ' 카테고리의 다른 글

밑반찬  (0) 2015.09.10
닭강정  (0) 2015.09.10
순두부찌개  (0) 2015.08.23
버섯덮밥이랑 캬라멜 맛탕  (0) 2015.08.16
계란된찌랑 김치비지찌개  (0) 2015.08.16

이번주 주말 아침메뉴, 순두부찌개



원래 고추기름만 내다가, 백종원 레시피처럼 파기름도 내봤는데 정말 맛있다..!

하지만 파 시원한 맛을 너무 좋아해서.. 마지막에서 한움큼 넣어주면

내가 좋아하는 칼칼하고 고소한 순두부찌개 캬~!


원래 우리집에는 마싰다 조리료같은게 없지만 항상 파는 것보다 좋은 맛이난다.

어디가서 당당하게 취미가 요리라고 말 할 수 있을 듯 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ






'취미 ㅋㅋ' 카테고리의 다른 글

닭강정  (0) 2015.09.10
초간단 대왕초코칩쿠키  (0) 2015.08.23
버섯덮밥이랑 캬라멜 맛탕  (0) 2015.08.16
계란된찌랑 김치비지찌개  (0) 2015.08.16
파래국 + 닭갈비  (0) 2015.08.11


# 가상메모리



# SMP (Symmetric Multiprocessing)

: 모든 CPU가 메모리와 입출력 버스 등을 공유하는 구조

=> 병목현상 발생


# NUMA (Non-Uniform Memory Access)

: SMP 구조에서 병목현상이 발생하여 CPU들을 몇개의 그룹으로 나누고 각 그룹에게 별도의 지역 메모리를 할당

<-> UMA (Uniform Memory Access)



# Node 

: 리눅스에서 뱅크를 표현하는 구조

- bank : 리눅스에서 접근 속도가 같은 메모리의 집합을 부르는 말

- ~/include/linux/mmzone.h


- UMA구조에서는 뱅크가 한개, NUMA 구조에서는 뱅크가 여러개

- 리눅스의 전역변수인 contig_page_data변수로 뱅크에 접근 가능

- NUMA처럼 뱅크가 복수개인 경우, pgdat_list라는 배열을 통해 뱅크에 접근이 가능


=> 리눅스에서는 하드웨어 시스템에 관계없이 노드라는 일관되 자료구조를 통하여 전체 물리메모리에 접근이 가능



# pg_data_t 자료구조

: UMA구조에서 단일노드를 contig_page_data변수로, NUMA구조에서 복수노드를 pgdat_list 배열로 가리켜도

 두 변수는 pg_data_t 구조체를 통해 표현


------------------------------------------------------------------------------------------------------------------------------------------------------------

typedef struct pglist_data {

struct zone node_zones[MAX_NR_ZONES];        // zone 구조체를 담기위한 배열

struct zonelist node_zonelists[GFP_ZONETYPES];    

int nr_zones;        // zone의 개수를 저장

...

unsigned log node_start_pfn;        // 해당 물리메모리가 메모리 맵의 번지수를 저장하는 변수

unsigned long node_present_pages;    // 해당 노드에 속해있는 물리메모리의 실제 양을 저장하는 변수

unsigned log 

...

} pg_data_t;

------------------------------------------------------------------------------------------------------------------------------------------------------------


* 물리메모리 할당 요청시 태스크가 수행되고있는 CPU와 가까운 노드에서 메모리 할당을 시도



# zone

: 일부 ISA 버스 기반의 디바이스를 지원하기위해, node의 일부분(16MB이하 부분)을 따로 관리할 수 있도록 자료구조를 만듬

(물리메모리 중 반드시 16MB 이하 부분을 할당해 주어야 했음)

- ~/include/linux/mmzone.h

- 동일한 속성을 가짐

- 다른 zone의 메모리와는 별도로 관리되는 메모리 집합

- ZONE_DMA, ZONE_DMA31 : 특별히 관리되는 16MB 이하의 메모리

(16MB 이상의 메모리는 ZONE_NORMAL이라고 함)

- ZONE_HIGHMEN : 1GB이상의 메모리를 필요로하는 경우 바로 커널의 가상주소공간과 1:1로 연결해주는 것은 비효율 적이라고 판단하여 

896MB의 물리메모리만 커널의 가상주소공간과 1:1로 연결하고, 나머지 부분은 필요할 때 동적으로 할당하는데,

이때 896MB 이상의 메모리 영역을 일컫는 용어


- 모든 시스템에서 언제나 DMA. NORMAL, HIGHMEN이라는 세개의 zone이 존재하는 것은 아님


- 각각의 zone은 자신에게 할당된 물리메모리의 관리를 위해 zone 구조체를 사용

해당 zone에 속해있는 물리 메모리의 시작주소, 크기

버디할당자가 사용할 free_area 구조체를 담는 변수 등등

- watermark와 vm_stat를 통해 남아있는 빈 공간이 부족한 경우 적절한 메모리 정책을 결정

- page가 부족하여 메모리 할당 요청에 대하여 실패한 경우 프로세스들을 wait_queue에 넣고 hashing을 수행하여 wait_table변수가 가리키게 함

- cat /proc/zoneinfo 명령어를 통해 확인



# Page Frame

: 물리메모리의 최소 단위

- zone은 자신에게 속한 물리메모리를 관리

- 각각의 페이지 프레임은 page 구조체로 관리 (~/include/linux/mm_types.h)

- 페이지 프레임 당 하나의 page 구조체가 존재. (모든 물리메모리에 접근이 가능해야하므로)


- page frame : 하나의 페이지로 관리

- zone : 복수개의 페이지 프레임으로 구성

- node : 하나 또는 복수개의 node로 구성

- 리눅스의 전체 물리 메모리 : 하나 또는 복수개의 node 


# Buddy와 Slab

- 내부 단편화문제를 해결하기 위해 슬랩할당자 사용

- 메모리관리의 부하와 외부 단편화의 해결을 위해 버디할당자 사용


* 물리메모리는 설정한 페이지프레임의 최소단위로 할당

(기본 4KB, 8KB와 2MB 등으로도 설정이 가능)



# Buddy Allocator

- 페이지프레임이 4KB의 경우 10KB를 할당하려할 때 3개의 페이지프레임으로 할당하지 않고 16KB를 할당        

=> 메모리관리의 부하를 줄이고 외부 단편화를 방지


* 커널 2.6.19버전 이전에서 사용되던 버디 


- zone 구조체에 존재하는 free_area[]배열을 통해 구축

- zone 당 하나의 버디가 존재

- free_area[] 배열의 각 엔트리는 free_area 구조체

- free_area 구조체는 free_list와 map이라는 필드를 가짐


------------------------------------------------------------------------------------------------------------------------------------------------------------  

/* ~/include/linux/mmzone.h  */

#define    MAX_ORDER    10        // 10개의 엔트리를 가짐. 0~9의 각 숫자는 해당 엔트리의 free_area가 관리하는 할당의 크기를 나타냄

// 0인경우 2^0으로 1개의 페이지프레임 할당, 1인경우 2^1이므로 2개의 페이지프레임 할당 

// 4KB, 8KB, 16KB... 4MB(2^10 * 4KB) ---> 이 단위들로 메모리 할당이 가능

struct zone {

...

struct free_area    free_area[MAX_ORDER];    // 

...

};

struct free_area {                

struct list_head    free_list;      // 자신에게 할당된 free 페이지 프레임을 list로 관리

// ex. free_list[1]에 free상태의 연속된 2개의 페이지 프레임들이 free_list로 연결

unsinged long     *map;         // 자신이 관리하는 수준에서 페이지의 상태를 bitmap으로 관리

// ex. 전체 물리메모리를 2개의 페이지 프레임 단위로 봤을 때의 상태를 map이라는 bitmap에 저장

};

------------------------------------------------------------------------------------------------------------------------------------------------------------  



그림 출처. https://lwn.net/Articles/121618/




* order(0) -> free_area[0]

  order(1) -> free_area[1]

  ...


* 버디할당자 동작방식

Linux kernel physical memory allocator (Buddy) - Part 2-1

http://woodz.tistory.com/57


http://woodz.tistory.com/58

http://woodz.tistory.com/59

http://woodz.tistory.com/60




# Lazy Buddy

- 커널 2.6.19부터는 free_area 구조와 버디 할당자의 구현이 조금 바뀐

- 프레임에 할당하거나 해제하는 작업에서 페이지를 쪼개거나 합치는데 이럴 때 비트맵 수정도 필요함

- 반복 과정에서 오버헤드가 발생

- 페이지프레임에 대한 작업을 조금 미루자!


 *변경된 free_area 구조체

------------------------------------------------------------------------------------------------------------------------------------------------------------

/* ~/include/linux/mmzone.h  */

#define    MAX_ORDER    11


struct zone {

...

struct free_area    free_area[MAX_ORDER];    // 

...

};


struct free_area {                

struct list_head    free_list;      

unsinged long    nr_free;    // 기존의 비트맵 포인터에서 자신이 관리하는 zone내에서 비사용중인 페이지 프레임의 갯수를 저장하는 변수로 바뀜

};

------------------------------------------------------------------------------------------------------------------------------------------------------------

- zone 마다 유지되고 있는 watermark(high, low, min)값과 현재 사용가능한 페이지 수를 비교

- zone에 가용 메모리가 충분한 경우 해제된 페이지의 병합 작업을 최대한 뒤로 미룸

- 가용 메모리가 부족해지는 경우 병합작업을 수행


* 병합작업

- __free_pages(), 버디에 메모리를 반납하는 함수

- __free_pages()함수는 내부적으로 __free_one_page()라는 함수를 호출

- __free_one_page(), MAX_ORDER만큼 루프를 돌면서 현재 해제하는 페이지가 버디와 합쳐져서 상위 order에서 관리될 수 있는지 확인

- 가능하면 현재 order의 nr_free를 감소시킴

, 상위로 페이지를 이동 후 상위 order의 nr_free를 증가  

=> 해당 작업을 반복하여 전체 order의 버디를 동작


- __alloc_pages() : 버디 할당자로부터 페이지를 할당받는 커널 내부 함수 중 가장 저수준의 함수

- __free_page() : 페이지를 해제하는 함수


- 2의 승수의 크기 단위로 관리하므로 함수 호출시에도 메모리의 크기를 2의 승수로 지정

- 복수개의 zone에 각각의 버디 할당자가 동작할 수 있는 상황에서는 어느 zone에서 메모리를 할당 받았는지 같은 몇몇 속성을 지정해 주어야 함

- 현재 시스템의 버디 할당자 관련 정보 조회 : "$ cat /proc/buddyinfo"



# Slab Allocator

일종의 캐시의 집합을 통하여 메모리를 관리하는 정책


- 페이지 프레임의 크기가 요청되는 메모리의 크기와의 차이가 상대적으로 많이 날 수록 내부 단편화로 낭비되는 공간이 증가

- 미리 페이지 프레임을 할당 받은 후 일정한 크기로 분할 해 둔 뒤 사용자가 메모리를 요청하면 버디할당자가 아닌 미리 할당받아 분할한 이 공간(일종의 캐시)에서 공간을 받아옴

- 해제 역시 중간의 이 공간에 이루어짐


- 현재 시스템의 slab 할당자와 관련된 정보조회 : "$ cat /proc/slabinfo"


출처. http://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/9_VirtualMemory.html



- 캐시의 크기? 




 


'System > Linux Kernel' 카테고리의 다른 글

[Unix V6] 시스템 부팅  (0) 2015.12.19
Device Tree, 리눅스 커널 4.0  (0) 2015.08.29
인터럽트 / 트랩  (0) 2015.08.16
VFS, Virtual File System  (0) 2015.08.16
리눅스 부팅과정과 런레벨  (0) 2015.08.13



# 인터럽트 

: 주변장치나 CPU가 자신에게 발생한 사건을 리눅스 커널에 알리는 매커니즘


- 외부 인터럽트. 하드웨어적 인터럽트 (인터럽트)

- 소프트웨어적 인터럽트 (트랩, 예외처리라고도 함)


# 인터럽트 핸들러의 수행

- 인터럽트 발생

- PC(or instruction pointer) 레지스터값을 미리 정해진 특정 번지로 설정

ex. ARM 

0x00000000 + offset로 점프

- reset interrupt : offset은 0

- undefined instruction : offset은 4

- software interrupt : offset은 8


# 인터럽트 백터 테이블

: 인터럽트는 간결히 작성해도 4Byte를 넘기때문에 다른위치에 인터럽트 핸들러를 작성하고 0x00000000에는 인터럽트 핸들러로 점프하는 명령어만 기록

     

ex. ARM CPU의 인터럽트 백터 테이블

--------------------------------------------------------------

0x00000000    _start :        b        reset

b        undefined_instruction

b        software_interrupt

b        prefetch_abort

b        data_abort

b        not_used

b        IRQ

b        FRQ        

--------------------------------------------------------------

- 보통 IDT(Interrupt Descriptor Table) 또는 IVT(Interrupt Vector Table)이라고 부름


# 인터럽트/트랩의 처리

: 문맥저장->인터럽트처리->문맥복원


- 리눅스에서는 인터럽트와 트랩을 동일한 방법으로 처리

- 외부인터럽트/트랩을 처리하기 위한 루틴을 함수로 구현

- 각 함수의 시작주소를 리눅스의 IDT인 idt_table이라는 이름의 배열에 기록

- 다양한 CPU를 지원하기위해 idt_table의 0~31까지 32개를 트랩핸들러를 위해 할당, 그 외의 엔트리는 전부 외부 인터럽트 핸들러를 위해 사용

- 외부 인터럽트를 발생할 수 있는 주변장치는 하드웨어적으로 PIC(Program-mable Interrupt Controller)라는 칩의 각 핀에 연결

- PIC는 CPU의 한 핀에 연결

- x86 CPU의 경우, idt_table의 32번 부터  PIC로 사용이 가능(31까지는 트랩이 사용하므로)

- 리눅스 커널 부팅중에 설정


ex. idt_table의 32번 엔트리에 timer 인터럽트 발생 (가정)

- timer는 PIC와 연결된 선에 펄스를 보냄

- PIC는 수신한 펄스를 적절한 번호로 변환

- I/O 포트에 저장하여 CPU가 버스를 통해 읽을 수 있도록 함

- CPU와 연결된 라인에 펄스를 보내 외부인터럽트 발생을 알림

- CPU가 인터럽트 발생을 알게되어 PIC의 I/O 포트를 읽어 발생한 외부인터럽트의 벡터번호를 확인

- 인터럽트 선을 원래대로 복원시켜 PIC가 다른 인터럽트를 받을 수 있게 함

- 리눅스 커널은 발생한 인터럽트의 번호를 확인

- 이 번호로 idt_table에 인덱싱을 하여 엔트리에 있는 핸들러를 실행


- x86 CPU에서의 idt_table


그림 출처. http://duksoo.tistory.com/entry/System-call-%EB%93%B1%EB%A1%9D-%EC%88%9C%EC%84%9C



# irq_desc table

: 외부 인터럽트가 발생되어 들어오는 라인은 한정되어 있으며, 디바이스 드라이버들은 동적으로 인터럽를 동적으로 할당받거나 해제할 수 있음.

따라서 별도의 관리 매커니즘이 필요. 


- idt_table의 32~255까지(128번 제외, 시스템 호출이 사용)를 같은 인터럽트 핸들러 함수가 등록

- 해당 함수들은 do_IRQ()를 호출

- do_IRQ() : 외부 인터럽트 번호로 irq_des 테이블을 인덱싱하여, 해당 인터럽트 번호와 관련한 irq_desc_t자료구조를 탐색

- irq_desc_t : 하나의 인터럽트를 공유할 수 있도록 action이라는 자료구조의ㅏ 리스트를 유지

- action : 이 리스트를 통해 단일 인터럽트 라인의 공유가 가능


# 문맥저장


- idt_table에 등록되어있는 common_interrupt (외부 이너럽트를 위한 공통 핸들러)

-----------------------------------------------------------------------------------------------------------------------------------

# define  SAVE_ALL     \

cld;    \

pushl    %es;    \

pushl    %ds;    \

pushl    %eax;    \

pushl    %ebp;    \

pushl    %edi;    \

pushl    %esi;    \

pushl    %edx;    \

pushl    %ecx;    \

pushl    %ebx;    \

novl    $(___USER_DS),    %edx;    \

novl    %edx,    %ds;    \

novl    %edx,    %es;


common_interrupt:

SAVE_ALL                    // 인터럽트가 발생한 시점에 수행중이던 태스크의 문맥 저장

call    do_IRQ                // do_IRQ() 함수를 호출하여 실제 인터럽트 서비스가 수행

jmp ret_from_intr         // 인터럽트 처리가  종료되면 SAVE_ALL 매크로로 저장했던 문맥을 RESTORE_ALL 매크로를 통해 복원

-----------------------------------------------------------------------------------------------------------------------------------



# 리눅스에서 트랩의 처리

- 트랩은 구분이 필요함

1. fault : fault를 일으킨 명령어 주소를 eip에 저장 후 해당 핸들러 종료 후 eip에 저장되어있는 주소부터 다시 수행

2. trap : trap을 일으킨 명령어의 다음 주소를 eip에 저장 후 해당 핸들러 종료후 다시 수행

3. abort : 심각한 에러. eip에 값을 저장할 필요가 없고 현재 태스크를 강제 종료


-  ret_from_exception()

: 시스템 콜을 제외한 트랩의 경우 ret_from_exception()을 호출하여 이전 문맥으로 돌아감

- ret_from_intr()

: 일반적인 외부 인터럽트의 경우 해당함수를 호출하여 이전 문맥으로 돌아감

- ret_from_sys_call()

: 0x80 인터럽트, 즉 시스템 콜의 경우

- ret_from_fork() 

: 시스템콜 중 fork(), vfork(), clone()의 경우



# 시스템 호출 처리과정 (intel CPU의 경우로 가정)

그림 출처. http://duksoo.tistory.com/entry/System-call-%EB%93%B1%EB%A1%9D-%EC%88%9C%EC%84%9C


- fork() 시스템 콜 호출

- /usr/lib/libc.a 표준 C 라이브러리에 구현되어있는 fork() 라이브러리 함수 호출

- CPU내의 범용 레지스터 중 eax 레지스터(ARM CPU의 경우 r7 레지스터)에 fork() 함수에 할당되어 있는 고유한 번호인 2를 저장

- 0x80인자(시스템콜)로 int명령으로 트랩을 발생시킴. (ARM CPU의 경우 swi 명령어)

- 트랩 발생 후 커널로 제어 이동

- 문맥저장 후 트랩의 번호(0x80으로 가정)에 대응되는 엔트리에 등록되어있는 함수(0x80이므로 sys_call())를 호출

- sys_call()에서 eax의 값을 인덱스(여기에서는 2)로 sys_call_table을 탐색하여 sys_fork()함수의 포인터를 얻어옴

sys_call() : arch/x86/kernel/의 entry_32.S 또는 entry_64.S에 구현

sys_call_table : arch/x86/kernel/의 syscall_32.c 또는 sysscall_64.c에 구현


=> 사용자 응용단에서 fork() 시스템 콜 호출 후 IDT 테이블과 sys_call_table을 이용해 커널에서 구현된 sys_fork()함수 호출



# 시스템 콜에 할당되어있는 고유번호 찾기(Intel CPU 기준)

- 리눅스 커널에서 제공하는 모든 시스템콜은 고유한 번호를 가짐

- ~/arch/x86/syscalls/syscall_64.tbl 또는 syscall_32.tbl에 정의

- 총 317개

- read()는 0, write()는 1, open()는 2



# 시스템 호출 함수 구현


1. 사전 등록처리, 시스템 호출 번호 할당

- ~/arch/x86/kernel/syscalls/syscall_64_tbl 파일에 새로운 번호를 할당

- 시스템 호출 테이블에 새로운 시스템 호출 처리 함수를 등록

- 할당한 번호를 인자로 sys_call_table이 접근될 때 호출할 함수를 등록

- ~/include/linux/syscalls.h파일에 sys_newsyscall 함수 원형을 등록


2. 시스템 호출 함수 구현

- 태스크관리관련 : kernel/ 디렉터리, 파일시스템 관련 : fs/ 디렉터리

- sys_ 접두어 사용

- asmlinkage : C로 구현된 함수가 어셈블리 언어로 구현된 함수에서 호출 할 수 있도록 해주는 키워드 

  -> 인텔 CPU에서는 특별한 기능은 없으며 알파 CPU의 경우 어셈블리 언어에서 C로 구현된 함수를 호출할 때 몇가지 전처리 작업을 수행함

- 커널에서 수행되는 함수이므로 표준 C라이브리를 사용할 수 없음


3. 커널컴파일 수행

4. 재부팅


* 시스템 호출 함수를 kernel/newfile.c 이라는 새로운 파일에 구현하였으면, 

make 명령이 컴파일 할 때 이 파일도 함께 컴파일할 수 있도록 해야함.

-> kernel/Makefile 아래에 해당 내용을 추가


* syscall() : 인자로 시스템콜의 번호를 받아 해당 시스템콜을 호출해주는 매크로



* 라이브러리를 이용한 시스템 호출 함수 구현 : ar 명령어를 사용하여 라이브러리 만들 수 있음.


* Glibc 라이브러리 ?

- 리눅스 배포판이 설치될 때 기본적으로 설치되는 라이브러리 중 하나

- fork(), open() 등의 함수를 호출하게 해주는 라이브러리

- 위에서 말한 syscall()도 해당 라이브러리에 구현되어 있음


# 인자를 전달하는 시스템 호출

--------------------------------------------------------------------------------------------------------------------------------------

// system call 번호를 318로 등록


#include<linux/unistd.h>

#include<linux/kernel.h>

#include<asm/uaccess.h>

asmlinkage int sys_show_mult(int x, int y, int* res)     // 앞의 2개의 인자를 곱하여 결과를 3번째 인자로 넘김

{

int error, comute;

int i;

error = access_ok(VERIFY_WRITE,res,sizeof(*res));    // access_ok() : res라는 사용자 공간에 쓰기가 가능한지 체크

if(error < 0)

{

printk("error in cdang \n");

printk("error is %d \n", error);

return error;

}

compute = x*y;        // current 포인터 변수 : 현재 실행중인 task_struct

printk("compute is %d \n", compute);

i = copy_to_user(res,&compute,sizoeof(int));    // copy_to_user() 매크로 : 

return 0;                                                    //     include/asm/uaccess.h에 정의. 값을 사용자 수준 공간에 전달하기위해 복사

}



// 호출

int main(void) 

{

...

i=syscall(318,x,y,&mult_ret);

...

}

--------------------------------------------------------------------------------------------------------------------------------------



- 시스템 콜의 매개변수는 레지스터의 크기인 32 혹은 64 bit을 넘을 수 없음

- 레지스터의 개수가 제한적임(인텔 CPU의 경우 6개를 넘을 수 없음)

=> 구조체 사용


- kmalloc() : C 라이브러리 함수인 malloc()과 유사하며 커널 내부함수로써 할당 받는 공간은 물리적으로 연속된 공간을 보장




참고

리눅스 커널 내부구조(책)



'System > Linux Kernel' 카테고리의 다른 글

Device Tree, 리눅스 커널 4.0  (0) 2015.08.29
메모리관리  (0) 2015.08.18
VFS, Virtual File System  (0) 2015.08.16
리눅스 부팅과정과 런레벨  (0) 2015.08.13
Linux File System  (0) 2015.08.13


역시 일요일엔.. 초간단 메뉴가 최고

간만에 버섯덮밥이랑 맛탕






올리고당을 좀 태워서 캬라멜이 되어버림. 엄지 척!

간만에 버섯덮밥도 맛있다.. 역시 한식엔 마늘이 많이 들어가야지 맛이 좋앙




'취미 ㅋㅋ' 카테고리의 다른 글

초간단 대왕초코칩쿠키  (0) 2015.08.23
순두부찌개  (0) 2015.08.23
계란된찌랑 김치비지찌개  (0) 2015.08.16
파래국 + 닭갈비  (0) 2015.08.11
감자수제비  (0) 2015.04.21

가끔 생각날때 종종가는 된장찌개집이 있는데, 신기하게 된장찌개에 계란을 넣어준다.


짱짱..!

그 이후에는 된장찌개에 꼭 계란을 넣어먹는다는..





 계란이 안터져야 맛있는데 너무 팔팔 끓여서 터졌당..





'취미 ㅋㅋ' 카테고리의 다른 글

순두부찌개  (0) 2015.08.23
버섯덮밥이랑 캬라멜 맛탕  (0) 2015.08.16
파래국 + 닭갈비  (0) 2015.08.11
감자수제비  (0) 2015.04.21
빼빼로랑 진저쿠키  (0) 2015.04.21


# 사용자의 task에서 file system으로의 접근
: open(), read(), write(), close(), ... 호출

# POSIX 표준 시스템
: Portable Operating System Interface. 서로 다른 UNIX OS의 공통 API를 정리하여 이식성이 높은 유닉스 응용 프로그램을 개발하기 위한 목적으로 IEEE가 책정한 애플리케이션 인턴페이스 규격.  
-> https://ko.wikipedia.org/wiki/POSIX

- 운영체제와 관련하여 IEEE에서 만들 규약
- UNIX를 고려하여 만들어졌기 때문에 X를 붙임임
- OS들의 호환성을 고려함.
- 시스템콜, 프로세스 환경, 파일/디렉터리, 시스템 데이터베이스, tar압출 포맷 등을 다룸

# VFS
Virtual File System
- POSIX 표준 시스템 호출을 이용
- 파일시스템과 사용자 태스크 사에에 가상층을 도입.
- 인자에 담겨있는 파일의 이름을 보고 파일을 관리하고있는 파일시스템이 무엇인지 판단.
- 해당 파일시스템의 함수를보고 해당하는 함수를 호출.
- 함수로부터 결과를 리턴받아 사용자 태스크에게 전달.

-> VFS를 통해 리눅스에서 다양한 파일시스템을 지원
- UFS, 유닉스 파일시스템
- ext2(3), 리눅스 기본 파일시스템
- NFS(Network File System), SUN에서 개발한 네트워크 파일시스템
- LFS(Log Structured File System), small write에 좋은 성능을 제공하는 파일 시스템
- CODA, CMU대학에서 개발하였으며 disconnected 연산 기능을 제공하는 파일시스템
- iso9660, CD를 위한 파일 시스템
- msdos, VFAT, MS의 DOS 파일 시스템
- 윈도우 NT 파일 시스템
- proc, 커널의 내부 상태를 볼 수 있는 파일 시스템
- sysfs, 장치를 통합 관리하는 파일 시스템

그림 출처. http://e2fsprogs.sourceforge.net/ext2intro.html


# VFS 동작 원리
: 예시. ext2 file system, /dev/hda2, b.txt

- 사용자 태스크가 b.txt라는 인자로 open()시스템 콜을 호출
- VFS가 b.txt의 정보를 저장하기위해 구조체를 만듬
- 생성한 구조체를 인자로 ext2 파일시스템 내부의 open()함수를 호출
- ext2는 자신의 inode table에서 b.txt의 inode를 찾아 해당 정보를 인자로 받은 구조체에 저장하여 리턴
- VFS는 리턴받은 구조체의 내용을 바탕으로 사용자 태스크에게 필요한 정보를 전달

# VFS의 4가지 객체
: VFS에서 다양한 파일시스템과의 호환을 위해 사용하며 사용자 태스크에게 제공할 일관된 인터페이스를 정의

1. 수퍼블럭 객체
: 파일시스템 자신이 관리하는 파티션에 파일시스템 마다 고유한 정보를 수퍼블록에 저장. 이를 관리하기위해  VFS에서 수퍼블럭 객체라는 범용적인 구조체를 정의
- 현재 마운트 되어 사용 중인 파일시스템당 하나씩 주어짐

2. 아이노드 객체
: 특정한 파일과 관련한 정보를 저자하기위해 정의된 구조체
- 파일에 대한 메타데이터 정보를 저장하기 위해 아이노드객체를 생성하고 파일시스템에 특정파일에 대한 정보를 요청하면
  파일 시스템은 자신의 관리영역에서 해당 정보를 아이노드 객체에 저장
- ext2의 경우 해당 파일의 디렉터리 엔트리와 inode를 찾아서 아이노드 객체에 저장
- msdos의 경우 해당 파일의 디렉터리 엔트리를 읽어서 아이노드 객체에 저장

3. 파일 객체
: 태스크가 open한 파일과 연관되어 있는 정보를 관리하기 위해 사용하는 구조체
- 2개 이상의 태스크가 하나의 파일에 접근할 때, 각각의 offset등과 같은 정보를 관리해야함
- 태스크 관련 정보를 유지하는 용도로 파일 객체를 사용
- 각 태스크가 아이노드 객체에 접근하는 동안만 메모리상에 유지

4. 디엔트리 객체
: 사용자 태스크가 파일에 접근하게 하기위해 아이노드 객체와 파일객체의 연결이 필요, 이때 빠른 연결을 위해 캐시역할을 수행하는 객체
   

# task_struct

: 프로세스는 자신이 사용하는 자원, 자원에서 수행되는 수행흐름으로 구성(resource + flow of control). 이를 관리하기 위해 각 프로세스마다 생성하는 자료구조.

- 프로세스, 스레드 마다 생성, 수행 이미지 공유여부 및 스레드 그룹정보를 통해 구분

- 리눅스에서는 프로세스와 쓰레드 모두 커널내부에서 태스크로 관리


fork(), clone(), pthread_create()     -->     sys_clone()     -->    do_fork()    ,task_struct

vfork()                                            -->     sys_vfork()     -->    do_fork()    ,task_struct


cf. task_struct 구조체 내부 필드 중

- pid : 태스크 별로 유일한 값

- tgid : 한 프로세스내의 쓰레드는 동일한 PID를 공유해야한다는 POSIX 표준에 따라 리눅스에서는 Thread Group ID라는 개념을 도입


- files : file_struct라는 자료구조를 가리킴(file_struct의 max_fds : 한 태스크가 오픈할 수 있는 파일의 최대 갯수를 나타내는 변수)

- fd_array : file_struct구조체의 file이라는 자료구조에 대한 포인터를 갖는 배열

유닉스 계열의 운영체제에서 일반적으로 fd, file descriptor라고 부름

fd는 함수의 리턴값을 받는 변수로, fd_array에서 해당되는 인덱스로 사용됨

일반적으로 fd_array[0]은 표준입력(stdin), fd_array[1]은 표준 출력(stdout), fd_array[2]는 표준 에러출력(stderr)으로 설정


# fd_array 

: task_struct의 files변수가 가리키는 file_struct구조체내의 값으로 fd_array의 각 값들은 파일 객체를 가리킴

- 유닉스 운영체제에서는 파일 테이블이라고 부름

- 사용자 태스크에게 fd라는 정수로 파일에 접근할 수 있도록 하는 추상화 계층을 제공하는 변수


- f_dentry : 디엔트리 객체를 가리킴(해당 디엔트리 객체는 다시 연결되어있는 아이노드 객체를 가리킴)

- f_pos : 현재 피일에서 읽거나 쓸 위치를 저장(처음 파일을 오픈하였을 때는 값이 0), lseek호출을 통해 f_pos값을 바꿀 수 있음

- f_op : file_operations라는 자료구조를 가리키는 포인터(8장) 

 

# file_operations와 inode_operations

- file_operations 구조체 : 가상적인 파일연산이 요청되면 커널에서는 요청된 파일의 유형정보 및 파일의 고유 함수를 사용하여 서비스를 제공해야하는데 이때 사용하는 구조

                                     각 파일 유형에 적합한 파일 연산들이 저장되는 변수


inode_operations 구조체 : 아이노드 객체에 있는 i_op 포인터 변수가 inode_operations를 가리킴
사용자가 create(), mkdir() 등 파일시스템의 메타데이터 관련된 연산을 요청하면,
커널은 요청한 연산이 어떤 파일시스템에서 발생하였는지 파악하고,
적절한 파일시스템의 고유한 함수를 사용하여 서비스를 제공하는데 이때 사용하는 구조체

각 파일시스템 유형에 적합한 파일시스템 연산들이 저장되는 변수


=> 리눅스가 다양한 파일과 파일시스템을 지원할 수 있는 비밀병기 



# task_struct와 VFS



그림 출처. http://www.redirfs.org/docs/thesis/


- 파일의 이름을 인자로 시스템콜을 호출

- VFS가 아이노드 객체를 인자로 파일시스템 내부의 해당 함수를 호출

- 필요한 정보를 아이노드 객체에 채운 후 리턴

- VFS는 해당 아이노드 객체를 디엔트리 객체에 연결시킨 후 사용자 태스크 구조와 연결



# f_op

: 파일시스템마다 구현된 함수들이 다른데, 해당되는 파일 유형에 맞는 연산이 등록되는 변수


예.  file -> f_op -> open()

- ext2 : ext2의 open(), linux/fs/ext2/file.c에 구현

- NFS : nfs_file_open()

- 파이프 : fifo_open()

- 장치파일 : chrdev_open() / blkdev_open(), linux/fs/device.c에 구현


# sys_open() 

- 특정파일 각각의 open()함수들의 호출 후 filp_open()함수 리턴

: 태스크에서 현재 사용하지 않는 fd_array의 한 항을 할당

- 해당 항이 생성된 파일 객체를 가리키도록 설정

- 태스크 구조와 VFS이 연결됨


# sys_read()함수 

: 인자로 전달된 fd를 이용해 파일 객체를 찾고 해당 f_op에 등록된 read함수를 호출, linux/fs/reead_write.c에 구현

- 우선 요청 데이터가 캐시에 있는지 찾음

- 캐시에 있으면 디스크에 안가고 바로 데이터를 사용자에게 전달, 없다면 디스크로 접근

- 이때 각 파일시스템은 서로 다른 방식으로 디스크를 관리하므로 각 파일시스템은 서로다른 디스크 연산함수를 사용하며 해당 처리가 필요함

-> 특정 파일시스템에 맞는 디스크 연산 함수를 호출할 수 있도록 inode_operations구조체를 사용

-> include/linux/fs.h에 정의

-> inode와 관련한 연산을 나타내는 변수로 구성(create, lookup, link, mkdir, mknod, readpage...)

-> 즉, 각 파일세스템에 고유한 연산들이 저장



# 파일의 사용과 파일시스템의 사용

- f_op와 i_op : 각 파일과 파일시스템에 고유한 연산을 제어를 전달하는 진입점 역할을 수행하는 변수

- 파일에 접근(새로운 장치를 위한 장치파일 연결)을 위해 디바이스 드라이버를 사용하여 새로운 file_operations 구조를 작성해 커널에 등록

- 파일시스템의 경우 file_operations구조 및 register_filesystem()이라는 커널내부함수를 사용하여 inode_operations구조도 작성하여 커널에 등록


# register_filesystem()

- linux/fs/filesystems.c에 구현

- struct_file_system_type 자료구조를 인자로 받음, include/linux/fs.h에 정의


<항목>

- name : 파일시스템을 나타내는 변수. ext2, ext3 ...

- fs_flags : 속성정보 저장 변수. 물리장치필요여부, 읽기전용여부...

- mount : 수퍼블록을 읽어 파티션을 마운트 하는 함수의 포인터 저장 변수

- 복수개의 file_system_type구조들의 연결을 위한 리스트와 모듈 정보 등

- ...


-  register_filesystem()으로 커널에 등록된 파일시스템은 하나의 file_system_type 자료구조를 가짐

- 커널의 존재하는 모든 file_system_type은 리스트로 연결

- file_systems라는 커널 내의 전역변수가 file_system_type리스트의 시작을 가리킴



# File System의 마운트 요청,

- file_systems에서 검색하여 요청된 file_system_type 자료구조 찾기

- get_sb에 기록된 함수를 호출하여 파일시스템의 수퍼블럭정보를 얻어옴

- 얻어온 수퍼블럭정보를 VFS의 수퍼블럭 객체에 저장

- 수퍼블럭을 읽어 해당 파일시스템의 자세한 정보를 얻어옴

- 이 자세한 정보로 inode_operations, file_operations에 접근이 가능



# VFS의 내부구조

그림 출처. http://www.read.cs.ucla.edu/111/2006fall/notes/lec14



그림 출처. https://www.usenix.org/legacy/event/usenix01/full_papers/kroeger/kroeger_html/node8.html



- 태스크는 시스템 콜 인터페이스로 VFS와 통신

- 태스크가 원하는 내용은 커널내부의 페이지캐시(캐시역할)을 통할수도 있음

- 캐시에 없다면 실제 디스크와 I/O 수행

- 이때 디엔트리 객체와 아이노드 객체를 위한 캐시를 일반데이터블럭을 위한 캐시공간과 분리하여 성능향상을 도모

- VFS내에 존재하는 객체의 연결관계를 이용해 inode_operations, file_operations 구조체의 함수를 호출

- 가상계층과 물리는 실제 디스크와 I/O하는 부분에서는

   커널내의 일반 블록 게층(Generic Block Layter)의 gendisk를 관리하는 블록 디바이스 드라이버에게 I/O 요청을 해야함

- 성능향상을 위해 리눅스는 자체적인 디스크 I/O 스케줄링 알고리즘(3가지 Elevator알고리즘)을 통해 요청을 보냄




참고. 

리눅스 커널 내부구조(책)





'System > Linux Kernel' 카테고리의 다른 글

Device Tree, 리눅스 커널 4.0  (0) 2015.08.29
메모리관리  (0) 2015.08.18
인터럽트 / 트랩  (0) 2015.08.16
리눅스 부팅과정과 런레벨  (0) 2015.08.13
Linux File System  (0) 2015.08.13

v6 책,



http://cafe.naver.com/linuxcare/3403


http://ttend.tistory.com/61


https://www.linux.co.kr/linux/tip/boot_sequence/


http://rootblog.tistory.com/1

'System > Linux Kernel' 카테고리의 다른 글

Device Tree, 리눅스 커널 4.0  (0) 2015.08.29
메모리관리  (0) 2015.08.18
인터럽트 / 트랩  (0) 2015.08.16
VFS, Virtual File System  (0) 2015.08.16
Linux File System  (0) 2015.08.13

KVM/KSM



http://noon.tistory.com/581

'System > Etc.' 카테고리의 다른 글

[OS기초] CPU Scheduling  (0) 2015.09.22
[OS기초] Process & Thread  (0) 2015.09.21
[OS기초] 개요  (0) 2015.09.17
RAID  (0) 2015.08.12
마이크로커널운영체제  (0) 2015.06.25

+ Recent posts