rootfs 없이 커널 부팅(FIT 이미지)

rootfs 없이 커널 부팅(FIT 이미지)

내가 사용하고 있는 임베디드 Linux 장치에는 다음과 같은 커널 매개변수가 있습니다.

root=/dev/ram0

또한 커널 이미지는 initrd 및 장치 트리와 함께 번들로 제공되어평면 이미지 트리, 또는맞다영상.

전체 부팅 후에는 장치에 영구 저장소가 없습니다. 즉, 파일 시스템에 기록된 모든 내용은 완전히 불안정합니다. root=커널에 전달된 매개변수를 고려하면 이는 놀라운 일이 아닙니다.

내 질문은: 이것이 어떻게 작동하나요?

  • Uboot가 커널을 RAM에 복사하고 명령을 사용하여 실행한다는 것을 알고 있지만 bootm파일 시스템 파일은 어디에서 왔습니까? initrd에 포함되어 있습니까? initrd에 대한 나의 이해는 그것이 임시 구조라는 것입니다. 그렇다면 FIT 이미지 blob의 오프셋이 됩니다. 그렇다면 root=/dev/ram0커널이 파일 시스템의 위치를 ​​알 수 있을 만큼만 전달하는 방법은 무엇일까요?

  • 커널은 내부 검사를 수행하고 FIT 이미지의 헤더를 읽어 구성 요소의 위치를 ​​결정합니까?

  • FIT 이미지가 커널 및 장치 트리 Blob과 함께 패키지된다는 점을 고려할 때 파일 시스템 변경은 어떻게 지원됩니까?

답변1

Uboot가 커널을 RAM에 복사하고 bootm 명령을 사용하여 실행한다는 것을 알고 있지만 파일 시스템 파일은 어디에서 왔습니까?

fitImage를 시작하기 전에 RAM에 로드해야 합니다. 그런 다음 를 사용하여 시작할 수 있습니다 bootm. 예를 들어, 이미지를 피팅할 때 Load Address커널에 대한 합계를 정의할 수 있습니다.Entry Point

initrd에 포함되어 있습니까? initrd에 대한 나의 이해는 그것이 임시 구조라는 것입니다. 그렇다면 FIT 이미지 blob의 오프셋이 됩니다. 그렇다면 커널이 파일 시스템의 위치를 ​​알 수 있도록 root=/dev/ram0을 전달하는 것만으로도 충분합니까?

파일 시스템의 정의는 시스템에 따라 다릅니다. RAMDISK에서 완전히 실행되고 구성을 모든 유형으로만 저장하는 일부 시스템이 있습니다.NVRAM아니면 플래시.

다른 시스템에서는 RAMDisk를 사용하여 루트 파일 시스템을 찾을 수 있는 위치를 확인합니다. 예를 들어 USB 버스, SATA 또는 SD 카드를 스캔합니다. 루트 파일 시스템이 마운트되면 해당 파티션에서 부팅 프로세스가 계속됩니다. init는 PID 1에서 실행되어야 하기 때문입니다. 일부기술이 필요합니다.

커널은 내부 검사를 수행하고 FIT 이미지의 헤더를 읽어 구성 요소의 위치를 ​​결정합니까?

아니요, fitImage는 u-boot로 구문 분석됩니다. u-boot가 DTB 및 RAMDISK가 있는 주소를 전달하는 방법은 사용되는 AFAIK 플랫폼에 따라 다릅니다.

FIT 이미지가 커널 및 장치 트리 Blob과 함께 패키지된다는 점을 고려할 때 파일 시스템 변경은 어떻게 지원됩니까?

파일 시스템을 정기적으로 변경해야 하는 경우 보다 유연한 시스템 사용을 고려해야 합니다. 그러나 이는 사용하는 하드웨어에 따라 다릅니다. SD 카드, NAND, NOR 또는 회전 디스크.

답변2

커널 소스 코드 보기:

  • mtdsplit_fit.c

        /* Search for the rootfs partition after the FIT image */
        ret = mtd_find_rootfs_from(mtd, fit_offset + fit_size, mtd->size,
                                   &rootfs_offset, NULL);
        if (ret) {
                pr_info("no rootfs found after FIT image in \"%s\"\n",
                        mtd->name);
                return ret;
        }
    
  • mtdsplit.c:

    int mtd_find_rootfs_from(struct mtd_info *mtd,
                             size_t from,
                             size_t limit,
                             size_t *ret_offset,
                             enum mtdsplit_part_type *type)
    {
            size_t offset;
            int err;
    
            for (offset = from; offset < limit;
                 offset = mtd_next_eb(mtd, offset)) {
                    err = mtd_check_rootfs_magic(mtd, offset, type);
                    if (err)
                            continue;
    
                    *ret_offset = offset;
                    return 0;
            }
    
            return -ENODEV;
    }
    EXPORT_SYMBOL_GPL(mtd_find_rootfs_from);
    
    
    
    int mtd_check_rootfs_magic(struct mtd_info *mtd, size_t offset,
                               enum mtdsplit_part_type *type)
    {
            u32 magic;
            size_t retlen;
            int ret;
    
            ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
                           (unsigned char *) &magic);
            if (ret)
                    return ret;
    
            if (retlen != sizeof(magic))
                    return -EIO;
    
            if (le32_to_cpu(magic) == SQUASHFS_MAGIC) {
                    if (type)
                            *type = MTDSPLIT_PART_TYPE_SQUASHFS;
                    return 0;
            } else if (magic == 0x19852003) {
                    if (type)
                            *type = MTDSPLIT_PART_TYPE_JFFS2;
                    return 0;
            } else if (be32_to_cpu(magic) == UBI_EC_MAGIC) {
                    if (type)
                            *type = MTDSPLIT_PART_TYPE_UBI;
                    return 0;
            }
    
            return -EINVAL;
    }
    EXPORT_SYMBOL_GPL(mtd_check_rootfs_magic);
    

관련 정보