[[완료]]kernel 안에서 physical memory 를 읽을 수 있나요?

choboja의 이미지

안녕하세요?
application 에서는 memory mapped된 내용을
아래의 코드로 잘 읽어오는데요.

#include <stdio.h>
#include <fcntl.h>
//#include <stdlib.h>
int main ()
{
        char buf[20];
        int  file;
 
        file = open("/dev/mem",O_RDWR);
        if (file < 0)
        {
                perror("open failed");
                exit(1);
        }
        lseek(file, 655360L, SEEK_SET);
        read( file, buf, 1);
        printf("My device return the value %d\n", buf[0]);
 
        close(file);
        return 0;
}

이런식으로 physical memory의 데이터를 읽어오는데,
kernel에서는 이걸 어떻게 읽어야 하나요?
우선 커널에서는 위의 함수들이 사용이 안되네요.

2가지 질문이 있습니다.

1. 위와 같은 함수를 사용할려면 어떤 header를 include하고 사용해야 되는지요?

2. kernel내에서는 위와 같은 번거러움없이 바로 액세스할 수 있는 방법이 있을꺼 같은데,
어떤식으로 접근을 해야되는지 궁금합니다.

여러가지 시도해보고 있는데 성공을 못하고 있네요.
답변 부탁드릴께요.

bushi의 이미지

iomap() 과 그 형제자매들이 있습니다.
http://lxr.linux.no 에서 찾아보세요.

OTL

choboja의 이미지

음.. 조금 더 힌트를 얻을 수 있을까요? ㅡㅡ;

bushi의 이미지

죄송합니다. 다시보니 틀리게 썼습니다.
ioremap() 과 그 형제자매들입니다.

OTL

choboja의 이미지


ioremap() 이라는 매핑을 시키니 잘 읽히네요. 감사합니다.

ioremap() 이라는 함수를 알아보니

"물리 주소는 offset에, 크기는 size 매개변수에 지정하는데, size는 MMU가 PAGE_SIZE단위로 관리되기 때문에 반드시 PAGE_SIZE의 배수여야 한다. 물리주소가 가상주소로 성공적으로 매핑되면 가상주소의 선두주소가 반환되고 실패하면 NULL이 반환된다."

즉. 실제 물리 주소를 커널에서 사용되는 가상주소로 매핑시켜서 사용하는 것 같은데,
그럼 데이터를 읽을때 다시 가상 주소에서 물리 주소로 변환을 거쳐서 읽게 되는 것인데,

혹시 이런 방법없이 커널에서 바로 물리 주소를 읽을 수 있나요?
포인터에 해당 물리 주소번지를 할당하고 실행을 하니 에러가 나네요.
혹시 방법이 있나요?

bushi의 이미지

없습니다.

OTL

choboja의 이미지


그럼 커널 역시 물리 메모리를 가상 메모리로 매핑을 해야 사용할 수 있네요.

그렇다면 커널은 모든 메모리 영역을 가상 메모리 주소로 다루는 것으로 이해하면 되겠네요?

barrios의 이미지

커널 또한 모든 메모리 접근을 가상주소로 하게됩니다.
어떤 것을 하려고 그렇게 하시는지 모르겠지만 접근하시는
주소가 low address라면(즉, high memory공간이 아니라면)
phys_to_virt 함수를 사용하여 물리주소에 해당하는 가상주소를
얻어 포인터 연산을 통해 접근하면 안되는 것인가요?

choboja의 이미지

할려는 것은 low address ( 0xa0000) 정도에 device를 mapping 시키고 매핑된 영역의 값을 리눅스 커널에서 읽을려고 하는 것입니다.
근데 barrios님이 말씀하신 phys_to_virt()라는 함수를 사용해 보진 않았지만
ioremap() 함수와 동일한 듯합니다.

ioremap()함수도 해당 물리 메모리를 가상 메모리로 매핑시키고 그 포인터를 이용하여 연산을 하네요.

혹 다른 장점이 있거나 잘못된 부분이 있다면 알려주세요.

barrios의 이미지

phys_to_virt는 단순합니다. pte가 매핑되어 있다는 가정하에
단순 변환을 하는 것이고요. ioremap은 원하는 물리주소를
임의의 가장수조에 매핑시켜 원하는 물리주소 접근을 허락하게 됩니다.
님의 경우, device mapping을 하여 사용하려고 하신다면 ioremap을
사용하시는 것이 좋은 방법입니다. 하지만 ioremap을 사용하여 mapping
하신다면 원하는 low address 0xa0000에는 매핑되지 않을 것입니다.

choboja의 이미지

제가 지금 full simulator에서 디바이스를 모델링하고 메모리에 매핑한것이라 그런지,
0xa0000으로 매핑을 해도 잘 읽히네요.
아마 시뮬레이터에서 physical memory의 공간 중 0xa0000 ~ 0x100000까지가 비어있어서 해당 부분에 매핑을 할 수 있게 되어 있어서 그런것 같네요.

리얼 시스템에서는 ioremap을 사용시 low address에는 매핑이 안되는가보네요?

barrios의 이미지

말씀하신 0xa0000이 physical memory 주소였군요?
그렇다면 가능합니다. 전 특정 물리 메모리 주소를 가상 주소
0xa0000에 매핑하려고 한다는 말씀으로 이해를 했었네요.
제가 오해를 했네요 ^^;

ioremap을 사용할 경우 매핑되는 가상주소는 VMALLOC area에서
할당하게 됩니다. 그러므로 일반적으로 low address를 할당받을 수 없게 됩니다.

choboja의 이미지


나머지 질문에서 궁금한 점은 스스로 찾아서 공부해보겠습니다.
답변 감사드리고, 즐거운 하루 되세요.

댓글 달기

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