메모리 매니지먼트가 헷갈립니다.

sephiron의 이미지

1. 인텔 CPU매뉴얼에서 말하는 태스크나 프로그램이 운영체제에서 말하는 프로세스랑 대응하는 개념인가요? 즉

Quote:

"Any task or program running on an IA-32 processor can address a linear address space of up to 4 GBytes (2^32 bytes) and a physical address space of up to 64 GBytes (2^36 bytes)"

에서 task or program을 process로 바꿀 수 있는지요.

2. Protected mode에서 각각의 프로그램이 각각의 linear address를 접근하는 방법으로 서로 다른 메모리 모델(플랫, 세그먼티드) 을 가질 수 있다고 하는데요.

main() {}

을 컴파일 하고 gdb로
(gdb) b main
(gdb) r
(gdb) disassemble

하면

Quote:
0x8048364 <main>: push %ebp
0x8048365 <main+1>: mov %esp,%ebp
0x8048367 <main+3>: sub $0x8,%esp
0x804836a <main+6>: and $0xfffffff0,%esp

....
이 되는 데 여기서 "0x804836a"는 linear address가 되는 것인가요?

3. 위에서

Quote:
(gdb) x/10i 0x8048000
하면

Quote:
0x8048000: jg 0x8048047
0x8048002: dec %esp
0x8048003: inc %esi
...

되지만

Quote:
(gdb) x/10i 0x8047999
하면

Quote:
0x8047999: Cannot access memory at address

가 나옵니다.

이럴 때, 0x8048000 부터 코드 세그먼트의 시작이 되는 건가요?

0x8047999 보다 작은 주소는 아직 세그먼티드 되지 않아서 세그먼테이션 폴트가 되는 건가요?

3. 2번이랑 비슷한 질문인 것 같은데
smack the stack 같은 문서들을 보면 C프로그램은

Quote:
0x0000
------------------
Text
------------------
Data
------------------
Heap
------------------
Stack
------------------
0xFFFF

의 구조를 갖는다고 하는데 0x0000(0000)부터 0xFFFF(FFFF)까지가 linear address space를 나타내는 것인가요?
Text, Data 등은 각각 GDT에 Segment descriptor를 갖는 별도의 세그먼트가 맞나요?

제가 알고싶은 것을 자세히 표현해야 어디서 개념이 틀렸는지 아실 것 같아 길게 적습니다.

dbdan의 이미지

sephiron wrote:
1. 인텔 CPU매뉴얼에서 말하는 태스크나 프로그램이 운영체제에서 말하는 프로세스랑 대응하는 개념인가요? 즉
Quote:

"Any task or program running on an IA-32 processor can address a linear address space of up to 4 GBytes (2^32 bytes) and a physical address space of up to 64 GBytes (2^36 bytes)"

에서 task or program을 process로 바꿀 수 있는지요.

task나 program은 process보다는 thread와 비슷하지 않나요?

dbdan의 이미지

sephiron wrote:
2. Protected mode에서 각각의 프로그램이 각각의 linear address를 접근하는 방법으로 서로 다른 메모리 모델(플랫, 세그먼티드) 을 가질 수 있다고 하는데요.
main() {}

을 컴파일 하고 gdb로
(gdb) b main
(gdb) r
(gdb) disassemble

하면

Quote:
0x8048364 <main>: push %ebp
0x8048365 <main+1>: mov %esp,%ebp
0x8048367 <main+3>: sub $0x8,%esp
0x804836a <main+6>: and $0xfffffff0,%esp

....
이 되는 데 여기서 "0x804836a"는 linear address가 되는 것인가요?

그런 것 같습니다.
dbdan의 이미지

sephiron wrote:
3. 위에서
Quote:
(gdb) x/10i 0x8048000
하면

Quote:
0x8048000: jg 0x8048047
0x8048002: dec %esp
0x8048003: inc %esi
...

되지만

Quote:
(gdb) x/10i 0x8047999
하면

Quote:
0x8047999: Cannot access memory at address

가 나옵니다.

이럴 때, 0x8048000 부터 코드 세그먼트의 시작이 되는 건가요?

0x8047999 보다 작은 주소는 아직 세그먼티드 되지 않아서 세그먼테이션 폴트가 되는 건가요?

실행파일의 코드 세그먼트의 시작이지 않나요?

0x8047999 보다 작은 주소는 페이지 매핑되지 않아서
페이지 폴트가 되는 것 같은데요?

dbdan의 이미지

sephiron wrote:
3. 2번이랑 비슷한 질문인 것 같은데
smack the stack 같은 문서들을 보면 C프로그램은

