CPU & OS

EEEFFEE·2023년 12월 1일
0

Linux 환경

목록 보기
7/9

23.12.01 최초 작성

1. 부팅 시나리오

1.1 마이크로 컨트롤러

  • 모든 소프트웨어의 부트로더, 디바이스 트리, OS, root filesystem은 boot flash에 내장됨
  • cpu reset vector가 boot 플래시 안에 내장됨
  • RAM은 마이크로 컨트롤러에 내장됨

1.2 SOC

  • 부트로더는 boot flash에 내장됨

  • cpu reset vector가 boot 플래시 안에 내장됨

  • 디바이스 트리, OS, root filesystem은 mass memory flash에 내장되어있고 bootloader에 의해 메모리에 적재됨

  • 메모리에 OS, root filesystem, 사용자 애플리케이션 등이 적재됨

  • boot flash, mass memory flash, bootloader는 같은 주소체계로 관리되며 각

  • 전원이 인가되면 boot flash의 reset vector(0x0000_0000)가 실행되고 bootloader로 분기 됨

  • CPU의 RAM memory controller 수행

  • Stack과 heap을 RAM에 mapping 하기 위해
    register 값 설정

  • device tree, operating system, system program,
    application 을 RAM 으로 복사

  • 응용을 위한 수행 환경 설정 / 응용 프로그램 시작

2. Device Tree

  • 커널이 하드웨어 자원의 명세(Hardware Description (I/O device, memory))를 확인하는 2가지 방법
    • 커널 바이너리 코드에 하드코딩 하기 :
    • bootloader가 커널 바이너리를 로드할 때 자원 명세 파일(device tree blob)을 가져오는 방법
  • DTB (device tree blob)
    • device tree source을 컴파일(scripts/dtc) 한 결과
    • 하드웨어 변경시 DTS 컴파일만 필요

2.1 Armv8에서 Device Tree

  • arch/arm/boot/dts or arch/arm64/boot/dts에 위치
  • device tree compiler로 DTS를 DTB로 컴파일

2.2 Device Tree 문법

2.2.1 Data Format


/dts-v1/;

/ {
    node1: node@0 {
        a-string-property = "A string";
        a-string-list-property = "first string", "second string";
        // hex is implied in byte arrays. no '0x' prefix is required
        a-byte-data-property = [01 23 34 56];
        child-node1 {
            first-child-property;
            second-child-property = <1>;
            a-string-property = "Hello, world";
            a-reference-to-something = <&node2>;
        };
        child-node2 {
        };
    };
    node2 {
        an-empty-property;
        a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
        child-node1 {
        };
    };
};

  • / : 루트 노드
  • node1, node2 : 자식 노드(노드 라벨)
  • node@0 : 노드 이름
  • child-node1, child-node2 : node1의 자식 노드

  • a-string-property, a-string-list-property : 문자열 정보
  • cell-property = <0xbeef 123 0xabcd1234> : unsigned 32bit 정보
  • binary-property = [0x01 0x23 0x45 0x67] : 이진 데이터
  • mixed-property = "a string", [0x01 0x23 0x45 0x67], <0x12345678> : 여려 형태의 데이터 정보
  • a-byte-data-property : 바이트값 정보
  • a-reference-to-something = <&node2> : 다른 노드의 주소 정보

2.2.2 Device Tree Addressing

  • 다음과 같은 스펙의 기기의 디바이스 트리
- One 32bit ARM CPU
- processor local bus attached to memory mapped serial port, spi bus controller, i2c controller, interrupt controller, and external bus bridge
256MB of SDRAM based at 0
- 2 Serial ports based at 0x101F1000 and 0x101F2000
- GPIO controller based at 0x101F3000
- SPI controller based at 0x10170000 with following devices
	- MMC slot with SS pin attached to GPIO #1
- External bus bridge with following devices
	- SMC SMC91111 Ethernet device attached to external bus based at 0x10100000
	- i2c controller based at 0x10160000 with following devices
	- Maxim DS1338 real time clock. Responds to slave address 1101000 (0x58)
	- 64MB of NOR flash based at 0x30000000

1. 초기 구조

  • compatible : 시스템 이름 정보 (제조업체, 모델)
    운영체제가 이 값을 통해 작동 방법을 지정
    (디바이스 드라이버를 부팅시 or 사용 시 초기화할지 결정)

/dts-v1/;

/ {
    compatible = "acme,coyotes-revenge";
};

2. cpu

  • cpus : cpu 모델 지정 (제조업체, 모델)
  • cpu@0 : cpu 노드 이름과 장치의 주소(구분을 위함, 실제 주소는 reg로 지정)

