Debian11_手工制作deb安装包_过程和例子_dpkg-gencontrol
转载注明来源: 本文链接 来自osnosn的博客,写于 2023-08-10.
参考
- 官方文档【4.Source packages】,【5.Control files and their fields】
- 【linux下deb包的管理及制作 | 一次成功】
- 【linux下制作deb的方法总结】
需求
- 想给 armbian 系统更换/升级内核。
内核包括 image,kmod 和 headers,文件很多,需要放置在不同的系统目录中。 - 但网上找到别人编译好的内核,是 tar.gz 的压缩包。
安装过程麻烦。解压后,要copy到指定位置。时间久了,就忘了copy到哪里了。
不方便安装,不方便卸载。 - 想把这些文件,打包成一个 deb 安装包。 用 "dpkg -i" 安装,用 "dpkg -r" 卸载。就方便多了。
制作 deb 包
- 按照参考中的帖子,制作 deb 包,似乎是不难。
无非就是两步。- 准备 deb 包内的文件目录。
- 创建"控制文件",即 "DEBIAN/" 目录。
碰到的问题
- "控制文件",最重要的就是 "control" 文件。
网上的教程都是让你手工自己创建,手工自己填内容。 - 但是,里头有个 "Installed-Size:" 就不知道怎么填了。网上的各种教程都回避了这个问题。
- 搜到一个帖子,【如何正确设置deb包的安装大小?】提到,如果设置不正确,安装时会报错。
尝试用 "du -s" 命令计算目录的大小,又不正确。
里头有个回复,说,应该用 dpkg-gencontrol 命令生成,它会自动计算 Installed-Size 。
这个帖子也提到【How to properly set installed-size for deb package】。 - 邮件列表中,2011年有提出【dpkg-gencontrol should use du --apparent-size】,
测试du --apparent-size -ks deb目录
,结果也不对,不过很接近了。
查看 【dpkg-gencontrol 的 perl 源码】,发现是用 perl循环自己加出来的结果。
所以,还是老老实实用 dpkg-gencontrol 生成 "Installed-Size:" 吧。 - 几经折腾,终于搞明白。
dpkg-gencontrol 需要两个关键的配置文件,"debian/changelog" 和 "debian/control" 。 - 而这两个配置文件,格式还挺复杂。
changelog 第一行的名称,要和 control 第一行的 "Source:" 匹配。 - 参考官方文档,【本贴的前面】。在当前目录上,建立了这两个文件。
这时候,执行 dpkg-gencontrol 命令,就不报错了,能给deb目录生成控制文件了。 - 跨架构: 如果你在 amd64 架构的 debian下,用 dpkg-gencontrol 生成 arm64 架构的 control文件。还是会报错。
解决办法是,在命令前,用一个环境变量指定cpu架构。
DEB_HOST_ARCH=arm64 dpkg-gencontrol -P...
- 至此,制作 deb 就没什么障碍了。
- 至于,想在 control 结果文件中,填写什么项目。
可以找一个现成的 deb 包,用dpkg -e xxxx.deb
把它的控制文件解出来。
照着别人的内容,慢慢调整自己的输出。 - "控制文件" 调整满意后。
用dpkg-deb -b ...
打包自己的 deb 即可。
如果是非 root 身份打包,按需加上--root-owner-group
参数 (如果希望所有文件/目录的 owner 是 root)。 - 备注:
dpkg-deb
命令,在apt install dpkg
中。
dpkg-gencontrol
命令,在apt install dpkg-dev
中。
最终写了个脚本
以下是完整的例子
- 此例子是为了【Armbian_N1_笔记--试试别人的内核】帖子而做的。
- 去 【ophub/kernel_dev】下载 "5.15.125.tar.gz",约 89MB。
- 脚本没有获取命令行参数。内核版本号,写在脚本的第二行,需要的时候,手工修改一下 "version=" 即可。
脚本执行后,会在当前目录创建几个目录,
"debian/", "img_root/", "head_root/", "5.15.125/"(解压 tar.gz 创建的目录)。
最后生成两个 deb 文件。脚本执行结束后,上述的 4 个目录就没用了,可以删除。 - 这个脚本,创建"文件目录"部分,参考了 ophub 内核升级脚本 【armbian-update】 "update_kernel()" 函数的安装步骤。
#!/bin/bash version=5.15.125 # export DEB_HOST_ARCH=arm64 #如果机器的cpu架构,不是arm64,则取消这行的注释 #为了给N1更换kernel,但ophub的kernel是以tar.gz发布,需要打包为 deb文件,方便安装。 #=== 解压tar.gz压缩包 === tar zxf "${version}.tar.gz" -C ./ kernel_boot="$(basename $(ls ${version}/boot-${inputs_kernel}*.tar.gz 2>/dev/null | head -n 1))" kernel_name="${kernel_boot:5:-7}" #=== 创建 源码包控制文件,Source package control files === mkdir -p debian cat <<EOF > debian/changelog linux-image-and-headers-amlogic-s905d-osn (0.1) focal; urgency=low * Custom built Linux kernel. -- System Administrator <root@localhost.localdomain> Fri, 15 Aug 2023 10:20:30 -0000 EOF cat <<EOF > debian/control Source: linux-image-and-headers-amlogic-s905d-osn Maintainer: System Administrator osn <root@localhost.localdomain> Package: linux-image-${kernel_name}-amlogic-s905d-osn Architecture: arm64 Section: kernel Priority: optional Homepage: https://www.kernel.org/ Description: Linux kernel, version ${kernel_name}-amlogic-s905d-osn This package contains the Linux kernel, modules and corresponding other files. Package: linux-headers-${kernel_name}-amlogic-s905d-osn Architecture: arm64 Section: kernel Priority: optional Homepage: https://www.kernel.org/ Description: Linux kernel headers for ${kernel_name}-amlogic-s905d-osn on arm64 This package provides kernel header files for ${kernel_name}-amlogic-s905d-osn on arm64. This is useful for people who need to build external modules EOF #==============image.deb========= IMAGE_ROOT=img_root mkdir -p "${IMAGE_ROOT}" # --- boot --- boot_dir=${IMAGE_ROOT}/boot mkdir -p "${boot_dir}" tar zxf "${version}/boot-${kernel_name}.tar.gz" -C ${boot_dir} #mv ${boot_dir}/uInitrd-${kernel_name} ${boot_dir}/bak.uInitrd-${kernel_name} #备份原来的uInitrd #cp ${boot_dir}/vmlinuz-${kernel_name} ${boot_dir}/zImage rm -f ${boot_dir}/{uInitrd*,initrd.img*} #去掉没用的文件 # --- dtb --- dtb_dir=${boot_dir}/dtb-${kernel_name}/ mkdir -p "${dtb_dir}" tar zxf "${version}/dtb-amlogic-${kernel_name}.tar.gz" -C ${dtb_dir} ls ${dtb_dir}/* | grep -v s905d |xargs rm -- #去掉非s905d的dtb文件 # --- kmod --- kmod_dir=${IMAGE_ROOT}/usr/lib/modules mkdir -p "${kmod_dir}" tar zxf "${version}/modules-${kernel_name}.tar.gz" -C ${kmod_dir} rm -f ${kmod_dir}/${kernel_name}/{build,source} #去掉两个链接,放到headers中去 # --- DEBIAN 控制文件和脚本 --- mkdir -p "${IMAGE_ROOT}/DEBIAN" touch ${IMAGE_ROOT}/DEBIAN/md5sums cat <<EOF > ${IMAGE_ROOT}/DEBIAN/postinst #!/bin/sh set -e # Pass maintainer script parameters to hook scripts export DEB_MAINT_PARAMS="\$*" # Tell initramfs builder whether it's wanted export INITRD=Yes test -d /etc/kernel/postinst.d && run-parts --arg="${kernel_name}" --arg="/boot/vmlinuz-${kernel_name}" /etc/kernel/postinst.d exit 0 EOF cat <<EOF > ${IMAGE_ROOT}/DEBIAN/postrm #!/bin/sh set -e # Pass maintainer script parameters to hook scripts export DEB_MAINT_PARAMS="\$*" # Tell initramfs builder whether it's wanted export INITRD=Yes test -d /etc/kernel/postrm.d && run-parts --arg="${kernel_name}" --arg="/boot/vmlinuz-${kernel_name}" /etc/kernel/postrm.d exit 0 EOF cat <<EOF > ${IMAGE_ROOT}/DEBIAN/preinst #!/bin/sh set -e # Pass maintainer script parameters to hook scripts export DEB_MAINT_PARAMS="\$*" # Tell initramfs builder whether it's wanted export INITRD=Yes test -d /etc/kernel/preinst.d && run-parts --arg="${kernel_name}" --arg="/boot/vmlinuz-${kernel_name}" /etc/kernel/preinst.d exit 0 EOF cat <<EOF > ${IMAGE_ROOT}/DEBIAN/prerm #!/bin/sh set -e # Pass maintainer script parameters to hook scripts export DEB_MAINT_PARAMS="\$*" # Tell initramfs builder whether it's wanted export INITRD=Yes test -d /etc/kernel/prerm.d && run-parts --arg="${kernel_name}" --arg="/boot/vmlinuz-${kernel_name}" /etc/kernel/prerm.d exit 0 EOF chmod +x ${IMAGE_ROOT}/DEBIAN/{postinst,postrm,preinst,prerm} #给4个脚本执行权限 dpkg-gencontrol -P${IMAGE_ROOT} -plinux-image-${kernel_name}-amlogic-s905d-osn -v${kernel_name}-amlogic-s905d-osn-1 -DSource=linux-upstream # --- 打包 deb --- dpkg-deb --root-owner-group -b ${IMAGE_ROOT} linux-image-${kernel_name}-amlogic-s905d-osn_arm64.deb #==============image.deb, finished========= # exit #不制作headers.deb, 就退出了 #==============headers.deb========= HEADER_ROOT=head_root mkdir -p "${HEADER_ROOT}" header_dir=${HEADER_ROOT}/usr/src/linux-headers-${kernel_name} mkdir -p "${header_dir}" tar zxf "${version}/header-${kernel_name}.tar.gz" -C ${header_dir} kmod_dir=${HEADER_ROOT}/usr/lib/modules mkdir -p "${kmod_dir}/${kernel_name}" ln -sf /usr/src/linux-headers-${kernel_name} ${kmod_dir}/${kernel_name}/build # --- DEBIAN 控制文件 --- mkdir -p "${HEADER_ROOT}/DEBIAN" touch ${HEADER_ROOT}/DEBIAN/md5sums dpkg-gencontrol -P${HEADER_ROOT} -plinux-headers-${kernel_name}-amlogic-s905d-osn -v${kernel_name}-amlogic-s905d-osn-1 -DSource=linux-upstream # --- 打包 deb --- dpkg-deb --root-owner-group -b ${HEADER_ROOT} linux-headers-${kernel_name}-amlogic-s905d-osn_arm64.deb #==============headers.deb, finished=========
- 在准备deb的文件中,如果有 "链接文件",要用
ln -sf /usr/src/... 链接文件
,
要按照 安装完deb后的情况,设置 "链接文件"。ln -sf
前面的参数路径,可以不存在。 - 在 N1 上执行这个脚本。耗时 2m55s ~ 3m08s 生成两个 deb 文件。文件还挺大的。
修改了一下脚本,删除 initrd,uInitrd 之后,image.deb体积小了好多。7.2M linux-headers-5.15.125-ophub-amlogic-s905d-osn_arm64.deb 64M linux-image-5.15.125-ophub-amlogic-s905d-osn_arm64.deb
26M linux-image-5.15.125-ophub-amlogic-s905d-osn_arm64.deb
- 拿去armbian中,安装顺利。卸载也顺利。
- 这个脚本的逻辑,对于制作 linux-image.deb 还有改进空间。
- 在 preinst 中,先备份 /boot/ 中的 zImage, uInitrd, uEnv.ini。
- 直接把 vmlinuz-xxx 拷贝为 zImage,就不用手工去做了。
在 dtb-5.15.125-ophub/ 中去掉不相干的 dtb文件,只留下 s905d 的 dtb文件。解压到 boot/ 目录的 uInitrd-xxx, initrd.img-xxx 是没用的,可以删除。
因为安装完成后,会被重新生成。- 在 postinst 中,直接修改 uEnv.ini 文件。
用 sed 把所有的 "dtb_name=" 的行,注释掉,然后再添加一行正确路径的 "dtb_name="。
----end----
转载注明来源: 本文链接 https://www.cnblogs.com/osnosn/p/17622874.html
来自 osnosn的博客 https://www.cnblogs.com/osnosn/ .