최근에는 블로그가 상당히 활성화되면서 맛집이나 상품, 홍보에 목적을 둔 블로그와 더불어 프로그래밍과 관련된 블로그 공급이 꾸준히 증가하고 있다. 필자 역시 공부한 내용을 정리하는 목적과 다른 사람들과 공유하고자 하는 목적에서 블로그를 시작했다. 그러나 기본적으로 제공되는 HTML/CSS 속에서 가독성 있는 코드를 작성하기란 쉽지 않다. 이런 문제점을 겪는 것이 비단 나뿐만은 아닐 것이라 생각하여 검색해보니 쉽게 답을 찾을 수 있었다. 검색 결과로 몇 가지 방법을 찾을 수 있었으나, 가장 간단했던 Highlight.js를 이용한 방법을 소개하고자 한다. 컴퓨터 전공이 아니더라도 간단한 HTML/CSS 편집은 크게 어려운 점이 없으니 따라해보면 쉽게 적용할 수 있을 것이라 생각한다. 블로그에 코드를 작성하는 사람들에게 도움이 되었으면 좋겠다.


1. 소개




Highlight.js는 파일 확장자에서 파악할 수 있듯이 자바스크립트로 작성된 코드 작성용 라이브러리다. 홈페이지를 통해 무료로 다운받아서 업로드하는 형식 또는 CDN(Contents Delivery Network)을 통해 끌어와서 사용하는 방법이 있다. CDN 방식을 이용하면 몇 가지 단점을 지니지만 간편하게 적용할 수 있으니 이 방법을 통해 진행하고자 한다.



2. 설정


티스토리 블로그 관리 → HTML/CSS 편집창에서 HTML 파일의 <head></head> 영역 사이에 아래의 코드를 삽입해도록 하자. 애매한 위치에 삽입할 경우 후에 알아보기 어려울 수 있으므로 </head> 바로 앞에 삽입하는 것을 추천한다. 삽입 후 바로 적용가능하도록 작성해놨기 때문에 복사해서 붙여넣으면 간단히 적용할 수 있을 것이다.

<link rel="stylesheet" href="//cdn.jsdelivr.net/highlight.js/8.7/styles/default.min.css">

<script src="//cdn.jsdelivr.net/highlight.js/8.7/highlight.min.js"></script>

<script>hljs.initHighlightingOnLoad();</script>


코드에서 주목할 만한 부분은 첫 번째 라인에 bold체로 표기된 default.min.css 부분이다. Highlight.js는 다양한 언어에 맞게 혹은 각종 IDE에 따라 제공되는 테마를 제공한다. 따라서 이 부분을 원하는 테마로 변경해주면 적용할 수 있다. 기본적으로 default.min.css로 작성했지만 데모 페이지에서 다양한 테마를 확인할 수 있으므로 자신에 취향에 맞는 테마 선택하여 첫 번째 라인에 default.min.css를 변경해주자.



3. 코드 작성


블로그에 글을 작성할 때 Highlight.js를 이용하기 위해서는 HTML 모드에서 다소 귀찮은 과정을 진행해야 한다. 기본적으로 코드는 아래에 [코드 입력 부분]에 기재하면 된다. 

<pre><code>[코드 입력 부분]</code></pre>


그런데 HTML 모드에서 '<' 또는 '/'과 같은 특수문자 처리가 원하는대로 안되는 경우가 발생하는데 이를 수정해줘야 깔끔하게 코드를 작성할 수 있다. 때문에 문제되는 부분을 HTML 특수문자 코드표를 확인한 뒤 문제되는 특수 문자를 치환해주자. 웹에서 글을 작성할 때에는 모든 문자를 한 번에 바꾸는 기능을 제공하지 않는 경우가 많아서 여간 귀찮은 일이 아니다. 따라서 애용하는 IDE 혹은 메모장 같은 텍스트 편집기에서 일괄적으로 변경해주면 편하게 작업할 수 있다. 


4. 확인


필자는 텍스트편집기로 sublimetext를 가장 선호해서 해당 테마로 설정해봤다. 위에서 설정했던 코드에서 default.min.css → monokai_sublime.min.css로 변경했으며, '<' 또는 '>'와 같은 특수문자들을 코드표를 보고 치환해주었다. 결과적으로 아래의 코드화면을 확인 할 수 있다.

