반도체 소프트웨어

코멘토 실무PT 후기 챌린지_"반도체 SW 엔지니어를 위한 새로운 SoC 위에 리눅스 디바이스 드라이버 포팅하기" 강의 1주 차 후기 본문

교육/코멘토 직무PT

코멘토 실무PT 후기 챌린지_"반도체 SW 엔지니어를 위한 새로운 SoC 위에 리눅스 디바이스 드라이버 포팅하기" 강의 1주 차 후기

반도체 소프트웨어 엔지니어 2024. 1. 12. 05:32

<학습 소감>

강의와 관련된 내용을 다른 책에서 일부 공부해본 경험이 있어 본 실무PT를 편안하게 수강할 수 있을 거라고 생각했었지만, 깊은 기술적 이론도 다뤄서 첫 주차만에 많은 것을 깨닫게 되었다. 또한, 혼자서 과제를 진행할 때 많은 오류가 발생해서 이를 해결하는데 시간을 많이 들었다. 가벼운 인강 정도 수준일 것이라 생각했던 오만함에 반성하게 되었고 앞으로 겸손한 자세로 예습 및 복습을 해야겠다. 결론적으로는 깊고 실무적인 내용을 학습할 수 있어서 대만족이다.

 

<실습중>

QEMU소스 및 디바이스 트리 빌드
빌드된 커널 이미지와 initramfs를 QEMU에서 부팅

 

<이번 주 수업 내용 리뷰>

[2024/01/10(수) 20:00]

  1. SoC 개발이 왜 필요한가: 팹리스 위에서 동작하는 리눅스 실무
    • ip: 지식재산, 모듈
    • 어차피 h/w와 s/w가 동시에 개발되기에 에뮬레이터를 사용하여 지속적으로 sw를 개발해야함
    • 새로운 장치를 만들면 그에 맞는 디바이스 드라이버 개발 필요
  2. 강의에서 사용하는 이미지: qemu(h/w), 커널, 빌드루트(rootfs)
    • 빌드루트
      • external toolchain 설정 하면 컴파일이 빠름
      • cpio the root filesystem 설정해야 initramfs사용가능
      • llvm쓰면 gcc와 달리 툴체인 변수 옵션 추가 없이 쉽게 컴파일할 수 있어서 좋음
  3. SoC 구조
    • 리눅스가 부팅되기 위한 최소한의 조합
      • 리눅스는 거의 제일 먼저 타이머 디바이스를 초기화함
      • 시분할 스케줄링을 위해 타이머를 먼저 초기화 (리눅스에는 무조건 타이머가 필요함)
  4. 소스코드 해석
    • COMENTO라는 SoC
    • 나도 qemu 헤더파일은 잘 모름
    • type_init()이 먼저 실행됨
    • 그후로 machine_class_init() 같은 초기화 코드가 실행됨
      • 이것들은 그냥 다른 코드를 복붙해온거임, 이걸 외우거나 할 것은 아님
    • mc->minimum_page_bits = 12:
      • mmu: 물리주소와 가상주소를 매핑해주는 모듈
      • 12bit라는게 4kbyte로 페이지 할당하는 걸 말함 2^12
    • 빨간색줄은 메모리 초기화하는 것
    • get_systm_memory: 시스템 메모리 할당
    • memory_region_Add_subregion: mmio 관련 개념
      • 모듈들(gic, ram, uart 등)을 다모아서 매모리맵형태로 만드는 것
      • 하드웨어 제조사가 정의해주는 것
      • COMENTO_BASE_MEM이 해당 정의임
      • bootinfo.loader_start: 부트로더 적재 주소
    • 부트로더: 시스템 초기화 + 커널을 RAM에 적재하는 소프트웨어
      • 강의에서는 QEMU에서 겸하고 있음
  5. 메모리맵
    • 요즘은 다 64bit 사용함
    • qemu는 meson.build라는 빌드시스템을 사용함
    • 결론적으로 qemu 하드웨어 초기화소스는 하드웨어 부서에서 fpga등으로 만든것을 qemu 오픈소스 에뮬레이터를 사용해서 구현하는 것임
      • 그러니 이거는 깊게 다룰 부분은 아니고 너가 필요하면 나중에 책같은거 찾아서 더 해보기

