Kernel 영역과 User 영역의 메모리 공간에 대해서..?

withpiano의 이미지

안녕하십니까, 디바이스 드라이버를 공부하고 있는 학생입니다.

책에 나와 있기로는

1. 커널상의 공간과, 사용자 영역의 공간 영역의 주소가
다르기 때문에, system call을 사용하여
주소의 값을 복사해 와야 한다고 나와 있던데..

꼭 그렇게 해야 하는지 알고 싶습니다.

hello.c라는 소스를 다음과 같이 만든다면..

char test_buffer[1000] = { 'a', 'b', 'c', ........ };

funcion()....

이 .c파일을 .o로 컴파일 한후에 모듈에 삽입했다고 하죠.

그러면 char test_buffer[1000]에 있는 캐릭터의 값이
커널 영역에 존재하게 되고, 이 것을 사용자 영역의
char *buffer 로 옮기고자 할때 단순히

strcpy(buffer, test_buffer);

하면 되지 않나요?

주소 영역이 다르다는 것이 잘 이해가 되지 않습니다.

커널 입장에서 보면, 변수들이 어디에 생겼는지 모를리가 없을 것 같은데요.. ( 순전히 제 생각인지.. )

2. 그리고, 어떤 소스에서 보니 다음과 같이 정의된 변수가
코드에 삽입이 되어 있었는데, 어떤 것들이
다음과 같이 define이 된 건지 궁금합니다.

O_ACCMODE, O_WRONLY,O_RDWR 

3. 마지막으로, read() 함수를 통해 char *buffer
로 들어온 값들을 실제 파일로 저장이 가능한지 알고 싶네요

sisbn의 이미지

주소 영역 개념을 이해하시려면, 일단 님이 데탑환경에서 만들
구 계시죠? 글면 intel 386 cpu 메뉴얼을 통해서
cpu의 세그멘테이션, 그리고 페이징부분에 대한 이해부터 하시고, 인터럽트가 발생할때 어떠한 동작등을 하는지에 대한 이해를 하셔야 제대로 이해를 하실 수 있을 것입니다.
리눅스 커널의 이해 책을 같이 보시면서요.

참고로, 유저 프로그램과 커널 프로그램간에는 주소영역이 다른것이 아니라, 같은 주소영역안에 있지만 접근 권한이 문제인것이구 주소영역이 다른경운, 서로 다른 프로세스들간에 서로 다른 주소공간을 갖는다구 할 수 있죠.

mach의 이미지

1) priviledge level에 대해 공부하세요.
-일반)보호모드란 무엇인가? 왜 보호모드가 필요한가?
-일반)메모리 보호 메카니즘이 없다면 무슨 문제가 있을까?
- 일반)왜 모든 자원은 커널을 통해서만 관리되어야 하는가?
-일반)유닉스/리눅스가 커널과 인터페이싱을 위해 시스템호출 (system call)이라는 유일한 창구를 만든 이유는 무엇인가?
-고수준) 만일 사용자 프로그램들이 커널 메모리를 마음대로 액세스가능하다면, 이때 발생가능한 문제점과 장점은 무엇이 있을까? 또한 반대로 커널이 사용자 메모리영역을 직접 액세스한다면 이때 장단점은?
이런 문제를 먼저 운영체제 기초를 통해 배우세요.
2) fcntl.h 를 보세요.
/usr/include/asm/fcntl.h
커널소스라면, include/asm-플랫폼(아마, i386일듯) 밑에 fcntl.h참조
3) 제대로 만들어진 read()시스템 호출로 사용자 영역에 읽어들였다면, 당연히 이를 파일로 저장가능하지요.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

익명 사용자의 이미지

우선 1번에 대한 답변을 하자면 (아직 배우는 학생으로써)
분명히 모듈을 적재하게 되면 커널 영역에서 동작하게 됩니다.

따라서, 만드신 hello.c 소스 코드 내에서 소스들은 커널 스레드일 것입니다.
그런데 여기서 커널 스레드는 커널 모드에서만 동작하기 때문에 0xc0000000
이하의 선형 주소 공간에는 직접적인 접근을 할 수 없습니다.

왜냐하면, 일반적으로 프로세스가 생성한 동적메모리영역은
각각의 프로세스 디스크립터가 가지고 있는 메모리 디스크립터에서
관리 되고 있습니다.

