최근 embedded system 관련 virtual address 와 swap에 관한 질문.

happyKYS의 이미지

안녕하세요. 간단히 조금 궁금한 점이 있어 가볍게 질문 드려봅니다. 고수분들 답변해 주시면 감사드리겠습니다.

과거 phys RAM이 매우 용량이 적었을 당시에 virtual address를 통한 swap이나 demand paging 과 같은 기법으로 부족한 RAM 용량을 커버했고 시스템 효율화를 꾀했다면, 이 같은 개념이 현재 4GB 물리 RAM이 내장되는 임베디드 system에도 똑같을지에 대한 질문입니다.

물론 임베디드 시스템에선 swap 영역을 사용하지 않는 부분이 많지만, 만약 1GB라는 스왑 영역이 주어진다 해도 이게 의미를 가지는지에 대한 질문입니다. 32bit 가상 주소에서 표현할 수 있는 최대 가상 address space가 4GB일때 이미 phys가 1:1로 4GB라면 swap 영역의 사용 자체가 의미가 없지 않나요. 왜냐면 "물리 주소를 다 썼다는 말 = 가상 주소도 남은게 없다" 즉, "예전처럼 물리주소는 다 썼는데 가상주소는 남았다." 라는 게 성립되지 않아 swap이고 뭐고 간에 가상 주소 자체도 할당해 줄 수 있는 address가 남지 않았는데 32bit swap이 phys 4GB RAM 내장 시스템에서 가능하긴 한 기법인지와 예전만큼 의미가 있는지가 궁금합니다.

또 demand paging이나 가상 address를 써서 가질 수 있는 기타 효과가 매우 크겠지만, excution 측면에서 가상 주소가 가지는 특장점은 프로그램 excution 측면에서 프로그램 code 즉, text section이 연속된 논리주소에 위치해야 하고 가상 주소에서는 이 측면에서 바라볼때 거의 대부분 항상 virtually 연속적인 영역을 할당 가능하기에 실제 phys의 fragmentation에도 excution 측면에서는 크게 구애받지 않는다고 보면 될까요? (물론 메모리 할당도 마찬가지지만 단순 code 영역 excution 측면에서 볼때 위 말이 맞는가요?)

감사합니다. (__)

kukyakya의 이미지

"물리 주소를 다 썼다는 말 = 가상 주소도 남은게 없다" 이 문장은 예전에도 성립하지 않았고 앞으로도 성립하지 않을 문장입니다.

물리 메모리가 4G이고 가상 주소 공간이 4G라고 하더라도, 단순 1:1로만 매핑해서 사용하지는 않습니다.

happyKYS의 이미지

답변 감사합니다. 그런데 좀 의문이 있습니다.

예전에 성립하지 않았다는 것은 이해합니다. 물론 kernel address 영역이 아니면 1:1로 매핑해서 사용하지도 않지요. 그러나 어쨋든 32bit system에서 표현하는 가상 메모리 주소 4GB는 이것이 2:1로 매핑이 되든, 3:1로 매핑이 되든 physical memory가 4GB라면 가상 주소 <= 물리 주소가 됩니다. 가상 주소 중 1GB가 page frame을 공유해 사용한다면 물리주소 1GB에 가상 주소 2GB가 붙어 있겠지요. 이 경우 가상 주소 2GB가 남고 물리 주소 3GB가 남습니다. 어떤 경우라도 physical RAM이 4GB를 만족한다면 가상 주소가 남는데 물리 주소가 부족한 경우는 없습니다. (fully 1:1 mapping일때조차 동일하므로, 물리주소 2개를 가상주소 1개에 mapping 시키는 방법은 없습니다. 0x80203000 이라는 virtual address가 physical address 어디를 mapping 하더라도 이것은 page frame 4KB mapping이지 0x80203000 virtual 시작 address가 MMU상에서 physical 16KB - pf 2개를 mapping하고, 그사이 virtual 4KB 뒤의 0x80603000이 다른 곳을 mapping 하진 않습니다.)

