커널 공간에 관한 질문

jsy0906의 이미지

안녕하세요 리눅스 커널 공부 입문잔데요,

지금까지 커널 공간이라하면 예를들어 4G 물리메모리를 딱 절반으로 나눠서 반틈은 프로세스의 주소공간으로,

나머지 반틈은 커널의 이미지가 로드되고 커널 코드가 수행되는 영역으로 알고있었는데요,

로버트 러브씨의 리눅스 커널 심층분석을 보니까 커널 공간이란

일반적으로 태스크에 4G의 주소공간이 할당되고, 0~3G까지는 태스크 자원(세그먼트 등),

나머지 1G는 8KB짜리 커널 스택이 존재하여 커널 코드가 수행되고

여타 레지스터값을 저장하기 위한 구조체, 프로세스 디스크립터를 저장하기 위한 구조체 등이 저장된다고 되있네요.

지금까지 알고 있던 내용과 달라서 혼란스럽습니다.

책에 의하면 태스크(프로세스)별로 할당 된 주소공간에 유저영역과 커널영역이 공존한다는 예긴데,

그렇다면 커널 이미지는 어디에 존재하는것인지...

공부가 부족하여 명확한게 하나없네요.

간략하나마 알려주시면 감사하겠습니다.

rgbi3307의 이미지

메모리 주소는 가상주소와 물리주소로 구분되는데,
가상주소는 32비트 주소크기(0~4GB)를 가상적으로 모두 사용하기 위해 커널에서 관리하는 주소입니다.
커널의 task_struct, mm_struct, kmalloc, page, slab 등의 방식으로 커널의 시야에서 메모리 할당하는 것이 가상주소 입니다.
위에서 말씀하신 것은 바로 커널 시야의 가상주소입니다.
가상주소는 page 단위 혹은 캐시 상태에 따라서 항당되는 위치가 커널의 메모리 관리 알고리즘에 의존됩니다.
(그래서 커널의 가상주소는 아키텍쳐에 의존되지 않는다 라고도 합니다.) 한마디로 커널이 알아서 합니다.

그럼 질문하신 "커널 이미지는 어디에 존재하는것인가?"에 대한 의문은 커널의 가상주소로 접근하면 찾아내기가 어렵습니다.
0~3GB 영역은 사용자를 위한 가상주소이고 3GB~4GB는 커널을 위한 가상 주소이므로 3GB~4GB 어디쯤에 있으리라고 추측은 합니다만,
정확한 가상주소 위치는 커널의 mm 코드들이 알고 있을겁니다.

"커널 이미지는 어디에 존재하는것인가?" 라는 의문은 실제 메모리의 물리주소에서 찾으면 정확하게 보입니다.
그런데, 물리주소는 특성상 아키텍쳐에 의존합니다. 아키텍쳐의 어드레싱에 따라서 달라집니다.
그렇다고 아키첵쳐별로 매뉴얼을 다 확인해볼 필요는 없습니다.
커널에서 /proc/iomem 파일을 제공해 주는데 이것을 확인해 보면 됩니다.

아래를 보시면, i386 아키텍쳐에서 커널 이미지가 있는 물리주소는 0x00100000 부터입니다.(00100000-003655e3 : Kernel code)

$ cat /proc/iomem

