rootfsなしのカーネルブート(FITイメージ)

rootfsなしのカーネルブート(FITイメージ)

私が使用している組み込みLinuxデバイスには、次のカーネルパラメータがあります。

root=/dev/ram0

さらに、カーネルイメージはinitrdとデバイスツリーと共にバンドルされていますフラット画像ツリーまたは正しいビデオ。

フルブート後、デバイスに永続ストレージはありません。つまり、ファイルシステムに書き込まれたすべての内容は完全に不安定です。root=カーネルに渡されたパラメータを考慮すると、これは驚くべきことではありません。

私の質問は:これはどのように機能しますか?

  • UbootはカーネルをRAMにコピーし、コマンドを使用して実行することを知っていますが、bootmファイルシステムファイルはどこから来ましたか? initrdに含まれていますか? initrdの私の理解は、それが一時的な構造であるということです。そうであれば、FITイメージブロブのオフセットになります。それでは、root=/dev/ram0カーネルがファイルシステムの場所を知ることができるだけに渡す方法は何ですか?

  • カーネルは内部チェックを実行し、FITイメージのヘッダーを読み取ってコンポーネントの位置を決定しますか?

  • FIT イメージがカーネルとデバイスツリー Blob でパッケージ化されていることを考慮すると、ファイルシステムの変更はどのようにサポートされますか?

答え1

UbootはカーネルをRAMにコピーし、bootmコマンドを使用して実行することを知っていますが、ファイルシステムファイルはどこから来ましたか?

fitImageを起動する前にRAMにロードする必要があります。その後、を使用して起動できますbootm。たとえば、イメージをフィットするときにLoad Addressカーネルの合計を定義できます。Entry Point

initrdに含まれていますか? initrdの私の理解は、それが一時的な構造であるということです。そうであれば、FITイメージブロブのオフセットになります。もしそうなら、カーネルがファイルシステムの場所を知ることができるように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);
    

関連情報