이처럼 physical RAM이 32bit original system에서 4GB를 만족한다면 "physical RAM을 fully 다 사용중이다.(이런 경우는 없습니다만 가정입니다.) = 가상 주소도 남은 주소가 없다(즉, 모든 가상주소는 physical page frame을 어딘가는 mapping 중이다)" 가 성립합니다.

제 말은 위처럼 physical RAM을 32bit 한계인 4GB까지 붙이고 ARM에서 지원하는 Huge page 기법을 사용하지 않은 오리지널 32bit virtual address system에서 swap이 가질 수 있는 의미를 여쭤보는 것입니다.

감사합니다.

익명 사용자의 이미지

뭔가 잘못 이해하고 계신 것 같은데, 그냥 상식적으로 생각해서 1개의 프로세스마다 4GB 의 공간을 가질 수 있고(물론 이론적으로만)
보통 운영체제에 돌아가는 프로세스는 어림 잡아도 20개는 기본인데 물리 메모리가 4GB 든 100GB 든 1:1 매핑을 어떻게 할까요?

OS 는 자주 쓰지 않는 메모리(페이지 단위)를 하드디스크에 swap 해서 저장해 놓고, 나중에 필요하면
불러다 씁니다. 이 때 물리 메모리엔 없고 하드디스크에 있어서 다시 로드해야 하는 경우를 Page fault 라고 합니다.
만약 시스템에서 데몬이 잘 쓰지 않아서 swap 된 메모리의 총 합이 2GB 정도 된다고 하고
swap 되지 않은 메모리가 3GB 정도라고 한다면 시스템은 실제로 5GB 를 쓰고 있다고 생각할 수 있습니다.
(순수하게 개념만 설명한 것으로 커널 영역 등은 고려하지도 않았습니다.)

물론 이 상태에서 만약 나머지 2GB 를 전부 다시 물리 메모리로 로드해야 하는 경우
시스템은 "메모리 부족" 오류 등을 띄울 수 있습니다.
하지만 결과적으로는 전체 메모리 합은 4GB 를 넘습니다.

Paging architecture 에서 swap 은 언제나 의미를 가지고 앞으로도 그럴 것입니다.
당연한 얘기지만, 하드디스크에 swap 을 하지 않게 설정할 수도 있습니다.
(가령 Windows 같은 경우 "페이지 파일 사용 안함" 등의 설정이 있습니다.)
이렇게 하게 되면 위에서 얘기한 상황은 일어날 수도 없고 그 전에 이미 메모리 부족 오류를 보게 됩니다.

사실 제가 설명하는 것을 보는 것보다, 운영체제론 책을 한번 쭉 읽어보시는 게 더 좋을 것 같습니다.

happyKYS의 이미지

또 한번 답변 감사드립니다.

그러나 제 질문 자체를 잘못 이해하고 계신것 같습니다.... 답변자께서 말씀하신 내용은 상식이고요..

"프로세스마다 4GB를 가질 수 있다. 이론적으로만 << virtual address + swap 사용으로 당연한 이야기입니다. 그러나 이 이야기가 동일한 시간에 block, running등 모든 상태 프로세스 포함하여 가상 메모리 4GB를 동시에 점유할 수 있다는 소리는 아닙니다. simple한 예로 kernel이 사용하는 0xc0000000-0xffffffff 가상주소는 특정 user 프로세스가 마음대로 가져갈 수 없습니다. 현실적인 예를 든것 뿐 저 이론 자체가 틀리다는 소리는 아닙니다.

즉, 이론적으로 한 프로세스가 4GB의 가상 주소 공간을 점유할 수 있지만, 한 순간에 여러 프로세스 각자가 각각 4GB를 점유할 수 있다는 소리가 아니란 점을 알려드리는 겁니다. 가상 주소는 프로세스가 kill 당하기 전에는 고정 할당입니다."

여기에 이어 "OS가 자주 쓰지 않는 메모리를 하드디스크에 스왑해서 저장해 놓는다 << 자주 쓰지 않는 메모리 스왑 외에, page demand 정책 후 실제 필요할 경우 디스크와 RAM page frame을 교체하거나, process context switching경우에도 동일 물리 page frame 사용시 디스크 백업하는 것도 스왑입니다."