<link rel="stylesheet" href="//cdn.jsdelivr.net/highlight.js/8.7/styles/monokai_sublime.min.css">
<script src="//cdn.jsdelivr.net/highlight.js/8.7/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>




[참고 자료]

http://egloos.zum.com/keep/v/1030642

https://highlightjs.org/static/demo/

http://webdir.tistory.com/439



리눅스 커널에 대해서 공부를 진행하면서, 이론 뿐만아니라 실제적으로 해볼 수 있는 실습들에 주목하고 있다. 한 번 해보고 지나가면 금방 잊어버리기 때문에 보다 오래 기억하고자, 그리고 다른 사람들과 공유하고자 공부한 내용을 정리하기로 했다. 오늘은 모듈 프로그래밍이다. 리눅스 커널에 대해서 공부하고 있는 다른 사람들에게도 좋은 예시가 될 것이라 생각하며 공부하는 동안 알게된 내용들을 정리해본다. 이전에 게시했던 버추얼박스 공유폴더 설정과 마찬가지로 버추얼박스 버전 5.0과 우분투 버전 14.04.3 LTS을 이용했음을 미리 알린다. 이와 더불어 아래에 진행되는 실습은 커널 3.19.0-25-generic 버전을 활용했다.



0. 준비




모듈 프로그래밍 실습을 하기 앞서 모듈 프로그래밍을 왜 사용하는지, 어떤 특징이 있는지 알아보자. 이를 파악하기 이전에 커널의 종류에 대해서 먼저 알아볼 필요가 있다. 위 그림을 참조해보면 커널을 크게 세 가지의 형태로 구분할 수 있다. Monolithic Kernel, Microkernel 그리고, Hybrid Kernel. 위 그림에서 빨간색으로 표시된 영역이 커널 영역인데 종류에 따라서 관장하는 부분이 각기 다르다.



0.1. Monolithic Kernel

Monolithic Kernel은 흔히 일체형 커널이라고 부른다. 모든 컴포넌트(VFS, System Call, IPC, File System, Scheduler, VM, Device Driver ...)들이 커널에 포함되어 있다. 각 커널 계층이 하나의 커널 프로그램으로 통합되고, 현재 프로세스를 대신하여 커널 모드에서 동작한다. 마이크로 커널에 비하여 성능이 좋은데, 그 이유는 이미 모든 컴포넌트를 포함하고 있기 때문에 계층 사이에 메시지 전달에 비용이 적게 소모된다. 대표적으로 Linux, BSD, Solaris, MS-DOS가 일체형 커널이다. 



0.2. Microkernel

마이크로커널은 일반적으로 매우 적은 기능만을 포함한다. 따라서 몇 가지 시스템 프로세스를 실행하여 Memory Management, Device Driver, System Call Handler 등의 일체형 커널에 적재되어 있는 컴포넌트를 구현한다. 가장 큰 장점은 불필요한 기능을 구현하는 시스템 프로세스를 스왑 아웃하거나 없앨 수 있어서일체형 커널보다 RAM 사용을 효율적으로 하는 경향이 있다. 그럼에도 불구하고 일체형 커널에 비해 성능이 떨어지는 단점을 안고있다. Mach, GNU hurd, Minix가 대표적인 마이크로커널이다.



0.3. Hybrid Kernel

하이브리드라는 단어에서 의미하는 것처럼 일체형 커널과 마이크로 커널의 혼합된 형태로 이해하면 될 것 같다. 일체형 커널의 장점과 마이크로 커널의 장점을 모으려한 의도를 엿볼 수 있다. 핵심적인 컴포넌트들은 일체형 커널처럼 포함시키며, 그 외의 자주 변경될만한 부분은 모듈로 분리해 놓은 방식이다. 커널 자체의 핵심 서비스가 변경되지 않는 다면 커널 자체를 재컴파일할 필요가 없다. 또한 핵심 서비스는 커널에 포함되어 있으므로 괜찮은 성능을 보장한다. 최근 발행되는 신형 운영체제들이 이와같은 방식을 따르고 있다고 한다.