/dts-v1/;

/ {
    compatible = "acme,coyotes-revenge";

    cpus {
        cpu@0 {
            compatible = "arm,cortex-a9";
        };
        cpu@1 {
            compatible = "arm,cortex-a9";
        };
    };
};

3. cpu addressing

  • cell : 주소나 길이를 나타내는 값 (32bit)
  • #address-cells : 시작주소를 나타내는데 필요한 셀 갯수
  • #size-cells : 할당받은 영역을 나타내는데 필요한 셀 갯수
32 bit64 bit
#address-cells12
#size-cells12
  • reg = <address1 length 1 [address2 length2]...> : 노드에 할당된 시작주소, 길이

  • #address-cells, #size-cells는 부모노드에서 정의되어 자식노드 reg의 데이터에 대한 규칙 지정

  • cpu는 유일한 ID를 가지기 때문에 #size-cells = <0>;으로 지정


cpus {
    #address-cells = <1>;
    #size-cells = <0>;
    cpu@0 {
        compatible = "arm,cortex-a9";
        reg = <0>;
    };
    cpu@1 {
        compatible = "arm,cortex-a9";
        reg = <1>;
    };
};

4. device

  • compatible = "samsung,k8f1315ebm", "cfi-flash"; : 플래시 노드의 경우 해당 장치와 호환되는 다른 장치를 나타냄

/dts-v1/;

/ {
    compatible = "acme,coyotes-revenge";

    cpus {
        cpu@0 {
            compatible = "arm,cortex-a9";
        };
        cpu@1 {
            compatible = "arm,cortex-a9";
        };
    };

    serial@101F0000 {
        compatible = "arm,pl011";
    };

    serial@101F2000 {
        compatible = "arm,pl011";
    };

    gpio@101F3000 {
        compatible = "arm,pl061";
    };

    interrupt-controller@10140000 {
        compatible = "arm,pl190";
    };

    spi@10115000 {
        compatible = "arm,pl022";
    };

    external-bus {
        ethernet@0,0 {
            compatible = "smc,smc91c111";
        };

        i2c@1,0 {
            compatible = "acme,a1234-i2c-bus";
            rtc@58 {
                compatible = "maxim,ds1338";
            };
        };

        flash@2,0 {
            compatible = "samsung,k8f1315ebm", "cfi-flash";
        };
    };
};

5. 메모리에 매핑된 장치

  • reg = <0x101f0000 0x1000 > : 메모리 상의 장치의 시작 주소와 할당받은 크기를 나타냄

/dts-v1/;

/ {
    #address-cells = <1>;
    #size-cells = <1>;

    ...

    serial@101f0000 {
        compatible = "arm,pl011";
        reg = <0x101f0000 0x1000 >;
    };

    serial@101f2000 {
        compatible = "arm,pl011";
        reg = <0x101f2000 0x1000 >;
    };

    gpio@101f3000 {
        compatible = "arm,pl061";
        reg = <0x101f3000 0x1000
               0x101f4000 0x0010>;
    };

    interrupt-controller@10140000 {
        compatible = "arm,pl190";
        reg = <0x10140000 0x1000 >;
    };

    spi@10115000 {
        compatible = "arm,pl022";
        reg = <0x10115000 0x1000 >;
    };

    ...

};

6. Chip select가 있는 외부 장치

  • #address-cells = <2> : 주소를 2개 사용
    (chip select number, chip select base에서 offset)

external-bus {
    #address-cells = <2>;
    #size-cells = <1>;

    ethernet@0,0 {
        compatible = "smc,smc91c111";
        reg = <0 0 0x1000>;
    };

    i2c@1,0 {
        compatible = "acme,a1234-i2c-bus";
        reg = <1 0 0x1000>;
        rtc@58 {
            compatible = "maxim,ds1338";
        };
    };

    flash@2,0 {
        compatible = "samsung,k8f1315ebm", "cfi-flash";
        reg = <2 0 0x4000000>;
    };
};

7. 비 메모리 매핑 장치

  • 주소 범위를 가질 수 있으나 cpu에서 직접 접근 불가능
  • 장치 드라이버를 통해 접근 가능

i2c@1,0 {
    compatible = "acme,a1234-i2c-bus";
    #address-cells = <1>;
    #size-cells = <0>;
    reg = <1 0 0x1000>;
    rtc@58 {
        compatible = "maxim,ds1338";
        reg = <58>;
    };
};

