diff --git a/ci/docker/fedora/patches/0001-media-visl-Fix-params-permissions-defaults-mismatch.patch b/ci/docker/fedora/patches/0001-media-visl-Fix-params-permissions-defaults-mismatch.patch new file mode 100644 index 0000000000..edac2dc5b0 --- /dev/null +++ b/ci/docker/fedora/patches/0001-media-visl-Fix-params-permissions-defaults-mismatch.patch @@ -0,0 +1,31 @@ +From 8bf85c9cc67073be10ba4bf83d0a1875907da9b6 Mon Sep 17 00:00:00 2001 +From: Detlev Casanova +Date: Mon, 2 Oct 2023 14:38:40 -0400 +Subject: [PATCH 1/5] media: visl: Fix params permissions/defaults mismatch + +`false` was used as the keep_bitstream_buffers parameter permissions. +This looks more like a default value for the parameter, so change it to +0 to avoid confusion. + +Reviewed-by: Daniel Almeida +Signed-off-by: Detlev Casanova +--- + drivers/media/test-drivers/visl/visl-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/test-drivers/visl/visl-core.c b/drivers/media/test-drivers/visl/visl-core.c +index 9970dc739ca5..df6515530fbf 100644 +--- a/drivers/media/test-drivers/visl/visl-core.c ++++ b/drivers/media/test-drivers/visl/visl-core.c +@@ -74,7 +74,7 @@ MODULE_PARM_DESC(visl_dprintk_nframes, + " the number of frames to trace with dprintk"); + + bool keep_bitstream_buffers; +-module_param(keep_bitstream_buffers, bool, false); ++module_param(keep_bitstream_buffers, bool, 0); + MODULE_PARM_DESC(keep_bitstream_buffers, + " keep bitstream buffers in debugfs after streaming is stopped"); + +-- +2.41.0 + diff --git a/ci/docker/fedora/patches/0002-media-visl-Add-a-stable_output-parameter.patch b/ci/docker/fedora/patches/0002-media-visl-Add-a-stable_output-parameter.patch new file mode 100644 index 0000000000..1628d2ed38 --- /dev/null +++ b/ci/docker/fedora/patches/0002-media-visl-Add-a-stable_output-parameter.patch @@ -0,0 +1,214 @@ +From f186d19313ffab22b0253a3fc3d569b67ddae859 Mon Sep 17 00:00:00 2001 +From: Detlev Casanova +Date: Mon, 2 Oct 2023 14:35:22 -0400 +Subject: [PATCH 2/5] media: visl: Add a stable_output parameter + +This parameter is used to ensure that for a given input, the output +frames are always identical so that it can be compared against +a reference in automatic tests. + +Reviewed-by: Daniel Almeida +Signed-off-by: Detlev Casanova +--- + drivers/media/test-drivers/visl/visl-core.c | 5 + + drivers/media/test-drivers/visl/visl-dec.c | 125 +++++++++++--------- + drivers/media/test-drivers/visl/visl.h | 1 + + 3 files changed, 77 insertions(+), 54 deletions(-) + +diff --git a/drivers/media/test-drivers/visl/visl-core.c b/drivers/media/test-drivers/visl/visl-core.c +index df6515530fbf..d28d50afec02 100644 +--- a/drivers/media/test-drivers/visl/visl-core.c ++++ b/drivers/media/test-drivers/visl/visl-core.c +@@ -88,6 +88,11 @@ module_param(bitstream_trace_nframes, uint, 0); + MODULE_PARM_DESC(bitstream_trace_nframes, + " the number of frames to dump the bitstream through debugfs"); + ++bool stable_output; ++module_param(stable_output, bool, 0644); ++MODULE_PARM_DESC(stable_output, ++ " only write stable data for a given input on the output frames"); ++ + static const struct visl_ctrl_desc visl_fwht_ctrl_descs[] = { + { + .cfg.id = V4L2_CID_STATELESS_FWHT_PARAMS, +diff --git a/drivers/media/test-drivers/visl/visl-dec.c b/drivers/media/test-drivers/visl/visl-dec.c +index 318d675e5668..61cfca49ead9 100644 +--- a/drivers/media/test-drivers/visl/visl-dec.c ++++ b/drivers/media/test-drivers/visl/visl-dec.c +@@ -197,19 +197,30 @@ static void visl_tpg_fill_sequence(struct visl_ctx *ctx, + { + u32 stream_ms; + +- stream_ms = jiffies_to_msecs(get_jiffies_64() - ctx->capture_streamon_jiffies); +- +- scnprintf(buf, bufsz, +- "stream time: %02d:%02d:%02d:%03d sequence:%u timestamp:%lld field:%s", +- (stream_ms / (60 * 60 * 1000)) % 24, +- (stream_ms / (60 * 1000)) % 60, +- (stream_ms / 1000) % 60, +- stream_ms % 1000, +- run->dst->sequence, +- run->dst->vb2_buf.timestamp, +- (run->dst->field == V4L2_FIELD_ALTERNATE) ? +- (run->dst->field == V4L2_FIELD_TOP ? +- " top" : " bottom") : "none"); ++ if (!stable_output) { ++ stream_ms = jiffies_to_msecs(get_jiffies_64() - ctx->capture_streamon_jiffies); ++ ++ scnprintf(buf, bufsz, ++ "stream time: %02d:%02d:%02d:%03d sequence:%u timestamp:%lld field:%s", ++ (stream_ms / (60 * 60 * 1000)) % 24, ++ (stream_ms / (60 * 1000)) % 60, ++ (stream_ms / 1000) % 60, ++ stream_ms % 1000, ++ run->dst->sequence, ++ run->dst->vb2_buf.timestamp, ++ (run->dst->field == V4L2_FIELD_ALTERNATE) ? ++ (run->dst->field == V4L2_FIELD_TOP ? ++ " top" : " bottom") : "none"); ++ } else { ++ scnprintf(buf, bufsz, ++ "sequence:%u timestamp:%lld field:%s", ++ run->dst->sequence, ++ run->dst->vb2_buf.timestamp, ++ (run->dst->field == V4L2_FIELD_ALTERNATE) ? ++ (run->dst->field == V4L2_FIELD_TOP ? ++ " top" : " bottom") : "none"); ++ ++ } + } + + static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run) +@@ -244,15 +255,17 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run) + frame_dprintk(ctx->dev, run->dst->sequence, ""); + line++; + +- visl_get_ref_frames(ctx, buf, TPG_STR_BUF_SZ, run); ++ if (!stable_output) { ++ visl_get_ref_frames(ctx, buf, TPG_STR_BUF_SZ, run); + +- while ((line_str = strsep(&tmp, "\n")) && strlen(line_str)) { +- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, line_str); +- frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", line_str); +- } ++ while ((line_str = strsep(&tmp, "\n")) && strlen(line_str)) { ++ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, line_str); ++ frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", line_str); ++ } + +- frame_dprintk(ctx->dev, run->dst->sequence, ""); +- line++; ++ frame_dprintk(ctx->dev, run->dst->sequence, ""); ++ line++; ++ } + + scnprintf(buf, + TPG_STR_BUF_SZ, +@@ -280,28 +293,30 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run) + frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); + } + +- line++; +- frame_dprintk(ctx->dev, run->dst->sequence, ""); +- scnprintf(buf, TPG_STR_BUF_SZ, "Output queue status:"); +- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf); +- frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); ++ if (!stable_output) { ++ line++; ++ frame_dprintk(ctx->dev, run->dst->sequence, ""); ++ scnprintf(buf, TPG_STR_BUF_SZ, "Output queue status:"); ++ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf); ++ frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); + +- len = 0; +- for (i = 0; i < out_q->num_buffers; i++) { +- char entry[] = "index: %u, state: %s, request_fd: %d, "; +- u32 old_len = len; +- char *q_status = visl_get_vb2_state(out_q->bufs[i]->state); ++ len = 0; ++ for (i = 0; i < out_q->num_buffers; i++) { ++ char entry[] = "index: %u, state: %s, request_fd: %d, "; ++ u32 old_len = len; ++ char *q_status = visl_get_vb2_state(out_q->bufs[i]->state); + +- len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len, +- entry, i, q_status, +- to_vb2_v4l2_buffer(out_q->bufs[i])->request_fd); ++ len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len, ++ entry, i, q_status, ++ to_vb2_v4l2_buffer(out_q->bufs[i])->request_fd); + +- len += visl_fill_bytesused(to_vb2_v4l2_buffer(out_q->bufs[i]), +- &buf[len], +- TPG_STR_BUF_SZ - len); ++ len += visl_fill_bytesused(to_vb2_v4l2_buffer(out_q->bufs[i]), ++ &buf[len], ++ TPG_STR_BUF_SZ - len); + +- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]); +- frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]); ++ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]); ++ frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]); ++ } + } + + line++; +@@ -333,25 +348,27 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run) + frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); + } + +- line++; +- frame_dprintk(ctx->dev, run->dst->sequence, ""); +- scnprintf(buf, TPG_STR_BUF_SZ, "Capture queue status:"); +- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf); +- frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); ++ if (!stable_output) { ++ line++; ++ frame_dprintk(ctx->dev, run->dst->sequence, ""); ++ scnprintf(buf, TPG_STR_BUF_SZ, "Capture queue status:"); ++ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf); ++ frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); + +- len = 0; +- for (i = 0; i < cap_q->num_buffers; i++) { +- u32 old_len = len; +- char *q_status = visl_get_vb2_state(cap_q->bufs[i]->state); ++ len = 0; ++ for (i = 0; i < cap_q->num_buffers; i++) { ++ u32 old_len = len; ++ char *q_status = visl_get_vb2_state(cap_q->bufs[i]->state); + +- len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len, +- "index: %u, status: %s, timestamp: %llu, is_held: %d", +- cap_q->bufs[i]->index, q_status, +- cap_q->bufs[i]->timestamp, +- to_vb2_v4l2_buffer(cap_q->bufs[i])->is_held); ++ len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len, ++ "index: %u, status: %s, timestamp: %llu, is_held: %d", ++ cap_q->bufs[i]->index, q_status, ++ cap_q->bufs[i]->timestamp, ++ to_vb2_v4l2_buffer(cap_q->bufs[i])->is_held); + +- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]); +- frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]); ++ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]); ++ frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]); ++ } + } + } + +diff --git a/drivers/media/test-drivers/visl/visl.h b/drivers/media/test-drivers/visl/visl.h +index 31639f2e593d..5a81b493f121 100644 +--- a/drivers/media/test-drivers/visl/visl.h ++++ b/drivers/media/test-drivers/visl/visl.h +@@ -85,6 +85,7 @@ extern unsigned int visl_dprintk_nframes; + extern bool keep_bitstream_buffers; + extern int bitstream_trace_frame_start; + extern unsigned int bitstream_trace_nframes; ++extern bool stable_output; + + #define frame_dprintk(dev, current, fmt, arg...) \ + do { \ +-- +2.41.0 + diff --git a/ci/docker/fedora/patches/0003-doc-visl-Document-stable_output-parameter.patch b/ci/docker/fedora/patches/0003-doc-visl-Document-stable_output-parameter.patch new file mode 100644 index 0000000000..6081e8e590 --- /dev/null +++ b/ci/docker/fedora/patches/0003-doc-visl-Document-stable_output-parameter.patch @@ -0,0 +1,29 @@ +From 9f42a31c52b39daa9062046b6f0241a0a41b3512 Mon Sep 17 00:00:00 2001 +From: Detlev Casanova +Date: Mon, 2 Oct 2023 14:35:52 -0400 +Subject: [PATCH 3/5] doc: visl: Document stable_output parameter + +Reviewed-by: Daniel Almeida +Signed-off-by: Detlev Casanova +--- + Documentation/admin-guide/media/visl.rst | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Documentation/admin-guide/media/visl.rst b/Documentation/admin-guide/media/visl.rst +index 7d2dc78341c9..5b26fd943571 100644 +--- a/Documentation/admin-guide/media/visl.rst ++++ b/Documentation/admin-guide/media/visl.rst +@@ -49,6 +49,10 @@ Module parameters + visl_dprintk_frame_start, visl_dprintk_nframes, but controls the dumping of + buffer data through debugfs instead. + ++- stable_output: Limit the information written on each output frame to make ++ sure that, for a given input, the output frames are always exactly the same. ++ This is useful for automated tests to check that output frames are correct. ++ + What is the default use case for this driver? + --------------------------------------------- + +-- +2.41.0 + diff --git a/ci/docker/fedora/patches/0004-visl-Add-a-codec-specific-variability-parameter.patch b/ci/docker/fedora/patches/0004-visl-Add-a-codec-specific-variability-parameter.patch new file mode 100644 index 0000000000..4dd4279705 --- /dev/null +++ b/ci/docker/fedora/patches/0004-visl-Add-a-codec-specific-variability-parameter.patch @@ -0,0 +1,96 @@ +From 79682503a0127df5ca4d5de74a7902e1de73e30e Mon Sep 17 00:00:00 2001 +From: Detlev Casanova +Date: Mon, 23 Oct 2023 10:36:14 -0400 +Subject: [PATCH 4/5] visl: Add a codec specific variability parameter + +When running tests with different input data, the stable output frames +could be too similar and hide possible issues. + +This commit adds variation by using some codec specific parameters. + +Only HEVC and H.264 support this. + +Reviewed-by: Daniel Almeida +Signed-off-by: Detlev Casanova +--- + drivers/media/test-drivers/visl/visl-core.c | 5 ++++ + drivers/media/test-drivers/visl/visl-dec.c | 27 +++++++++++++++++++++ + drivers/media/test-drivers/visl/visl.h | 1 + + 3 files changed, 33 insertions(+) + +diff --git a/drivers/media/test-drivers/visl/visl-core.c b/drivers/media/test-drivers/visl/visl-core.c +index d28d50afec02..e7466f6a91e1 100644 +--- a/drivers/media/test-drivers/visl/visl-core.c ++++ b/drivers/media/test-drivers/visl/visl-core.c +@@ -93,6 +93,11 @@ module_param(stable_output, bool, 0644); + MODULE_PARM_DESC(stable_output, + " only write stable data for a given input on the output frames"); + ++bool codec_variability; ++module_param(codec_variability, bool, 0644); ++MODULE_PARM_DESC(codec_variability, ++ " add codec specific variability data to generate more unique frames. (Only h.264 and hevc)"); ++ + static const struct visl_ctrl_desc visl_fwht_ctrl_descs[] = { + { + .cfg.id = V4L2_CID_STATELESS_FWHT_PARAMS, +diff --git a/drivers/media/test-drivers/visl/visl-dec.c b/drivers/media/test-drivers/visl/visl-dec.c +index 61cfca49ead9..002d5e3b0ea4 100644 +--- a/drivers/media/test-drivers/visl/visl-dec.c ++++ b/drivers/media/test-drivers/visl/visl-dec.c +@@ -223,6 +223,26 @@ static void visl_tpg_fill_sequence(struct visl_ctx *ctx, + } + } + ++static bool visl_tpg_fill_codec_specific(struct visl_ctx *ctx, ++ struct visl_run *run, ++ char buf[], size_t bufsz) ++{ ++ switch (ctx->current_codec) { ++ case VISL_CODEC_H264: ++ scnprintf(buf, bufsz, ++ "H264: %u", run->h264.dpram->pic_order_cnt_lsb); ++ break; ++ case VISL_CODEC_HEVC: ++ scnprintf(buf, bufsz, ++ "HEVC: %d", run->hevc.dpram->pic_order_cnt_val); ++ break; ++ default: ++ return false; ++ } ++ ++ return true; ++} ++ + static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run) + { + u8 *basep[TPG_MAX_PLANES][2]; +@@ -255,6 +275,13 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run) + frame_dprintk(ctx->dev, run->dst->sequence, ""); + line++; + ++ if (codec_variability && visl_tpg_fill_codec_specific(ctx, run, buf, TPG_STR_BUF_SZ)) { ++ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf); ++ frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); ++ frame_dprintk(ctx->dev, run->dst->sequence, ""); ++ line++; ++ } ++ + if (!stable_output) { + visl_get_ref_frames(ctx, buf, TPG_STR_BUF_SZ, run); + +diff --git a/drivers/media/test-drivers/visl/visl.h b/drivers/media/test-drivers/visl/visl.h +index 5a81b493f121..4ac2d1783020 100644 +--- a/drivers/media/test-drivers/visl/visl.h ++++ b/drivers/media/test-drivers/visl/visl.h +@@ -86,6 +86,7 @@ extern bool keep_bitstream_buffers; + extern int bitstream_trace_frame_start; + extern unsigned int bitstream_trace_nframes; + extern bool stable_output; ++extern bool codec_variability; + + #define frame_dprintk(dev, current, fmt, arg...) \ + do { \ +-- +2.41.0 + diff --git a/ci/docker/fedora/patches/0005-doc-visl-Document-codec_variability-parameter.patch b/ci/docker/fedora/patches/0005-doc-visl-Document-codec_variability-parameter.patch new file mode 100644 index 0000000000..59bf2a73be --- /dev/null +++ b/ci/docker/fedora/patches/0005-doc-visl-Document-codec_variability-parameter.patch @@ -0,0 +1,30 @@ +From c563c097286b2183f2d00f8f60ad96b6331d7692 Mon Sep 17 00:00:00 2001 +From: Detlev Casanova +Date: Mon, 23 Oct 2023 10:47:41 -0400 +Subject: [PATCH 5/5] doc: visl: Document codec_variability parameter + +Reviewed-by: Daniel Almeida +Signed-off-by: Detlev Casanova +--- + Documentation/admin-guide/media/visl.rst | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Documentation/admin-guide/media/visl.rst b/Documentation/admin-guide/media/visl.rst +index 5b26fd943571..56d2e9ab72cc 100644 +--- a/Documentation/admin-guide/media/visl.rst ++++ b/Documentation/admin-guide/media/visl.rst +@@ -53,6 +53,11 @@ Module parameters + sure that, for a given input, the output frames are always exactly the same. + This is useful for automated tests to check that output frames are correct. + ++- codec_variability: Add codec specific variability in the ouput frames. It ++ adds a text line on the ouptut frames containing parameters that is specific ++ to the format of the input stream to ensure that different inputs do not give ++ the same output. ++ + What is the default use case for this driver? + --------------------------------------------- + +-- +2.41.0 + diff --git a/ci/docker/fedora/prepare.sh b/ci/docker/fedora/prepare.sh index 038dfc924b..86b9d2c539 100644 --- a/ci/docker/fedora/prepare.sh +++ b/ci/docker/fedora/prepare.sh @@ -289,6 +289,16 @@ git -C /gstreamer submodule update --init --depth=1 meson subprojects download --sourcedir /gstreamer /gstreamer/ci/scripts/handle-subprojects-cache.py --build --cache-dir /subprojects /gstreamer/subprojects/ +# Build a linux image for virtme fluster tests +/gstreamer/ci/scripts/build-linux.sh \ + "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git" \ + "v6.5.8" \ + /opt/linux/bzImage \ + 'MEDIA_SUPPORT' \ + 'MEDIA_TEST_SUPPORT' \ + 'V4L_TEST_DRIVERS' \ + 'CONFIG_VIDEO_VISL' + # Run git gc to prune unwanted refs and reduce the size of the image for i in $(find /subprojects/ -mindepth 1 -maxdepth 1 -type d); do diff --git a/ci/scripts/build-linux.sh b/ci/scripts/build-linux.sh new file mode 100755 index 0000000000..b10a59d6cf --- /dev/null +++ b/ci/scripts/build-linux.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# +# Based on the build-linux.sh script from the Mutter project: +# https://gitlab.gnome.org/GNOME/mutter/-/blob/main/src/tests/kvm/build-linux.sh +# +# Script for building the Linux kernel from git. It aims to build a kernel image +# that is suitable for running in a virtual machine and is aimed to used for +# testing. +# +# Usage: build-linux.sh [REPO-URL] [BRANCH|TAG] [OUTPUT-FILE] [...CONFIGS] +# +# Where [..CONFIGS] can be any number of configuration options, e.g. +# --enable CONFIG_DRM_VKMS +# + +set -e + +# From scripts/subarch.include in linux +function get-subarch() +{ + uname -m | sed -e s/i.86/x86/ \ + -e s/x86_64/x86/ \ + -e s/sun4u/sparc64/ \ + -e s/arm.*/arm/ -e s/sa110/arm/ \ + -e s/s390x/s390/ -e s/parisc64/parisc/ \ + -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ + -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ + -e s/riscv.*/riscv/ +} + +REPO="$1" +BRANCH_OR_TAG="$2" +IMAGE="$3" + +ARCH=$(uname -m) +SUBARCH=$(get-subarch) + +shift +shift +shift + +# ./scripts/config --enable CONFIG_VIDEO_VISL +CONFIGS=() +while [[ "x$1" != "x" ]]; do + CONFIGS+=( "$1" ) + shift +done + +echo Building Linux for $ARCH \($SUBARCH\)... + +set -x + +if [ -d linux ]; then + pushd linux + git fetch --depth=1 $REPO $BRANCH_OR_TAG + git checkout FETCH_HEAD +else + git clone --depth=1 --branch=$BRANCH_OR_TAG $REPO linux + pushd linux +fi + +# Apply visl patches until they are upstreamed +for patch in /gstreamer/ci/docker/fedora/patches/*.patch; do + patch -p1 < "${patch}" +done + +make defconfig +sync +make kvm_guest.config + +echo "Disabling unused features..." +./scripts/config \ + --disable USB \ + --disable SOUND \ + --disable SND \ + --disable NETDEVICES \ + --disable DRM \ + --disable INPUT \ + --disable I2C \ + --disable HID \ + --disable CRYPTO \ + --disable IPV6 + +echo Enabling ${CONFIGS[@]}... +./scripts/config ${CONFIGS[@]/#/--enable } + +make olddefconfig +make -j8 WERROR=0 + +popd + +TARGET_DIR="$(dirname "$IMAGE")" +mkdir -p "$TARGET_DIR" +mv linux/arch/$SUBARCH/boot/bzImage "$IMAGE" +mv linux/.config $TARGET_DIR/.config +rm -rf linux