하이브리드 커널에서 잠시 언급한 것처럼 커널의 핵심 서비스가 변경된다면 커널 자체를 재컴파일 해야한다. 실제로 이를 진행해봤지만 커널 크기가 상당한 관계(특히, 일체형 커널)로 시간을 많이 잡아먹는 작업이다. 이런 불편함을 개선하기 위해 커널 전체를 재컴파일 할 필요 없이 필요한 기능을 적재하고, 필요없어지면 다시 제거하는 방식으로 커널의 서비스를 부분적으로 수정할 수 있다. 이를 위해 필요한 것이 바로 모듈 프로그래밍이다.


비로소 왜 모듈 프로그래밍을 해야하는지 이유가 나왔다. 하지만 위의 이유는 모듈 프로그래밍을 해야하는 큰 이유 중에 곁가지에 불과하다. 모듈 프로그래밍을 통해서 얻을 수 있는 가장 큰 이점은 모듈이 정적으로 링크된 커널의 오브젝트와 동등하게 취급되므로 함수를 호출할 때 별도의 메시지 전달이 필요없다는 것이다. 한 마디로 성능이 떨어지지 않는다. 또한 실행 중에 링크/언링크가 가능하여 커널의 각 컴포넌트에 모듈화된 접근을 가능케하며, 덩달아 주 메모리를 효율적으로 쓸 수 있다.


그럼 이제부터 본격적인 모듈 프로그래밍 실습을 해보자.



1. 모듈 프로그래밍 과정




모듈 프로그래밍은 다음과 같은 과정을 통해 진행된다.

[1] 모듈 프로그램 작성

[2] 모듈 프로그램 컴파일

[3] 모듈 로드 - insmod

[4] 모듈 확인 - lsmod

[5] 모듈 제거 - rmmod



[1] 모듈 프로그램 작성


함수가 정의되어 있는 callee와 이를 호출하여 사용하는 caller를 제작해보자. 우선 callee부터 작성해보면,


[callee.c]

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

int __init init_callee(void) {
	return 0;
}

void __exit exit_callee(void) {

}

int add(int a, int b) {
	printk(KERN_ALERT "[callee] add called...\n");
	return a + b;
}

int sub(int a, int b) {
	printk(KERN_ALERT "[callee] sub called...\n");
	return a - b;
}

EXPORT_SYMBOL(add);
EXPORT_SYMBOL(sub);
module_init(init_callee);
module_exit(exit_callee);
MODULE_LICENSE("GPL");


[caller.c]

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

int add(int, int);
int sub(int, int);

int __init init_caller(void) {
	printk(KERN_ALERT "[caller] I'll call add(), sub() from callee.\n");
	printk(KERN_ALERT "[caller] add: %d\n", add(3, 2));
	printk(KERN_ALERT "[caller] sub: %d\n", sub(3, 2));
	return 0;
}

void __exit exit_caller(void) {

}

module_init(init_caller);
module_exit(exit_caller);
MODULE_LICENSE("GPL")


간단한 모듈 callee와 caller 작성이 완료됐다. 코드에 대해서 필요한 설명을 추가하자면 callee의 23~27라인, caller의 19~21라인에 주목할 필요가 있다. EXPORT_SYMBOL의 경우 모듈에서 작성한 함수(add, sub)들을 심볼 테이블에 등록하는 것인데, 커널 내부의 모든 함수와 전역변수, 모듈에서 작성한 함수와 전역변수는 모두 심볼로 제공된다. 더불어 모듈을 등록하기 위해서는 모듈 작성 당시 모듈의 초기화 루틴과 종료 루틴을 설정해야 한다. module_init, module_exit가 바로 그 부분에 해당한다. 이제 이들을 적재할 수 있도록 컴파일 해보자



[2] 모듈 프로그램 컴파일


컴파일 하기 위해 Makefile을 이용하자. 위에서 작성한 callee와 caller와 같은 위치에 Makefile을 다음과 같이 작성한다.


[Makefile]

KERNELDIR = /lib/modules/$(shell uname -r)/build

obj-m = callee.o caller.o

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
	rm -rf *.ko
	rm -rf *.mod.*
	rm -rf .*.cmd
	rm -rf *.o


Makefile을 통해 두 모듈을 적재가능한 형태로 컴파일하고 있다. 이때 주의할 점은 ##행과 ##행 이후의 부분은 반드시 탭으로 띄어쓰기를 해야한다. 컴파일이 완료되면 폴더에 callee.ko 파일과 caller.ko 파일이 생성된 것을 확인할 수 있다. 그럼 이제 모듈을 직접 커널에 적재하고 확인해 볼 차례다.