8. 주소 변환

  • 루트의 직계 자식 노드는 cpu의 주소 체계를 사용하므로 명시적인 매핑이 필요하지 않음

  • 그렇지 않은 노드는 cpu의 주소 체계를 사용하지 않으므로 메모리 매핑된 주소를 얻으러면 주소를 변환해 줘야 함

  • range : 직계 자식 노드의 주소를 cpu체계에 맞게 변환해주는 방법 지정

  • range = <자식주소1 부모주소1 자식주소크기1, ...> : 자식의 주소를 cpu체계에 맞는 부모주소로 변환

  • 0 0 0x10100000 0x10000 : chip select 0의 오프셋 0은 주소 범위 0x10100000 ~ 0x1010ffff에 매핑


/dts-v1/;

/ {
    compatible = "acme,coyotes-revenge";
    #address-cells = <1>;
    #size-cells = <1>;
    ...
    external-bus {
        #address-cells = <2>
        #size-cells = <1>;
        ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet
        		//0 0 : 자식주소 정보 ~~
                  1 0  0x10160000   0x10000     // Chipselect 2, i2c controller
                  2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash

        ethernet@0,0 {
            compatible = "smc,smc91c111";
            reg = <0 0 0x1000>;
        };

        i2c@1,0 {
            compatible = "acme,a1234-i2c-bus";
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <1 0 0x1000>;
            rtc@58 {
                compatible = "maxim,ds1338";
                reg = <58>;
            };
        };

        flash@2,0 {
            compatible = "samsung,k8f1315ebm", "cfi-flash";
            reg = <2 0 0x4000000>;
        };
    };
};

9. 인터럽트

  • interrupt-controller : 인터럽트 신호를 수신하는 장치로 노드를 선언하는 빈 속성. 해당 장치가 인터럽트 신호를 수신하는 장치임을 나타냄.
  • #interrupt-cells : 인터럽트에 대한 정보를 속성값으로 표현할때  사용될 셀 갯수
  • interrupt-parent : 연결된 인터럽트 컨트롤러에 대한 디바이스 노드의 속성. 해당 값이 없는 노드는 부모 노드로 부터 상속받을 수 있음.
  • interrupts : interrupts  속성은 디바이스가 발생하는 인터럽트 출력 신호에 대한 정보의 리스트를 값으로 표현

/dts-v1/;

/ {
    compatible = "acme,coyotes-revenge";
    #address-cells = <1>;
    #size-cells = <1>;
    interrupt-parent = <&intc>;

    cpus {
        #address-cells = <1>;
        #size-cells = <0>;
        cpu@0 {
            compatible = "arm,cortex-a9";
            reg = <0>;
        };
        cpu@1 {
            compatible = "arm,cortex-a9";
            reg = <1>;
        };
    };

    serial@101f0000 {
        compatible = "arm,pl011";
        reg = <0x101f0000 0x1000 >;
        interrupts = < 1 0 >;
    };

    serial@101f2000 {
        compatible = "arm,pl011";
        reg = <0x101f2000 0x1000 >;
        interrupts = < 2 0 >;
    };

    gpio@101f3000 {
        compatible = "arm,pl061";
        reg = <0x101f3000 0x1000
               0x101f4000 0x0010>;
        interrupts = < 3 0 >;
    };

    intc: interrupt-controller@10140000 {
        compatible = "arm,pl190";
        reg = <0x10140000 0x1000 >;
        interrupt-controller;
        #interrupt-cells = <2>;
    };

    spi@10115000 {
        compatible = "arm,pl022";
        reg = <0x10115000 0x1000 >;
        interrupts = < 4 0 >;
    };

    external-bus {
        #address-cells = <2>
        #size-cells = <1>;
        ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet
                  1 0  0x10160000   0x10000     // Chipselect 2, i2c controller
                  2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash

        ethernet@0,0 {
            compatible = "smc,smc91c111";
            reg = <0 0 0x1000>;
            interrupts = < 5 2 >;
        };

        i2c@1,0 {
            compatible = "acme,a1234-i2c-bus";
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <1 0 0x1000>;
            interrupts = < 6 2 >;
            rtc@58 {
                compatible = "maxim,ds1338";
                reg = <58>;
                interrupts = < 7 3 >;
            };
        };

        flash@2,0 {
            compatible = "samsung,k8f1315ebm", "cfi-flash";
            reg = <2 0 0x4000000>;
        };
    };
};

10. 특수 노드

  • aliases : 노드에 별칭 지정
  • chosen : boot time에 kernel에 넘길 인자를 정의하는 노드. 실제 장치를 나타내지 않지만 부팅 인수와 같이 펌웨어와 운영 체제간에 데이터를 전달하는 장소 역할.

aliases {
    ethernet0 = &eth0;
    serial0 = &serial0;
};

chosen {
    bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
};

0개의 댓글

관련 채용 정보