Quote:
0x0000
------------------
Text
------------------
Data
------------------
Heap
------------------
Stack
------------------
0xFFFF

의 구조를 갖는다고 하는데 0x0000(0000)부터 0xFFFF(FFFF)까지가 linear address space를 나타내는 것인가요?
Text, Data 등은 각각 GDT에 Segment descriptor를 갖는 별도의 세그먼트가 맞나요?

제가 알고싶은 것을 자세히 표현해야 어디서 개념이 틀렸는지 아실 것 같아 길게 적습니다.


0x0000(0000)부터 0xFFFF(FFFF)까지가 linear address space를 나타내는 것이 아니라 프로그램 실행시 메모리 배치가 처런 형태를 띄는 것으로 생각합니다.
Text, Data 등은 실행 파일내에서 메모리 사용을 구분하는 것을 나타낸다고 생각합니다. 실행 파일은 여러 세그먼트를 가지지만 이 것은 x86 메모리 관리에서의 세그먼트와는 전혀 다른것으로 생각합니다.
sephiron의 이미지

페이징 메카니즘은 프로그램 입장에서는 전혀 관여할 바가 안되는 것 아닌가요? 프로그램은 linear address space 까지만 참조할 수 있고 피지컬 메모리는 CPU와 운영체제가 알아서 매핑해주는 것이 아닌가요?

즉 메모리 주소 0x8047999에 있는 값을 읽고 싶다고 지정만 해주면 세그먼트 디스크립터에 등록되어 있는 세그먼트에 한하여 디스크에 스와핑이 되어있어도 자동으로 메모리로 불러 읽어 주는 것이 아닌가요?

제가 무슨 문서를 읽어야 개념을 찾을 수 있을 지도 조언해 주시면 감사하겠습니다.

sephiron의 이미지

Quote:
실행 파일은 여러 세그먼트를 가지지만 이 것은 x86 메모리 관리에서의 세그먼트와는 전혀 다른것으로 생각합니다

이 설명이 중요한 것 같은데요. 위의 Text 세그먼트(세그먼트가 아닌가요?)를 접근하기 위해서 Logical address를 사용하여 세그먼트 셀렉터+오프셋=>GDT의 Base address+오프셋의 변환과정을 거치는 것이 아닌가요?

dbdan의 이미지

sephiron wrote:
페이징 메카니즘은 프로그램 입장에서는 전혀 관여할 바가 안되는 것 아닌가요? 프로그램은 linear address space 까지만 참조할 수 있고 피지컬 메모리는 CPU와 운영체제가 알아서 매핑해주는 것이 아닌가요?

즉 메모리 주소 0x8047999에 있는 값을 읽고 싶다고 지정만 해주면 세그먼트 디스크립터에 등록되어 있는 세그먼트에 한하여 디스크에 스와핑이 되어있어도 자동으로 메모리로 불러 읽어 주는 것이 아닌가요?

제가 무슨 문서를 읽어야 개념을 찾을 수 있을 지도 조언해 주시면 감사하겠습니다.


페이징은 프로그램 입장에서도 매우 중요합니다.
프로그램에서 쓸 부분만 페이지 매핑시키고
나머지는 없는 페이지로 표시하고
"없는 페이지"로 메모리 접근을 해버리면
페이징 폴트가 나고 잘못된 메모리 접근이 있었다는 것을
운영체제의 커널이 바로 알 수 있게 되니까요.
http://www.intel.com/design/pentium4/manuals/index_new.htm#sdm_vol3
dbdan의 이미지

sephiron wrote:
Quote:
실행 파일은 여러 세그먼트를 가지지만 이 것은 x86 메모리 관리에서의 세그먼트와는 전혀 다른것으로 생각합니다

이 설명이 중요한 것 같은데요. 위의 Text 세그먼트(세그먼트가 아닌가요?)를 접근하기 위해서 Logical address를 사용하여 세그먼트 셀렉터+오프셋=>GDT의 Base address+오프셋의 변환과정을 거치는 것이 아닌가요?


아닙니다. 실행파일에서의 세그먼트는
다른 이름으로는 섹션이라고 부릅니다.
메모리의 용도에 따라 실행 파일을
논리적으로 구분지어 놓은 것입니다.
리눅스에서는 2개의 세그먼트만 이용하기 때문에
보통 실행 파일에서의 주소가 세그먼트의
offset이 된다고 생각하시면 됩니다.
dbdan의 이미지