[3] 모듈 로드 - insmod


이전 과정들에 비하면 비교적 간단하게 적재할 수 있다. 다만 한 가지 주의할 점은 두 모듈을 순서에 맞게 적재해야 한다. 만약 caller 모듈을 먼저 적재한다면 다음과 같은 에러 메세지를 확인할 수 있다.

$sudo insmod caller.ko

insmod: ERROR: could not insert module caller.ko: Unknown symbol in module


caller 모듈에는 callee의 함수를 호출하고 있는데 callee가 없다면 적재가 불가능하기 때문이다. 이런 이유로 callee → caller 순으로 적재 해야함을 명심하자.

$sudo insmod callee.ko

$sudo insmod caller.ko


이제 정상적으로 두 모듈이 커널에 적재되었다.


[4] 모듈 확인 - lsmod


적재된 모듈을 확인하기 위해 아래의 명령어를 쉘에 입력한다.

$sudo lsmod | grep call



위의 명령어를 입력하면 정상적으로 두 모듈이 적재된 것을 확인할 수 있다. 두 숫자를 통해 모듈의 사이즈, 해당 모듈을 참조하는 모듈의 이름과 개수를 파악할 수 있다. caller 모듈의 경우 '0'. 즉 caller 모듈을 참조하는 다른 모듈이 없음을 알 수 있으며, callee의 경우 하나의 모듈이 callee를 참조하고 있는데 그것이 바로 caller 임을 표시하고 있다.


모듈이 정상적으로 적재된 것을 lsmod 명령어를 통해 확인할 수 있지만, 다른 방법을 통해서 확인할 수 있다.

$dmesg | grep calle


위 명령어 dmesg는 커널의 메세지 버퍼를 출력하는 것인데 작성한 모듈 코드의 printk 함수를 통해 커널 메세지 영역에 작성한 것을 쉘 상에서 볼 수 있는 명령어다. 따라서 위 명령어를 입력해보면 아래와 같이 출력되는 것을 확인할 수 있다.



뿐만아니라 앞서 설명할 때 모듈 내에서 작성한 함수는 EXPORT_SYMBOL 명령어를 통해 심볼로써 심볼 테이블에 등록된다고 언급했다. 정상적으로 심볼 테이블에 등록이 되었는지 확인해볼 수 있다. /proc/kallsyms 내에서 등록한 심볼들을 확인할 수 있다.

$sudo cat /proc/kallsyms | grep calle


위 명령어를 이용하면 아래와 같이 정상적으로 심볼 테이블에 등록되었음을 알 수 있다.




[5] 모듈 제거 - rmmod


모듈은 필요할 때 적재하여 사용하고, 더이상 사용하지 않을 때 제거할 수 있는 특장점이 있었다. 지금까지 성공적으로 커널에 모듈을 적재했다면, 이번에는 반대로 제거해보자. 모듈을 제거하는 명령어는 다음과 같다.

$sudo rmmod caller

$sudo rmmod callee


이 때, 커널에 모듈을 적재할 때와 반대로 진행해야 한다는 점에 주목할 필요가 있다. 앞선 이유와 마찬가지로 참조되는 모듈을 먼저 제거하려고 하면 아래와 같은 에러 메세지를 확인할 수 있다. caller라는 모듈에서 참조되고 있으므로 제거할 수 없다는 의미다. 따라서 이번에는 caller → callee 순으로 제거하자.

$sudo rmmod callee

rmmod: ERROR: Module callee is in use by: caller



이론적으로는 각 커널의 특징부터 모듈 프로그래밍의 필요성을 알아봤고, 실습을 통해 모듈을 작성, 적재, 확인, 제거까지 하는 과정을 완료했다. 일회성 실습에 그치지 않고 꾸준히 학습한 내용을 기억하여 보다 유연하게 커널을 조작할 수 있기를 희망한다.



[참고 자료]

http://tmdgus.tistory.com/114

http://goo.gl/sTC4pX

https://en.wikipedia.org/wiki/Kernel_(operating_system)

















12. 05

분명 내가 무슨 대외활동에 쓸 사진을 찍으러 나온거였는데. 꼴 보니 가관이네.

이 형들 차암 좋은데, 사진 올린거 보면 노하시겠지?


16. 01

덧붙여보면, 범성이형은 참 아는 것도 많고 활동적인 형이고, 기현이형은 차분하고 성실해보이는 형이었다.

