diff --git a/01_build_src.sh b/01_build_src.sh index 8172079..66f4d6c 100755 --- a/01_build_src.sh +++ b/01_build_src.sh @@ -1,14 +1,96 @@ #!/bin/sh -core_num=`nproc` -kernel_install=`pwd`"/work/kernel_install" -glibc_install=`pwd`"/work/glibc_install" -busybox_install=`pwd`"/work/busybox_install" -libgcc_install=`pwd`"/work/libgcc_install" -binutils_install=`pwd`"/work/binutils_install" +#----------------------------------------------- +# +# 导入公共变量 +# +#----------------------------------------------- +. ./common.sh + +#LINUX_SRC_URL=https://kernel.org/pub/linux/kernel/v4.x/linux-4.14.9.tar.xz +LINUX_SRC_URL=https://mirror.bjtu.edu.cn/kernel/linux/kernel/v4.x/linux-4.14.9.tar.xz +#GLIBC_SRC_URL=https://ftp.gnu.org/gnu/glibc/glibc-2.32.tar.bz2 +GLIBC_SRC_URL=https://mirrors.ustc.edu.cn/gnu/glibc/glibc-2.32.tar.bz2 +BUSYBOX_SRC_URL=https://busybox.net/downloads/busybox-1.34.1.tar.bz2 +#GCC_SRC_URL=https://ftpmirror.gnu.org/gcc/gcc-7.5.0/gcc-7.5.0.tar.xz +GCC_SRC_URL=https://mirrors.ustc.edu.cn/gnu/gcc/gcc-7.5.0/gcc-7.5.0.tar.xz +#BINUTILS_SRC_URL=https://ftp.gnu.org/gnu/binutils/binutils-2.36.tar.xz +BINUTILS_SRC_URL=https://mirrors.ustc.edu.cn/gnu/binutils/binutils-2.36.tar.xz export CFLAGS="-Os -s -fno-stack-protector -fomit-frame-pointer -U_FORTIFY_SOURCE" +#---------------------------------------------- +# +# 下载源码 +# +#---------------------------------------------- +mkdir -pv source +cd source + +LINUX_SRC_NAME=$(file_name ${LINUX_SRC_URL}) +if [ ! -f ${LINUX_SRC_NAME} ]; then + wget $LINUX_SRC_URL +fi + +GLIBC_SRC_NAME=$(file_name ${GLIBC_SRC_URL}) +if [ ! -f ${GLIBC_SRC_NAME} ]; then + wget $GLIBC_SRC_URL +fi + +BUSYBOX_SRC_NAME=$(file_name ${BUSYBOX_SRC_URL}) +if [ ! -f ${BUSYBOX_SRC_NAME} ]; then + wget $BUSYBOX_SRC_URL +fi + +GCC_SRC_NAME=$(file_name ${GCC_SRC_URL}) +if [ ! -f ${GCC_SRC_NAME} ]; then + wget $GCC_SRC_URL +fi + +BINUTILS_SRC_NAME=$(file_name ${BINUTILS_SRC_URL}) +if [ ! -f ${BINUTILS_SRC_NAME} ]; then + wget $BINUTILS_SRC_URL +fi + +cd .. + +#--------------------------------------------- +# +# 解压源码 +# +#--------------------------------------------- +mkdir -pv ${build_dir} + +LINUX_SRC_DIR=${build_dir}"/"$(file_dirname ${LINUX_SRC_NAME} .tar.xz) +if [ ! -d ${LINUX_SRC_DIR} ]; then + echo "unzip ${LINUX_SRC_NAME} source code" + tar xf source/${LINUX_SRC_NAME} -C ${build_dir} +fi + +GLIBC_SRC_DIR=${build_dir}"/"$(file_dirname ${GLIBC_SRC_NAME} .tar.bz2) +if [ ! -d ${GLIBC_SRC_DIR} ]; then + echo "unzip ${GLIBC_SRC_NAME} source code" + tar xf source/${GLIBC_SRC_NAME} -C ${build_dir} +fi + +BUSYBOX_SRC_DIR=${build_dir}"/"$(file_dirname ${BUSYBOX_SRC_NAME} .tar.bz2) +if [ ! -d ${BUSYBOX_SRC_DIR} ]; then + echo "unzip ${BUSYBOX_SRC_NAME} source code" + tar xf source/${BUSYBOX_SRC_NAME} -C ${build_dir} +fi + +GCC_SRC_DIR=${build_dir}"/"$(file_dirname ${GCC_SRC_NAME} .tar.xz) +if [ ! -d ${GCC_SRC_DIR} ]; then + echo "unzip ${GCC_SRC_NAME} source code" + tar xf source/${GCC_SRC_NAME} -C ${build_dir} +fi + +BINUTILS_SRC_DIR=${build_dir}"/"$(file_dirname ${BINUTILS_SRC_NAME} .tar.xz) +if [ ! -d ${BINUTILS_SRC_DIR} ]; then + echo "unzip ${BINUTILS_SRC_NAME} source code" + tar xf source/${BINUTILS_SRC_NAME} -C ${build_dir} +fi + #----------------------------------------------- # # 重新生成目标文件 @@ -19,137 +101,67 @@ if [ "$1" != "" ]; then exit fi echo "rebuild" - cd work - rm -rf kernel_install glibc_install busybox_install libgcc_install binutils_install + cd ${build_dir} + rm -rf linux_install glibc_install busybox_install gcc_install binutils_install # 编译内核, 最终所有模块都装到目录 /lib/modules/4.14.9 - if [ ! -d "kernel_install" ]; then - mkdir -pv kernel_install && cd linux-4.14.9 - make INSTALL_HDR_PATH=${kernel_install} headers_install -j8 && cp arch/x86_64/boot/bzImage ${kernel_install} && cd .. + if [ ! -d "linux_install" ]; then + mkdir -pv linux_install && cd ${LINUX_SRC_DIR} + make INSTALL_HDR_PATH=${linux_install} headers_install -j8 && cp arch/x86_64/boot/bzImage ${linux_install} && cd .. fi # 编译glibc if [ ! -d "glibc_install" ]; then - mkdir -pv glibc_install && cd glibc-2.32 + mkdir -pv glibc_install && cd ${GLIBC_SRC_DIR} mkdir -pv build && cd build make install -j8 DESTDIR=${glibc_install} && cd .. && cd .. fi # 编译 busybox if [ ! -d "busybox_install" ]; then - mkdir -pv busybox_install && cd busybox-1.34.1 + mkdir -pv busybox_install && cd ${BUSYBOX_SRC_DIR} make CONFIG_PREFIX=${busybox_install} install && cd .. fi # 编译 libgcc - if [ ! -d "libgcc_install" ]; then - mkdir -pv libgcc_install && cd gcc-7.5.0 - make install -j8 DESTDIR=${libgcc_install} && cd .. + if [ ! -d "gcc_install" ]; then + mkdir -pv gcc_install && cd ${GCC_SRC_DIR} + make install -j8 DESTDIR=${gcc_install} && cd .. fi # 编译 binutils if [ ! -d "binutils_install" ]; then - mkdir -pv binutils_install && cd binutils-2.36 + mkdir -pv binutils_install && cd ${BINUTILS_SRC_DIR} make install -j8 DESTDIR=${binutils_install} && cd .. fi cd .. exit fi -#---------------------------------------------- -# -# 下载源码 -# -#---------------------------------------------- -mkdir -pv source -cd source - -#KERNEL_SOURCE_URL=https://kernel.org/pub/linux/kernel/v4.x/linux-4.14.9.tar.xz -KERNEL_SOURCE_URL=https://mirror.bjtu.edu.cn/kernel/linux/kernel/v4.x/linux-4.14.9.tar.xz -if [ ! -f "linux-4.14.9.tar.xz" ]; then - wget $KERNEL_SOURCE_URL -fi - -#GLIBC_SOURCE_URL=https://ftp.gnu.org/gnu/glibc/glibc-2.32.tar.bz2 -GLIBC_SOURCE_URL=https://mirrors.ustc.edu.cn/gnu/glibc/glibc-2.32.tar.bz2 -if [ ! -f "glibc-2.32.tar.bz2" ]; then - wget $GLIBC_SOURCE_URL -fi - -BUSYBOX_SOURCE_URL=https://busybox.net/downloads/busybox-1.34.1.tar.bz2 -if [ ! -f "busybox-1.34.1.tar.bz2" ]; then - wget $BUSYBOX_SOURCE_URL -fi - -#GCC_SOURCE_URL=https://ftpmirror.gnu.org/gcc/gcc-7.5.0/gcc-7.5.0.tar.xz -GCC_SOURCE_URL=https://mirrors.ustc.edu.cn/gnu/gcc/gcc-7.5.0/gcc-7.5.0.tar.xz -if [ ! -f "gcc-7.5.0.tar.xz" ]; then - wget $GCC_SOURCE_URL -fi - -#BINUTILS_SOURCE_URL=https://ftp.gnu.org/gnu/binutils/binutils-2.36.tar.xz -BINUTILS_SOURCE_URL=https://mirrors.ustc.edu.cn/gnu/binutils/binutils-2.36.tar.xz -if [ ! -f "binutils-2.36.tar.xz" ]; then - wget $BINUTILS_SOURCE_URL -fi - -cd .. - -#--------------------------------------------- -# -# 解压源码 -# -#--------------------------------------------- -mkdir -pv work - -if [ ! -d "./work/linux-4.14.9" ]; then - echo "unzip kernel source" - tar xf source/linux-4.14.9.tar.xz -C work/ -fi - -if [ ! -d "./work/glibc-2.32" ]; then - echo "unzip glibc source" - tar xf source/glibc-2.32.tar.bz2 -C work/ -fi - -if [ ! -d "./work/busybox-1.34.1" ]; then - echo "unzip busybox source" - tar xf source/busybox-1.34.1.tar.bz2 -C work/ -fi - -if [ ! -d "./work/gcc-7.5.0" ]; then - echo "unzip gcc source" - tar xf source/gcc-7.5.0.tar.xz -C work/ -fi - -if [ ! -d "./work/binutils-2.36" ]; then - echo "unzip binutils source" - tar xf source/binutils-2.36.tar.xz -C work/ -fi #--------------------------------------------- # # 编译源码 # #--------------------------------------------- -cd work +cd ${build_dir} # 编译内核, 最终所有模块都装到目录 /lib/modules/4.14.9 -if [ ! -d "kernel_install" ]; then - mkdir -pv kernel_install && cd linux-4.14.9 && make mrproper && make x86_64_defconfig +if [ ! -d "linux_install" ]; then + mkdir -pv linux_install && cd ${LINUX_SRC_DIR} && make mrproper && make x86_64_defconfig # Enable the VESA framebuffer for graphics support. sed -i "s/.*CONFIG_FB_VESA.*/CONFIG_FB_VESA=y/" .config # 网络需要 TUN/TAP 驱动 [ Device Drivers ] ---> [ Network device support ] ---> [ Universal TUN/TAP device driver support ] make bzImage -j8 #cd linux-4.14.9 && make x86_64_defconfig && make bzImage -j8 && make modules && make modules_install && cd .. - make INSTALL_HDR_PATH=${kernel_install} headers_install -j8 && cp arch/x86_64/boot/bzImage ${kernel_install} && cd .. + make INSTALL_HDR_PATH=${linux_install} headers_install -j8 && cp arch/x86_64/boot/bzImage ${linux_install} && cd .. fi # 编译glibc if [ ! -d "glibc_install" ]; then - mkdir -pv glibc_install && cd glibc-2.32 + mkdir -pv glibc_install && cd ${GLIBC_SRC_DIR} mkdir -pv build && cd build && make distclean ../configure --prefix=/usr \ - --with-headers=${kernel_install}/include \ + --with-headers=${linux_install}/include \ --enable-kernel=4.0.1 \ --without-selinux \ --disable-werror \ @@ -160,24 +172,24 @@ fi # 编译 busybox if [ ! -d "busybox_install" ]; then - mkdir -pv busybox_install && cd busybox-1.34.1 && make distclean && make defconfig + mkdir -pv busybox_install && cd ${BUSYBOX_SRC_DIR} && make distclean && make defconfig # 静态编译 sed -i "s/# CONFIG_STATIC is not set/CONFIG_STATIC=y/g" .config sed -i "s|.*CONFIG_SYSROOT.*|CONFIG_SYSROOT=\"${glibc_install}\"|" .config - sed -i "s|.*CONFIG_EXTRA_CFLAGS.*|CONFIG_EXTRA_CFLAGS=\"-I${kernel_install}/include -I${glibc_install}/include -L${glibc_install}/usr/lib64 $CFLAGS\"|" .config + sed -i "s|.*CONFIG_EXTRA_CFLAGS.*|CONFIG_EXTRA_CFLAGS=\"-I${linux_install}/include -I${glibc_install}/include -L${glibc_install}/usr/lib64 $CFLAGS\"|" .config make busybox -j8 && make CONFIG_PREFIX=${busybox_install} install && cd .. fi -# 编译 libgcc -if [ ! -d "libgcc_install" ]; then - mkdir -pv libgcc_install && cd gcc-7.5.0 && make distclean && rm ./config.cache +# 编译 gcc +if [ ! -d "gcc_install" ]; then + mkdir -pv gcc_install && cd ${GCC_SRC_DIR} && make distclean && rm ./config.cache ./contrib/download_prerequisites ./configure --prefix=/usr --enable-languages=c,c++ --disable-multilib --disable-static --disable-libquadmath --enable-shared - CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${libgcc_install} && cd .. + CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${gcc_install} && cd .. fi # 编译 binutils if [ ! -d "binutils_install" ]; then - mkdir -pv binutils_install && cd binutils-2.36 && make distclean + mkdir -pv binutils_install && cd ${BINUTILS_SRC_DIR} && make distclean ./configure --prefix=/usr CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${binutils_install} && cd .. cd .. diff --git a/02_build_img.sh b/02_build_img.sh index 146f690..bcef7a3 100755 --- a/02_build_img.sh +++ b/02_build_img.sh @@ -15,8 +15,8 @@ CYAN='\e[1;36m' WHITE='\e[1;37m' # 白色 NC='\e[0m' # 没有颜色 -# ./02_build_img.sh gcc 这样就能编译带 gcc 的系统 -with_gcc=$1 +# 导入公共环境 +. ./common.sh #---------------------------------------------- # @@ -32,7 +32,7 @@ with_gcc=$1 #---------------------------------------------- echo "${CYAN}--- build disk --- ${NC}" # 创建磁盘 64M -if [ ! -n "${with_gcc}" ]; then +if [ "${with_gcc}" = false ]; then dd if=/dev/zero of=disk.img bs=1M count=128 else dd if=/dev/zero of=disk.img bs=1M count=256 @@ -82,30 +82,30 @@ mkdir -pv rootfs/lib64 mkdir -pv rootfs/lib/modules # 拷贝内核镜像 -cp work/kernel_install/bzImage ${diskfs}/boot/bzImage +cp ${linux_install}/bzImage ${diskfs}/boot/bzImage # 拷贝 glibc 到 rootfs -cp work/glibc_install/* rootfs/ -r +cp ${glibc_install}/* rootfs/ -r rm -rf rootfs/var/db rm -rf rootfs/share rm -rf rootfs/usr/share find rootfs/ -name "*.a" -exec rm -rf {} \; # 编译的镜像带有 gcc 编译器 -if [ ! -n "${with_gcc}" ]; then - echo "without-gcc tools." - #rm -rf rootfs/include +if [ "${with_gcc}" = false ]; then + rm -rf rootfs/usr/include else echo "${RED} with-gcc tools --- you can build your world${NC}" - cp work/glibc_install/usr/lib64/libc_nonshared.a rootfs/usr/lib64 + cp ${glibc_install}/usr/lib64/libc_nonshared.a rootfs/usr/lib64 fi #---------------------------------------------------------------------- # 这个解释器必须设置对,否则系统会启动时 crash, 导致启动失败 !!!!!! +# 这个现在 glibc 编译时,已经自动生成,先注释掉 #----------------------------------------------------------------------- -ln -s /lib/ld-2.32.so rootfs/lib64/ld-linux-x86-64.so.2 +# ln -s /lib/ld-2.32.so rootfs/lib64/ld-linux-x86-64.so.2 # 拷贝 busybox 到 rootfs -cp work/busybox_install/* rootfs/ -r +cp ${busybox_install}/* rootfs/ -r #----------------------------------------------- # @@ -122,7 +122,6 @@ make_init() { cat<<"EOF">init #!/bin/sh - # 必须首先挂载,否则 mdev 不能正常工作 mount -t sysfs none /sys mount -t proc none /proc @@ -131,21 +130,19 @@ mount -t tmpfs none /tmp -o mode=1777 # 必须挂载一下,否则下面的 mount 不上 mdev -s mount -t ext3 /dev/sda1 /mnt - # 关闭内核烦人的输出信息 echo 0 > /proc/sys/kernel/printk +# 热插拔处理都交给 mdev +echo /sbin/mdev > /proc/sys/kernel/hotplug echo -e "\n\e[0;32mBoot took $(cut -d' ' -f1 /proc/uptime) seconds\e[0m" - mkdir -p /dev/pts mount -t devpts none /dev/pts - # 切换之前,修改 mount 路径 mount --move /dev /mnt/dev mount --move /sys /mnt/sys mount --move /proc /mnt/proc mount --move /tmp /mnt/tmp - -# 切换到真正的磁盘系统上 rootfs(initramfs) ---> diskfs +# 切换到真正的磁盘系统上 rootfs ---> diskfs exec switch_root /mnt /sbin/init EOF @@ -192,17 +189,17 @@ cd .. echo "${CYAN}--- build diskfs ---${NC}" cp rootfs/* ${diskfs} -r # 带有 gcc 编译器 -if [ "${with_gcc}" ]; then +if [ "${with_gcc}" = true ]; then echo "${RED} with-gcc tools --- you can build your world${NC}" - cp work/libgcc_install/* ${diskfs} -r - cp work/binutils_install/usr/x86_64-pc-linux-gnu/* ${diskfs} -r + cp ${gcc_install}/* ${diskfs} -r + cp ${binutils_install}/usr/x86_64-pc-linux-gnu/* ${diskfs} -r fi rm -rf ${diskfs}/init ${diskfs}/lost+found # 我们测试驱动, 制作的镜像启动后,我们进入此目录 insmod hello_world.ko 即可 ./mk_drv.sh $(pwd)/${diskfs}/lib/modules # 编译网卡驱动 ( 目前版本内核已集成 e1000 ) -# cd work/linux-4.14.9 && make M=drivers/net/ethernet/intel/e1000/ && cd ../.. +# cd ${build_dir}/linux-4.14.9 && make M=drivers/net/ethernet/intel/e1000/ && cd ../.. # 生成 grub.cfg 文件, 增加 console=ttyS0 就会让 qemu 输出日志到 qemu.log cat - > ${diskfs}/boot/grub/grub.cfg << EOF diff --git a/common.sh b/common.sh new file mode 100755 index 0000000..e16ec7d --- /dev/null +++ b/common.sh @@ -0,0 +1,30 @@ +# 处理器 +core_num=`nproc` + +# 是否开启 gcc +with_gcc=false + +# 编译工程目录 +build_dir=`pwd`"/build" + +# 公共目录 +linux_install=${build_dir}"/linux_install" +glibc_install=${build_dir}"/glibc_install" +busybox_install=${build_dir}"/busybox_install" +gcc_install=${build_dir}"/gcc_install" +binutils_install=${build_dir}"/binutils_install" + +# 从完整路径获取文件名 +file_name() { + filename=$(echo $1 | rev | awk -v FS='/' '{print $1}' | rev) + echo ${filename} +} + +# 获取去掉扩展名的文件名 +file_dirname() { + filename=$(file_name $1) + filedir=`echo $filename | sed "s/$2//g"` + echo $filedir +} + + diff --git a/mk_drv.sh b/mk_drv.sh index f02bef9..9334d1c 100755 --- a/mk_drv.sh +++ b/mk_drv.sh @@ -27,9 +27,9 @@ EOF cat<Makefile obj-m += hello_world.o all: - make -C ../work/linux-4.14.9 M=`pwd` modules + make -C ../build/linux-4.14.9 M=`pwd` modules clean: - make -C ../work/linux-4.14.9 M=`pwd` clean + make -C ../build/linux-4.14.9 M=`pwd` clean EOF echo $1 diff --git a/mk_strip.sh b/mk_strip.sh index 8d2b68e..a1be920 100755 --- a/mk_strip.sh +++ b/mk_strip.sh @@ -1,5 +1,8 @@ #!/bin/sh +# 导入公共环境 +. ./common.sh + strip_dir() { for file in `ls $1` do @@ -24,18 +27,18 @@ strip_dir() { } # strip glibc -rm -rf work/glibc_install/usr/share -strip_dir work/glibc_install +rm -rf ${glibc_install}/usr/share +strip_dir ${glibc_install} # strip busybox -rm -rf work/busybox_install/linuxrc -strip work/busybox_install/bin/busybox +rm -rf ${busybox_install}/linuxrc +strip ${busybox_install}/bin/busybox # strip gcc #rm -rf work/libgcc_install/usr/share -strip_dir work/libgcc_install +strip_dir ${gcc_install} # strip binutils #rm -rf work/binutils_install/usr/share -strip_dir work/binutils_install +strip_dir ${binutils_install}