제가 전제로 말씀드린건 1:1 매핑을 한다는 이야기가 아닙니다.

좀 더 체계적으로 말씀을 드리겠습니다.

system 물리 메모리가 2GB 인 상황에 swap은 매우 많은 의미를 가집니다. 가상 주소 4GB를 사용할 경우 system 입장에서 마치 4GB를 온전히 사용하는 듯한 착각에 빠지게 할 수 있습니다.

1. 2GB physical memory 2GB를 프로세스 N개가 사용중일 때, 아직 swap이나 메모리 회수 정책을 통해 물리 메모리 회수가 전혀 이루어 지지 않았다 가정합시다.
(가상 메모리는 2GB 여유가 있습니다. 물론 공유 page나 따로 사용할 목적으로 MMU table 내에서 가상 메모리 3,4개가 동일한 page frame을 가르킬 수도 있겠지요.
물리 메모리 2GB 상황에선 어떤 경우든 "가상 메모리 >= 물리 메모리" 입니다. 물론 필요이상으로 가상 주소를 물리 페이지 하나에 매핑해놓지 않는다는 일반적인 시스템 구동 측면에서입니다.)

2. N+1번째 process가 execution된다고 합시다. 이렇게 무식하게 swap하진 않겠지만, 어쨋든 이처럼 모든 process가 running 중으로 물리 메모리를 풀로 mapping 해서 사용 중이라 할 때, 추가적인 process를 execution을 위해 RAM에 전개시키려면 기존 process를 kill을 하든 특정 물리 page frame을 swap을 해서 잠시 빼놓던 해야겠죠, 아니면 자기 자신을 조금만 올려놓고 page fault가 나면 swap해서 가져오는 방식으로 사용해도 되고요.

3. 여기서부터 제가 질문하게 된 부분하고 관계가 있습니다. 위처럼 새로운 process가 memory full 상황에서 swap을 어떻게 할 수 있을 까요. 예를 들어 기존 A 프로세스가 가상 주소 0x85968000에 물리 페이지 프레임(간단히 1번이라 하겠습니다.) 1번을 자신의 process mmu table로 매핑하고 있다 합시다. 새롭게 들어오는 B process는 "남아있는" 가상 주소 0x90000000에 물리 페이지 프레임 1번을 할당하고 swap을 통해서 A process의 1번 물리 페이지 프레임을 disk에 백업하고 B process 본인이 쓴다 합시다. 이런 swap을 어떻게 할 수 있을까요.. 가상 메모리가 남아있기 때문입니다. 가상 메모리가 남아있지 않으면, swap이건 뭐건간에 할 수 없겠죠 매핑 시켜줄 가상 주소가 남아있질 않는데 물리 페이지 프레임을 어디다 매핑 시킬건지요..

위와 같은 이유로 가상 메모리(4GB) > 물리 메모리 시스템에서 swap이 상당히 의미가 있다 생각합니다.

제 질문의 요지는 위 이야기가 아닙니다. 위 시스템은 물리 주소가 2GB인 시스템입니다. 일반적인 시스템 구동중에 가상 주소는 물리 주소보다 여유 영역이 항상 많습니다. 1:1 매핑은 이야기 하실 필요가 없는 부분입니다. 최악의 경우를 산정해놓은 이야기이지 virtual address를 사용하는 linux system에서 1:1 고정 mapping으로 한정되 있는 부분은 user configuration이 없는 이상 896MB 뿐입니다. (이 외에는 MMU page table 수정하기 나름입니다.) 이럴 경우 위에서 이야기 한대로 상대적으로 direct memory access 보다 몇 차례 더 과정을 거치고 disk에 접근해서 RAM으로 물리 페이지를 백업/복사 해야하는 swap이라도 큰 의미를 가지겠죠.

이제 제 질문대로 반대로 생각해보겠습니다.

system 물리 메모리가 4GB인 상황입니다. 가상 주소 4GB를 사용할 경우 위와 동일한 상황입니다.