작년 대학원을 준비하면서 범성이 형이 직장을 가지면 돈은 모이는데 쓸 곳이 없다며 드마리스 뷔페를 한 턱 쏘고,

오리역 19번 버스에서 기현이 형을 참으로 오랜만에 만나 유쾌한 시간을 보내느라 내 정거장을 지나쳤다.

좋은 인연들인데 가끔 연락 좀 하며 살아야겠다. 직장인이라 다들 바쁘겠지만.
































12. 04. 02 - 12. 04. 05

초저가항공으로 목숨값 내놓고 떠난 제주도 여행. 말도 많고 탈도 많았지. 남는건 사진뿐인가봐 홍주야.



 





-13. 05. 02

아침일찍 떠난 대전여행, 발표는 만족스럽지 못했지만 좋은 사람들과.


금의한양-

희민이형, 원경이, 승주, 마음이.


-16.01.27

연락이 뜸한 희민이형은 현대로

취업을 절대 못할 것이라 생각했던 원경이는 SK로

어디서든 잘할 것 같았던 마음이는 LINE으로

난 광주과학기술원으로.


나만 잘되면 되겠다.










이름 - 남 택호

닉네임 - NamTech

학교 - GIST

메일 - common.thnam@gmail.com



[수상]

TEPS Speaking UCC 공모전 / 최우수상 수상 (쪼꼬 Team) / 2012. 04 - 2012. 04

굽네치킨 UCC 페스티벌 / 투데이스타 수상 (개인) / 2012. 04 - 2012. 05

SW동아리 재능기부 챌린지 / 본선 진출(30 Team) / 2013. 04 - 2013. 11

한양대학교 ERICA IeT 2013 대회 / 은상(개인, 3위) 수상 /  2013. 10

대한물리학회 2013 대학생 물리 UCC 공모전 / 동상 수상 / 2013. 09 - 2013. 11

SW동아리 재능기부 챌린지 / 본선 진출(30 Team) / 2014. 04 - 2014. 11

한양대학교 ERICA IeT 2014 대회 / 금상(개인, 2위) 수상 / 2014. 10

한양대학교 SID Audition 결선 진출 / 2015. 03. 25



[전공활동]

한양대학교 ERICA 컴퓨터 프로그래밍 캠프 [C] / 2013. 08. 05 - 2013. 08. 16

한양대학교 ERICA 리눅스 캠프 1차 / 2013. 08. 19 - 2013. 08. 23

한양대학교 ERICA 웹 프로그래밍 온라인 교육 / 2014. 02. 10 - 2014. 02. 29 

한양대학교 ERICA 리눅스 캠프 2차 / 2014. 02. 17 - 2014. 02. 21

SW동아리 재능기부 챌린지 (홈페이지 및 셀프주문모니터 제작)  / 2013. 04 - 2013. 11

한양대학교 ERICA SMaSH 2기 과정 수료 / 2013. 12 - 2015. 02

SW동아리 재능기부 챌린지 (홈페이지 및 어플리케이션 제작) / 2014. 04 - 2014. 11

한양대학교 ERICA SMaSH 해외대학 방문교육(Kansas State University) 2014. 06 - 2014. 08

- Real-time Embedded System/ Cyber Security 수료



[자격증]

운전면허 1종 보통 / 2012. 03

컴퓨터 활용능력 1급 / 2012. 03

상공회의소 IT Plus / 2012. 03

워드프로세서 1급 / 2012. 04

정보처리기능사 / 2012 .08

GTQ 포토샵 1급 / 2012. 10. 12

진흥회 한자자격시험 2급 / 2012. 12

정보처리기사 / 2015. 05



[대외활동]

글라소 비타민워터 블로그 기자단 Trend 부문 / 4기 / 2011. 12 - 2012. 02

기획재정부 블로그 기자단 MOSFERS / 5기 / 2012. 01 - 2012. 12

오뚜기 진라면 서포터즈 / 1기 / 2012. 05 - 2012. 10

삼성 직업멘토링 2013 / 2013. 05 - 



[어학]

TOEIC 860 / 2015. 02

한양대학교 ERICA SMaSH 해외대학 방문교육(Kansas State University) / 2014. 06 - 2014. 08

-Technical Communication 수료

필리핀 어학연수 / 2015. 01 - 2015. 02