님께서는 x86 보호모드에 대한 정보가 많이 부족하신듯 합니다.

http://www.intel.com/design/pentium4/manuals/index_new.htm#sdm_vol3
Volume 3: System Programming Guide
와 "리눅스 커널의 이해"라는 책과
오재준님이 쓰신 "고급개발자들만이 알고 있던 OS제작의 원리 그리고 CODES"를 읽어 보시면 제가 말씀드리는 것을 모두 이해하실 수 있습니다.

sephiron의 이미지

마지막으로 한 가지만 질문드리고 권해주신 문서를 다시 한 번 읽어보아야 겠습니다.

Quote:
리눅스에서는 2개의 세그먼트만 이용하기 때문에
보통 실행 파일에서의 주소가 세그먼트의
offset이 된다고 생각하시면 됩니다.

리눅스에서 2개의 세그먼트(코드)는 무엇무엇인가요? 커널, 프로세스?

0x804836a 등등이 linear address라고 하셨는데 이게 오프셋이라는 말씀은 아니겠고 실행파일의 주소라 함은 EAX등에 집어넣어 jmp등으로 사용할 수 있는 주소를 말씀하시나요?

sephiron의 이미지

dbdan wrote:
님께서는 x86 보호모드에 대한 정보가 많이 부족하신듯 합니다.

http://www.intel.com/design/pentium4/manuals/index_new.htm#sdm_vol3
Volume 3: System Programming Guide
와 "리눅스 커널의 이해"라는 책과
오재준님이 쓰신 "고급개발자들만이 알고 있던 OS제작의 원리 그리고 CODES"를 읽어 보시면 제가 말씀드리는 것을 모두 이해하실 수 있습니다.

제가 컴공 전공이 아니고 필요한 부분만 배우려고 욕심을 부리다 보니 여러가지로 민폐를 끼치는 군요. 도움에 감사드립니다.

dbdan의 이미지

sephiron wrote:
마지막으로 한 가지만 질문드리고 권해주신 문서를 다시 한 번 읽어보아야 겠습니다.

Quote:
리눅스에서는 2개의 세그먼트만 이용하기 때문에
보통 실행 파일에서의 주소가 세그먼트의
offset이 된다고 생각하시면 됩니다.

리눅스에서 2개의 세그먼트(코드)는 무엇무엇인가요? 커널, 프로세스?

0x804836a 등등이 linear address라고 하셨는데 이게 오프셋이라는 말씀은 아니겠고 실행파일의 주소라 함은 EAX등에 집어넣어 jmp등으로 사용할 수 있는 주소를 말씀하시나요?

리눅스에서는 Instruction에 관계되는 code 세그먼트와
Heap, stack 등의 메모리 접근에 관계되는 data 세그먼트
2개를 각각 커널 모드와 유저 모드를 위해 사용합니다.(2*2 == 4)

실행 파일은 그 자체로 가상 주소 공간에 올려져서 사용될 수 있지만, 주소 재배치라는 과정이 필요합니다. 예를 들어 실행 파일의 주소가 0x400000을 기준으로 정해져 있는데 실행 파일이 가상 주소 0x10000000에 올라져 있다면 실행 파일의 모든 주소는 잘못된 접근을 유발하게 되므로 0x400000을 기준한 주소에 (0x10000000 - 0x400000)을 더해서 적절한 주소가 되도록 해줍니다.

리눅스에서 세그먼트는 0x0부터 시작해서 0xffffffff까지 모든 메모리 영역을 잡고 있습니다. 따라서 재배치된 실행 파일에서의 주소는 세그먼트의 오프셋이 되고 세그먼트가 0x0부터 시작함으로 가상주소도 됩니다.

sephiron의 이미지

많은 것을 배우고 갑니다.

익명 사용자의 이미지

태스크라고 칭하는 주된 이유 중 하나는 특정 운영체제들이 프로세스를 기반하고, 또다른 운영체제들은 쓰레드를 기반으로 합니다.
하드웨어를 만드는 사람입장에서 쓰레드, 프로세스를 칭하게 되면, 상위에 대한 제약만을 걸게 되겠지요.
그래서, 보통 저수준 설계를 할때는 그냥 태스크라는 말을 사용합니다.
태스크를 프로세스랑 비교하거나, 쓰레드랑 비교하는 것은 마음이지만, 대체로는 그냥 작업 단위라고 보시는게 맞고, 쓰레드에 익숙한 사람이라면 쓰레드같은 것이겠거니... 또는 프로세스 같은 것이겠거니,.. 하면 대충 맞습니다.

댓글 달기

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