1. 4GB physical memory 4GB를 프로세스 N개가 사용중일 때, 아직 swap이나 메모리 회수 정책을 통해 물리 메모리 회수가 전혀 이루어 지지 않았다 가정합시다.
(가상 메모리는 0GB 여유가 있습니다. 물론 공유 page나 따로 사용할 목적으로 MMU table 내에서 가상 메모리 3,4개가 동일한 page frame을 가르킬 수도 있겠지요.
물리 메모리 4GB 상황에선 어떤 경우든 "가상 메모리 <= 물리 메모리" << 위 시스템이랑은 반대입니다.)

2. N+1번째 process가 execution된다고 합시다. 이렇게 무식하게 swap하진 않겠지만, 어쨋든 이처럼 모든 process가 running 중으로 물리 메모리를 풀로 mapping 해서 사용 중이라 할 때, 추가적인 process를 execution을 위해 RAM에 전개시키려면 기존 process를 kill을 하든 특정 물리 page frame을 swap을 해서 잠시 빼놓던 해야겠죠, 아니면 자기 자신을 조금만 올려놓고 page fault가 나면 swap해서 가져오는 방식으로 사용해도 되고요.

3. 이 경우 2번을 어떻게 할까요..??????????? 남은 가상 메모리 공간이 없는데 process execution은 말이 안되는 소리입니다. swap? 못합니다. 가질 수 있는 가상 주소가 없는데 A process 기준 swap시킨 1번 물리 페이지 프레임을 본인의 가상 주소 어디다 매핑을 시킬건지요.. process kill을 해서 가상 주소 회수를 해야겠지요. 결과적으로 물리 주소 회수도 되겠지만요.

제 질문의 요는 이처럼 과거와 RAM 용량이 달라진 현재 32bit에서 실제 4GB physical을 가지는 시스템의 경우 swap이 가질 수 있는 장점을 여쭤본겁니다. 과거와 달리 없는 메모리를 있는 것처럼 꾸며주는 장점은 없어졌으니까요.

감사합니다. 아 이제 이해 안되시면 제 필력으로 한계입니다. ㅋㅋ 혹시 제가 잘못 이해하는 부분이 있으면 상세 설명 부탁드립니다.(제 질문을 오해하시는것 같아 좀 길게 설명드렸습니다.)

peecky의 이미지

‘남아있는 가상 주소’ 라는게 어떤 의미인가요?
A 프로세스가 OS로부터 0x85968000 주소의 가상메모리를 할당 받았을 때, B 프로세스는 절대로 OS로부터 같은 주소 값인 0x85968000 주소를 받을 수 없다는 의미인가요?

익명 사용자의 이미지

윗 분이 먼저 써주셨는데, 위에서부터 계속 이해안되는게 "남아있는 가상 메모리" , "가상 메모리는 0GB 여유가 있습니다." 이게 당최 무슨 소리인가요?
제일 위에 답변하신 분도 마찬가지로 이 용어때문에 1:1 매핑을 말씀하신 걸로 생각하신 것 같고 저도 마찬가지입니다.

mirheekl의 이미지

아마도 유저 프로세스용으로 변환된 메모리가 아닌 커널에서의 메모리 모델을 말씀하시는 거겠죠. 가령 4GB까지만 메모리를 제어할 수 있는 커널이 "있다 치고", 이 때 4G를 통채로 물리메모리로 가지고 있으면 외부기억장치의 도움을 받는게 의미가 없지 않느냐 하는 얘기로 보입니다. 헌데 모든 시스템이 4GB 메모리를 갖고 나오는건 아닙니다. 2GB만 달린 녀석도 있고 1GB만 달린 것도 있을 수 있는데 정확히 4GB를 달고 나오는 녀석만을 위해서 별도의 메모리 관리 시스템을 도입할 이유는 없다 봅니다. 게다가 앞서 다른 분들이 말씀하신 대로 32비트라고 무조건 4GB가 제한이라고 볼 수도 없고요.