여기서 또 하나 모든 프로세스의 선형 주소 공간의 0xc0000000이상의
주소공간은 커널영역입니다.

그런데 모든 프로세스는 똑 같은 내용의 커널영역을 가지고 있습니다.

그럼 커널에서 동작하고 있는 커널스레드가 커널내의 내용을 사용자영역으로
복사하려고 할 때 어느 프로세스로 복사를 해야 할까요?

[ 검증 부탁드립니다. ]

익명 사용자의 이미지

4 /* open/fcntl - O_SYNC is only implemented on blocks devices and on files
5 located on an ext2 file system */
6 #define O_ACCMODE 0003
7 #define O_RDONLY 00
8 #define O_WRONLY 01
9 #define O_RDWR 02
10 #define O_CREAT 0100 /* not fcntl */
11 #define O_EXCL 0200 /* not fcntl */
12 #define O_NOCTTY 0400 /* not fcntl */
13 #define O_TRUNC 01000 /* not fcntl */
14 #define O_APPEND 02000
15 #define O_NONBLOCK 04000
16 #define O_NDELAY O_NONBLOCK
17 #define O_SYNC 010000
18 #define FASYNC 020000 /* fcntl, for BSD compatibility */
19 #define O_DIRECT 040000 /* direct disk access hint */
20 #define O_LARGEFILE 0100000
21 #define O_DIRECTORY 0200000 /* must be a directory */
22 #define O_NOFOLLOW 0400000 /* don't follow links */

출처 : http://lxr.linux.no/source/include/asm-i386/fcntl.h?v=2.4.18#L6

kkojiband의 이미지

system call 을 통해서 커널 모드로 진입한 경우에는 유저 영역의 주소가 유효합니다. 이 때는 요청한 프로세스의 메모리 공간에서 커널 모드가 동작하므로 당연히 주소에 대한 접근이 가능하겠죠...일반적인 책에선 이걸 흔히 process context 라고 부르죠...
그리고 interrupt context 는 interrupt 발생에 의해 커널 모드로 진입했을 경우를 얘기하는데, 이 때는 유저 영역의 주소가 어느 곳을 나타내고 있는지 알수없습니다. 당연히 interrupt 발생시 실행 중이던 process 가 어느 것일지는 예측할수없으므로 유저 영역의 주소에 직접 접근한다는건 심각한 오류를 발생시킵니다...

모듈로 드라이버를 등록하면, 사용되는 함수를 크게 두 가지로 read(), write() 와 같은 system call 과 interrupt handler 로 나눌수 있는데, 방금 위에서 설명드린 내용과 마찬가지고 read(), write() 에서는 유저 공간의 주소를 사용할 수 있고, interrupt handler 에서는 절대 사용하면 안 됩니다...

그럼...이만...

이제 졸업이다...사랑하는 SKKULUG 후배들아 안녕~

익명 사용자의 이미지

=====================================
3. 마지막으로, read() 함수를 통해 char *buffer
로 들어온 값들을 실제 파일로 저장이 가능한지 알고 싶네요
=====================================

리눅스에서는 보통 read()함수를 시스템 콜이라고 하죠?
사실 read()는 Application(사용자프로그램)에서 동작하는
라이버러리 함수입니다.

1번에서 물어보셨듯이 read(fd, buf, sizeof(buf), 0)
라고 하셨을 때 함수 내부에서는 여러가지 작업을 하죠

read() -> 소프트인터럽트() |<유저영역||커널영역>| sys_read() -> xxx_read()

결국은 read를 하게 되면 커널에 있는 소스코드, 즉 커널함수 sys_read()를
호출하게 되고 fd에 따라 major 번호를 알아낸 다음에 장치별로 그에 맞는
xxx_read()를 실행하게 됩니다.

xxx_read()를 어떻게 만드느냐에 따라 작업을 한 다음에
(보통 copy_to_user()함수를 이용해서 사용자영역으로 복사작업을 함)
리턴하게되면
read에서 넘겼던 매개변수 buf에 데이타가 들어가게 됩니다.
그럼 read()함수 다음 라인에서 이 buf내용을 저장하는 루틴을 사용하면
됩니다.

[검증 부탁드립니다.]

댓글 달기

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