00000000-0000ffff : reserved
00010000-0009f7ff : System RAM
0009f800-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000cefff : Video ROM
000d0000-000d3fff : reserved
000e4000-000fffff : reserved
000f0000-000fffff : System ROM
00100000-37e9ffff : System RAM
00100000-003655e3 : Kernel code
003655e4-00522f4f : Kernel data
0058a000-00721793 : Kernel bss
37ea0000-37eb1fff : ACPI Tables
37eb2000-37efffff : ACPI Non-volatile Storage
37f00000-37ffffff : reserved
38000000-3bffffff : PCI Bus 0000:08
38000000-3bffffff : PCI CardBus 0000:09
3c000000-3fffffff : PCI CardBus 0000:09
c0000000-c0003fff : 0000:00:14.2
c0000000-c0003fff : ICH HD audio
c0004000-c0004fff : 0000:00:13.0
c0004000-c0004fff : ohci_hcd
c0005000-c0005fff : 0000:00:13.1
c0005000-c0005fff : ohci_hcd
c0006000-c0006fff : 0000:00:13.2
c0006000-c0006fff : ehci_hcd
c0007000-c00073ff : 0000:00:14.0
c0100000-c01fffff : PCI Bus 0000:01
c0100000-c010ffff : 0000:01:05.0
c0120000-c013ffff : 0000:01:05.0
c0200000-c02fffff : PCI Bus 0000:02
c0200000-c0203fff : 0000:02:00.0
c0200000-c0203fff : sky2
c0300000-c03fffff : PCI Bus 0000:08
c0300000-c0303fff : 0000:08:00.2
c0304000-c0305fff : 0000:08:00.3
c0304000-c0305fff : tifm_7xx1
c0306000-c0307fff : 0000:08:02.0
c0306000-c0307fff : 0000:08:02.0
c0309000-c03097ff : 0000:08:00.2
c0309000-c03097ff : ohci1394
c0309800-c03098ff : 0000:08:00.4
c0309800-c03098ff : mmc2
c0309c00-c0309cff : 0000:08:00.4
c0309c00-c0309cff : mmc1
c030a000-c030a0ff : 0000:08:00.4
c030a000-c030a0ff : mmc0
d0000000-dfffffff : PCI Bus 0000:01
d0000000-dfffffff : 0000:01:05.0
d0000000-d7ffffff : vesafb
e0000000-efffffff : reserved
e0000000-efffffff : pnp 00:01
e0000000-e0dfffff : PCI MMCONFIG 0000 [bus 00-0d]
fec00000-fec0ffff : reserved
fec00000-fec003ff : IOAPIC 0
fedff000-fedfffff : 0000:08:00.0
fedff000-fedfffff : yenta_socket
fee00000-fee00fff : Local APIC
fee00000-fee00fff : reserved
fff80000-ffffffff : reserved
fff80000-ffffffff : pnp 00:09

ARM 아키텍쳐에서 커널 이미지가 있는 물리주소는 0x30000000 부터입니다.(3004a000-30442fff : Kernel text)

$ cat /proc/iomem

30000000-4fffffff : System RAM
3004a000-30442fff : Kernel text
30444000-304a77b3 : Kernel data
88000000-880000ff : ax88796b-2nd
88000000-880000fe : ax88796b-2nd
a0000000-a0000007 : serial
a0001000-a0001007 : serial
a0002000-a0002007 : serial
a0003000-a0003007 : serial
a0004000-a0004007 : serial
a0005000-a0005007 : serial
a0006000-a0006007 : serial
a8000000-a80000ff : ax88796b
a8000000-a80000fe : ax88796b
b0e00000-b0efffff : s5p-nand
b0e00000-b0efffff : s5p-nand
e0900000-e0901000 : dma-pl330.0
e0900000-e0901000 : dma-pl330
e0a00000-e0a01000 : dma-pl330.1
e0a00000-e0a01000 : dma-pl330
e1700000-e1700fff : s3c-adc
e1700000-e1700fff : s3c-ts
e1701000-e1701fff : s3c-ts
e2700000-e2700fff : s3c2410-wdt
e2900000-e2900100 : s5pv210-uart.0
e2900000-e29000ff : s5pv210-uart
e2900400-e2900500 : s5pv210-uart.1
e2900400-e29004ff : s5pv210-uart
e2900800-e2900900 : s5pv210-uart.2
e2900800-e29008ff : s5pv210-uart
e2900c00-e2900d00 : s5pv210-uart.3
e2900c00-e2900cff : s5pv210-uart
ec200000-ec2fffff : s5p-ehci
ec200000-ec2fffff : ehci_hcd
ec300000-ec3fffff : s5p-ohci
eee30000-eee300ff : s3c64xx-iis-v4
eee30000-eee300ff : s3c64xx-i2s-v4
f8000000-f80fffff : s3cfb
f8000000-f80fffff : s3cfb
fab00000-fab00fff : s3c2440-i2c.1
fab00000-fab00fff : s3c2440-i2c

From:
*알지비 (메일: rgbi3307(at)nate.com)
*커널연구회(http://www.kernel.bz/) 내용물들을 만들고 있음.
*((공부해서 남을 주려면 남보다 더많이 연구해야함.))

jsy0906의 이미지

처음엔 이해못했는데 여러번 보면서 그림그리고 하니깐

놓쳤던 부분(커널 코드 처리를 위해 가상 주소에 커널이 매핑되어야 한다던지)을 알게되면서

이해했습니다. 덕분에 많이 알아갑니다^^

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.