시스템 통틀어 4GB이상 메모리를 사용할 방법이 절대 없다는 확신이 있고 현재 상황이 비효율적이라 생각이 되시면 페이징을 꺼보면 어떨까요? 다만 일부 애플리케이션이 명시적으로 페이징 파일을 이용할 수도 있어서 문제의 소지는 있습니다. 실제로 최근 일부 SSD사용자들이 쓰고 있는 방법입니다. 언급한 이유때문에 권장되지는 않지만.

--

happyKYS의 이미지

답변 감사합니다.

조금 오해의 소지가 있었나봅니다. 제가 말씀드린건 가상 메모리 주소 입니다. 아시다시피 특별한 처리를 하지 않으면 0x00000000-0xffffffff까지이지요.

"A 프로세스가 OS로부터 0x85968000 주소의 가상메모리를 할당 받았을 때, B 프로세스는 절대로 OS로부터 같은 주소 값인 0x85968000 주소를 받을 수 없다는 의미인가요?"

이 질문을 한 분께 제가 오히려 반문하고 싶습니다.

위 시스템은 현재 RAM에 적재되어 있는 process들이 state에 상관없이 같은 공간에 적재되어 있을 수 있다는 물리적으로 불가능한 말씀을 하고 계십니다... 커널 swap이 물리 페이지와 disk간의 관계이지 virtual address와 disk간의 관계가 아닙니다.

반문 드립니다. user process A, B가 있다고 합시다. 둘다 RAM에 적재되서 부팅 초반부터 돌고 있는 쓰레드입니다. A, B 모두 logbuf라는 전역변수를 잡고 해당 주소를 커널로 내려주는 function이 call되서 커널로 주소가 내려간다고 합시다. kernel이 이제 그 user process mapping을 해서 값을 읽거나 쓴다고 합시다. 질문자의 말대로 시스템이 돌지는 않지만 A,B 프로세스가 같은 가상주소를 가질 수 있다면, kernel은 자신이 가진 두개의 logbuf 주소가 어느 프로세스의 것인지 어떻게 알까요? (이런 시스템을 사용중이라고 생각하시는건지 오히려 제가 여쭤보고 싶습니다...)

두 개의 process가 다른 가상주소를 가지고 동일 물리페이지를 사상할 순 있습니다. kernel TTB외에 각 process가 사용하는 MMU table이 있기 때문이죠. 질문자께서는 지금 RAM에 전개되어 있는 process들이 서로 같은 가상 주소를 가질 수 있다고 말씀하시는데 이건 위와 반대입니다. 실제 CPU에서 running 중인 process A와 block 상태인 process B가 동일 가상 주소(말씀드린대로 swap과 mmu modify를 이용하면 동일 물리페이지를 사상할 순 있겠지만 이건 역입니다.)를 사용할 수 있다고 말씀하시는건데 이렇게 생각하시는건가요?
이렇게 사용할 수 있다면 system이 watchdog과 같은 이유로 down되었고, ramdump를 떳을때 그 dump상 kernel, user process 각각의 모든 mmu table이 백업되서 정상 복원되었다 치더라도, 지금 덤프 상 특정 물리 주소에 있는건 A process인가요 B process인가요... 이렇게 linux system memory model이 동작중이라고 하시는건지 궁금합니다.

위처럼 시스템이 돌면 memory dump는 아무 의미가 없습니다. memory dump 상에서 해당하는 모든 심볼 정보를 해당 process공간들에 정확히 loading 해주었다고 치고, linux awareness같은 정보를 통해 scheduling같은 정보나 현재 dump상에 가지고 있는 값들이 process 마다 파악된다고 해도 dump 상 물리 메모리에 있는 값은 대체 어느 프로세스의 값인가요.

그래서.. "A 프로세스가 OS로부터 0x85968000 주소의 가상메모리를 할당 받았을 때, B 프로세스는 절대로 OS로부터 같은 주소 값인 0x85968000 주소를 받을 수 없다는 의미인가요?" 이 질문에 대한 답을 하면 A 또는 B process가 종료되고 해당 가상 주소를 반환하지 않으면 불가능하다고 답변드리고 싶습니다.

