request_standard_resources()

2 개의 루트 리소스에 관련 표준 리소스를 등록한다.

  • 전역 iomem_resource에 System RAM을 등록하고 커널 코드와 커널 데이터 영역이 System RAM 영역에 포함되는 경우 System RAM의 child 리소스로 추가한다.
    • XIP 커널의 경우 커널 커드는 ROM에 포함되므로 System RAM의 child 리소스로 추가되지 않는다.
  • 전역 ioport_resource에는 lp0~lp2가 머신에 등록되어 있는 경우 리소스로 추가한다.

 

request_standard_resources-1

 

request_standard_resources()

arch/arm/kernel/setup.c

static void __init request_standard_resources(const struct machine_desc *mdesc)
{
        struct memblock_region *region;
        struct resource *res;

        kernel_code.start   = virt_to_phys(_text);
        kernel_code.end     = virt_to_phys(_etext - 1);
        kernel_data.start   = virt_to_phys(_sdata);
        kernel_data.end     = virt_to_phys(_end - 1);

        for_each_memblock(memory, region) {
                res = memblock_virt_alloc(sizeof(*res), 0);
                res->name  = "System RAM";
                res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
                res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; 
                res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;

                request_resource(&iomem_resource, res);

                if (kernel_code.start >= res->start &&
                    kernel_code.end <= res->end)
                        request_resource(res, &kernel_code);
                if (kernel_data.start >= res->start &&
                    kernel_data.end <= res->end)
                        request_resource(res, &kernel_data);
        }

        if (mdesc->video_start) {
                video_ram.start = mdesc->video_start;
                video_ram.end   = mdesc->video_end;
                request_resource(&iomem_resource, &video_ram);
        }

        /*
         * Some machines don't have the possibility of ever
         * possessing lp0, lp1 or lp2
         */
        if (mdesc->reserve_lp0)
                request_resource(&ioport_resource, &lp0);
        if (mdesc->reserve_lp1)
                request_resource(&ioport_resource, &lp1);
        if (mdesc->reserve_lp2)
                request_resource(&ioport_resource, &lp2);
}
  • 커널 코드와 커널 데이터 물리 주소를 구한다.
  • for_each_memblock(memory, region) {
    • memory memblock의 각 영역을 루프를 돈다.
  •  res = memblock_virt_alloc(sizeof(*res), 0);
    • 구조체 배열 resource의 사이즈 만큼 memblock 할당을 받는다.
  •  res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
    • 리소스 시작에 memblock의 시작 주소를 기록한다.
  • res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) – 1;
    • 리소스 끝에 memblock의 끝 주소를 기록한다.
  • request_resource(&iomem_resource, res);
    • 전역 iomem_resource에 System RAM 영역(memblock 영역)에 대한 리소스를 등록한다.
  • if (kernel_code.start >= res->start && kernel_code.end <= res->end) request_resource(res, &kernel_code);
    • 커널 코드영역이 System RAM 영역에 포함된 경우 커널 코드 영역을 System RAM의 child로 추가한다.
  • if (kernel_data.start >= res->start && kernel_data.end <= res->end) request_resource(res, &kernel_data);
    • 커널 데이터영역이 System RAM 영역에 포함된 경우 커널 데이터 영역을 System RAM의 child로 추가한다.
  • if (mdesc->video_start) {
    • 머신에 비디오 정보가 있는 경우
  • request_resource(&iomem_resource, &video_ram);
    • 전역 iomem_resource에 비디오 램 리소스 정보를 추가한다.
  • if (mdesc->reserve_lp0) request_resource(&ioport_resource, &lp0);
    • 머신에 reserve_lp0 정보가 있는 경우 전역 ioport_resource에 lp0 리소스를 추가한다.
    • 또한 머신에 lp1과 lp2 정보가 있는 경우 역시 전역 ioport_resource에 lp1, lp2 정보를 추가한다.

아래 그림은 루트 리소스 iomem_resource에 등록된 System RAM, Video RAM 등을 보여준다. System RAM 내부  Kernel code와 Kernel data도 존재한다. 만일 XIP 커널이라면 Kernel code는 존재하지 않을 것이다.

request_standard_resources-2a

아래 그림은 루트 리소스 ioport_resource에 등록된 lp0~lp2 리소스 등을 보여준다.

request_standard_resources-3a

 

Standard Resource

kernel/resource.c

struct resource ioport_resource = {
        .name   = "PCI IO",
        .start  = 0,
        .end    = IO_SPACE_LIMIT,
        .flags  = IORESOURCE_IO,
};
EXPORT_SYMBOL(ioport_resource);

struct resource iomem_resource = {
        .name   = "PCI mem",
        .start  = 0,
        .end    = -1,
        .flags  = IORESOURCE_MEM,
};
EXPORT_SYMBOL(iomem_resource);
  • ioport_resource와 iomem_resource 루트 리소스이다.

 

arch/arm/kernel/setup.c

/*
 * Standard memory resources
 */
static struct resource mem_res[] = {
        {
                .name = "Video RAM",
                .start = 0,
                .end = 0,
                .flags = IORESOURCE_MEM
        },
        {
                .name = "Kernel code",
                .start = 0,
                .end = 0,
                .flags = IORESOURCE_MEM
        },
        {
                .name = "Kernel data",
                .start = 0,
                .end = 0,
                .flags = IORESOURCE_MEM
        }
};

#define video_ram   mem_res[0]
#define kernel_code mem_res[1]
#define kernel_data mem_res[2]
  • 루트 리소스 iomem_resource에 등록될 Video RAM, Kernel code, Kernel data 리소스의 초기데이터이다.

 

arch/arm/kernel/setup.c

static struct resource io_res[] = {
        {
                .name = "reserved",
                .start = 0x3bc,
                .end = 0x3be,
                .flags = IORESOURCE_IO | IORESOURCE_BUSY
        },
        {
                .name = "reserved",
                .start = 0x378,
                .end = 0x37f,
                .flags = IORESOURCE_IO | IORESOURCE_BUSY
        },
        {
                .name = "reserved",
                .start = 0x278,
                .end = 0x27f,
                .flags = IORESOURCE_IO | IORESOURCE_BUSY
        }
};

#define lp0 io_res[0]
#define lp1 io_res[1]
#define lp2 io_res[2]
  • 루트 리소스 ioport_resource 루트 리소스에 등록될 lp0~lp2 리소스의 초기데이터이다.

 

참고

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.