@@ -83,56 +83,88 @@ rm *.iso
8383echo " Extracting initrd..."
8484
8585# initrd extraction
86- if [[ " ${EXTRACT_INITRD} " == " true" ]] && [[ " ${INITRD_TYPE} " != " lz4 " ]] ; then
86+ if [[ " ${EXTRACT_INITRD} " == " true" ]]; then
8787 INITRD_ORG=${INITRD_NAME}
88- COUNTER=1
8988 cd /buildout
90- while :
91- do
92- # strip microcode from initrd if it has it
93- LAYERCOUNT=$( cat ${INITRD_NAME} | cpio -tdmv 2>&1 > /dev/null | wc -c)
94- if [[ ${LAYERCOUNT} -lt 5000 ]] && [[ " ${INITRD_TYPE} " != " uncomp" ]]; then
95- # This is a microcode cpio wrapper
96- BLOCKCOUNT=$( cat ${INITRD_NAME} | cpio -tdmv 2>&1 > /dev/null | awk ' END{print $1}' )
97- dd if=${INITRD_NAME} of=${INITRD_NAME}${COUNTER} bs=512 skip=${BLOCKCOUNT}
98- INITRD_NAME=${INITRD_NAME}${COUNTER}
89+
90+ # Try using unmkinitramfs first (handles multi-layer initrds properly)
91+ # Modern distros (Ubuntu, Debian, Clonezilla, etc.) use multi-layer initrds with:
92+ # - early: microcode
93+ # - early2: kernel modules/drivers
94+ # - main: actual initramfs
95+ if command -v unmkinitramfs > /dev/null 2>&1 ; then
96+ echo " Using unmkinitramfs for proper multi-layer extraction..."
97+ mkdir -p initrd_extracted
98+ if unmkinitramfs ${INITRD_NAME} initrd_extracted/ 2> /dev/null; then
99+ mkdir -p initrd_files
100+ # Merge all layers (early, early2, main, etc.) preserving drivers and modules
101+ for layer in initrd_extracted/* /; do
102+ if [ -d " $layer " ]; then
103+ echo " Merging layer: $( basename $layer ) "
104+ rsync -a " $layer " initrd_files/
105+ fi
106+ done
107+ rm -rf initrd_extracted
108+ echo " Successfully extracted multi-layer initrd"
99109 else
100- # this is a compressed archive
101- mkdir initrd_files
102- cd initrd_files
103- # display file type
104- file ../${INITRD_NAME}
105- if [[ " ${INITRD_TYPE} " == " xz" ]] || [[ " ${INITRD_TYPE} " == " arch-xz" ]] ; then
106- cat ../${INITRD_NAME} | xz -d | cpio -i -d
107- elif [[ " ${INITRD_TYPE} " == " zstd" ]]; then
108- cat ../${INITRD_NAME} | zstd -d | cpio -i -d
109- elif [[ " ${INITRD_TYPE} " == " gz" ]]; then
110- zcat ../${INITRD_NAME} | cpio -i -d
111- elif [[ " ${INITRD_TYPE} " == " uncomp" ]]; then
112- cat ../${INITRD_NAME} | cpio -i -d
113- fi
114- break
110+ echo " unmkinitramfs failed, falling back to manual extraction"
111+ EXTRACT_MANUALLY=true
115112 fi
116- COUNTER=$(( COUNTER+ 1 ))
117- done
118- elif [[ " ${EXTRACT_INITRD} " == " true" ]] && [[ " ${INITRD_TYPE} " == " lz4" ]]; then
119- INITRD_ORG=${INITRD_NAME}
120- cd /buildout
121- if [[ " ${LZ4_SINGLE} " == " true" ]]; then
122- BLOCKCOUNT=$( cat ${INITRD_NAME} | cpio -tdmv 2>&1 > /dev/null | awk ' END{print $1}' )
123- dd if=${INITRD_NAME} of=${INITRD_NAME} 1 bs=512 skip=${BLOCKCOUNT}
124- INITRD_NAME=${INITRD_NAME} 1
125113 else
126- # lz4 extraction detection is a clusterfuck here we just assume we drill twice for gold
127- for COUNTER in 1 2; do
128- BLOCKCOUNT=$( cat ${INITRD_NAME} | cpio -tdmv 2>&1 > /dev/null | awk ' END{print $1}' )
129- dd if=${INITRD_NAME} of=${INITRD_NAME}${COUNTER} bs=512 skip=${BLOCKCOUNT}
130- INITRD_NAME=${INITRD_NAME}${COUNTER}
131- done
114+ echo " unmkinitramfs not available, using manual extraction"
115+ EXTRACT_MANUALLY=true
116+ fi
117+
118+ # Fallback: manual extraction for simple single-layer initrds or when unmkinitramfs fails
119+ if [[ " ${EXTRACT_MANUALLY} " == " true" ]]; then
120+ if [[ " ${INITRD_TYPE} " != " lz4" ]]; then
121+ COUNTER=1
122+ while :
123+ do
124+ # strip microcode from initrd if it has it
125+ LAYERCOUNT=$( cat ${INITRD_NAME} | cpio -tdmv 2>&1 > /dev/null | wc -c)
126+ if [[ ${LAYERCOUNT} -lt 5000 ]] && [[ " ${INITRD_TYPE} " != " uncomp" ]]; then
127+ # This is a microcode cpio wrapper
128+ BLOCKCOUNT=$( cat ${INITRD_NAME} | cpio -tdmv 2>&1 > /dev/null | awk ' END{print $1}' )
129+ dd if=${INITRD_NAME} of=${INITRD_NAME}${COUNTER} bs=512 skip=${BLOCKCOUNT} 2> /dev/null
130+ INITRD_NAME=${INITRD_NAME}${COUNTER}
131+ else
132+ # this is a compressed archive
133+ mkdir -p initrd_files
134+ cd initrd_files
135+ # display file type
136+ file ../${INITRD_NAME}
137+ if [[ " ${INITRD_TYPE} " == " xz" ]] || [[ " ${INITRD_TYPE} " == " arch-xz" ]] ; then
138+ cat ../${INITRD_NAME} | xz -d | cpio -i -d
139+ elif [[ " ${INITRD_TYPE} " == " zstd" ]]; then
140+ cat ../${INITRD_NAME} | zstd -d | cpio -i -d
141+ elif [[ " ${INITRD_TYPE} " == " gz" ]]; then
142+ zcat ../${INITRD_NAME} | cpio -i -d
143+ elif [[ " ${INITRD_TYPE} " == " uncomp" ]]; then
144+ cat ../${INITRD_NAME} | cpio -i -d
145+ fi
146+ break
147+ fi
148+ COUNTER=$(( COUNTER+ 1 ))
149+ done
150+ elif [[ " ${INITRD_TYPE} " == " lz4" ]]; then
151+ if [[ " ${LZ4_SINGLE} " == " true" ]]; then
152+ BLOCKCOUNT=$( cat ${INITRD_NAME} | cpio -tdmv 2>&1 > /dev/null | awk ' END{print $1}' )
153+ dd if=${INITRD_NAME} of=${INITRD_NAME} 1 bs=512 skip=${BLOCKCOUNT} 2> /dev/null
154+ INITRD_NAME=${INITRD_NAME} 1
155+ else
156+ # lz4 extraction detection is a clusterfuck here we just assume we drill twice for gold
157+ for COUNTER in 1 2; do
158+ BLOCKCOUNT=$( cat ${INITRD_NAME} | cpio -tdmv 2>&1 > /dev/null | awk ' END{print $1}' )
159+ dd if=${INITRD_NAME} of=${INITRD_NAME}${COUNTER} bs=512 skip=${BLOCKCOUNT} 2> /dev/null
160+ INITRD_NAME=${INITRD_NAME}${COUNTER}
161+ done
162+ fi
163+ mkdir -p initrd_files
164+ cd initrd_files
165+ cat ../${INITRD_NAME} | lz4 -d - | cpio -i -d
166+ fi
132167 fi
133- mkdir initrd_files
134- cd initrd_files
135- cat ../${INITRD_NAME} | lz4 -d - | cpio -i -d
136168fi
137169
138170exit 0
0 commit comments