만약 linux가 위에 여쭤본 2가지 경우처럼 돌고 있고, 현재 구동중인 N개의 process가 가상 주소를 같이 사용할 수 있는 시스템이라면 제가 한참 잘못 알고 있으니 자세히 설명좀 부탁드리겠습니다.

감사합니다.

익명 사용자의 이미지

제가 위에서 말씀드렸다시피 "1개의 프로세스마다 4GB 의 공간을 가질 수 있다" 라는 말의 의미를 그냥 단순하게 생각해 보시기 바랍니다.
말 그대로 A 라는 프로세스 내에서의 0x85968000 주소와 B 프로세스의 0x85968000 은 당연히 다릅니다.
서로 다른 4GB 의 가상 주소 공간을 가지는데 이게 어떻게 같을 수가 있을까요?

뭔가 happyKYS 님 말도 계속 왔다갔다 애매해서 정말 확실하게 이렇게 오해하고 계신게 맞는 건지도 헷갈립니다.
간단히 말해서 페이지 테이블이 대략 이렇게 구성이 된다는 얘기입니다.
(실제로 이렇진 않지만 개념적으로)

pid vm address phys addrs
77 0x85968000 0x12345678
88 0x85968000 0x23456789

두 프로세스에 있는 0x85968000 에 있는 데이터는 당연히 다르고, 달라야 합니다.

happyKYS의 이미지

제가 말씀드리는건 page table이 동시간에 저렇게 구성될 수 없다고 말씀드리는겁니다... 제 글을 다시 한번 읽어주시기 바랍니다.

pid vm address phys addrs
77 0x85968000 0x12345678
88 0x96590000 0x12345678

이건 가능합니다.

익명 사용자의 이미지

당연히 말씀하신 것도 가능합니다. 아니면 Dynamic Link 라는 건 존재하지도 않았을 겁니다.
근데 그건 문제가 아니고, "동시간에 불가능하다" 는 또 무슨 의미인가요?

happyKYS의 이미지

너무 갇혀서 논쟁을 했네요.. 제 말도 된다고 해서 다시 생각해봤더니 제가 좀 삼천포로 가고 있었네요...

여태까지 제가 했던 주장이 다 말이 안되는 소리였다는걸 지금 알았네요.. 저는 계속 kernel 측면을 보듯이 user 측면을 생각하고 있었네요 ㅡㅡ.... (kernel만 보다보니 user 영역을 kernel 1:1 고정 mapping 방식하고 분리하지 못했네요..)

답변자 분이 해주신 것도 가능하고 제것도 가능하고 다 가능한 소리였네요....

결국 제 처음 질문 swap 영역과 물리 RAM 크기와는 관계도 없는 질문이었군요... swap은 그냥 그 자체로 의미가 있는 system이네요..

논쟁하다 그만뒀으면 한참 착각하고 살 뻔했습니다. ㅋㅋ 감사드립니다. 조금 민망하군요.

PS : "위에 장황한 글들은 다 잘못된 정보이니 나중에라도 글 보는 분들은 무시하시기 바랍니다. 죄송합니다."

익명 사용자의 이미지

익명으로는 내용 추가가 안되는군요.

제가 위에서 개념적으로 쓴 페이지 테이블은 당연히 동시간에 테이블 내에 저 두 항목이 들어가 있다고 가정하고 쓴 것입니다.
또한 실제로 현대의 모든 운영체제들이 저렇게 하고 있으며, 또한 가능합니다.

happyKYS의 이미지

윗글에 답변 달았습니다. 감사합니다.

happyKYS의 이미지

다시 쭉 읽어봤는데 우매한 주제에 흥분해서 글 쓴 흔적이 보이네요. ㅋㅋ 답변했던 분들께 다시 한번 죄송하단 말씀 드립니다.

역시 한쪽을 열고 살아야지 닫힌 사고는 위험하군요.. ㅠ..ㅠ

익명 사용자의 이미지

덕분에 재밌었습니다.

익명 사용자의 이미지

덕분에 공부도 되고 재밌게 읽었다는 뜻입니다 ㅠㅠ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.