[2024/01/10(수) 21:00]

  1. 개요
    • Ip: 칩을 설계하기 위한 building block
    • cpu 아키텍처가 다르다는 것은 어셈블리어나 레지스터 구성 등이 다른 것
    • ip(하드웨어, 블록)을 사와서 SoC를 구성하는 것임(cpu를 만들순 없으니)
    • cortex-R,M는 저전력, 저용량 프로세서여서 리눅스가 포팅되지 않음
  2. CPU 아키텍처
    • NUMA: CPU마다 메모리를 가져서 사용하는 것, 속도 좀 느림
    • SMP: CPU들이 하나의 메모리를 공유, 속도 빠름
      • 동시적 메모리 접근으로 충돌이 발생하기도 함(COHERENCY)
    • PSCI: CPU를 제어하기 위한 인터페이스(이걸로 CPU 전원ON/OFF 가능, 이걸로 CPU 전원 관리함, 이거 없을때는 일일이 구현했어야함, 디바이스트리로 선언하면 쉽게 사용 가능)
      • 리눅스가 모든 CPU들을 초기화시킴
      • HVC, SMC(Trustzone의 monitor 모드에서 구현해놓은 사항임, 커널조차 맘대로 제어하면 안되기에 더 깊은 레벨에서 처리하는 것)
  3. 소스코드 해석
    • 새 cpu 추가
      • smp_cpus: cpu 개수만큼 초기화 반복(실행시에 -smp 옵션으로 선언함)
      • CBAR은 시스템 레지스터임 -> 사실상 CPU초기화 어셈블리 코드를 API화 했다고 보면 됨
    • 인터럽트
      • 인터럽트: 물리적인 핀에 전압이 감지되면 발생 -> 디바이스(인터럽트핸들러)에서 인터럽트 처리후 핀 상태를 low로 만드는 것임
      • 인터럽트 초기화안되어있으면 리눅스 실행도 제대로 안됨
      • 종류
        1. 페리페럴에서 오는 인터럽터는 spi
        2. cpu안에도 timer가 있음(cpu내 timer가 생성하는 인터럽트 종류는 ppi)
        3. GIC에 SPI, PPI, SGI로 나뉜 이유는 하드웨어 회로 등을 간단히 하기 위해서가 한가지 이유
      • gic를 시스템 메모리에 매핑(메모리맵 I/O)
  4. CPU 타이머
    • 타이머: 시분할 스케줄링을 구현하기 위해 가장 필수가 되는 디바이스
    • 타이머 디바이스가 없으면 리눅스가 부팅되지 않음(프로세스를 실행시킬수없어서)
    • 하이퍼바이저, 트러스트존에서 스케줄링을 위한 타이머들도 있지만, 강의에서는 커널모드용 타이머 디바이스를 주로 사용함

[2024/01/10(수) 22:00]

  1. 디바이스트리
    • 리눅스포팅을 위해 필요한 기초적인 메타데이터
    • 현재 soc 디바이스에 대한 정보를 트리 형태로 적어놓은 데이터
    • ARM이 최초로 cpu를 ip방식으로 팔았음(실제 하드웨어를 파는게 아니라) 그래서 다양한 soc가 나온거고 그래서 디바이스트리가 도입이된거임!!, 그전에는 인텔이 결과물만 팔았음
    • qemu에서는 virt 머신 사용해서 자동 디바이스 트리 만들긴함
    • Kconfig가 커널 컨피그(커널에 새로운 디바이스 트리 추가할때 사용했음)
      • config의 관리 파일
    • cell은 "<2>" 부분을 말함, 한 개당 32bit 숫자를 의미
      • "#size-cells = <2> : <0x0000 0x8000>" 이렇게 64bit사용한다는 의미임
    • 디바이스트리 문법은 어느정도 알면좋지만 실제적으로 실무 코드에서 복붙해오는 경우가 많은듯
    • gic에서 reg 내용은 다른 것들과 달리 시작주소, 크기로 구성되어짐(커널에 메뉴얼이 다 있음)
    • interrupts = <GIC_PPI 0 IRQ_TYPE_LEVEL_HIGH> ==> 다 의미가 있음
  2. UART
    1. UART를 추가해야 검은화면이 아닌 시리얼로 데이터 받을 수 있음
    2. 터미널창을 시리얼통신을 기반으로 출력하는거임
    3. 통신 모드 분류
      • 시리얼: 한 핀으로 모든 데이터 비트를 다 보냄. 1/0을 사용하는 거임
        • 각 데이터를 분리하기 위해, 이 타이밍을 분리하기 위해 CLOCK을 사용
        • 송신과 수신측이 동일한 타이밍을 유지하기 위한 신호가 필요한 것
      • 페러럴: 보내는 데이터 비트마다 핀이 있음, 즉 병렬로 보냄
    4. soc에서 부팅한 리눅스에서 명령어를 사용하기 위해 UART를 이용
    5. USART는 클럭신호를 한 선으로 다 처리함
    6.  시스템버스: AMBA, CPU와 메모리 등이 통신하는 버스
    7. UART도 AMBA사용하기에 초기화하는 코드가 QEMU에 포함됨
      • pl011도 arm ip임
      • 고객사에게 메모리맵도 보내야되는거구나
    8. 디바이스트리를 넣어야 장치들을 읽고 부팅이 진행되는 구만
    9. 루트파일시스템이 없으면 init 프로그램을 읽을 수 없으므로 에러를 발생시킴
    10. sd장치 초기화를 안해서 아직 mmc 사용 불가능하므로 대체적으로 initramfs를 임시 루트파일시스템으로 사용함
      • 즉 initramfs에 저장된 /sbin/init을 읽은 후 저장매체에 맞게 파일시스템 마운트
  3. Initramfs를 지원하도록 linux build시에 menuconfig로 설정해줘야함!!

 

링크: https://bit.ly/3D9XCOz