mirror of
https://github.com/superconvert/smart-os.git
synced 2025-04-03 05:45:04 +08:00
Compare commits
141 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a9dae8732d | ||
|
3b2260fa48 | ||
|
afdd01da4d | ||
|
4fa5e4e777 | ||
|
f489a35d32 | ||
|
e52c566997 | ||
|
c6b21cbfa4 | ||
|
3a0a5762b4 | ||
|
15374080d6 | ||
|
089ef059e1 | ||
|
5d1564b38a | ||
|
b4153d2f65 | ||
|
e9c9c533bf | ||
|
a513a34d71 | ||
|
f2fd01f9d1 | ||
|
0b2a902a28 | ||
|
2f5adf9e6c | ||
|
7b90a2171a | ||
|
7c88f91bf6 | ||
|
7d2f6a77e3 | ||
|
437cfed85a | ||
|
643a60907d | ||
|
04f777b5cd | ||
|
e87a814c50 | ||
|
3074c3014d | ||
|
7b792a967d | ||
|
4e53696d30 | ||
|
3aa22d52d1 | ||
|
e537fbed20 | ||
|
c8463bba4f | ||
|
fcca13978b | ||
|
1aa23da0b0 | ||
|
b1356c1b65 | ||
|
94e3e14e13 | ||
|
c4c25e8bdb | ||
|
a4c2f39987 | ||
|
15fecf743f | ||
|
62d7211be2 | ||
|
64e259b360 | ||
|
9d956731f1 | ||
|
d1a95e421c | ||
|
a4a40ea129 | ||
|
08a82e30ed | ||
|
e1045b8901 | ||
|
054b8f577d | ||
|
b5c05a5c00 | ||
|
b5c9d2f931 | ||
|
a7996afe36 | ||
|
ac5823d539 | ||
|
67524810e3 | ||
|
ac52714964 | ||
|
3f72afae09 | ||
|
e4fa469d49 | ||
|
29bbb54275 | ||
|
d1b47387c3 | ||
|
56de968b9b | ||
|
2d13af3221 | ||
|
cf7f3da1bf | ||
|
e8f34bfa38 | ||
|
ee1daa96fe | ||
|
738c64116f | ||
|
35d89a90c6 | ||
|
a002dfe29e | ||
|
3d977da3de | ||
|
8a35393138 | ||
|
2132acdca6 | ||
|
fbac185ad7 | ||
|
8506de4f3d | ||
|
a740e0f0da | ||
|
e8dab70705 | ||
|
40f3f911dd | ||
|
788de643ba | ||
|
3914f7f258 | ||
|
b003ac728b | ||
|
8da4f4e441 | ||
|
77484ea06a | ||
|
3f6318462d | ||
|
008d91d445 | ||
|
9e7f1cef70 | ||
|
f8f29b48cb | ||
|
00fded63ba | ||
|
1c0f3e8a40 | ||
|
b322b03dfd | ||
|
67469d3784 | ||
|
b89ba7113a | ||
|
7f976686d9 | ||
|
b30db2fe72 | ||
|
435005135c | ||
|
9ebc990f12 | ||
|
3737e997dc | ||
|
d4910fc02a | ||
|
9e268413e9 | ||
|
d3101db0e9 | ||
|
7bbca096d6 | ||
|
e16183c0e2 | ||
|
a42907616e | ||
|
1304bb56cb | ||
|
87a3f123a2 | ||
|
212b889524 | ||
|
7908dd4dbe | ||
|
1d30aff8ee | ||
|
97068da0d4 | ||
|
78b988877a | ||
|
551dc04910 | ||
|
d48c2591e7 | ||
|
6a9f80fc9d | ||
|
6f0f7c0b2a | ||
|
7010635d63 | ||
|
3f117e4747 | ||
|
b93432353f | ||
|
32b86194a2 | ||
|
2a668a1e62 | ||
|
0f5e99044e | ||
|
eaa06dea59 | ||
|
4ffcf2d369 | ||
|
f4ee0ccc7c | ||
|
e896ec59b4 | ||
|
68593d5738 | ||
|
6358fe0e5b | ||
|
9f4814d970 | ||
|
db0dfebf71 | ||
|
5330c766a9 | ||
|
6f317ff786 | ||
|
b26c1e2da0 | ||
|
b6596ae8b7 | ||
|
7c20939ede | ||
|
8b20c14682 | ||
|
edef2e31a4 | ||
|
423d7aa06a | ||
|
23ee4ebf24 | ||
|
46d18d4cf2 | ||
|
9aa8c878ed | ||
|
f6ffd34c27 | ||
|
ba0a0a0243 | ||
|
e7746eb439 | ||
|
4793cb5dbe | ||
|
1341bd119b | ||
|
19f704325b | ||
|
dde1c4f5e8 | ||
|
0d4c5932bc | ||
|
2a953f0b1e |
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm work/kernel_install/ work/glibc_install/ work/busybox_install/ work/libgcc_install work/binutils_install -rf
|
||||
# rm work/kernel_install/ work/glibc_install/ work/busybox_install/ work/libgcc_install work/binutils_install -rf
|
||||
|
||||
if [ -f "/usr/bin/apt" ]; then
|
||||
apt -y install gcc g++ make gawk bison libelf-dev bridge-utils qemu-system docker.io
|
||||
|
523
01_build_src.sh
523
01_build_src.sh
@ -1,24 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -f "/usr/bin/apt" ]; then
|
||||
apt -y install gcc g++ make gawk flex bison libelf-dev libssl-dev bridge-utils
|
||||
fi
|
||||
|
||||
if [ -f "/usr/bin/yum" ]; then
|
||||
yum -y install gcc gcc-c++ make gawk flex bison elfutils-libelf libssl-dev bridge-utils
|
||||
fi
|
||||
|
||||
#-----------------------------------------------
|
||||
#
|
||||
# 导入公共变量
|
||||
# 导入公共变量 ( xfce4 需要 5.4.0 的内核, glibc 必须为 2.27 否则 xfce4 相关的编译有问题 )
|
||||
#
|
||||
#-----------------------------------------------
|
||||
. ./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
|
||||
LINUX_SRC_URL=https://mirror.bjtu.edu.cn/kernel/linux/kernel/v5.x/linux-5.8.6.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
|
||||
GLIBC_SRC_URL=https://mirrors.ustc.edu.cn/gnu/glibc/glibc-2.27.tar.xz
|
||||
BUSYBOX_SRC_URL=https://busybox.net/downloads/busybox-1.34.1.tar.bz2
|
||||
LSHW_SRC_URL=https://www.ezix.org/software/files/lshw-B.02.19.2.tar.gz
|
||||
LSOF_SRC_URL=https://github.com/lsof-org/lsof/releases/download/4.95.0/lsof_4.95.0.linux.tar.bz2
|
||||
STRACE_SRC_URL=https://github.com/strace/strace/releases/download/v5.19/strace-5.19.tar.xz
|
||||
PCIUTILS_SRC_URL=http://mj.ucw.cz/download/linux/pci/pciutils-3.8.0.tar.gz
|
||||
OPENSSL_SRC_URL=https://www.openssl.org/source/openssl-1.1.1q.tar.gz
|
||||
OPENSSH_SRC_URL=https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.8p1.tar.gz
|
||||
LIBMNL_SRC_URL=https://netfilter.org/projects/libmnl/files/libmnl-1.0.5.tar.bz2
|
||||
LIBNFTNL_SRC_URL=https://netfilter.org/projects/libnftnl/files/libnftnl-1.2.3.tar.bz2
|
||||
IPTABLES_SRC_URL=https://www.netfilter.org/projects/iptables/files/iptables-1.8.8.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"
|
||||
|
||||
#----------------------------------------------
|
||||
#
|
||||
# 下载源码
|
||||
@ -26,32 +40,20 @@ export CFLAGS="-Os -s -fno-stack-protector -fomit-frame-pointer -U_FORTIFY_SOURC
|
||||
#----------------------------------------------
|
||||
mkdir -pv source
|
||||
cd source
|
||||
|
||||
LINUX_SRC_NAME=$(file_name ${LINUX_SRC_URL})
|
||||
if [ ! -f ${LINUX_SRC_NAME} ]; then
|
||||
wget -c -t 0 $LINUX_SRC_URL
|
||||
fi
|
||||
|
||||
GLIBC_SRC_NAME=$(file_name ${GLIBC_SRC_URL})
|
||||
if [ ! -f ${GLIBC_SRC_NAME} ]; then
|
||||
wget -c -t 0 $GLIBC_SRC_URL
|
||||
fi
|
||||
|
||||
BUSYBOX_SRC_NAME=$(file_name ${BUSYBOX_SRC_URL})
|
||||
if [ ! -f ${BUSYBOX_SRC_NAME} ]; then
|
||||
wget -c -t 0 $BUSYBOX_SRC_URL
|
||||
fi
|
||||
|
||||
GCC_SRC_NAME=$(file_name ${GCC_SRC_URL})
|
||||
if [ ! -f ${GCC_SRC_NAME} ]; then
|
||||
wget -c -t 0 $GCC_SRC_URL
|
||||
fi
|
||||
|
||||
BINUTILS_SRC_NAME=$(file_name ${BINUTILS_SRC_URL})
|
||||
if [ ! -f ${BINUTILS_SRC_NAME} ]; then
|
||||
wget -c -t 0 $BINUTILS_SRC_URL
|
||||
fi
|
||||
|
||||
LINUX_SRC_NAME=$(download_src ${LINUX_SRC_URL})
|
||||
GLIBC_SRC_NAME=$(download_src ${GLIBC_SRC_URL})
|
||||
BUSYBOX_SRC_NAME=$(download_src ${BUSYBOX_SRC_URL})
|
||||
LSHW_SRC_NAME=$(download_src ${LSHW_SRC_URL})
|
||||
LSOF_SRC_NAME=$(download_src ${LSOF_SRC_URL})
|
||||
STRACE_SRC_NAME=$(download_src ${STRACE_SRC_URL})
|
||||
PCIUTILS_SRC_NAME=$(download_src ${PCIUTILS_SRC_URL})
|
||||
OPENSSL_SRC_NAME=$(download_src ${OPENSSL_SRC_URL})
|
||||
OPENSSH_SRC_NAME=$(download_src ${OPENSSH_SRC_URL})
|
||||
LIBMNL_SRC_NAME=$(download_src ${LIBMNL_SRC_URL})
|
||||
LIBNFTNL_SRC_NAME=$(download_src ${LIBNFTNL_SRC_URL})
|
||||
IPTABLES_SRC_NAME=$(download_src ${IPTABLES_SRC_URL})
|
||||
GCC_SRC_NAME=$(download_src ${GCC_SRC_URL})
|
||||
BINUTILS_SRC_NAME=$(download_src ${BINUTILS_SRC_URL})
|
||||
cd ..
|
||||
|
||||
#---------------------------------------------
|
||||
@ -60,100 +62,240 @@ 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
|
||||
LINUX_SRC_DIR=$(unzip_src ".tar.xz" ${LINUX_SRC_NAME}); echo "unzip ${LINUX_SRC_NAME} source code"
|
||||
GLIBC_SRC_DIR=$(unzip_src ".tar.xz" ${GLIBC_SRC_NAME}); echo "unzip ${GLIBC_SRC_NAME} source code"
|
||||
BUSYBOX_SRC_DIR=$(unzip_src ".tar.bz2" ${BUSYBOX_SRC_NAME}); echo "unzip ${BUSYBOX_SRC_NAME} source code"
|
||||
LSHW_SRC_DIR=$(unzip_src ".tar.gz" ${LSHW_SRC_NAME}); echo "unzip ${LSHW_SRC_NAME} source code"
|
||||
LSOF_SRC_DIR=$(unzip_src ".tar.bz2" ${LSOF_SRC_NAME}); echo "unzip ${LSOF_SRC_NAME} source code"
|
||||
STRACE_SRC_DIR=$(unzip_src ".tar.xz" ${STRACE_SRC_NAME}); echo "unzip ${STRACE_SRC_NAME} source code"
|
||||
PCIUTILS_SRC_DIR=$(unzip_src ".tar.gz" ${PCIUTILS_SRC_NAME}); echo "unzip ${PCIUTILS_SRC_NAME} source code"
|
||||
OPENSSL_SRC_DIR=$(unzip_src ".tar.gz" ${OPENSSL_SRC_NAME}); echo "unzip ${OPENSSL_SRC_NAME} source code"
|
||||
OPENSSH_SRC_DIR=$(unzip_src ".tar.gz" ${OPENSSH_SRC_NAME}); echo "unzip ${OPENSSH_SRC_NAME} source code"
|
||||
LIBMNL_SRC_DIR=$(unzip_src ".tar.bz2" ${LIBMNL_SRC_NAME}); echo "unzip ${LIBMNL_SRC_NAME} source code"
|
||||
LIBNFTNL_SRC_DIR=$(unzip_src ".tar.bz2" ${LIBNFTNL_SRC_NAME}); echo "unzip ${LIBNFTNL_SRC_NAME} source code"
|
||||
IPTABLES_SRC_DIR=$(unzip_src ".tar.bz2" ${IPTABLES_SRC_NAME}); echo "unzip ${IPTABLES_SRC_NAME} source code"
|
||||
GCC_SRC_DIR=$(unzip_src ".tar.xz" ${GCC_SRC_NAME}); echo "unzip ${GCC_SRC_NAME} source code"
|
||||
BINUTILS_SRC_DIR=$(unzip_src ".tar.xz" ${BINUTILS_SRC_NAME}); echo "unzip ${BINUTILS_SRC_NAME} source code"
|
||||
|
||||
#-----------------------------------------------
|
||||
#
|
||||
# 重新生成目标文件
|
||||
#
|
||||
#-----------------------------------------------
|
||||
if [ "$1" != "" ]; then
|
||||
if [ $1 != "rebuild" ]; then
|
||||
exit
|
||||
fi
|
||||
if [ "$1" = "rebuild" ]; then
|
||||
echo "rebuild"
|
||||
cd ${build_dir}
|
||||
rm -rf linux_install glibc_install busybox_install gcc_install binutils_install
|
||||
# 编译内核, 最终所有模块都装到目录 /lib/modules/4.14.9
|
||||
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_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_SRC_DIR}
|
||||
make CONFIG_PREFIX=${busybox_install} install && cd ..
|
||||
fi
|
||||
|
||||
# 编译 libgcc
|
||||
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_SRC_DIR}
|
||||
make install -j8 DESTDIR=${binutils_install} && cd ..
|
||||
fi
|
||||
rm -rf linux_install glibc_install busybox_install lshw_install lsof_install pciutils_install strace_install \
|
||||
openssl_install openssh_install gcc_install binutils_install
|
||||
cd ..
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
#---------------------------------------------
|
||||
#
|
||||
# 编译源码
|
||||
#
|
||||
#---------------------------------------------
|
||||
export CFLAGS="-Os -s -fno-stack-protector -fomit-frame-pointer -U_FORTIFY_SOURCE"
|
||||
|
||||
cd ${build_dir}
|
||||
|
||||
# 编译内核, 最终所有模块都装到目录 /lib/modules/4.14.9
|
||||
# 编译内核, 最终所有模块都装到目录 /lib/modules/5.8.6
|
||||
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
|
||||
|
||||
# 下面的配置主要显卡相关的配置,必须开启, 内核 3d 加速 https://wiki.gentoo.org/wiki/Xorg/Hardware_3D_acceleration_guide
|
||||
# xfce4 需要 drm 支持,内核版本尽量大于等于 18.04 的,所以选取了 5.8.6 的内核
|
||||
sed -i "s/# CONFIG_X86_SYSFB is not set/CONFIG_X86_SYSFB=y/" .config
|
||||
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_HAVE_KVM_IRQCHIP=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_HAVE_KVM_IRQFD=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_HAVE_KVM_IRQ_ROUTING=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_HAVE_KVM_EVENTFD=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_KVM_MMIO=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_KVM_ASYNC_PF=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_HAVE_KVM_MSI=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_KVM_VFIO=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_KVM_COMPAT=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_HAVE_KVM_IRQ_BYPASS=y" .config
|
||||
sed -i "/CONFIG_VIRTUALIZATION=y/i\CONFIG_HAVE_KVM_NO_POLL=y" .config
|
||||
|
||||
sed -i "s/# CONFIG_KVM is not set/CONFIG_KVM=y/" .config
|
||||
sed -i "/CONFIG_AS_AVX512=y/i\CONFIG_KVM_INTEL=y" .config
|
||||
sed -i "/CONFIG_AS_AVX512=y/i\CONFIG_KVM_AMD=y" .config
|
||||
sed -i "/CONFIG_AS_AVX512=y/i\CONFIG_KVM_MMU_AUDIT=y" .config
|
||||
|
||||
sed -i "/CONFIG_HAVE_IOREMAP_PROT=y/i\CONFIG_USER_RETURN_NOTIFIER=y" .config
|
||||
sed -i "/CONFIG_BLK_PM=y/i\CONFIG_BLK_MQ_VIRTIO=y" .config
|
||||
sed -i "/CONFIG_ASN1=y/i\CONFIG_PREEMPT_NOTIFIERS=y" .config
|
||||
sed -i "/# CONFIG_MEMORY_HOTPLUG is not set/i\CONFIG_MEMORY_ISOLATION=y" .config
|
||||
sed -i "/CONFIG_PHYS_ADDR_T_64BIT=y/i\CONFIG_CONTIG_ALLOC=y" .config
|
||||
|
||||
sed -i "s/# CONFIG_CMA is not set/CONFIG_CMA=y/" .config
|
||||
sed -i "/# CONFIG_ZPOOL is not set/i\# CONFIG_CMA_DEBUG is not set" .config
|
||||
sed -i "/# CONFIG_ZPOOL is not set/i\# CONFIG_CMA_DEBUGFS is not set" .config
|
||||
sed -i "/# CONFIG_ZPOOL is not set/i\CONFIG_CMA_AREAS=7" .config
|
||||
|
||||
sed -i "/CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y/i\CONFIG_HMM_MIRROR=y" .config
|
||||
sed -i "/# end of Memory Management options/i\CONFIG_MAPPING_DIRTY_HELPERS=y" .config
|
||||
|
||||
sed -i "/CONFIG_ALLOW_DEV_COREDUMP=y/i\CONFIG_WANT_DEV_COREDUMP=y" .config
|
||||
sed -i "/# CONFIG_DEBUG_DRIVER is not set/i\CONFIG_DEV_COREDUMP=y" .config
|
||||
sed -i "/# CONFIG_BLK_DEV_RBD is not set/i\# CONFIG_VIRTIO_BLK is not set" .config
|
||||
sed -i "/# CONFIG_NLMON is not set/i\# CONFIG_VIRTIO_NET is not set" .config
|
||||
sed -i "/# CONFIG_IPMI_HANDLER is not set/i\# CONFIG_VIRTIO_CONSOLE is not set" .config
|
||||
sed -i "/# CONFIG_APPLICOM is not set/i\# CONFIG_HW_RANDOM_VIRTIO is not set" .config
|
||||
|
||||
sed -i "s/# CONFIG_AGP_SIS is not set/CONFIG_AGP_SIS=y/" .config
|
||||
sed -i "s/# CONFIG_AGP_VIA is not set/CONFIG_AGP_VIA=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_DP_AUX_CHARDEV is not set/CONFIG_DRM_DP_AUX_CHARDEV=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set/CONFIG_DRM_LOAD_EDID_FIRMWARE=y/" .config
|
||||
|
||||
sed -i "/# CONFIG_DRM_DP_CEC is not set/a\CONFIG_DRM_TTM=y" .config
|
||||
sed -i "/CONFIG_DRM_TTM=y/a\CONFIG_DRM_TTM_DMA_PAGE_POOL=y" .config
|
||||
sed -i "/CONFIG_DRM_TTM_DMA_PAGE_POOL=y/a\CONFIG_DRM_VRAM_HELPER=y" .config
|
||||
sed -i "/CONFIG_DRM_VRAM_HELPER=y/a\CONFIG_DRM_TTM_HELPER=y" .config
|
||||
sed -i "/CONFIG_DRM_TTM_HELPER=y/a\CONFIG_DRM_GEM_SHMEM_HELPER=y" .config
|
||||
sed -i "/CONFIG_DRM_GEM_SHMEM_HELPER=y/a\CONFIG_DRM_VM=y" .config
|
||||
sed -i "/CONFIG_DRM_VM=y/a\CONFIG_DRM_SCHED=y" .config
|
||||
|
||||
sed -i "/# CONFIG_DRM_RADEON is not set/d" .config
|
||||
sed -i "/# CONFIG_DRM_AMDGPU is not set/d" .config
|
||||
sed -i "/# CONFIG_DRM_NOUVEAU is not set/d" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_RADEON=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_RADEON_USERPTR=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_AMDGPU=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_AMDGPU_SI=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_AMDGPU_CIK=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_AMDGPU_USERPTR=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set\n" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\#\n# ACP (Audio CoProcessor) Configuration\n#" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\# CONFIG_DRM_AMD_ACP is not set" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\# end of ACP (Audio CoProcessor) Configuration\n" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\#\n# Display Engine Configuration\n#" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_AMD_DC=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_AMD_DC_DCN=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\# CONFIG_DRM_AMD_DC_HDCP is not set" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\# CONFIG_DEBUG_KERNEL_DC is not set" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\# end of Display Engine Configuration\n" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_HSA_AMD=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_NOUVEAU=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT=y" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_NOUVEAU_DEBUG=5" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_NOUVEAU_DEBUG_DEFAULT=3" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\# CONFIG_NOUVEAU_DEBUG_MMU is not set" .config
|
||||
sed -i "/CONFIG_DRM_I915=y/i\CONFIG_DRM_NOUVEAU_BACKLIGHT=y" .config
|
||||
|
||||
sed -i "s/# CONFIG_DRM_I915_GVT is not set/CONFIG_DRM_I915_GVT=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_VGEM is not set/CONFIG_DRM_VGEM=y/" .config
|
||||
|
||||
sed -i "s/# CONFIG_DRM_VKMS is not set/CONFIG_DRM_VKMS=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_VMWGFX is not set/CONFIG_DRM_VMWGFX=y\nCONFIG_DRM_VMWGFX_FBCON=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_GMA500 is not set/CONFIG_DRM_GMA500=y\nCONFIG_DRM_GMA600=y\nCONFIG_DRM_GMA3600=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_MGAG200 is not set/CONFIG_DRM_MGAG200=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_QXL is not set/CONFIG_DRM_QXL=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_BOCHS is not set/CONFIG_DRM_BOCHS=y\n# CONFIG_DRM_VIRTIO_GPU is not set/" .config
|
||||
sed -i "s/# CONFIG_DRM_VIRTIO_GPU is not set/CONFIG_DRM_VIRTIO_GPU=y/" .config
|
||||
|
||||
sed -i "s/# CONFIG_DRM_ETNAVIV is not set/CONFIG_DRM_ETNAVIV=y\nCONFIG_DRM_ETNAVIV_THERMAL=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_CIRRUS_QEMU is not set/CONFIG_DRM_CIRRUS_QEMU=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_GM12U320 is not set/CONFIG_DRM_GM12U320=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_VBOXVIDEO is not set/CONFIG_DRM_VBOXVIDEO=y/" .config
|
||||
sed -i "s/# CONFIG_DRM_LEGACY is not set/CONFIG_DRM_LEGACY=y/" .config
|
||||
sed -i "/CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y/i\# CONFIG_DRM_TDFX is not set" .config
|
||||
sed -i "/CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y/i\# CONFIG_DRM_R128 is not set" .config
|
||||
sed -i "/CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y/i\# CONFIG_DRM_I810 is not set" .config
|
||||
sed -i "/CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y/i\# CONFIG_DRM_MGA is not set" .config
|
||||
sed -i "/CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y/i\# CONFIG_DRM_SIS is not set" .config
|
||||
sed -i "/CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y/i\# CONFIG_DRM_VIA is not set" .config
|
||||
sed -i "/CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y/i\# CONFIG_DRM_SAVAGE is not set" .config
|
||||
|
||||
sed -i "s/# CONFIG_FIRMWARE_EDID is not set/CONFIG_FIRMWARE_EDID=y\nCONFIG_FB_DDC=y\nCONFIG_FB_BOOT_VESA_SUPPORT=y/" .config
|
||||
sed -i "/CONFIG_FB_MODE_HELPERS=y/i\CONFIG_FB_SVGALIB=y" .config
|
||||
sed -i "/CONFIG_FB_MODE_HELPERS=y/i\CONFIG_FB_BACKLIGHT=y" .config
|
||||
|
||||
sed -i "s/# CONFIG_FB_CIRRUS is not set/CONFIG_FB_CIRRUS=y/" .config
|
||||
sed -i "s/# CONFIG_FB_VGA16 is not set/CONFIG_FB_VGA16=y/" .config
|
||||
sed -i "s/# CONFIG_FB_UVESA is not set/CONFIG_FB_UVESA=y/" .config
|
||||
sed -i "s/# CONFIG_FB_VESA is not set/CONFIG_FB_VESA=y/" .config
|
||||
|
||||
sed -i "s/# CONFIG_FB_OPENCORES is not set/CONFIG_FB_OPENCORES=y/" .config
|
||||
|
||||
sed -i "s/# CONFIG_FB_NVIDIA is not set/CONFIG_FB_NVIDIA=y\nCONFIG_FB_NVIDIA_I2C=y\nCONFIG_FB_NVIDIA_DEBUG=y\nCONFIG_FB_NVIDIA_BACKLIGHT=y/" .config
|
||||
sed -i "s/# CONFIG_FB_RIVA is not set/CONFIG_FB_RIVA=y\n# CONFIG_FB_RIVA_I2C is not set\n# CONFIG_FB_RIVA_DEBUG is not set\nCONFIG_FB_RIVA_BACKLIGHT=y/" .config
|
||||
sed -i "s/# CONFIG_FB_I740 is not set/CONFIG_FB_I740=y/" .config
|
||||
sed -i "s/# CONFIG_FB_RADEON is not set/CONFIG_FB_RADEON=y\nCONFIG_FB_RADEON_I2C=y\nCONFIG_FB_RADEON_BACKLIGHT=y\n# CONFIG_FB_RADEON_DEBUG is not set/" .config
|
||||
|
||||
sed -i "s/# CONFIG_FB_3DFX is not set/CONFIG_FB_3DFX=y\nCONFIG_FB_3DFX_ACCEL=y\nCONFIG_FB_3DFX_I2C=y/" .config
|
||||
sed -i "s/# CONFIG_FB_VOODOO1 is not set/CONFIG_FB_VOODOO1=y/" .config
|
||||
sed -i "s/# CONFIG_FB_VT8623 is not set/CONFIG_FB_VT8623=y/" .config
|
||||
sed -i "s/# CONFIG_FB_TRIDENT is not set/CONFIG_FB_TRIDENT=y/" .config
|
||||
sed -i "s/# CONFIG_FB_IBM_GXT4500 is not set/CONFIG_FB_IBM_GXT4500=y/" .config
|
||||
sed -i "s/# CONFIG_FB_SIMPLE is not set/CONFIG_FB_SIMPLE=y/" .config
|
||||
|
||||
sed -i "/CONFIG_HDMI=y/i\CONFIG_VGASTATE=y" .config
|
||||
sed -i "/# CONFIG_VIRT_DRIVERS is not set/i\CONFIG_IRQ_BYPASS_MANAGER=y" .config
|
||||
sed -i "/CONFIG_VIRTIO_MENU=y/i\CONFIG_VIRTIO=y" .config
|
||||
|
||||
sed -i "s/# CONFIG_VIRTIO_PCI is not set/CONFIG_VIRTIO_PCI=y\nCONFIG_VIRTIO_PCI_LEGACY=y\n# CONFIG_VIRTIO_BALLOON is not set\n# CONFIG_VIRTIO_INPUT is not set/" .config
|
||||
sed -i "s/# CONFIG_ACPI_WMI is not set/CONFIG_ACPI_WMI=y/" .config
|
||||
sed -i "/# CONFIG_ACERHDF is not set/i\CONFIG_WMI_BMOF=y" .config
|
||||
sed -i "/# CONFIG_ACERHDF is not set/i\# CONFIG_ALIENWARE_WMI is not set" .config
|
||||
sed -i "/# CONFIG_ACERHDF is not set/i\# CONFIG_HUAWEI_WMI is not set" .config
|
||||
sed -i "/# CONFIG_ACERHDF is not set/i\# CONFIG_INTEL_WMI_SBL_FW_UPDATE is not set" .config
|
||||
sed -i "/# CONFIG_ACERHDF is not set/i\# CONFIG_INTEL_WMI_THUNDERBOLT is not set" .config
|
||||
sed -i "/# CONFIG_ACERHDF is not set/i\CONFIG_MXM_WMI=y" .config
|
||||
sed -i "/# CONFIG_ACERHDF is not set/i\# CONFIG_PEAQ_WMI is not set" .config
|
||||
sed -i "/# CONFIG_ACERHDF is not set/i\# CONFIG_XIAOMI_WMI is not set" .config
|
||||
|
||||
sed -i "/# CONFIG_APPLE_GMUX is not set/i\# CONFIG_ACER_WMI is not set" .config
|
||||
sed -i "/CONFIG_EEEPC_LAPTOP=y/i\# CONFIG_ASUS_WMI is not set" .config
|
||||
sed -i "/# CONFIG_AMILO_RFKILL is not set/i\# CONFIG_DELL_WMI_AIO is not set" .config
|
||||
sed -i "/# CONFIG_AMILO_RFKILL is not set/i\# CONFIG_DELL_WMI_LED is not set" .config
|
||||
sed -i "/# CONFIG_IBM_RTL is not set/i\# CONFIG_HP_WMI is not set" .config
|
||||
sed -i "/# CONFIG_SAMSUNG_LAPTOP is not set/i\# CONFIG_MSI_WMI is not set" .config
|
||||
sed -i "/# CONFIG_ACPI_CMPC is not set/i\# CONFIG_TOSHIBA_WMI is not set" .config
|
||||
sed -i "/# CONFIG_PANASONIC_LAPTOP is not set/i\# CONFIG_LG_LAPTOP is not set" .config
|
||||
|
||||
sed -i "/# CONFIG_CRYPTO_TEST is not set/a\CONFIG_CRYPTO_ENGINE=m" .config
|
||||
sed -i "/# CONFIG_CRYPTO_DEV_SAFEXCEL is not set/i\CONFIG_CRYPTO_DEV_VIRTIO=m" .config
|
||||
|
||||
sed -i "/# CONFIG_DMA_API_DEBUG is not set/i\CONFIG_DMA_CMA=y\n" .config
|
||||
sed -i "/# CONFIG_DMA_API_DEBUG is not set/i\#\n# Default contiguous memory area size:\n#" .config
|
||||
sed -i "/# CONFIG_DMA_API_DEBUG is not set/i\CONFIG_CMA_SIZE_MBYTES=0" .config
|
||||
sed -i "/# CONFIG_DMA_API_DEBUG is not set/i\CONFIG_CMA_SIZE_SEL_MBYTES=y" .config
|
||||
sed -i "/# CONFIG_DMA_API_DEBUG is not set/i\# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set" .config
|
||||
sed -i "/# CONFIG_DMA_API_DEBUG is not set/i\# CONFIG_CMA_SIZE_SEL_MIN is not set" .config
|
||||
sed -i "/# CONFIG_DMA_API_DEBUG is not set/i\# CONFIG_CMA_SIZE_SEL_MAX is not set" .config
|
||||
sed -i "/# CONFIG_DMA_API_DEBUG is not set/i\CONFIG_CMA_ALIGNMENT=8" .config
|
||||
|
||||
# 鼠标的配置 ( 否则 xfce4 界面上鼠标不能操作 /dev/input/mice, 上层需要 xf86-input-evdev, libevdev )
|
||||
sed -i "/# CONFIG_INPUT_MOUSEDEV is not set/a\CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768" .config
|
||||
sed -i "/# CONFIG_INPUT_MOUSEDEV is not set/a\CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024" .config
|
||||
sed -i "/# CONFIG_INPUT_MOUSEDEV is not set/a\CONFIG_INPUT_MOUSEDEV_PSAUX=y" .config
|
||||
sed -i "s/# CONFIG_INPUT_MOUSEDEV is not set/CONFIG_INPUT_MOUSEDEV=y/" .config
|
||||
|
||||
sed -i "s/# CONFIG_UHID is not set/CONFIG_UHID=y/" .config
|
||||
sed -i "s/# CONFIG_USB_DYNAMIC_MINORS is not set/CONFIG_USB_DYNAMIC_MINORS=y/" .config
|
||||
sed -i "s/# CONFIG_USB_XHCI_PLATFORM is not set/CONFIG_USB_XHCI_PLATFORM=y/" .config
|
||||
sed -i "s/# CONFIG_USB_EHCI_ROOT_HUB_TT is not set/CONFIG_USB_EHCI_ROOT_HUB_TT=y/" .config
|
||||
sed -i "s/# CONFIG_USB_EHCI_HCD_PLATFORM is not set/CONFIG_USB_EHCI_HCD_PLATFORM=y/" .config
|
||||
sed -i "s/# CONFIG_USB_OHCI_HCD_PLATFORM is not set/CONFIG_USB_OHCI_HCD_PLATFORM=y/" .config
|
||||
|
||||
# 键盘驱动 ( libevdev https://linuxfromscratch.org/blfs/view/11.0/x/x7driver.html )
|
||||
sed -i "s/# CONFIG_INPUT_UINPUT is not set/CONFIG_INPUT_UINPUT=y/" .config
|
||||
|
||||
# wacom 驱动支持 ( xf86-input-wacom )
|
||||
sed -i "s/# CONFIG_HID_WACOM is not set/CONFIG_HID_WACOM=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=${linux_install} headers_install -j8 && cp arch/x86_64/boot/bzImage ${linux_install} && cd ..
|
||||
make modules -j8
|
||||
#cd linux-5.8.6 && make x86_64_defconfig && make bzImage -j8 && make modules && make modules_install && cd ..
|
||||
make INSTALL_HDR_PATH=${linux_install} headers_install -j8
|
||||
make modules_install INSTALL_MOD_PATH=${linux_install} -j8 && cp arch/x86_64/boot/bzImage ${linux_install} || exit
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# 编译glibc
|
||||
@ -167,43 +309,174 @@ if [ ! -d "glibc_install" ]; then
|
||||
--disable-werror \
|
||||
--disable-werror \
|
||||
CFLAGS="$CFLAGS"
|
||||
make -j8 && make install -j8 DESTDIR=${glibc_install} && cd .. && cd ..
|
||||
make -j8 && make install -j8 DESTDIR=${glibc_install} || exit
|
||||
cd .. && cd ..
|
||||
fi
|
||||
|
||||
# 编译 busybox
|
||||
if [ ! -d "busybox_install" ]; then
|
||||
mkdir -pv busybox_install && cd ${BUSYBOX_SRC_DIR} && make distclean && make defconfig
|
||||
# 屏蔽掉 lsof 这个自带的太简单
|
||||
sed -i "s/CONFIG_LSOF=y/# CONFIG_LSOF is not set/" .config
|
||||
# 屏蔽掉 lspci 这个自带的太简单
|
||||
sed -i "s/CONFIG_LSPCI=y/# CONFIG_LSPCI is not set/" .config
|
||||
# 静态编译 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${linux_install}/include -I${glibc_install}/include -L${glibc_install}/usr/lib64 $CFLAGS\"|" .config
|
||||
make busybox -j8 && make CONFIG_PREFIX=${busybox_install} install && cd ..
|
||||
# 环境变量 PATH 的设定,因为 busybox 的 init 会覆盖用户设置的 PATH,只能源码进行编译
|
||||
sed -i "s|#define BB_ADDITIONAL_PATH \"\"|#define BB_ADDITIONAL_PATH \":/usr/local/sbin:/usr/local/bin\"|" include/libbb.h
|
||||
make busybox -j8 && make CONFIG_PREFIX=${busybox_install} install || exit
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# 编译 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=${gcc_install} && cd ..
|
||||
#------------------------------------------------------------------
|
||||
# 编译通用工具
|
||||
#------------------------------------------------------------------
|
||||
if [ "${with_util}" = true ]; then
|
||||
# 编译 lshw ( 调试方便 )
|
||||
if [ ! -d "lshw_install" ]; then
|
||||
mkdir -pv lshw_install && cd ${LSHW_SRC_DIR}
|
||||
CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${lshw_install} PREFIX=/usr || exit
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# 编译 pciutils ( busybox 的 lspci 太简单 )
|
||||
if [ ! -d "pciutils_install" ]; then
|
||||
mkdir -pv pciutils_install && cd ${PCIUTILS_SRC_DIR}
|
||||
CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${pciutils_install} PREFIX=/usr || exit
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# 编译 lsof ( busybox 的太简单 )
|
||||
if [ ! -d "lsof_install" ]; then
|
||||
mkdir -pv lsof_install && cd ${LSOF_SRC_DIR}
|
||||
./Configure linux -n
|
||||
CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && mkdir -pv ${lsof_install}/usr/bin && cp ./lsof ${lsof_install}/usr/bin || exit
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# 编译 strace ( 方便调试 )
|
||||
if [ ! -d "strace_install" ]; then
|
||||
mkdir -pv strace_install && cd ${STRACE_SRC_DIR}
|
||||
./configure --prefix=/usr --enable-mpers=no
|
||||
CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${strace_install} PREFIX=/usr || exit
|
||||
cd ..
|
||||
fi
|
||||
fi
|
||||
|
||||
# 编译 binutils
|
||||
if [ ! -d "binutils_install" ]; then
|
||||
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 ..
|
||||
#------------------------------------------------------------------
|
||||
# 编译 openssh
|
||||
#------------------------------------------------------------------
|
||||
if [ "${with_ssh}" = true ]; then
|
||||
# 编译 openssl
|
||||
if [ ! -d "openssl_install" ]; then
|
||||
mkdir -pv openssl_install && cd ${OPENSSL_SRC_DIR}
|
||||
./config --prefix=/usr shared
|
||||
CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${openssl_install} PREFIX=/usr || exit
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# 编译 openssh ( 需要 openssl )
|
||||
if [ ! -d "openssh_install" ]; then
|
||||
mkdir -pv openssh_install && cd ${OPENSSH_SRC_DIR}
|
||||
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-ssl-dir=${openssl_install}/usr/ --without-openssl-header-check
|
||||
CFLAGS="-L${glibc_install}/lib64 -L${openssl_install}/usr/lib $CFLAGS" make -j8 && make install -j8 DESTDIR=${openssh_install} PREFIX=/usr
|
||||
# 修改配置文件
|
||||
sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/" ${openssh_install}/etc/ssh/sshd_config
|
||||
echo "HostKeyAlgorithms=ssh-rsa,ssh-dss" >> ${openssh_install}/etc/ssh/sshd_config
|
||||
echo "KexAlgorithms=diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" >> ${openssh_install}/etc/ssh/sshd_config
|
||||
# 准备环境
|
||||
if [ ! -d "${openssh_install}/var/empty" ]; then
|
||||
mkdir -pv ${openssh_install}/var/empty
|
||||
fi
|
||||
chmod 744 ${openssh_install}/var/empty/
|
||||
chown root ${openssh_install}/var/empty/
|
||||
if [ ! -f "${openssh_install}/etc/ssh/ssh_host_dsa_key" ]; then
|
||||
ssh-keygen -t dsa -P "" -f ${openssh_install}/etc/ssh/ssh_host_dsa_key
|
||||
fi
|
||||
if [ ! -f "${openssh_install}/etc/ssh/ssh_host_rsa_key" ]; then
|
||||
ssh-keygen -t rsa -P "" -f ${openssh_install}/etc/ssh/ssh_host_rsa_key
|
||||
fi
|
||||
# 开启 sftp, 可以进行文件上传
|
||||
if [ -f "${openssh_install}/etc/ssh/sshd_config" ]; then
|
||||
sed -i "s/\/usr\/libexec\/sftp-server/internal-sftp/" ${openssh_install}/etc/ssh/sshd_config
|
||||
fi
|
||||
cd ..
|
||||
fi
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------
|
||||
# 编译防火墙
|
||||
#------------------------------------------------------------------
|
||||
if [ "${with_ufw}" = true ]; then
|
||||
ufw_include=" \
|
||||
-I${libmnl_install}/usr/include \
|
||||
-I${libnftnl_install}/usr/include"
|
||||
|
||||
ufw_library=" \
|
||||
-L${libmnl_install}/usr/lib -lmnl \
|
||||
-L${libnftnl_install}/usr/lib -lnftnl"
|
||||
|
||||
# 编译 libmnl
|
||||
if [ ! -d "libmnl_install" ]; then
|
||||
mkdir -pv libmnl_install && cd ${LIBMNL_SRC_DIR}
|
||||
./configure --prefix=/usr
|
||||
CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${libmnl_install} PREFIX=/usr || exit
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# 编译 libnftnl
|
||||
if [ ! -d "libnftnl_install" ]; then
|
||||
mkdir -pv libnftnl_install && cd ${LIBNFTNL_SRC_DIR}
|
||||
export LIBMNL_CFLAGS="-I${libmnl_install}/usr/include"
|
||||
export LIBMNL_LIBS="-L${libmnl_install}/usr/lib -lmnl"
|
||||
./configure --prefix=/usr
|
||||
CFLAGS="-L${glibc_install}/lib64 $CFLAGS" make -j8 && make install -j8 DESTDIR=${libnftnl_install} PREFIX=/usr || exit
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# 编译 iptables ( 需要 libmnl, libnftnl )
|
||||
if [ ! -d "iptables_install" ]; then
|
||||
mkdir -pv iptables_install && cd ${IPTABLES_SRC_DIR}
|
||||
export libmnl_CFLAGS="-I${libmnl_install}/usr/include"
|
||||
export libmnl_LIBS="-L${libmnl_install}/usr/lib -lmnl"
|
||||
export libnftnl_CFLAGS="-I${libnftnl_install}/usr/include"
|
||||
export libnftnl_LIBS="-L${libnftnl_install}/usr/lib -lnftnl"
|
||||
./configure --prefix=/usr
|
||||
CFLAGS="-L${glibc_install}/lib64 ${ufw_include} $CFLAGS" make -j8 && make install -j8 DESTDIR=${iptables_install} PREFIX=/usr || exit
|
||||
cd ..
|
||||
fi
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------
|
||||
# 编译 gcc ( xfce 需要开启这个 )
|
||||
#------------------------------------------------------------------
|
||||
if [ "${with_gcc}" = true ]; then
|
||||
# 编译 gcc
|
||||
if [ ! -d "gcc_install" ]; then
|
||||
mkdir -pv gcc_install && cd ${GCC_SRC_DIR}
|
||||
if [ -f "config.cache" ]; then
|
||||
rm ./config.cache
|
||||
fi
|
||||
./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=${gcc_install} && cd ..
|
||||
fi
|
||||
|
||||
# 编译 binutils
|
||||
if [ ! -d "binutils_install" ]; then
|
||||
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} || exit
|
||||
cd ..
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ..
|
||||
|
||||
# 编译 xorg [ no same time with xfce ]
|
||||
if [ "${with_xorg}" = true ]; then
|
||||
./mk_xorg.sh
|
||||
fi
|
||||
|
||||
# 编译 xfce [ no same time with xorg ]
|
||||
if [ "${with_xfce}" = true ]; then
|
||||
./mk_xfce.sh
|
||||
# 编译 xfce ( 需要 gcc 的支持 )
|
||||
if [ "${with_xfce}" = true ] && [ "${with_gcc}" = true ]; then
|
||||
./mk_xfce.sh img
|
||||
fi
|
||||
|
||||
echo "Run the next script: 02_build_img.sh"
|
||||
|
293
02_build_img.sh
293
02_build_img.sh
@ -1,6 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
#----------------------------------------------
|
||||
#
|
||||
# 导入公共环境
|
||||
#
|
||||
#----------------------------------------------
|
||||
. ./common.sh
|
||||
|
||||
#----------------------------------------------
|
||||
@ -16,21 +20,12 @@
|
||||
#
|
||||
#----------------------------------------------
|
||||
echo "${CYAN}--- build disk --- ${NC}"
|
||||
# 创建磁盘 64M
|
||||
# 创建磁盘 128M 或 256M
|
||||
if [ "${with_gcc}" = false ]; then
|
||||
dd if=/dev/zero of=disk.img bs=1M count=128
|
||||
create_disk disk.img 4096
|
||||
else
|
||||
dd if=/dev/zero of=disk.img bs=1M count=256
|
||||
create_disk disk.img 4096
|
||||
fi
|
||||
# 对磁盘进行分区一个主分区
|
||||
fdisk disk.img << EOF
|
||||
n
|
||||
p
|
||||
|
||||
|
||||
|
||||
w
|
||||
EOF
|
||||
echo "${GREEN}+++ build disk ok +++${NC}"
|
||||
|
||||
# 磁盘镜像挂载到具体设备
|
||||
@ -40,6 +35,7 @@ losetup -o 1048576 ${loop_dev} disk.img
|
||||
# 对磁盘进行格式化
|
||||
mkfs.ext3 ${loop_dev}
|
||||
|
||||
# 如果制作的 disk.img
|
||||
diskfs="diskfs"
|
||||
# 挂载磁盘到本地目录
|
||||
mkdir -pv ${diskfs}
|
||||
@ -49,7 +45,7 @@ grub-install --boot-directory=${diskfs}/boot/ --target=i386-pc --modules=part_ms
|
||||
|
||||
#---------------------------------------------
|
||||
#
|
||||
# 制作内核和 rootfs
|
||||
# 制作内核和 rootfs ( run 目录下 udev 被服务 udevd 使用,否则 xfce 鼠标不能使用 )
|
||||
#
|
||||
#---------------------------------------------
|
||||
rm -rf rootfs
|
||||
@ -58,16 +54,19 @@ mkdir -pv rootfs/dev
|
||||
mkdir -pv rootfs/etc
|
||||
mkdir -pv rootfs/sys
|
||||
mkdir -pv rootfs/mnt
|
||||
mkdir -pv rootfs/run
|
||||
mkdir -pv rootfs/tmp
|
||||
mkdir -pv rootfs/lib
|
||||
mkdir -pv rootfs/sbin
|
||||
mkdir -pv rootfs/proc
|
||||
mkdir -pv rootfs/root
|
||||
mkdir -pv rootfs/lib64
|
||||
mkdir -pv rootfs/var/run
|
||||
mkdir -pv rootfs/lib/modules
|
||||
|
||||
# 拷贝内核镜像
|
||||
cp ${linux_install}/bzImage ${diskfs}/boot/bzImage
|
||||
cp ${linux_install}/lib ${diskfs}/ -r
|
||||
|
||||
# 拷贝 glibc 到 rootfs
|
||||
cp ${glibc_install}/* rootfs/ -r
|
||||
@ -75,11 +74,11 @@ rm -rf rootfs/var/db
|
||||
rm -rf rootfs/share
|
||||
rm -rf rootfs/usr/share
|
||||
find rootfs/ -name "*.a" -exec rm -rf {} \;
|
||||
|
||||
# 编译的镜像带有 gcc 编译器
|
||||
if [ "${with_gcc}" = false ]; then
|
||||
rm -rf rootfs/usr/include
|
||||
else
|
||||
echo "${RED} with-gcc tools --- you can build your world${NC}"
|
||||
cp ${glibc_install}/usr/lib64/libc_nonshared.a rootfs/usr/lib64
|
||||
fi
|
||||
|
||||
@ -103,22 +102,30 @@ echo "${CYAN}--- build initrd ---${NC}"
|
||||
# 这种方法也可以 mkinitramfs -k -o ./${diskfs}/boot/initrd 4.14.9
|
||||
# 利用 Busybox 采用脚本制作 init 脚本 https://blog.csdn.net/embeddedman/article/details/7721926
|
||||
|
||||
# 光驱挂载 : /dev/cdrom 是 /dev/sr0 的软连接,也就是说 /dev/sr0 才是实际意义上的光驱。所以没有软连接,
|
||||
# 照样可以挂载光驱。使用命令"mount /dev/sr0 /mnt/cdrom"便可以实现挂载。
|
||||
|
||||
make_init() {
|
||||
|
||||
cat<<"EOF">init
|
||||
#!/bin/sh
|
||||
|
||||
# 必须首先挂载,否则 mdev 不能正常工作
|
||||
mount -t sysfs sysfs /sys
|
||||
mount -t proc proc /proc
|
||||
mount -t devtmpfs udev /dev
|
||||
mount -t tmpfs tmpfs /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 /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 devpts /dev/pts
|
||||
@ -127,7 +134,11 @@ mount --move /dev /mnt/dev
|
||||
mount --move /sys /mnt/sys
|
||||
mount --move /proc /mnt/proc
|
||||
mount --move /tmp /mnt/tmp
|
||||
# 切换到真正的磁盘系统上 rootfs ---> diskfs
|
||||
|
||||
# 因为 busybox 的 init 会重置环境变量 PATH 等,因此需要放到这里加载
|
||||
export LD_LIBRARY_PATH="/lib:/lib64:/usr/lib:/usr/lib64:/usr/local/lib:/usr/local/lib64:/usr/lib/x86_64-linux-gnu"
|
||||
|
||||
# 切换到真正的磁盘系统上 rootfs ---> diskfs, 切换到真正的文件系统
|
||||
exec switch_root /mnt /sbin/init
|
||||
EOF
|
||||
|
||||
@ -148,21 +159,60 @@ make_init
|
||||
|
||||
# 指定了利用 /etc/init.d/rcS 启动
|
||||
cat<<"EOF">etc/inittab
|
||||
|
||||
# 启动 syslogd ( 日志系统 )
|
||||
::sysinit:/bin/echo "starting syslogd ... ..."
|
||||
::sysinit:/sbin/syslogd
|
||||
::sysinit:/sbin/klogd
|
||||
|
||||
# 启动 udevd 服务,保证鼠标设备能正常监视,否则桌面系统下键盘不能使用
|
||||
::sysinit:/bin/echo "starting udevd ... ..."
|
||||
::sysinit:/usr/sbin/udevd --daemon
|
||||
::sysinit:/usr/sbin/udevadm trigger
|
||||
::sysinit:/usr/sbin/udevadm settle
|
||||
|
||||
# 基本启动信息都放到这个脚本里
|
||||
::sysinit:echo "sysinit ++++++++++++++++++++++++++++++++++++++"
|
||||
::sysinit:/etc/init.d/rcS
|
||||
::sysinit:echo "sysinit ++++++++++++++++++++++++++++++++++++++"
|
||||
|
||||
# /bin/sh invocations on selected ttys
|
||||
#
|
||||
# Note below that we prefix the shell commands with a "-" to indicate to the
|
||||
# shell that it is supposed to be a login shell. Normally this is handled by
|
||||
# login, but since we are bypassing login in this case, BusyBox lets you do
|
||||
# this yourself...
|
||||
#
|
||||
# Start an "askfirst" shell on the console (whatever that may be) -f root 自动登录
|
||||
|
||||
# 一定要加 tty1 ,否则登录时,会提示 : root login on 'UNKNOWN'
|
||||
tty1::respawn:-/bin/login -f root
|
||||
# Start an "askfirst" shell on /dev/tty2-4
|
||||
tty2::respawn:-/bin/sh
|
||||
tty3::respawn:-/bin/sh
|
||||
tty4::respawn:-/bin/sh
|
||||
|
||||
# /sbin/getty invocations for selected ttys
|
||||
tty4::respawn:/sbin/getty 38400 tty5
|
||||
tty5::respawn:/sbin/getty 38400 tty6
|
||||
|
||||
# Example of how to put a getty on a serial line (for a terminal)
|
||||
#::respawn:/sbin/getty -L ttyS0 9600 vt100
|
||||
#::respawn:/sbin/getty -L ttyS1 9600 vt100
|
||||
#
|
||||
# Example how to put a getty on a modem line.
|
||||
#::respawn:/sbin/getty 57600 ttyS2
|
||||
|
||||
# Stuff to do when restarting the init process
|
||||
::restart:/sbin/init
|
||||
|
||||
# Stuff to do before rebooting
|
||||
::ctrlaltdel:/sbin/reboot
|
||||
::shutdown:/bin/umount -a -r
|
||||
::shutdown:/sbin/swapoff -a
|
||||
::sysinit:echo "sysinit 1++++++++++++++++++++++++++++++++++++++"
|
||||
::sysinit:/etc/init.d/rcS
|
||||
::sysinit:echo "sysinit 2++++++++++++++++++++++++++++++++++++++"
|
||||
tty1::once:echo "hello smart-os tty1"
|
||||
tty1::respawn:/bin/sh
|
||||
tty2::once:echo "hello smart-os tty2"
|
||||
tty2::respawn:/bin/sh
|
||||
tty3::once:echo "hello smart-os tty3"
|
||||
tty3::respawn:/bin/sh
|
||||
EOF
|
||||
|
||||
# 制作 initrd 文件系统
|
||||
find . | cpio -R root:root -H newc -o | gzip -9 > ../${diskfs}/boot/initrd
|
||||
echo "${GREEN}+++ build initrd ok +++${NC}"
|
||||
cd ..
|
||||
@ -174,9 +224,47 @@ cd ..
|
||||
#--------------------------------------------------------------
|
||||
echo "${CYAN}--- build diskfs ---${NC}"
|
||||
cp rootfs/* ${diskfs} -r
|
||||
# 带有 gcc 编译器
|
||||
|
||||
# +++ 通用工具 +++
|
||||
if [ "${with_util}" = true ]; then
|
||||
echo "${RED} ... build with-util${NC}"
|
||||
# 单独的 lshw
|
||||
cp ${lshw_install}/* ${diskfs} -r
|
||||
# 单独的 lsof
|
||||
cp ${lsof_install}/* ${diskfs} -r
|
||||
# 单独的 pciutils
|
||||
cp ${pciutils_install}/* ${diskfs} -r
|
||||
if [ -f "${diskfs}/usr/share/pci.ids.gz" ]; then
|
||||
mkdir -pv ${diskfs}/usr/local/share
|
||||
mv ${diskfs}/usr/share/pci.ids.gz ${diskfs}/usr/local/share/pci.ids.gz
|
||||
fi
|
||||
# 单独的 strace
|
||||
cp ${strace_install}/* ${diskfs} -r
|
||||
fi
|
||||
|
||||
# +++ ufw +++
|
||||
if [ "${with_ufw}" = true ]; then
|
||||
echo "${RED} ... build with-ufw${NC}"
|
||||
# 拷贝 libmnl
|
||||
cp ${libmnl_install}/* ${diskfs} -r
|
||||
# 拷贝 libnftnl
|
||||
cp ${libnftnl_install}/* ${diskfs} -r
|
||||
# 拷贝 iptables
|
||||
cp ${iptables_install}/* ${diskfs} -r
|
||||
fi
|
||||
|
||||
# +++ openssh +++
|
||||
if [ "${with_ssh}" = true ]; then
|
||||
echo "${RED} ... build with-ssh${NC}"
|
||||
# 带有 openssl
|
||||
cp ${openssl_install}/* ${diskfs} -r
|
||||
# 带有 openssh
|
||||
cp ${openssh_install}/* ${diskfs} -r
|
||||
fi
|
||||
|
||||
# +++ gcc +++
|
||||
if [ "${with_gcc}" = true ]; then
|
||||
echo "${RED} with-gcc tools --- you can build your world${NC}"
|
||||
echo "${RED} ... build with-gcc${NC}"
|
||||
cp ${gcc_install}/* ${diskfs} -r
|
||||
cp ${binutils_install}/usr/x86_64-pc-linux-gnu/* ${diskfs} -r
|
||||
fi
|
||||
@ -184,21 +272,106 @@ rm -rf ${diskfs}/init ${diskfs}/lost+found
|
||||
|
||||
# 测试用户登陆模式: root/123456
|
||||
if [ "${with_login}" = true ]; then
|
||||
echo "${RED} with-login --- it's an exciting time ${NC}"
|
||||
echo "${RED} ... build with-login${NC}"
|
||||
./mk_login.sh ${diskfs}
|
||||
fi
|
||||
|
||||
# +++ xfce desktop +++
|
||||
if [ "${with_xfce}" = true ]; then
|
||||
echo "${RED} ... build xfce desktop${NC}"
|
||||
# 构建 Xorg 的键盘数据
|
||||
rm ${xfce_install}/usr/local/share/X11/xkb -rf
|
||||
ln -s /usr/share/X11/xkb ${xfce_install}/usr/local/share/X11
|
||||
# 依赖版本 libpcre.so.3
|
||||
if [ -f "${xfce_install}/usr/local/lib/libpcre.so.1" ]; then
|
||||
cp ${xfce_install}/usr/local/lib/libpcre.so.1 ${xfce_install}/usr/local/lib/libpcre.so.3
|
||||
fi
|
||||
# 依赖版本 libedit2
|
||||
if [ -f "${xfce_install}/usr/local/lib/libedit.so.0" ]; then
|
||||
cp ${xfce_install}/usr/local/lib/libedit.so.0 ${xfce_install}/usr/local/lib/libedit.so.2
|
||||
fi
|
||||
# 依赖版本 libtinfo.so.5
|
||||
if [ -f "${xfce_install}/usr/lib/libtinfo.so.6" ]; then
|
||||
cp ${xfce_install}/usr/lib/libtinfo.so.6 ${xfce_install}/usr/lib/libtinfo.so.5
|
||||
fi
|
||||
# 依赖版本 libffi.so.6
|
||||
if [ -f "${xfce_install}/usr/local/lib/libffi.so.8" ]; then
|
||||
cp ${xfce_install}/usr/local/lib/libffi.so.8 ${xfce_install}/usr/local/lib/libffi.so.6
|
||||
fi
|
||||
|
||||
# dbus 用户添加
|
||||
echo "video:x:44:" >> ${diskfs}/etc/group
|
||||
echo "messagebus:x:107:" >> ${diskfs}/etc/group
|
||||
echo "messagebus:x:103:107::/nonexistent:/usr/sbin/nologin" >> ${diskfs}/etc/passwd
|
||||
# dbus 启动需要这个,否则 upowerd 就不能正常工作
|
||||
cp ${xfce_install}/usr/share/dbus-1/* ${xfce_install}/usr/local/share/dbus-1/ -r
|
||||
|
||||
# dbus 启动脚本
|
||||
# dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
|
||||
# dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
|
||||
# dbus-daemon --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork --print-address 3
|
||||
# 常用的 dbus 命令
|
||||
# 列出所有的dbus服务 :
|
||||
# dbus-send --system --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListActivatableNames
|
||||
# UPower 的dbus服务 :
|
||||
# dbus-send --print-reply --system --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.EnumerateDevices
|
||||
|
||||
# 产生 xfce 启动脚本,进入系统后,手工执行这个就能拉起桌面
|
||||
echo "if [ -f "/swapfile" ]; then" > ${diskfs}/xfce.sh
|
||||
echo " dd if=/dev/zero of=/swapfile bs=1M count=2048" >> ${diskfs}/xfce.sh
|
||||
echo " mkswap /swapfile" >> ${diskfs}/xfce.sh
|
||||
echo "fi" >> ${diskfs}/xfce.sh
|
||||
echo "swapon /swapfile" >> ${diskfs}/xfce.sh
|
||||
echo "/usr/libexec/upowerd &" >> ${diskfs}/xinitrc
|
||||
echo "/usr/local/bin/xfce4-session" >> ${diskfs}/xinitrc
|
||||
echo "dbus-daemon --system --nopidfile --systemd-activation" >> ${diskfs}/xfce.sh
|
||||
echo "xinit /xinitrc -- /usr/local/bin/Xorg :10" >> ${diskfs}/xfce.sh
|
||||
chmod +x ${diskfs}/xfce.sh ${diskfs}/xinitrc
|
||||
|
||||
# 添加 machine-id
|
||||
mkdir -p ${diskfs}/usr/local/var/lib/dbus
|
||||
echo "2add25d2f5994832ba171755bc21f9fe" > ${diskfs}/etc/machine-id
|
||||
echo "2add25d2f5994832ba171755bc21f9fe" > ${diskfs}/usr/local/var/lib/dbus/machine-id
|
||||
|
||||
# 这些本来需要编译完成,目前暂且拷贝
|
||||
# cp /usr/lib/x86_64-linux-gnu/libLLVM-10.so.1 build/xfce_install/usr/lib/x86_64-linux-gnu/
|
||||
|
||||
# 拷贝 xfce4 到镜像目录,删除 .a 文件减少体积,其实编译选型不编译文档和测试代码会更小
|
||||
find ${xfce_install}/ -name "*.a" -exec rm -rf {} \;
|
||||
find ${xfce_install}/ -name "man" -exec rm -rf {} \;
|
||||
find ${xfce_install}/ -name "*doc" -exec rm -rf {} \;
|
||||
cp ${xfce_install}/* ${diskfs} -r -n
|
||||
|
||||
# 删除冗余文件,防止后续编译很多警告
|
||||
# 依赖版本 libpcre.so.3
|
||||
if [ -f "${xfce_install}/usr/local/lib/libpcre.so.1" ]; then
|
||||
rm ${xfce_install}/usr/local/lib/libpcre.so.3 -rf
|
||||
fi
|
||||
# 依赖版本 libedit2
|
||||
if [ -f "${xfce_install}/usr/local/lib/libedit.so.0" ]; then
|
||||
rm ${xfce_install}/usr/local/lib/libedit.so.2 -rf
|
||||
fi
|
||||
# 依赖版本 libtinfo.so.5
|
||||
if [ -f "${xfce_install}/usr/lib/libtinfo.so.6" ]; then
|
||||
rm ${xfce_install}/usr/lib/libtinfo.so.5 -rf
|
||||
fi
|
||||
# 依赖版本 libffi.so.6
|
||||
if [ -f "${xfce_install}/usr/local/lib/libffi.so.8" ]; then
|
||||
rm ${xfce_install}/usr/local/lib/libffi.so.6 -rf
|
||||
fi
|
||||
fi
|
||||
|
||||
# 我们测试驱动, 制作的镜像启动后,我们进入此目录 insmod hello_world.ko 即可
|
||||
./mk_drv.sh $(pwd)/${diskfs}/lib/modules
|
||||
# 编译网卡驱动 ( 目前版本内核已集成 e1000 )
|
||||
# cd ${build_dir}/linux-4.14.9 && make M=drivers/net/ethernet/intel/e1000/ && cd ../..
|
||||
# cd ${build_dir}/linux-5.8.6 && make M=drivers/net/ethernet/intel/e1000/ && cd ../..
|
||||
|
||||
# 生成 grub.cfg 文件, 增加 console=ttyS0 就会让 qemu 输出日志到 qemu.log
|
||||
# 生成 grub.cfg 文件, 增加 console=ttyS0 就会让 qemu 输出日志到 qemu.log, quiet 屏蔽内核过多的信息输出
|
||||
cat - > ${diskfs}/boot/grub/grub.cfg << EOF
|
||||
set timeout=3
|
||||
menuentry "smart-os" {
|
||||
root=(hd0,msdos1)
|
||||
linux /boot/bzImage console=tty0
|
||||
linux /boot/bzImage console=tty0 quiet
|
||||
initrd /boot/initrd
|
||||
}
|
||||
EOF
|
||||
@ -209,6 +382,7 @@ nameserver 8.8.8.8
|
||||
nameserver 114.114.114.114
|
||||
EOF
|
||||
|
||||
# 生成 /etc/fstab 挂载文件
|
||||
cat -> ${diskfs}/etc/fstab << EOF
|
||||
# <file system> <dir> <type> <options> <dump> <pass>
|
||||
proc /proc proc defaults 0 0
|
||||
@ -229,6 +403,8 @@ title=$(cat<<EOF
|
||||
\e[0m
|
||||
EOF
|
||||
)
|
||||
|
||||
# 生成 /etc/init.d/rcS 脚本
|
||||
mkdir -pv ${diskfs}/etc/init.d
|
||||
cat - > ${diskfs}/etc/init.d/rcS << EOF
|
||||
#!/bin/sh
|
||||
@ -238,18 +414,60 @@ echo -e "\n“${title}”\n"
|
||||
cd /lib/modules && insmod hello_world.ko
|
||||
|
||||
# dns 测试 busybox 必须动态编译 动态编译 glibc 已经集成 dns 功能
|
||||
ifconfig eth0 192.168.100.6 && ifconfig eth0 up
|
||||
route add default gw 192.168.100.1
|
||||
# qemu 网卡设置(调试方便)
|
||||
# ifconfig eth0 192.168.100.6 && ifconfig eth0 up
|
||||
# route add default gw 192.168.100.1
|
||||
|
||||
# vmware 网卡设置 ( 调试方便 )
|
||||
ifconfig eth0 192.168.222.195 && ifconfig eth0 up
|
||||
route add default gw 192.168.222.2
|
||||
|
||||
# exec 执行 /etc/init.d/rc.local 脚本
|
||||
# 启动 sshd 服务,保证远程连接,调试跟踪非常方便
|
||||
/usr/sbin/sshd
|
||||
|
||||
EOF
|
||||
chmod +x ${diskfs}/etc/init.d/rcS
|
||||
|
||||
# 登陆 login shell ,非 non-login shell
|
||||
if [ "${with_login}" = true ]; then
|
||||
# 必须设置这个 /usr/libexe/upowerd 才能启动,否则,就会提示 "name lost, exiting"
|
||||
echo "export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/usr/local/var/run/dbus/system_bus_socket" >> ${diskfs}/etc/profile
|
||||
echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> ${diskfs}/etc/profile
|
||||
echo "export LD_LIBRARY_PATH=/lib:/lib64:/usr/lib:/usr/lib64:/usr/local/lib:/usr/local/lib64:/usr/lib/x86_64-linux-gnu" >> ${diskfs}/etc/profile
|
||||
else
|
||||
# 必须设置这个 /usr/libexe/upowerd 才能启动,否则,就会提示 "name lost, exiting"
|
||||
echo "export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/usr/local/var/run/dbus/system_bus_socket" >> ${diskfs}/etc/profile
|
||||
echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> ${diskfs}/etc/bash.bashrc
|
||||
echo "export LD_LIBRARY_PATH=/lib:/lib64:/usr/lib:/usr/lib64:/usr/local/lib:/usr/local/lib64:/usr/lib/x86_64-linux-gnu" >> ${diskfs}/etc/bash.bashrc
|
||||
fi
|
||||
|
||||
echo "${GREEN}+++ build diskfs ok +++${NC}"
|
||||
|
||||
# 卸载映射
|
||||
umount ${loop_dev}
|
||||
losetup -d ${loop_dev}
|
||||
|
||||
#----------------------------------------------------------------
|
||||
#
|
||||
# 常用命令
|
||||
#
|
||||
#----------------------------------------------------------------
|
||||
# 查看CPU信息:cat /proc/cpuinfo
|
||||
# 查看板卡信息:cat /proc/pci
|
||||
# 查看PCI信息:lspci (相比cat /proc/pci更直观)
|
||||
# 查看内存信息:cat /proc/meminfo
|
||||
# 查看USB设备:cat /proc/bus/usb/devices
|
||||
# 查看键盘和鼠标:cat /proc/bus/input/devices
|
||||
# 查看系统硬盘信息和使用情况:fdisk & disk - l & df
|
||||
# 查看各设备的中断请求(IRQ):cat /proc/interrupts
|
||||
# 查看系统体系结构:uname -a
|
||||
# dmidecode查看硬件信息,包括bios、cpu、内存等信息
|
||||
# dmesg | more 查看硬件信息
|
||||
# modinfo命令可以单看指定的模块/驱动的信息
|
||||
# 查看设备名称 cat /sys/class/input/mouse2/device/name
|
||||
# linux为什么访问设备数据先要mount? https://www.zhihu.com/question/524667726
|
||||
|
||||
#---------------------------------------------------------------
|
||||
#
|
||||
# 查看磁盘内容
|
||||
@ -257,4 +475,13 @@ losetup -d ${loop_dev}
|
||||
#---------------------------------------------------------------
|
||||
./ls_img.sh
|
||||
|
||||
#---------------------------------------------------------------
|
||||
#
|
||||
# 转换为 vmware 格式, 虚拟机的磁盘类型一定设置为 SATA ,否则启动失败
|
||||
# SCSI 格式转换, 命令查询 : qemu-img convert -O vmdk -o ?
|
||||
# 需要二次转换 vmkfstools -i 11.vmdk esxi-compatible.vmdk
|
||||
#
|
||||
#---------------------------------------------------------------
|
||||
qemu-img convert disk.img -f raw -O vmdk disk_sata.vmdk
|
||||
|
||||
echo "Run the next script: 03_run_qemu.sh or 04_run_docker.sh"
|
||||
|
@ -91,6 +91,9 @@ else
|
||||
sdb_img="-hdb extra.img"
|
||||
fi
|
||||
|
||||
# 指定内存
|
||||
memory="-m 4G"
|
||||
|
||||
# 主磁盘
|
||||
disk="-drive format=raw,file=disk.img"
|
||||
|
||||
@ -101,8 +104,11 @@ logfile="-serial file:./qemu.log"
|
||||
# 网络参数
|
||||
network="-netdev tap,id=nd0,ifname=tap0,script=no,downscript=no -device e1000,netdev=nd0"
|
||||
|
||||
# 启动镜像 网络对应 run_nat.sh 里面的配置
|
||||
qemu-system-x86_64 ${disk} ${sdb_img} ${network} ${logfile}
|
||||
# 显卡参数 需要编译 xf86-video-vmware, see mk_xfce.sh
|
||||
display="-vga qxl"
|
||||
|
||||
# 启动镜像 网络对应 run_nat.sh 里面的配置 ( -enable-kvm : vmware 里面 CPU 设置需要支持虚拟化 Intel VT-x/EPT 或 AMD-V/RVI )
|
||||
# 命令 qemu-system-x86_64 -device help 可以查看支持哪些设备
|
||||
qemu-system-x86_64 -device qxl ${display} ${memory} ${disk} ${sdb_img} ${network} ${logfile}
|
||||
# stop nat
|
||||
stop_nat
|
||||
|
50
README.md
50
README.md
@ -1,16 +1,20 @@
|
||||
# smart-os 一个小巧的 linux 系统
|
||||
本项目给大家演示了怎么样快速制作一个小巧切功能齐全的 linux 操作系统, 项目地址 https://github.com/superconvert/smart-os
|
||||
本项目给大家演示了怎么样快速制作一个小巧且功能齐全的 linux 操作系统, 项目地址 https://github.com/superconvert/smart-os
|
||||
|
||||
# 功能与特点
|
||||
1. 支持挂载多块硬盘
|
||||
2. 支持网络功能
|
||||
3. 支持 DNS 域名解析
|
||||
4. 支持 GCC 编译器
|
||||
5. 支持 qemu 启动
|
||||
6. 支持 docker 启动
|
||||
7. 最精简模式 64 M
|
||||
8. 支持驱动相关演示
|
||||
9. 支持 smart_rtmpd 流媒体服务器运行 https://github.com/superconvert/smart_rtmpd
|
||||
1. 支持挂载多硬盘挂载
|
||||
2. 支持网络功能,DNS 解析
|
||||
3. 支持 GCC 编译器,c,c++
|
||||
4. 支持 qemu 方式启动
|
||||
5. 支持 docker 方式启动
|
||||
6. 系统最精简模式 64 M大小
|
||||
7. 支持驱动制作相关演示
|
||||
8. 支持防火墙 iptables
|
||||
9. 支持远程服务 openssh-server
|
||||
10. 支持桌面系统 xfce4 desktop
|
||||

|
||||
11. 支持常用工具集 lshw,lspci,lsof,strace 等
|
||||
12. 支持 smart_rtmpd 流媒体服务器运行 https://github.com/superconvert/smart_rtmpd
|
||||
|
||||
# 用途与场景
|
||||
1. 操作系统原理教学
|
||||
@ -23,7 +27,15 @@
|
||||
1. 增加 arm 版本
|
||||
2. 增加图形界面演示
|
||||
3. 支持 ISO 制作
|
||||
4. 防火墙
|
||||
4. 时区
|
||||
|
||||
# 整体思路演进
|
||||
|
||||
1. 我们为什么选择 server 版本进行制作?
|
||||
server 版本不包含窗口系统所依赖的大部分包;如果系统自带这些包,就会存在包的多版本的问题,编译问题,依赖问题,链接问题,运行时问题,会给我们的给工作带来很多干扰,况且解决这些问题都是无意义的,我们需要纯净版本的依赖包
|
||||
|
||||
2. 为什么窗口系统工作如此庞大?
|
||||
我们所有利用 apt 安装的包(工具除外),理论上都需要我们进行源码编译,包括包的依赖及粘连,都需要解决,这是一个极其庞大的工作量,没办法,新系统上一无所有,所需的环境都需要我们交叉编译提供出来。工程 A 依赖包 b ,包 b 依赖包 c, 包 c 又依赖包 d,我们所要做的就是把所有的包都需要编译出来!
|
||||
|
||||
# 制作流程
|
||||
本脚本 Ubuntu 18.04 上做的,别的系统应该改动不大,有需要的朋友可以自行修改。
|
||||
@ -112,7 +124,10 @@
|
||||
4. 我们怎么跟踪一个可执行程序的加载那些库,利用 LD_DEBUG=libs ./test 就可以了, 我们预加载库可以利用 LD_PRELOAD 强制预加载库
|
||||
|
||||
5. 我们编译 cairo 通常情况下会遇到很多问题,如果 cairo 编译出现问题,怎么办,有些错误信息网上很难搜到
|
||||
一定看它编译时生成的 config.log 文件,错误信息很详细!可以根据提示信息去解决问题
|
||||
一定看它编译时生成的 config.log 文件,错误信息很详细!可以根据提示信息去解决问题
|
||||
|
||||
6. 关于 busybox 的 init 系统变量
|
||||
即使利用 grub 的内核参数,传递环境变量也不行,busybox 的 init 会自动生成默认的环境变量 PATH ,因此需要改动源码支持自定制路径。当然 shell 的登录模式,会读取 /etc/profile ,对于非登录模式,此模式失效,所以通过 /etc/profile 有局限性。
|
||||
|
||||
# libxcb 的编译,具体详情参见 mk_xorg.sh
|
||||
1. 需要安装 apt install -y python-xcbgen 这个库,这个库会根据 xcbproto 提供的 xml 文件生成对应的 h 文件和 c 文件
|
||||
@ -134,7 +149,16 @@
|
||||
6. 编译有循环依赖的比如:freetype && harfbuzz && cairo 具体解决方式,参见 mk_xfce.sh 脚本的处理
|
||||
|
||||
# 有关 xfce4 的编译,配置,安装与运行
|
||||
这块知识牵涉的知识相对比较庞大,国内包括国外专门介绍 xfce4 的编译及使用文章相对较少,我也是摸着石头过河,尽量把这块知识演示清楚,我会专门开一个章节专门讲解这个,对于 xfce4 移植到 smart-os 内,我没有十分的把握,但我会尽力做到这一点,给国人揭示图形系统的奥秘
|
||||
这块知识牵涉的知识相对比较庞大,国内包括国外专门介绍 xfce4 的编译及使用文章相对较少,我也是摸着石头过河,尽量把这块知识演示清楚,我会专门开一个章节专门讲解这个,对于 xfce4 移植到 smart-os 内,给国人揭示图形系统的奥秘,具体详情请参见 [xfce4.md](./xfce4.md)
|
||||
|
||||
# 桌面系统的总结
|
||||
整个图形系统的整合工作量特别庞大,牵涉到系统的方方面面,国外相关此方面系统性的资料都比较少,国内几乎就更少了。目标是全部自己 DIY 所有的环境,个人的开源项目,让整个图形系统完整的运行起来,smart-os 不是第一个,基本上也是前三名。目前我还不知道。整个整合过程非常漫长,遇到的问题非常非常多,不断的调试,编译,这些重复性的工作就不说了,工作量特别庞大,我几乎可以用呕心沥血来形容我的工作,绝对不为过。其次,遇到的知识点也比较多,很多都是现学现卖,需要迅速了解其工作机制,出问题的原因,然后解决问题。下面就整体的思路大体说一下,方便新学者,快速了解思路,对系统维护有个指引,对于解决系统性问题提供一个模型。
|
||||
|
||||
1. 硬件模块必须具备,图形系统基本要求 显示器 + 显卡 + 输入(键盘,鼠标),本项目基本上就是采用 vmware 和 qemu 软件,软件自带各类模拟硬件
|
||||
2. 驱动目前内核基本上都支持,需要一一寻找相关资料,需要很多驱动,这些对内核进行配置,并开启大部分以 built-in 的方式,编译到内核,具体参考 <<01_build_src.sh>> 内核配置文件替换的部分
|
||||
xorg 输入驱动, xorg 视频驱动,xorg 视频加速 ( 可选 ), 常用的设备 /dev/input/xxx, /dev/dri/xxx 等
|
||||
3. 服务层部分,我们用到了 dbus-1, udevd,dbus-1 如果配置不正确,会导致 upower 相关部分的组件不能正常工作,xwindows 的整个运转也有问题;udevd 不正常工作,会导致鼠标,键盘不能正常工作,导致进入界面后,这些设备都不能正常工作;此外 dbus 的用户需要创建,环境变量需要配置
|
||||
4. xorg 层面对键盘数据,schema, font 等基本数据都需要安装和产生,最关键的还是有 mine 数据库 desktop 的 application 都需要产生对应的数据, xinit 负责 x client 和 xserver 同时拉起,当然也可以手工一个 shell 里面启动 xorg, 另外一个 shell 里面启动 xfce4-session,这种模式,对于调试比较方便,我们调试单个组件的启动,都是用这个方式比较方便
|
||||
|
||||
# 拓展知识
|
||||
|
||||
|
84
common.sh
84
common.sh
@ -18,49 +18,91 @@ NC='\e[0m' # 没有颜色
|
||||
# 处理器
|
||||
core_num=`nproc`
|
||||
|
||||
# 是否开启 ssh
|
||||
with_ssh=true
|
||||
|
||||
# 是否开启 ufw
|
||||
with_ufw=true
|
||||
|
||||
# 是否开启 gcc
|
||||
with_gcc=true
|
||||
|
||||
# 是否开启 xorg
|
||||
with_xorg=false
|
||||
# 是否带有工具
|
||||
with_util=true
|
||||
|
||||
# 是否开启 xfce
|
||||
with_xfce=false
|
||||
|
||||
# 开启编译后 xfce 本地测试
|
||||
with_xfce_test=true
|
||||
# 是否开启 xfce ( 需要开启 gcc )
|
||||
with_xfce=true
|
||||
|
||||
# 是否挂载第二块硬盘
|
||||
with_sdb=false
|
||||
|
||||
# 是否登陆模式
|
||||
with_login=false
|
||||
|
||||
# 编译工程目录
|
||||
build_dir=`pwd`"/build"
|
||||
with_login=true
|
||||
|
||||
#----------------------------------------------
|
||||
# 公共目录
|
||||
#----------------------------------------------
|
||||
build_dir=`pwd`"/build"
|
||||
linux_install=${build_dir}"/linux_install"
|
||||
glibc_install=${build_dir}"/glibc_install"
|
||||
busybox_install=${build_dir}"/busybox_install"
|
||||
lshw_install=${build_dir}"/lshw_install"
|
||||
lsof_install=${build_dir}"/lsof_install"
|
||||
strace_install=${build_dir}"/strace_install"
|
||||
pciutils_install=${build_dir}"/pciutils_install"
|
||||
openssl_install=${build_dir}"/openssl_install"
|
||||
openssh_install=${build_dir}"/openssh_install"
|
||||
libmnl_install=${build_dir}"/libmnl_install"
|
||||
libnftnl_install=${build_dir}"/libnftnl_install"
|
||||
iptables_install=${build_dir}"/iptables_install"
|
||||
gcc_install=${build_dir}"/gcc_install"
|
||||
binutils_install=${build_dir}"/binutils_install"
|
||||
xorg_install=${build_dir}"/xorg_install"
|
||||
xfce_install=${build_dir}"/xfce_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
|
||||
}
|
||||
|
||||
#----------------------------------------------
|
||||
# 下载一个指定 URL 的源码包, 并存为指定的名字
|
||||
#----------------------------------------------
|
||||
download_src() {
|
||||
SRC_NAME=$2$(file_name $1)
|
||||
if [ ! -f ${SRC_NAME} ]; then
|
||||
wget -c -t 0 $1 -O $SRC_NAME --no-check-certificate || (echo "download $1 failed" && exit)
|
||||
fi
|
||||
echo $SRC_NAME
|
||||
}
|
||||
|
||||
#----------------------------------------------
|
||||
# 解压一个下载的源码包到去掉扩展名的目录内
|
||||
#----------------------------------------------
|
||||
unzip_src() {
|
||||
SRC_NAME=$2
|
||||
SRC_DIR=${build_dir}"/"$(file_dirname ${SRC_NAME} $1)
|
||||
if [ ! -d ${SRC_DIR} ]; then
|
||||
tar xf source/${SRC_NAME} -C ${build_dir}
|
||||
fi
|
||||
echo $SRC_DIR
|
||||
}
|
||||
|
||||
#----------------------------------------------
|
||||
# 获取一个目录下所有的文件,包括子目录
|
||||
#----------------------------------------------
|
||||
ls_dir() {
|
||||
for file in `ls $1`
|
||||
do
|
||||
@ -74,3 +116,23 @@ ls_dir() {
|
||||
done
|
||||
}
|
||||
|
||||
#---------------------------------------------
|
||||
# 创建一个磁盘文件并分区
|
||||
#---------------------------------------------
|
||||
create_disk() {
|
||||
# 输入参数磁盘文件和大小
|
||||
disk=$1
|
||||
size=$2
|
||||
# 创建一个磁盘文件
|
||||
dd if=/dev/zero of=${disk} bs=1M count=${size}
|
||||
|
||||
# 对磁盘进行分区一个主分区
|
||||
fdisk ${disk} << EOF
|
||||
n
|
||||
p
|
||||
|
||||
|
||||
|
||||
w
|
||||
EOF
|
||||
}
|
||||
|
@ -27,9 +27,9 @@ EOF
|
||||
cat<<EOF>Makefile
|
||||
obj-m += hello_world.o
|
||||
all:
|
||||
make -C ../build/linux-4.14.9 M=`pwd` modules
|
||||
make -C ../build/linux-5.8.6 M=`pwd` modules
|
||||
clean:
|
||||
make -C ../build/linux-4.14.9 M=`pwd` clean
|
||||
make -C ../build/linux-5.8.6 M=`pwd` clean
|
||||
EOF
|
||||
|
||||
echo $1
|
||||
|
12
mk_login.sh
12
mk_login.sh
@ -10,6 +10,7 @@ EOF
|
||||
# 用户密码文件
|
||||
cat<<EOF>${diskfs}/etc/passwd
|
||||
root:x:0:0:root:/:/bin/sh
|
||||
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
|
||||
EOF
|
||||
|
||||
# 用户 shadow 文件
|
||||
@ -30,12 +31,5 @@ export PS1 HOSTNAME
|
||||
EOF
|
||||
|
||||
# 重新生成 inittab 文件
|
||||
cat<<EOF>${diskfs}/etc/inittab
|
||||
::sysinit:/bin/hostname -F /etc/hostname
|
||||
::sysinit:/etc/init.d/rcS
|
||||
tty0::respawn:-/bin/login
|
||||
::restart:/sbin/init
|
||||
::ctrlaltdel:/sbin/reboot
|
||||
::shutdown:/bin/umount -a -r
|
||||
::shutdown:/sbin/swapoff -a
|
||||
EOF
|
||||
sed -i "1i\::sysinit:\/bin\/hostname -F \/etc\/hostname" ${diskfs}/etc/inittab
|
||||
sed -i "1i\# 加载主机名称" ${diskfs}/etc/inittab
|
||||
|
16
mk_sdb.sh
16
mk_sdb.sh
@ -1,5 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 导入公共环境
|
||||
. ./common.sh
|
||||
|
||||
#----------------------------------------------
|
||||
#
|
||||
# 制作磁盘
|
||||
@ -13,18 +16,7 @@ fi
|
||||
echo "${CYAN}开始制作磁盘...${NC}"
|
||||
|
||||
# 创建磁盘 64M
|
||||
dd if=/dev/zero of=extra.img bs=1M count=64
|
||||
|
||||
# 对磁盘进行分区一个主分区
|
||||
fdisk extra.img << EOF
|
||||
n
|
||||
p
|
||||
|
||||
|
||||
|
||||
w
|
||||
EOF
|
||||
|
||||
create_disk extra.img 64
|
||||
echo "${GREEN}磁盘制作成功!!!${NC}"
|
||||
echo ".........................................................."
|
||||
|
||||
|
25
mk_strip.sh
25
mk_strip.sh
@ -3,6 +3,7 @@
|
||||
# 导入公共环境
|
||||
. ./common.sh
|
||||
|
||||
# 对指定的目录进行 strip
|
||||
strip_dir() {
|
||||
for file in `ls $1`
|
||||
do
|
||||
@ -32,7 +33,25 @@ strip_dir ${glibc_install}
|
||||
|
||||
# strip busybox
|
||||
rm -rf ${busybox_install}/linuxrc
|
||||
strip ${busybox_install}/bin/busybox
|
||||
strip_dir ${busybox_install}/bin/busybox
|
||||
|
||||
# strip lshw
|
||||
strip_dir ${lshw_install}
|
||||
|
||||
# strip pciutils_install
|
||||
strip_dir ${pciutils_install}
|
||||
|
||||
# strip lsof
|
||||
strip_dir ${lsof_install}
|
||||
|
||||
# strip strace
|
||||
strip_dir ${strace_install}
|
||||
|
||||
# strip openssl
|
||||
strip_dir ${openssl_install}
|
||||
|
||||
# strip openssh
|
||||
strip_dir ${openssh_install}
|
||||
|
||||
# strip gcc
|
||||
#rm -rf work/libgcc_install/usr/share
|
||||
@ -42,3 +61,7 @@ strip_dir ${gcc_install}
|
||||
#rm -rf work/binutils_install/usr/share
|
||||
strip_dir ${binutils_install}
|
||||
|
||||
# strip xfce
|
||||
if [ "${with_xfce}" = true ]; then
|
||||
strip_dir ${xfce_install}
|
||||
fi
|
||||
|
1467
mk_xfce.sh
1467
mk_xfce.sh
File diff suppressed because it is too large
Load Diff
128
mk_xorg.sh
128
mk_xorg.sh
@ -29,12 +29,7 @@ XSVR_SRC_URL=https://www.x.org/archive/individual/xserver/xorg-server-1.20.11.ta
|
||||
#----------------------------
|
||||
mkdir -pv source
|
||||
cd source
|
||||
|
||||
XSVR_SRC_NAME=$(file_name ${XSVR_SRC_URL})
|
||||
if [ ! -f ${XSVR_SRC_NAME} ]; then
|
||||
wget -c -t 0 $XSVR_SRC_URL
|
||||
fi
|
||||
|
||||
XSVR_SRC_NAME=$(download_src ${XSVR_SRC_URL})
|
||||
cd ..
|
||||
|
||||
#---------------------------
|
||||
@ -43,12 +38,7 @@ cd ..
|
||||
#
|
||||
#---------------------------
|
||||
mkdir -pv ${build_dir}
|
||||
|
||||
XSVR_SRC_DIR=${build_dir}"/"$(file_dirname ${XSVR_SRC_NAME} .tar.bz2)
|
||||
if [ ! -d ${XSVR_SRC_DIR} ]; then
|
||||
echo "unzip ${XSVR_SRC_NAME} source code"
|
||||
tar xf source/${XSVR_SRC_NAME} -C ${build_dir}
|
||||
fi
|
||||
XSVR_SRC_DIR=$(unzip_src ".tar.bz2" ${XSVR_SRC_NAME}); echo "unzip ${XSVR_SRC_NAME} source code"
|
||||
|
||||
#---------------------------------------------
|
||||
#
|
||||
@ -110,89 +100,37 @@ else
|
||||
tar zxf xclient.tar.gz
|
||||
fi
|
||||
|
||||
echo "${GREEN}build macros begin${NC}"
|
||||
cd macros
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build macros success${NC}"
|
||||
cd .. && sleep 1
|
||||
#---------------------------
|
||||
# 公共编译函数定义
|
||||
#---------------------------
|
||||
xorg_build() {
|
||||
local name=$1
|
||||
echo "${GREEN}build ${name} begin${NC}" && cd ${name}
|
||||
if [ "${name}" = "libxcb" ]; then
|
||||
# 解决 libxcb 编译问题
|
||||
sed -i "8 i reload(sys)" src/c_client.py
|
||||
sed -i "9 i sys.setdefaultencoding('utf8')" src/c_client.py
|
||||
fi
|
||||
./autogen.sh && ./configure ${CFGOPT}
|
||||
make -j8 && make install DESTDIR=${xclient_dir} && echo "${GREEN}build ${name} success${NC}"
|
||||
cd .. && sleep 1
|
||||
}
|
||||
|
||||
echo "${GREEN}build xcbproto begin${NC}"
|
||||
cd xcbproto
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build xcbproto success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build xorgproto begin${NC}"
|
||||
cd xorgproto
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build xorgproto success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxau begin${NC}"
|
||||
cd libxau
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxau success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxcb begin${NC}"
|
||||
cd libxcb
|
||||
# 解决 libxcb 编译问题
|
||||
sed -i "8 i reload(sys)" src/c_client.py
|
||||
sed -i "9 i sys.setdefaultencoding('utf8')" src/c_client.py
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxcb success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxtrans begin${NC}"
|
||||
cd libxtrans
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxtrans success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libx11 begin${NC}"
|
||||
cd libx11
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libx11 success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libice begin${NC}"
|
||||
cd libice
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libice success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libsm begin${NC}"
|
||||
cd libsm
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libsm success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxt begin${NC}"
|
||||
cd libxt
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxt success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxext begin${NC}"
|
||||
cd libxext
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxext success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxmu begin${NC}"
|
||||
cd libxmu
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxmu success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxpm begin${NC}"
|
||||
cd libxpm
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxpm success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxaw begin${NC}"
|
||||
cd libxaw
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxaw success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build libxdmcp begin${NC}"
|
||||
cd libxdmcp
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build libxdmcp success${NC}"
|
||||
cd .. && sleep 1
|
||||
|
||||
echo "${GREEN}build xload begin${NC}"
|
||||
|
||||
# 编译 xclient application
|
||||
cd xload
|
||||
./autogen.sh && ./configure ${CFGOPT} && make -j8 && make install -j8 DESTDIR=${xclient_dir} && echo "${GREEN}build xload success${NC}"
|
||||
cd .. && sleep 1
|
||||
xorg_build macros
|
||||
xorg_build xcbproto
|
||||
xorg_build xorgproto
|
||||
xorg_build libxau
|
||||
xorg_build libxcb
|
||||
xorg_build libxtrans
|
||||
xorg_build libx11
|
||||
xorg_build libice
|
||||
xorg_build libsm
|
||||
xorg_build libxt
|
||||
xorg_build libxext
|
||||
xorg_build libxmu
|
||||
xorg_build libxpm
|
||||
xorg_build libxaw
|
||||
xorg_build libxdmcp
|
||||
xorg_build xload
|
||||
|
||||
cd ..
|
||||
|
338
samba.md
Normal file
338
samba.md
Normal file
@ -0,0 +1,338 @@
|
||||
# samba 配置整体说明
|
||||
samba 是基于 smb 协议实现的不同系统之间实现文件共享,打印资源共享的一套框架。smb 协议用来解决局域网内的文件或打印机等资源共享的问题,由微软公司和英特尔公司共同制定。
|
||||
目前主要的类 UNIX 系统平台都支持此协议,这样在大部分常用的系统中都满足文件共享及打印资源共享需求。
|
||||
|
||||
samba 分为服务器端和客户端,本文档基于 UOS Server 20 1070a 作为 Samba 服务器做基准,win10, win11 作为客户端为基准,进行配置流程说明
|
||||
|
||||
# samba 服务器端
|
||||
下面的章节主要是阐述服务器端一些准备工作,包括安装,环境配置,运行等基本工作
|
||||
|
||||
## 安装 samba
|
||||
~~~shell
|
||||
yum install -y samba
|
||||
~~~
|
||||
|
||||
## 查询是否安装 samba
|
||||
~~~shell
|
||||
[root@localhost ~]# rpm -qa | grep samba
|
||||
samba-common-tools-4.17.5-2.0.1.uelc20.03.x86_64
|
||||
samba-ldb-ldap-modules-4.17.5-2.0.1.uelc20.03.x86_64
|
||||
samba-client-libs-4.17.5-2.0.1.uelc20.03.x86_64
|
||||
samba-4.17.5-2.0.1.uelc20.03.x86_64
|
||||
samba-libs-4.17.5-2.0.1.uelc20.03.x86_64
|
||||
samba-dcerpc-4.17.5-2.0.1.uelc20.03.x86_64
|
||||
samba-common-libs-4.17.5-2.0.1.uelc20.03.x86_64
|
||||
samba-common-4.17.5-2.0.1.uelc20.03.noarch
|
||||
~~~
|
||||
如果出现上述包,则表明 samba 已经安装成功
|
||||
|
||||
## 开通防火墙放行
|
||||
~~~shell
|
||||
firewall-cmd --zone=public --add-port=139/tcp --permanent
|
||||
firewall-cmd --zone=public --add-port=445/tcp --permanent
|
||||
firewall-cmd --reload 或 systemctl restart firewalld
|
||||
~~~
|
||||
|
||||
## 开通 SELinux 放行或关闭 SELinux
|
||||
~~~shell
|
||||
setsebool -P samba_enable_home_dirs=1
|
||||
chcon -t samba_share_t /home/centos/share ---> 放行的目录
|
||||
~~~
|
||||
经过验证系统默认不阻挡 samba 服务器对外提供服务,这一步可以省略!!!
|
||||
|
||||
## 运行 samba 服务
|
||||
~~~shell
|
||||
systemctl restart smb.service
|
||||
~~~
|
||||
理想情况下都是启动成功,如果出现失败,会出现很多提示信息,根据信息进行排查,下面就一些错误进行简单的说明
|
||||
|
||||
1. 配置文件格式错误
|
||||
samba 配置文件错误会导致 samba 启动失败,比如:yes 多了空格, set_variable_helper(yes ): value is not boolean
|
||||
|
||||
2. 查看启动失败原因
|
||||
tail -f /var/log/samba/log.smbd
|
||||
|
||||
## 查看运行状态
|
||||
~~~shell
|
||||
[root@localhost ~]# systemctl status smb.service
|
||||
● smb.service - Samba SMB Daemon
|
||||
Loaded: loaded (/usr/lib/systemd/system/smb.service; disabled; vendor preset: disabled)
|
||||
Active: active (running) since Tue 2025-02-25 04:00:58 CST; 5min ago
|
||||
Docs: man:smbd(8)
|
||||
man:samba(7)
|
||||
man:smb.conf(5)
|
||||
Main PID: 13499 (smbd)
|
||||
Status: "smbd: ready to serve connections..."
|
||||
Tasks: 3
|
||||
Memory: 4.1M
|
||||
CGroup: /system.slice/smb.service
|
||||
├─13499 /usr/sbin/smbd --foreground --no-process-group
|
||||
├─13501 /usr/sbin/smbd --foreground --no-process-group
|
||||
└─13502 /usr/sbin/smbd --foreground --no-process-group
|
||||
|
||||
2月 25 04:00:58 localhost.localdomain systemd[1]: Starting Samba SMB Daemon...
|
||||
2月 25 04:00:58 localhost.localdomain smbd[13499]: [2025/02/25 04:00:58.114320, 0] ../../source3/smbd/server.c:1741(main)
|
||||
2月 25 04:00:58 localhost.localdomain smbd[13499]: smbd version 4.17.5 started.
|
||||
2月 25 04:00:58 localhost.localdomain smbd[13499]: Copyright Andrew Tridgell and the Samba Team 1992-2022
|
||||
2月 25 04:00:58 localhost.localdomain smbd[13499]: [2025/02/25 04:00:58.115092, 0] ../../lib/param/loadparm.c:749(lpcfg_map_parameter)
|
||||
2月 25 04:00:58 localhost.localdomain smbd[13499]: Unknown parameter encountered: "browse"
|
||||
2月 25 04:00:58 localhost.localdomain smbd[13499]: [2025/02/25 04:00:58.115138, 0] ../../lib/param/loadparm.c:1936(lpcfg_do_service_parameter)
|
||||
2月 25 04:00:58 localhost.localdomain smbd[13499]: Ignoring unknown parameter "browse"
|
||||
2月 25 04:00:58 localhost.localdomain systemd[1]: Started Samba SMB Daemon.
|
||||
~~~
|
||||
|
||||
我们发现状态 active (running) 表明 samba 服务器启动成功。
|
||||
|
||||
## 查看运行端口
|
||||
~~~shell
|
||||
[root@localhost ~]# netstat -anp | grep smbd
|
||||
tcp 0 0 192.168.112.132:139 0.0.0.0:* LISTEN 13499/smbd
|
||||
tcp 0 0 192.168.112.132:445 0.0.0.0:* LISTEN 13499/smbd
|
||||
unix 2 [ ] DGRAM 336690 13499/smbd /var/lib/samba/private/msg.sock/13499
|
||||
unix 2 [ ] DGRAM 335554 13501/smbd /var/lib/samba/private/msg.sock/13501
|
||||
unix 2 [ ] DGRAM 334795 13502/smbd /var/lib/samba/private/msg.sock/13502
|
||||
unix 3 [ ] STREAM CONNECTED 335562 13499/smbd
|
||||
unix 2 [ ] STREAM CONNECTED 336695 13499/smbd
|
||||
unix 2 [ ] DGRAM 336673 13499/smbd
|
||||
~~~
|
||||
我们看到端口 139 和 445 已经正确绑定
|
||||
|
||||
## 配置文件说明
|
||||
配置文件就是 /etc/samba/smb.conf, 这里面的内容太多,大部分采用默认配置即可,没必要一一进行解释和使用。
|
||||
|
||||
# windows 客户端配置
|
||||
|
||||
## windows 配置 SMB 功能
|
||||
windows 需要开启 SMB 1.0/CIFS 共享文件支持 , 分别从系统设置里面进行配置,配置完成,需要重启机器
|
||||
win11 ---> 设置 ---> 应用 ---> 可选功能 ---> 更多 windows 功能 ---> SMB 1.0/CIFS 共享文件支持
|
||||
win10 ---> 设置 ---> 应用 ---> 程序和功能 ---> 启用或关闭 windows 功能 ---> SMB 1.0/CIFS 共享文件支持
|
||||
|
||||
# 基本使用场景说明
|
||||
下面就针对组,用户,配置文件,使用场景进行分别说明,由于是对账号和组的操作,所以必须在 root 账号下进行操作。
|
||||
|
||||
## 组管理
|
||||
这里可以根据咱们的部门进行分组,比如:td(技术部), fd(财务部), md(市场部),这样对应部门的用户可以加入到相应的组内
|
||||
1. 添加组 技术部
|
||||
~~~shell
|
||||
groupadd td
|
||||
~~~
|
||||
|
||||
2. 删除组 技术部
|
||||
~~~shell
|
||||
groupdel td
|
||||
~~~
|
||||
|
||||
3. 查看组成员
|
||||
~~~shell
|
||||
cat /etc/group | grep 组名
|
||||
~~~
|
||||
|
||||
这是属于 linux 的一些基本命令,不一一介绍了
|
||||
|
||||
4. 要查看 samba 用户所属的用户组
|
||||
~~~shell
|
||||
pdbedit -Lv -u <samba用户名>
|
||||
~~~
|
||||
|
||||
|
||||
## 用户 管理
|
||||
添加用户需要两步,第一步是添加系统用户,其次是添加 samba 用户
|
||||
1. 添加用户
|
||||
1.1 添加系统用户( 不能登录系统 )
|
||||
~~~shell
|
||||
useradd -s /sbin/nologin dev001
|
||||
~~~
|
||||
|
||||
1.2 添加 samba 用户,并配置密码
|
||||
~~~shell
|
||||
smbpasswd -a dev001
|
||||
~~~
|
||||
|
||||
2. 删除用户
|
||||
2.1 删除 samba 用户
|
||||
~~~shell
|
||||
smbpasswd -x dev001
|
||||
~~~
|
||||
|
||||
2.2 删除系统用
|
||||
~~~shell
|
||||
userdel dev001
|
||||
~~~
|
||||
|
||||
3. 把用户添加到组
|
||||
把用户 dev001 添加到组 td 中
|
||||
~~~shell
|
||||
usermod -a -G td dev001
|
||||
~~~
|
||||
|
||||
4. 把用户从组中删除
|
||||
把用户 dev001 从组 td 中删除
|
||||
~~~shell
|
||||
gpasswd -d dev001 td
|
||||
~~~
|
||||
|
||||
## 配置文件说明
|
||||
1. 配置文件路径
|
||||
/etc/samba/smb.conf
|
||||
|
||||
2. 配置项说明
|
||||
通常情况下,smb.conf 配置文件是不需要修改的,如果我们想共享一个目录,则需要追加类似下面格式的文字到 smb.conf,保存后,重新启动 samba 服务
|
||||
~~~shell
|
||||
[company] # 共享名
|
||||
comment = company share # 注释说明
|
||||
path = /home/company # 共享文件路径
|
||||
guest ok = no # 不允许匿名访问
|
||||
writeable = yes # 允许用户写入数据
|
||||
browseable = no # 当设置为 yes 时,表示该共享目录是可浏览的,其他计算机上的用户可以在网络浏览器中看到该共享目录,并能够浏览其中的文件和文件夹
|
||||
# 当设置为no时,表示该共享目录是不可浏览的,其他计算机上的用户无法在网络浏览器中看到该共享目录,从而增加共享资源的隐私保护 ---> 虽然看不到,但输入路径还是能进入的
|
||||
printable = no #
|
||||
valid users=admin,xsuser # 指定用户访问
|
||||
write list=xzuser # 指定用户有写入权限
|
||||
read list=user2
|
||||
|
||||
create mask = 755 # 新建文件掩码
|
||||
directory mask = 755 # 新建目录掩码
|
||||
|
||||
host allow = 192.168.0. EXCEPT 192.168.0.99 # 只允许192.168.0.0/24但不包括192.168.0.99的客户端访问Samba服务器上的smbtest目录。
|
||||
192.168.0.99 192.168.0.100 # 中间是空格
|
||||
hosts deny :拒绝访问
|
||||
~~~
|
||||
|
||||
# 配置示例
|
||||
1. 场景描述
|
||||
领导:王总(wangzong)
|
||||
正式员工:张三(zhang3), 李四(li4),于老大(yu1), 于老二(yu2)
|
||||
实习生:楚乔乔(chuxx),小马(xiaoma)
|
||||
|
||||
整个共享区域分为两部分,日常区,读写区,其中王总有整个盘的读写权限,子目录如下:
|
||||
1.1 日常区
|
||||
| 子目录 | 读写权限 | 查询权限 |
|
||||
| --- | --- | --- |
|
||||
| 重大事项 | wangzong | |
|
||||
| 财务报表 | li4 | yu1, yu2 |
|
||||
| 战略规划 | li4, yu1 | 正式员工 |
|
||||
| 公司建议 | 正式员工 | |
|
||||
| 共享资料 | 正式员工 | 实习生 |
|
||||
|
||||
1.2 读写区
|
||||
| 子目录 | 读写权限 |
|
||||
| --- | --- |
|
||||
| 周报总结 | yu2 |
|
||||
| 工作记录 | 正式员工 |
|
||||
| 休闲娱乐 | 正式员工,实习生 |
|
||||
|
||||
2. 创建共享目录
|
||||
~~~shell
|
||||
[root@samba-server ~]# useradd samba
|
||||
[root@samba-server ~]# mkdir -p /data/samba/daily
|
||||
[root@samba-server ~]# mkdir -p /data/samba/read-write
|
||||
[root@samba-server ~]# chown -R samba.samba /data/samba
|
||||
~~~
|
||||
共享根目录 /data/samba,里面有两个目录 daily 和 read-write,并把此目录所有者指定为 samba
|
||||
|
||||
3. 添加用户账号
|
||||
~~~shell
|
||||
[root@samba-server ~]# useradd -d /data/samba -s /sbin/nologin wangzong
|
||||
[root@samba-server ~]# useradd -d /data/samba -s /sbin/nologin zhang3
|
||||
[root@samba-server ~]# useradd -d /data/samba -s /sbin/nologin li4
|
||||
[root@samba-server ~]# useradd -d /data/samba -s /sbin/nologin yu1
|
||||
[root@samba-server ~]# useradd -d /data/samba -s /sbin/nologin yu2
|
||||
[root@samba-server ~]# useradd -d /data/samba -s /sbin/nologin chuxx
|
||||
[root@samba-server ~]# useradd -d /data/samba -s /sbin/nologin xiaoma
|
||||
~~~
|
||||
|
||||
4. 创建对应的 samba 用户
|
||||
~~~shell
|
||||
[root@samba-server ~]# smbpasswd -a wangzong
|
||||
new password:
|
||||
retype new password:
|
||||
.......
|
||||
~~~
|
||||
依次把用户添加进来,这里只举例了 wangzong 这个账号
|
||||
|
||||
5. 设置共享目录的权限
|
||||
~~~shell
|
||||
# 日常区配置
|
||||
[root@samba-server samba]# cd daily
|
||||
|
||||
[root@samba-server daily]# mkdir 重大事项
|
||||
[root@samba-server daily]# chown -R wangzong.wangzong /data/samba/daily/重大事项
|
||||
[root@samba-server daily]# chmod -R 700 /data/samba/daily/重大事项
|
||||
|
||||
[root@samba-server daily]# mkdir 财务报表
|
||||
[root@samba-server daily]# chown -R li4.li4 /data/samba/daily/财务报表
|
||||
[root@samba-server daily]# chmod -R 700 /data/samba/daily/财务报表
|
||||
[root@samba-server daily]# setfacl -R -m u:yu1:rx /data/samba/daily/财务报表
|
||||
[root@samba-server daily]# setfacl -R -m u:yu2:rx /data/samba/daily/财务报表
|
||||
|
||||
[root@samba-server daily]# mkdir 战略规划
|
||||
[root@samba-server daily]# chown -R li4.li4 /data/samba/daily/战略规划
|
||||
[root@samba-server daily]# chmod -R 700 /data/samba/daily/战略规划
|
||||
[root@samba-server daily]# setfacl -R -m u:yu1:rwx /data/samba/daily/战略规划
|
||||
[root@samba-server daily]# setfacl -R -m g:regular:rx /data/samba/daily/战略规划
|
||||
// 把正式员工添加到正式员工 (regular) 的组内
|
||||
[root@samba-server daily]# gpasswd -a zhang3 regular
|
||||
[root@samba-server daily]# gpasswd -a li4 regular
|
||||
[root@samba-server daily]# gpasswd -a yu1 regular
|
||||
[root@samba-server daily]# gpasswd -a yu2 regular
|
||||
|
||||
[root@samba-server daily]# mkdir 公司建议
|
||||
[root@samba-server daily]# chown -R zhang3.zhang3 /data/samba/daily/公司制度
|
||||
[root@samba-server daily]# chmod -R 700 /data/samba/daily/公司制度
|
||||
[root@samba-server daily]# setfacl -R -m g:regular:rwx /data/samba/daily/公司制度
|
||||
|
||||
[root@samba-server daily]# mkdir 共享资料
|
||||
[root@samba-server daily]# chown -R zhang3.zhang3 /data/samba/daily/共享资料
|
||||
[root@samba-server daily]# chmod -R 700 /data/samba/daily/共享资料
|
||||
[root@samba-server daily]# setfacl -R -m g:regular:rwx /data/samba/daily/共享资料
|
||||
[root@samba-server daily]# setfacl -R -m g:intern:rx /data/samba/daily/共享资料
|
||||
// 把实习生添加到实习生 (intern) 的组内
|
||||
[root@samba-server daily]# gpasswd -a chuxx intern
|
||||
[root@samba-server daily]# gpasswd -a xiaoma intern
|
||||
|
||||
# 读写区
|
||||
[root@samba-server daily]# cd ../read-write/
|
||||
[root@samba-server read-write]# mkdir /data/samba/read-write/周报总结
|
||||
[root@samba-server read-write]# chown -R yu2.yu2 /data/samba/read-write/周报总结
|
||||
[root@samba-server read-write]# chmod -R 700 /data/samba/read-write/周报总结
|
||||
|
||||
[root@samba-server read-write]# mkdir /data/samba/read-write/工作记录
|
||||
[root@samba-server read-write]# chown -R zhang3.zhang3 /data/samba/read-write/工作记录
|
||||
[root@samba-server read-write]# chmod -R 700 /data/samba/read-write/工作记录
|
||||
[root@samba-server read-write]# setfacl -R -m g:regular:rwx /data/samba/read-write/作记录
|
||||
|
||||
[root@samba-server read-write]# mkdir /data/samba/read-write/休闲娱乐
|
||||
[root@samba-server read-write]# chown -R zhang3.zhang3 /data/samba/read-write/休闲娱乐
|
||||
[root@samba-server read-write]# chmod -R 700 /data/samba/read-write/休闲娱乐
|
||||
[root@samba-server read-write]# setfacl -R -m g:regular:rwx /data/samba/read-write/休闲娱乐
|
||||
[root@samba-server read-write]# setfacl -R -m g:intern:rwx /data/samba/read-write/休闲娱乐
|
||||
~~~
|
||||
|
||||
王总 (wangzong) 对整个共享具有读写权限, 还要赋权给王总
|
||||
~~~shell
|
||||
[root@samba-server ~]# setfacl -R -m u:wangzong:rwx /data/samba/daily/重大事项
|
||||
[root@samba-server ~]# setfacl -R -m u:wangzong:rwx /data/samba/daily/财务报表
|
||||
[root@samba-server ~]# setfacl -R -m u:wangzong:rwx /data/samba/daily/战略规划
|
||||
[root@samba-server ~]# setfacl -R -m u:wangzong:rwx /data/samba/daily/公司建议
|
||||
[root@samba-server ~]# setfacl -R -m u:wangzong:rwx /data/samba/daily/共享资料
|
||||
|
||||
[root@samba-server ~]# setfacl -R -m u:wangzong:rwx /data/samba/read-write/周报总结
|
||||
[root@samba-server ~]# setfacl -R -m u:wangzong:rwx /data/samba/read-write/工作记录
|
||||
[root@samba-server ~]# setfacl -R -m u:wangzong:rwx /data/samba/read-write/休闲娱乐
|
||||
~~~
|
||||
|
||||
6. 修订 samba 服务器配置文件
|
||||
编辑 /etc/samba/smb.conf,追加
|
||||
~~~shell
|
||||
[share]
|
||||
comment = "公司共享文件系统s"
|
||||
path= /data/samba
|
||||
public = no
|
||||
valid users = wangzong,zhang3,li4,yu1,yu2,chuxx,xiaoma,@samba
|
||||
printable = no
|
||||
write list = wangzong,zhang3,li4,yu1,yu2,chuxx,xiaoma
|
||||
|
||||
7. 重启 samba 服务器
|
||||
~~~shell
|
||||
[root@samba-server ~]# systemctl restart smb.service
|
||||
~~~
|
477
xfce4.md
Normal file
477
xfce4.md
Normal file
@ -0,0 +1,477 @@
|
||||
# 单独运行 xfce4 组件 ( 不编译 smart-os, 单独编译 xfce4 )
|
||||
1. 利用 wmare 安装 Ubuntu 18.04 Server 版本,安装完毕,配置 apt 源,ssh 等操作,就不要再做过多的操作了,尽量保持系统纯净
|
||||
2. 修订 common.sh 文件里面的 with_xfce_test=true
|
||||
3. ./mk_xfce.sh 进行 xfce4 的编译,编译完毕会自动生成 startxfce.sh
|
||||
4. 重启系统,重启完毕。在 wmware 虚拟机里面执行 startxfce.sh 就可以成功拉起桌面了
|
||||
运行效果图如下
|
||||

|
||||
|
||||
# xfce4 组件介绍
|
||||
* [ Gtk+ ] 这些组件 gtk 最庞大
|
||||
libffi
|
||||
libmount
|
||||
glib
|
||||
pixman
|
||||
freetype
|
||||
harfbuzz
|
||||
fontconfig
|
||||
cairo
|
||||
fribidi
|
||||
pango
|
||||
gdkpixbuf
|
||||
libeproxy
|
||||
graphene
|
||||
wayland-protocols
|
||||
gettext( libintl )
|
||||
gtk+
|
||||
* [ xfce ] 这些组件编译顺序也有要求
|
||||
libwnck
|
||||
xfce4-dev-tools
|
||||
xlibxfce4util
|
||||
xfconf
|
||||
libxfce4ui
|
||||
garcon
|
||||
exo
|
||||
xfce4-panel
|
||||
thunar
|
||||
xfce4-settings
|
||||
xfce4-session
|
||||
xfwm4
|
||||
xfdesktop
|
||||
thunar-volman
|
||||
tumbler
|
||||
xfce4-power-manager
|
||||
xfce4-appfinder
|
||||
|
||||
# Cairo
|
||||
cairo is a vector graphics library with cross-device output support
|
||||
cairo能够做各种复杂的点线图案绘制、填充、文字渲染、图像变换、剪切、层混合等等操作。但是他没有涉及到用户交互,如鼠标、touch、事件处理,交互窗口,这些统统没有,他只有专一的绘图。他有surface可以理解为画布,这个surface可以是基于内存(image surface,必选的surface)也可以基于某种backend(和操作系统或驱动接口对接),使用过程是创建一个surface,然后在surface里做各种绘图,最后使用Painting类的functions时图像就显示在了surface上。当然surface也是一块image,可以把image通过png(源码有对接libpng库)图像压缩输出png文件
|
||||
|
||||
# harfbuzz
|
||||
HarfBuzz 是一个文本整形引擎。它主要支持OpenType,但也 支持Apple Advanced Typography。HarfBuzz 用于 Android、Chrome、ChromeOS、Firefox、GNOME、GTK+、KDE、LibreOffice、OpenJDK、PlayStation、Qt、XeTeX 等地方。
|
||||
|
||||
|
||||
# xfce 运行黑屏怎么办
|
||||
比如黑屏,我们由屏幕想到可能是 xfdesktop 这个应用负责渲屏,黑屏可能是 xfdesktop 未能正确运行,这个就需要我们手工调试跟踪了,通常情况下我们会这么做:
|
||||
```shell
|
||||
# 设置屏幕,这个是 xfce 默认的值 10
|
||||
export DISPLAY=:10
|
||||
# 执行这个,正常执行理论上就不会黑屏,不能执行,可能是依赖库路径不对,版本不对,配置不对,逐步根据提示解决问题
|
||||
xfdesktop
|
||||
```
|
||||
|
||||
# xrdp 远程访问 linux 桌面流程分析( 重要 )
|
||||
|
||||
1. xrdp 服务依赖 xrdp-sesman 服务
|
||||
我们可以通过 grep 全局查找 xrdp-sesman,发现下面这句
|
||||
```shell
|
||||
./lib/systemd/system/xrdp.service:4:Requires=xrdp-sesman.service
|
||||
```
|
||||
因此 xrdp 启动时,肯定 xrdp-sesman 也相应启动,具体机制待研究(TODO)
|
||||
|
||||
2. 配置文件 /etc/xrdp/sesman.ini
|
||||
```shell
|
||||
[Globals]
|
||||
ListenAddress=127.0.0.1
|
||||
ListenPort=3350
|
||||
```
|
||||
|
||||
3. 确认 xrdp 和 xrdp-sesman 服务
|
||||
```shell
|
||||
root@freeabc:/# netstat -anpt | grep xrdp
|
||||
tcp6 0 0 :::3389 :::* LISTEN 6288/xrdp
|
||||
tcp6 0 0 ::1:3350 :::* LISTEN 6259/xrdp-sesman
|
||||
```
|
||||
其中 xrdp 是 3389 对外提供服务, xrdp-sesman 是 3350 对 xrdp 提供服务,xrdp 把请求转给 xrdp-sesman (经过 tcpdump 抓包确认是)
|
||||
|
||||
```shell
|
||||
root@freeabc:/# tcpdump -s 0 -i lo port 3350 -v -n
|
||||
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
|
||||
01:37:24.538435 IP6 (flowlabel 0xc281a, hlim 64, next-header TCP (6) payload length: 40) ::1.52600 > ::1.3350: Flags [S], cksum 0x0030 (incorrect -> 0x3f1d), seq 213438096, win 65476, options [mss 65476,sackOK,TS val 4262615841 ecr 0,nop,wscale 7], length 0
|
||||
01:37:24.538457 IP6 (flowlabel 0xe10b3, hlim 64, next-header TCP (6) payload length: 40) ::1.3350 > ::1.52600: Flags [S.], cksum 0x0030 (incorrect -> 0xbea4), seq 3363004107, ack 213438097, win 65464, options [mss 65476,sackOK,TS val 4262615841 ecr 4262615841,nop,wscale 7], length 0
|
||||
01:37:24.538472 IP6 (flowlabel 0xc281a, hlim 64, next-header TCP (6) payload length: 32) ::1.52600 > ::1.3350: Flags [.], cksum 0x0028 (incorrect -> 0xe53a), ack 1, win 512, options [nop,nop,TS val 4262615841 ecr 4262615841], length 0
|
||||
01:37:25.149700 IP6 (flowlabel 0xc281a, hlim 64, next-header TCP (6) payload length: 109) ::1.52600 > ::1.3350: Flags [P.], cksum 0x0075 (incorrect -> 0x6a7f), seq 1:78, ack 1, win 512, options [nop,nop,TS val 4262616452 ecr 4262615841], length 77
|
||||
01:37:25.149734 IP6 (flowlabel 0xe10b3, hlim 64, next-header TCP (6) payload length: 32) ::1.3350 > ::1.52600: Flags [.], cksum 0x0028 (incorrect -> 0xe028), ack 78, win 511, options [nop,nop,TS val 4262616452 ecr 4262616452], length 0
|
||||
01:37:25.216918 IP6 (flowlabel 0xe10b3, hlim 64, next-header TCP (6) payload length: 62) ::1.3350 > ::1.52600: Flags [P.], cksum 0x0046 (incorrect -> 0xd13d), seq 1:31, ack 78, win 512, options [nop,nop,TS val 4262616519 ecr 4262616452], length 30
|
||||
01:37:25.216969 IP6 (flowlabel 0xc281a, hlim 64, next-header TCP (6) payload length: 32) ::1.52600 > ::1.3350: Flags [.], cksum 0x0028 (incorrect -> 0xdf83), ack 31, win 512, options [nop,nop,TS val 4262616519 ecr 4262616519], length 0
|
||||
01:37:25.254713 IP6 (flowlabel 0xe10b3, hlim 64, next-header TCP (6) payload length: 32) ::1.3350 > ::1.52600: Flags [F.], cksum 0x0028 (incorrect -> 0xdf5c), seq 31, ack 78, win 512, options [nop,nop,TS val 4262616557 ecr 4262616519], length 0
|
||||
01:37:25.297973 IP6 (flowlabel 0xc281a, hlim 64, next-header TCP (6) payload length: 32) ::1.52600 > ::1.3350: Flags [.], cksum 0x0028 (incorrect -> 0xdf0b), ack 32, win 512, options [nop,nop,TS val 4262616600 ecr 4262616557], length 0
|
||||
01:37:25.886713 IP6 (flowlabel 0xc281a, hlim 64, next-header TCP (6) payload length: 32) ::1.52600 > ::1.3350: Flags [F.], cksum 0x0028 (incorrect -> 0xdcbd), seq 78, ack 32, win 512, options [nop,nop,TS val 4262617189 ecr 4262616557], length 0
|
||||
01:37:25.886737 IP6 (flowlabel 0xc429c, hlim 64, next-header TCP (6) payload length: 32) ::1.3350 > ::1.52600: Flags [.], cksum 0x0028 (incorrect -> 0xda45), ack 79, win 512, options [nop,nop,TS val 4262617189 ecr 4262617189], length 0
|
||||
01:37:41.603074 IP6 (flowlabel 0x461f5, hlim 64, next-header TCP (6) payload length: 32) ::1.46136 > ::1.3350: Flags [F.], cksum 0x0028 (incorrect -> 0x23fc), seq 3577026672, ack 1112127163, win 512, options [nop,nop,TS val 4262632906 ecr 4262596309], length 0
|
||||
01:37:41.603101 IP6 (flowlabel 0xeaed7, hlim 64, next-header TCP (6) payload length: 32) ::1.3350 > ::1.46136: Flags [.], cksum 0x0028 (incorrect -> 0x9506), ack 1, win 512, options [nop,nop,TS val 4262632906 ecr 4262632906], length 0
|
||||
```
|
||||
|
||||
我们也可以利用 journalctl -xf 查看日志
|
||||
|
||||
```shell
|
||||
Aug 18 01:45:02 freeabc xrdp[10507]: (10507)(139797313210176)[INFO ] Socket 12: AF_INET6 connection received from ::ffff:192.168.222.1 port 56030
|
||||
Aug 18 01:45:02 freeabc xrdp[10507]: (10507)(139797313210176)[DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.222.178 port 3389)
|
||||
Aug 18 01:45:02 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] Closed socket 11 (AF_INET6 :: port 3389)
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] Using default X.509 certificate: /etc/xrdp/cert.pem
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] Using default X.509 key file: /etc/xrdp/key.pem
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] TLSv1.2 enabled
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] TLSv1.1 enabled
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] TLSv1 enabled
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] Security layer: requested 11, selected 1
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] connected client computer name: DESKTOP-9PAUEP4
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] TLS connection established from ::ffff:192.168.222.1 port 56030: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] xrdp_000029bf_wm_login_mode_event_00000001
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] Cannot find keymap file /etc/xrdp/km-00000804.ini
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] Cannot find keymap file /etc/xrdp/km-00000804.ini
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] Loading keymap file /etc/xrdp/km-00000409.ini
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[WARN ] local keymap file for 0x00000804 found and doesn't match built in keymap, using local keymap file
|
||||
Aug 18 01:45:03 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] xrdp_wm_log_msg: connecting to sesman ip 127.0.0.1 port 3350
|
||||
Aug 18 01:45:03 freeabc xrdp-sesman[10471]: (10471)(140145709626688)[INFO ] A connection received from ::1 port 36482
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] xrdp_wm_log_msg: sesman connect ok
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] xrdp_wm_log_msg: sending login info to session manager, please wait...
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] return value from xrdp_mm_connect 0
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10471]: (10471)(140145709626688)[INFO ] ++ created session (access granted): username root, ip ::ffff:192.168.222.1:56030 - socket: 12
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10471]: (10471)(140145709626688)[INFO ] starting Xorg session...
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10471]: (10471)(140145709626688)[DEBUG] Closed socket 9 (AF_INET6 :: port 5911)
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10471]: (10471)(140145709626688)[DEBUG] Closed socket 9 (AF_INET6 :: port 6011)
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10471]: (10471)(140145709626688)[DEBUG] Closed socket 9 (AF_INET6 :: port 6211)
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[INFO ] calling auth_start_session from pid 10688
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10471]: (10471)(140145709626688)[DEBUG] Closed socket 8 (AF_INET6 ::1 port 3350)
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] xrdp_wm_log_msg: login successful for display 11
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: pam_unix(xrdp-sesman:session): session opened for user root by (uid=0)
|
||||
Aug 18 01:45:04 freeabc systemd-logind[1076]: New session c15 of user root.
|
||||
-- Subject: A new session c15 has been created for user root
|
||||
-- Defined-By: systemd
|
||||
-- Support: http://www.ubuntu.com/support
|
||||
-- Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
|
||||
--
|
||||
-- A new session with the ID c15 has been created for the user root.
|
||||
--
|
||||
-- The leading process of the session is 10688.
|
||||
Aug 18 01:45:04 freeabc systemd[1]: Started Session c15 of user root.
|
||||
-- Subject: Unit session-c15.scope has finished start-up
|
||||
-- Defined-By: systemd
|
||||
-- Support: http://www.ubuntu.com/support
|
||||
--
|
||||
-- Unit session-c15.scope has finished starting up.
|
||||
--
|
||||
-- The start-up result is RESULT.
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[DEBUG] Closed socket 7 (AF_INET6 ::1 port 3350)
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] xrdp_wm_log_msg: started connecting
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[DEBUG] Closed socket 8 (AF_INET6 ::1 port 3350)
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10690]: (10690)(140145709626688)[INFO ] /usr/lib/xorg/Xorg :11 -auth .Xauthority -config xrdp/xorg.conf -noreset -nolisten tcp -logfile .xorgxrdp.%s.log
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[CORE ] waiting for window manager (pid 10689) to exit
|
||||
Aug 18 01:45:04 freeabc systemd[1487]: Started GnuPG cryptographic agent and passphrase cache.
|
||||
-- Subject: Unit UNIT has finished start-up
|
||||
-- Defined-By: systemd
|
||||
-- Support: http://www.ubuntu.com/support
|
||||
--
|
||||
-- Unit UNIT has finished starting up.
|
||||
--
|
||||
-- The start-up result is RESULT.
|
||||
Aug 18 01:45:04 freeabc gpg-agent[10760]: gpg-agent (GnuPG) 2.2.4 starting in supervised mode.
|
||||
Aug 18 01:45:04 freeabc gpg-agent[10760]: using fd 3 for ssh socket (/run/user/0/gnupg/S.gpg-agent.ssh)
|
||||
Aug 18 01:45:04 freeabc gpg-agent[10760]: using fd 4 for extra socket (/run/user/0/gnupg/S.gpg-agent.extra)
|
||||
Aug 18 01:45:04 freeabc gpg-agent[10760]: using fd 5 for std socket (/run/user/0/gnupg/S.gpg-agent)
|
||||
Aug 18 01:45:04 freeabc gpg-agent[10760]: using fd 6 for browser socket (/run/user/0/gnupg/S.gpg-agent.browser)
|
||||
Aug 18 01:45:04 freeabc gpg-agent[10760]: listening on: std=5 extra=4 browser=6 ssh=3
|
||||
Aug 18 01:45:04 freeabc kernel: xfce4-session[10742]: segfault at 2c ip 0000556e4a4fe8c6 sp 00007ffedc54cd30 error 4 in xfce4-session[556e4a4d2000+45000]
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] lib_mod_log_peer: xrdp_pid=10687 connected to X11rdp_pid=10690 X11rdp_uid=0 X11rdp_gid=0 client_ip=::ffff:192.168.222.1 client_port=56030
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] xrdp_wm_log_msg: connected ok
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] xrdp_mm_connect_chansrv: chansrv connect successful
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] Closed socket 20 (AF_INET6 ::1 port 36482)
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] The following channel is allowed: rdpdr (0)
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] The following channel is allowed: rdpsnd (1)
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] The following channel is allowed: cliprdr (2)
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[INFO ] The following channel is allowed: drdynvc (3)
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] The allow channel list now initialized for this session
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[CORE ] window manager (pid 10689) did exit, cleaning up session
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[INFO ] calling auth_stop_session and auth_end from pid 10688
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: pam_unix(xrdp-sesman:session): session closed for user root
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[DEBUG] cleanup_sockets:
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] Closed socket 22 (AF_UNIX)
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[DEBUG] cleanup_sockets: deleting /var/run/xrdp/sockdir/xrdp_chansrv_audio_out_socket_11
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.222.178 port 3389)
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[DEBUG] cleanup_sockets: deleting /var/run/xrdp/sockdir/xrdp_chansrv_audio_in_socket_11
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] xrdp_mm_module_cleanup
|
||||
Aug 18 01:45:04 freeabc xrdp[10687]: (10687)(139797313210176)[DEBUG] Closed socket 21 (AF_UNIX)
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10688]: (10688)(140145709626688)[DEBUG] cleanup_sockets: deleting /var/run/xrdp/sockdir/xrdpapi_11
|
||||
Aug 18 01:45:04 freeabc xrdp-sesman[10471]: (10471)(140145709626688)[INFO ] ++ terminated session: username root, display :11.0, session_pid 10688, ip ::ffff:192.168.222.1:56030 - socket: 12
|
||||
Aug 18 01:45:14 freeabc systemd-logind[1076]: Removed session c15.
|
||||
-- Subject: Session c15 has been terminated
|
||||
```
|
||||
|
||||
这个日志可以看到更清楚的流程,具体日志见上
|
||||
我们看到这个没启动起来是 xfce4-session[10742]: segfault at 2c ip 0000556e4a4fe8c6 sp 00007ffedc54cd30 error 4 in xfce4-session[556e4a4d2000+45000] 有段错误
|
||||
这个错误,我们可以单独运行 xfce4-session 查看原因
|
||||
|
||||
```shell
|
||||
xfwm4-Message: 02:00:03.303: Another Window Manager (Xfwm4) is already running on screen :10.0
|
||||
xfwm4-Message: 02:00:03.303: To replace the current window manager, try "--replace"
|
||||
(xfwm4:11384): xfwm4-WARNING **: 02:00:03.303: Could not find a screen to manage, exiting
|
||||
```
|
||||
|
||||
我们看到是另外一个 Xfwn4 已经启动在 screen :10.0 了,可以运行 xfwm4 --replace 替换一下
|
||||
对用户的授权,我们通过日志可以观察到是通过文件 ~/.Xauthority
|
||||
|
||||
5. xrdp-sesman 会根据 sesman.ini 调用 /etc/xrdp/startwm.sh,这个脚本最终会调用 /etc/X11/Xsession 这个脚本, Xsession 这个脚本大有文章
|
||||
```shell
|
||||
SYSSESSIONDIR=/etc/X11/Xsession.d
|
||||
USERXSESSION=$HOME/.xsession ---> 看到没有这就是我们经常看到的很多文章推荐的 echo "xfce4-session" > ~/.xsession 的原因,设置 Xsession 的环境变量
|
||||
...
|
||||
SESSIONFILES=$(run-parts --list $SYSSESSIONDIR) ---> 最终会执行 /etc/X11/Xsession.d 下的脚本,我们所有的窗口会话实现,应该放到这个里面
|
||||
|
||||
if [ -n "$SESSIONFILES" ]; then
|
||||
set +e
|
||||
for SESSIONFILE in $SESSIONFILES; do
|
||||
echo $SESSIONFILES >> /root/my.log
|
||||
. $SESSIONFILE
|
||||
done
|
||||
set -e
|
||||
fi
|
||||
```
|
||||
|
||||
/etc/X11/Xsession.d/20dbus_xdg-runtime
|
||||
/etc/X11/Xsession.d/20x11-common_process-args
|
||||
/etc/X11/Xsession.d/30x11-common_xresources
|
||||
/etc/X11/Xsession.d/35x11-common_xhost-local
|
||||
/etc/X11/Xsession.d/40x11-common_xsessionrc
|
||||
/etc/X11/Xsession.d/50x11-common_determine-startup
|
||||
/etc/X11/Xsession.d/60x11-common_localhost
|
||||
/etc/X11/Xsession.d/60x11-common_xdg_path
|
||||
/etc/X11/Xsession.d/75dbus_dbus-launch
|
||||
/etc/X11/Xsession.d/90gpg-agent
|
||||
/etc/X11/Xsession.d/90qt-a11y
|
||||
/etc/X11/Xsession.d/90x11-common_ssh-agent
|
||||
/etc/X11/Xsession.d/95dbus_update-activation-env
|
||||
/etc/X11/Xsession.d/99x11-common_start
|
||||
|
||||
参数 STARTUP 赋值
|
||||
我们看到执行 /etc/X11/Xsession.d/50x11-common_determine-startup 时,会 STARTUP="$shell $STARTUPFILE" 其实就是 /bin/bash /root/.xsession , root就是 ~ 我们用 root 登录的。
|
||||
|
||||
参数 STARTUP 运行
|
||||
我们跟踪执行 /etc/X11/Xsession.d/99x11-common_start/99x11-common_start 时,exec $STARTUP 这个其实就是执行 xfce4-session 了,至此 xfce4-session 启动完成
|
||||
|
||||
xfce4-session 会读取 下面的文件,并执行里面的命令
|
||||
https://manpages.ubuntu.com/manpages/xenial/man1/xfce4-session.1.html
|
||||
xfce4-session reads its configuration from Xfconf. xfce4-session stores its session data into $XDG_CACHE_HOME/sessions/.
|
||||
|
||||
具体配置文件就是 /usr/local/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<channel name="xfce4-session" version="1.0">
|
||||
<property name="general" type="empty">
|
||||
<property name="FailsafeSessionName" type="string" value="Failsafe"/>
|
||||
<property name="LockCommand" type="string" value=""/>
|
||||
</property>
|
||||
<property name="sessions" type="empty">
|
||||
<property name="Failsafe" type="empty">
|
||||
<property name="IsFailsafe" type="bool" value="true"/>
|
||||
<property name="Count" type="int" value="5"/>
|
||||
<property name="Client0_Command" type="array">
|
||||
<value type="string" value="xfwm4"/>
|
||||
</property>
|
||||
<property name="Client0_Priority" type="int" value="15"/>
|
||||
<property name="Client0_PerScreen" type="bool" value="false"/>
|
||||
<property name="Client1_Command" type="array">
|
||||
<value type="string" value="xfsettingsd"/>
|
||||
</property>
|
||||
<property name="Client1_Priority" type="int" value="20"/>
|
||||
<property name="Client1_PerScreen" type="bool" value="false"/>
|
||||
<property name="Client2_Command" type="array">
|
||||
<value type="string" value="xfce4-panel"/>
|
||||
</property>
|
||||
<property name="Client2_Priority" type="int" value="25"/>
|
||||
<property name="Client2_PerScreen" type="bool" value="false"/>
|
||||
<property name="Client3_Command" type="array">
|
||||
<value type="string" value="Thunar"/>
|
||||
<value type="string" value="--daemon"/>
|
||||
</property>
|
||||
<property name="Client3_Priority" type="int" value="30"/>
|
||||
<property name="Client3_PerScreen" type="bool" value="false"/>
|
||||
<property name="Client4_Command" type="array">
|
||||
<value type="string" value="xfdesktop"/>
|
||||
</property>
|
||||
<property name="Client4_Priority" type="int" value="35"/>
|
||||
<property name="Client4_PerScreen" type="bool" value="false"/>
|
||||
</property>
|
||||
</property>
|
||||
</channel>
|
||||
```
|
||||
|
||||
我们看到一个会话启动五个最基本的服务 xfwm4, xfsettingsd, xfce4-panel, Thunar, xfdesktop,如果启动失败,请依次排查这几个服务是否正常
|
||||
如果只出状态栏和 Dock ,桌面出现黑屏,基本上是 xfdesktop 启动失败,可能依赖的库不满足,缺少什么库,这个需要具体问题具体分析了。
|
||||
进程关系如下图
|
||||
```shell
|
||||
systemd--
|
||||
|-xrdp---xrdp
|
||||
|-xrdp-sesman---xrdp-sesman---Xorg---9*[{Xorg}]
|
||||
|-bash---ssh-agent
|
||||
| |-xfce4-session---Thunar---2*[{Thunar}]
|
||||
| |-xfce4-panel---panel-14-action---2*[{panel-14-action}]
|
||||
| | |-panel-6-systray---2*[{panel-6-systray}]
|
||||
| | |-panel-9-power-m---2*[{panel-9-power-m}]
|
||||
| | |-2*[{xfce4-panel}]
|
||||
| |-xfce4-power-man---2*[{xfce4-power-man}]
|
||||
| |-xfdesktop---2*[{xfdesktop}]
|
||||
| |-xfsettingsd---2*[{xfsettingsd}]
|
||||
| |-xfwm4---2*[{xfwm4}]
|
||||
| |-10*[{xfce4-session}]
|
||||
|-xrdp-chansrv---{xrdp-chansrv}
|
||||
```
|
||||
|
||||
Xorg 就是我们通常说的 xserver, 有关整个流程的调试,我们可以用下述命令进行错误排除
|
||||
```shell
|
||||
env LD_LIBRARY_PATH="/root/test/build/test/a/usr/lib:/root/test/build/test/a/usr/local/lib:/root/test/build/test/a/usr/lib/x86_64-linux-gnu:/root/test/build/test/a/opt/libjpeg-turbo/lib64" DBUS_SESSION_BUS_ADDRESS="unix:path=/var/run/dbus/session_bus_socket" strace -f xrdp-sesman -n
|
||||
```
|
||||
基本上 xrdp-sesman 会启动 Xorg ( xserver ), Xorg 会通过 tcp 或 Unix socket 与 xclient 进行通讯;还会启动 xsession, 还会启动 xrdp-chansrv,从上述我们可以得知,这些组件都必须启动成功,否则,就会看不到图像界面。我们通过 strace -f 跟踪得知 xrdp-sesman 是通过接口 execve 启动的 Xorg ,这个接口执行后,来自父进程的环境变量将会被清除,导致 LD_LIBRARY_PATH 失效,因此 Xorg 所依赖的动态库就找不到,解决方法就是把库直接拷贝到系统库的位置,就行,比如:
|
||||
```shell
|
||||
cp /root/smart-os/build/test/a/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0 /usr/lib/x86_64-linux-gnu/
|
||||
```
|
||||
|
||||
# 常见问题解决方法
|
||||
1. 解决 Fontconfig error: Cannot load default config file: No such file
|
||||
cp /root/test/a/usr/local/etc/* /usr/local/etc/ -rf
|
||||
|
||||
2. 解决 Cannot read private key file /etc/xrdp/key.pem: Permission denied
|
||||
```shell
|
||||
adduser xrdp ssl-cert
|
||||
reboot
|
||||
```
|
||||
|
||||
3. 解决 libpango 库多版本的环境下,系统的低版本优先加载,导致 xfdesktop 不能正常启动的问题我们可以这么做
|
||||
```shell
|
||||
libdir=`pwd`"/a/usr"
|
||||
echo "LD_LIBRARY_PATH=\"${libdir}/lib:${libdir}/local/lib:${libdir}/lib/x86_64-linux-gnu\" xfce4-session" > ~/.xsession
|
||||
```
|
||||
这样就可以优先加载我们编译的动态库了
|
||||
|
||||
4. xfce4-session 其实相应的配置也可以通过命令行工具查看
|
||||
xfconf-query -c xfce4-session -p /sessions/Failsafe/Client3_Command
|
||||
我们可以逐行查看每个属性,然后通过 ps -aef | grep xf* 查看相应的进程是否正确启动,如果没有启动,就会导致出现问题,然后单独手工启动那个进程,查看是什么原因导致不能正常启动的,解决问题就非常简单了。
|
||||
|
||||
5. xfdesktop 启动时,提示:Settings schema 'org.gtk.Settings.FileChooser' is not installed
|
||||
方法:apt install libgtk-3-common
|
||||
|
||||
6. xfce4 编译后,启动远程桌面,发现面板上相应的 item 都没有图标,进入文件管理器,对应的文件也没有图标,只显示文字,需要安装
|
||||
方法:apt install gnome-icon-theme,当然这两个问题只装 libgtk-3-common 都可以解决
|
||||
|
||||
7. 编译 libxi 库时,会提示下面的错误,我们去官方网站去看 发现 inputproto 项目已经被废弃,怎么办?
|
||||
```shell
|
||||
configure: error: Package requirements (xproto >= 7.0.13 x11 >= 1.6 xextproto >= 7.0.3 xext >= 1.0.99.1 inputproto >= 2.3.99.1) were not met:
|
||||
Requested 'inputproto >= 2.3.99.1' but version of InputProto is 2.3.2
|
||||
```
|
||||
方法:其实现在这些(inputproto)都被合并到项目 xorgproto 里面了,编译这个库就行了,这个问题折腾我好久
|
||||
|
||||
8. 编译 libx11 遇到问题
|
||||
```shell
|
||||
checking keysym definitions... configure: error: /usr/local/include/X11 doesn't exist or isn't a directory
|
||||
```
|
||||
方法: --with-keysymdefdir="${xfce_install}/usr/local/include/X11"
|
||||
|
||||
9. 编译 pciaccess, libxcb-util 遇到问题
|
||||
```shell
|
||||
error: must install xorg-macros 1.8 or later before running autoconf/autogen
|
||||
error: must install xorg-macros 1.16.0 or later before running autoconf/autogen
|
||||
```
|
||||
方法: 原因就是 aclocal 的路径设置的不完全
|
||||
```shell
|
||||
export ACLOCAL="aclocal -I /usr/share/aclocal -I ${xfce_share}/aclocal -I ${xfce_loc_share}/aclocal"
|
||||
```
|
||||
10. 我们利用 xrdp 远程访问 xfce 桌面黑屏,查看日志 .xsession-errors,发现提示下述错误
|
||||
```shell
|
||||
(xfce4-session:1904): xfce4-session-WARNING **: 11:23:52.330: ICE connection 0x55b030d772e0 rejected
|
||||
(xfwm4:1942): xfwm4-WARNING **: 11:23:52.330: Failed to connect to session manager: Failed to connect to the session manager: Authentication Rejected, reason : None of the authentication protocols specified are supported and host-based authentication failed
|
||||
(xfce4-session:1904): xfce4-session-WARNING **: 11:24:00.217: ICE connection 0x55b030ddb520 rejected
|
||||
Failed to connect to session manager: Failed to connect to the session manager: Authentication Rejected, reason : None of the authen
|
||||
tication protocols specified are supported and host-based authentication failed
|
||||
```
|
||||
我们进一步追踪,journalctl -xf
|
||||
```shell
|
||||
Aug 28 11:30:52 freeabc xrdp[2172]: (2172)(139849385854784)[INFO ] Using default X.509 key file: /etc/xrdp/key.pem
|
||||
Aug 28 11:30:52 freeabc xrdp[2172]: (2172)(139849385854784)[ERROR] Cannot read private key file /etc/xrdp/key.pem: Permission denied
|
||||
Aug 28 11:30:52 freeabc xrdp[2172]: (2172)(139849385854784)[DEBUG] TLSv1.2 enabled
|
||||
Aug 28 11:30:52 freeabc xrdp[2172]: (2172)(139849385854784)[DEBUG] TLSv1.1 enabled
|
||||
Aug 28 11:30:52 freeabc xrdp[2172]: (2172)(139849385854784)[DEBUG] TLSv1 enabled
|
||||
Aug 28 11:30:52 freeabc xrdp[2172]: (2172)(139849385854784)[DEBUG] Security layer: requested 11, selected 0
|
||||
Aug 28 11:30:52 freeabc xrdp[2172]: (2172)(139849385854784)[DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.1.101 port 3389)
|
||||
Aug 28 11:30:52 freeabc xrdp[1289]: (1289)(139849385854784)[INFO ] Socket 12: AF_INET6 connection received from ::ffff:192.168.1.105 port 11281
|
||||
Aug 28 11:30:52 freeabc xrdp[1289]: (1289)(139849385854784)[DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.1.101 port 3389)
|
||||
Aug 28 11:30:52 freeabc xrdp[2173]: (2173)(139849385854784)[DEBUG] Closed socket 11 (AF_INET6 :: port 3389)
|
||||
Aug 28 11:30:52 freeabc xrdp[2173]: (2173)(139849385854784)[INFO ] Using default X.509 certificate: /etc/xrdp/cert.pem
|
||||
Aug 28 11:30:52 freeabc xrdp[2173]: (2173)(139849385854784)[INFO ] Using default X.509 key file: /etc/xrdp/key.pem
|
||||
Aug 28 11:30:52 freeabc xrdp[2173]: (2173)(139849385854784)[ERROR] Cannot read private key file /etc/xrdp/key.pem: Permission denied
|
||||
```
|
||||
我们看到是 key.pem 的权限不允许导致的, sudo adduser xrdp ssl-cert 重启系统,这个问题解决
|
||||
|
||||
11. 如果我们运行 xsession 提示 Can't open display, 即使我们设置环境变量 export DISPLAY=:10 ,也是这个提示,引起这个问题的原因有很多,但我们首先第一步要做的是要检查 Xorg( xserver ) 服务在不在,一般情况通常会忽略这个检查
|
||||
|
||||
12. Xorg(xserver) 启动时,提示错误
|
||||
```shell
|
||||
Using system config directory "/usr/local/share/X11/xorg.conf.d"
|
||||
MESA-LOADER: failed to open vmwgfx (search paths /usr/lib/x86_64-linux-gnu/dri)
|
||||
failed to load driver: vmwgfx
|
||||
MESA-LOADER: failed to open kms_swrast (search paths /usr/lib/x86_64-linux-gnu/dri)
|
||||
failed to load driver: kms_swrast
|
||||
MESA-LOADER: failed to open swrast (search paths /usr/lib/x86_64-linux-gnu/dri)
|
||||
failed to load swrast driver
|
||||
couldn't get display device
|
||||
```
|
||||
解决:缺失显卡驱动
|
||||
apt install libgl1-mesa-dri
|
||||
|
||||
13. Xorg(xserver)启动时,提示错误
|
||||
```shell
|
||||
XKB: Failed to compile keymap
|
||||
Keyboard initialization failed. This could be a missing or incorrect setup of xkeyboard-config.
|
||||
(EE)
|
||||
Fatal server error:
|
||||
(EE) Failed to activate virtual core keyboard: 2(EE)
|
||||
(EE)
|
||||
```
|
||||
解决:
|
||||
ln -s /usr/share/X11/xkb /usr/local/share/X11/xkb
|
||||
这样再运行 Xorg 就可以正常运行了。
|
||||
|
||||
14. failed to load driver: swrast
|
||||
```shell
|
||||
LD_LIBRARY_PATH="/root/smart-os/build/test/a/usr/lib:/root/smart-os/build/test/a/usr/local/lib:/root/smart-os/build/test/a/usr/lib/x86_64-linux-gnu:/root/smart-os/build/test/a/opt/libjpeg-turbo/lib64" xfwm4
|
||||
MESA-LOADER: failed to open swrast (search paths /usr/lib/x86_64-linux-gnu/dri)
|
||||
libGL error: failed to load driver: swrast
|
||||
```
|
||||
解决:
|
||||
apt install libgl1-mesa-dri
|
||||
|
||||
15. 我们的 upower.service 运行依赖我们编译的 glib 库,系统自带的 glib 版本有点低,我们为 systemd 的服务单元增加环境变量,才能让 unit 正确运行
|
||||
因此我们需要编辑 vi /lib/systemd/system/upower.service
|
||||
```shell
|
||||
[Service]
|
||||
Type=dbus
|
||||
BusName=org.freedesktop.UPower
|
||||
ExecStart=/usr/libexec/upowerd
|
||||
Restart=on-failure
|
||||
Environment="LD_LIBRARY_PATH=/root/smart-os/build/test/a/usr/lib:/root/smart-os/build/test/a/usr/local/lib:/root/smart-os/build/test/a/usr/lib/x86_64-linux-gnu:/root/smart-os/build/test/a/opt/libjpeg-turbo/lib64"
|
||||
```
|
||||
|
||||
16. 通过 systemctl start upower.service ,启动会被系统强杀 SIGSYS ( syscall=12 ),apport.log 会提示下面的错误
|
||||
```shell
|
||||
ERROR: apport (pid 3268) Thu Sep 15 10:25:01 2022: host pid 3257 crashed in a separate mount namespace, ignoring
|
||||
```
|
||||
journalctl -xf 会提示下面的错误
|
||||
```shell
|
||||
Sep 15 10:25:01 freeabc kernel: [ 5505.813250] audit: type=1326 audit(1663237501.505:66): auid=4294967295 uid=0 gid=0 ses=4294967295 pid=3300 comm="upowerd"
|
||||
exe="/usr/local/bin/upowerd" sig=31 arch=c000003e syscall=12 compat=0 ip=0x7f40bfa9c0a9 code=0x0
|
||||
```
|
||||
单独执行 /usr/libexec/upowerd -v ,也能成功执行。这个问题让我困惑了好久,目前找到解决方法了;我们需要做的是把 upower.service 里面的几句话注释掉即可
|
||||
```shell
|
||||
# System call interfaces
|
||||
LockPersonality=yes
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallFilter=ioprio_get
|
||||
```
|
||||
猜测这样可能就不会启动 seccomp 的功能了,upower.service 调用的系统调用就能正确进行了,保证 systemctl start upower.service 启动成功
|
||||
|
||||
17. 如果采用高版本的 glibc 库,mk_xfce4.sh 的编译就会出现很多问题,编译 harfbuzz,gdk-pixbuf 都会遇到问题: linking of temporary binary failed,died with <Signals.SIGSEGV: 11>,目前采用降低 glibc ( 2.32 ---> 2.27 ) 版本的方法,编译通过
|
||||
|
||||
18. 编译 llvm 时,对内存要求特别高,小内存会导致编译失败,现象就是被系统 kill
|
||||
```shell
|
||||
collect2: fatal error: ld terminated with signal 9 [Killed]
|
||||
```
|
||||
所以一定保持系统的内存 >= 8G
|
57
初识 initramfs .md
Normal file
57
初识 initramfs .md
Normal file
@ -0,0 +1,57 @@
|
||||
# 简述
|
||||
下述资料,大部分都是采摘于网上对应的博客,感觉内容不错,简单做了一下归纳,感谢大拿们的精彩分享!
|
||||
|
||||
内核启动时,并没加载根文件系统,有些是内核启动阶段不易完成的工作(驱动现在和内核很多都是分开的,位于外存储系统上,所以内核启动后很多事情都做不了),还有些根文件系统是加密的,反正有多种限制和需求。
|
||||
所以内核启动后会先启动一个内存模式的根文件系统,通常就是 initramfs ,早期一般都是采用 initrd, initrd 是一个位于内存中的完整模拟的块设备,需要整个文件系统的开销,有固定的大小,不灵活,它是一个真
|
||||
实的,静态的设备,消耗 Linux 内核中的缓存和文件分页,带来更多的内存开销. 鉴于 initrd 存在很多弊端,后续逐步被 initramfs 所代替. initramfs 不是设备,而是能直接运行在内存中的根文件系统,规避了 initrd
|
||||
的弊端,好处大大的。
|
||||
|
||||
### 为什么驱动不集成到内核?
|
||||
1. Linux 是一个通用的系统,目标是针对各种不同的硬件平台,况且还有很多新的设备源源不断的出来并集成到内核,将所有的驱动全部集成到内核非常不合理,因此需要把驱动和内核解耦分开,通常这些驱动模块编译成模块,存在外部的根文件系统中
|
||||
2. 根文件系统不可能在一个简单的硬盘上,当使用磁盘阵列 RAID 时,根文件系统可能跨几个存储设备,根文件系统也可能在某个网络设备上,比如:NFS ,还需要网络配置,网络认证,还有加解密的需要,等各种需求场景
|
||||
为了解决这些问题,initramfs 横空出世,initramfs 是一个临时的文件系统,其中包含了必要的设备如硬盘、网卡、文件系统等的驱动以及加载驱动的工具及其运行环境,比如基本的 C 库,动态库的链接加载器等等
|
||||
|
||||
早期的处理时基于 initrd , initrd 是基于 ramdisk 技术的,而 ramdisk 就是一个基于内存的块设备,因此 initrd 也具有块设备的一切属性。比如 initrd 容量是固定的,一旦创建 initrd 时设定了一个大小,就不能再进行动态调整,所以后续被 initramfs 逐步代替
|
||||
|
||||
# initramfs 的好处
|
||||
我们知道 Linux 存在着 live 版本,live 启动后会卸载光盘,把系统加载到内存中,这样尝试一个新系统或对另一个系统进行修复时不会伤害到已安装的系统,非常方便。
|
||||
此外还可以
|
||||
1. 加载模块,如第三方驱动
|
||||
2. 定制化启动系统
|
||||
3. 制作一个很小的 rescue shell
|
||||
4. 内核不能,但是用户态可以完成的命令
|
||||
5. 逻辑卷管理器
|
||||
6. 软件 RAID
|
||||
7. 蓝牙驱动
|
||||
|
||||
# initramfs 的组成
|
||||
内核挂载 initramfs 时,文件系统的根分区并没挂载,所以无法访问文件系统中的文件。所以 initramfs 至少包含一个文件 /init ,内核的第一个进程,就是咱们常常听说的大名鼎鼎的 init 进程。
|
||||
别的根据需要定制,当然 /usr, /bin 等目录也是必要的。initramfs 是通过 cpio 进行归档的,能够兼容大部分设备。
|
||||
|
||||
# initramfs 的运行
|
||||
initramfs 通常和内核一起存储,bootloader 引导内核时,通常会把 initramfs 以参数的形式传递给内核,内核检测到 initramfs ,会创建一个 tmpfs 文件系统,并把 initramfs 解压到 tmpfs 中,内核启动 tmpfs 文件系统中的 init 脚本,该程序将探测硬件设备、加载驱动,挂载真正的文件系统,执行文件系统上的 /sbin/init,进而切换到真正的用户空间。真正的文件系统挂载后,initramfs 即完成了使命,其占用的内存也会被释放,继而进行后续的启动过程
|
||||
|
||||
当2.6版本的内核引导时,在挂载真正的根文件系统之前,首先将挂载一个名为 rootfs 的文件系统,并将 rootfs 的根作为虚拟文件系统目录树的总根。那么为什么要使用 rootfs 这么一个中间过程呢?原因之一还是为了解决鸡和蛋的问题。内核需要根文件系统上的驱动以及程序来驱动和挂载根文件系统,但是这些驱动和程序有可能没有编译进内核,而在根文件系统上。如果不借助第三方,内核是没有办法挂载真正的根文件系统的。而 rootfs 虽然名称为 rootfs,但是并不是什么新的文件系统,事实上,rootfs 就是一个 ramfs,只不过换了一个名称。换句话说,rootfs 是在内存中的,内核不需要特殊的驱动就可以挂载 rootfs,所以内核使用 rootfs 作为一个过渡的桥梁。
|
||||
|
||||
在挂载了 rootfs 后,内核将 Bootloader 加载到内存中的 initramfs 中打包的文件解压到 rootfs 中,而这些文件中包含了驱动以及挂载真正的根文件系统的工具,内核通过加载这些驱动、使用这些工具,实现了挂载真正的根文件系统。此后,rootfs 也完成了历史使命,被真正的根文件系统覆盖(overmount)。但是 rootfs 作为虚拟文件系统目录树的总根,并不能被卸载。但是这没有关系,前面我们已经谈到了,rootfs 基于 ramfs,删除其中的文件即可释放其占用的空间
|
||||
|
||||
1、挂载 rootfs
|
||||
用于不同操作系统的文件系统其物理存储结构是不同的,但是 Linux 的虚拟文件系统通过为这些文件系统建立中间适配层,实现了 Linux 对各个文件系统的支持,Linux 的虚拟文件系统将文件系统组织为树形结构。在初始化阶段,内核挂载 rootfs 文件系统,虚拟文件系统从无到有,rootfs 的根作为虚拟文件系统这棵大树中的第一个节点,自然成为所有后来创建的节点的祖先。也就是说,虚拟文件系统目录树的根就是 rootfs 的根,本质上,rootfs 就是一个 ramfs 文件系统。
|
||||
通过挂载 rootfs,虚拟文件系统的根目录已经建立起来,根目录已经可以容纳文件了。所以,接下来内核解压 initramfs 的内容到虚拟文件系统的根中,利用 initramfs 中的内容挂载并切换到真正的根文件系统。
|
||||
|
||||
2、解压 initramfs 到 rootfs
|
||||
在挂载了 rootfs 后,内核将 Bootloader 加载到内存中的 initramfs 中的文件解压到 rootfs 中。而这些文件中包含了驱动以及挂载真正的根文件系统的工具,内核通过加载这些驱动、使用这些工具实现挂载真正的根文件系统。
|
||||
|
||||
3、挂载并切换到真正的根目录
|
||||
将 initramfs 成功解压后,挂载真正的根文件系统所需的驱动、程序等已经全部俱备,可以挂载真正的根文件系统了,在 grub.cfg 文件中对应的就是 root=XXX。内核将真正的根文件系统挂载到 initramfs 文件系统中的 /root 目录下。
|
||||
挂载真正的根文件系统后,rootfs 中的内容已经没有保留的意义,但是并不能将 rootfs 卸载,因为 rootfs 是整个虚拟文件系统的根。因此,为了不占用内存空间,将 rootfs 中的内容(文件)释放掉即可,然后将真正的根文件系统移动到虚拟文件系统的根(即 rootfs 的根)下,最后再将进程的文件系统的 namespace 切换到真正的根文件系统。
|
||||
|
||||
# initramfs文件基本操作
|
||||
1. 查看 initramfs
|
||||
lsinitrd
|
||||
|
||||
2. 解压 initramfs
|
||||
/usr/lib/dracut/skipcpio initramfs-3.10.0-229.el7.x86_64.img | zcat | cpio -ivd
|
||||
|
||||
3. 创建 initramfs
|
||||
find . | cpio -o -H newc | gzip -9 > /tmp/test.img
|
308
计算机运作原理.md
Normal file
308
计算机运作原理.md
Normal file
@ -0,0 +1,308 @@
|
||||
# 概述
|
||||
下述资料,大部分都是采摘于网上对应的博客,感觉内容不错,简单做了一下归纳,感谢大拿们的精彩分享!
|
||||
有些流程是重复描述的,我没有调整,多读几次加深印象!
|
||||
|
||||
# 启动
|
||||
启动可以分为两种,一种为冷启动,是指计算机在关机状态下按 POWER 键启动,又叫硬件启动,比如开机,这种启动方式在启动之前计算机处于断电状态,像内存这种需要加电维持的存储部件里面的内容都丢失了,加电开机那一刻里面的值都是随机的,操作系统会对其进行初始化。
|
||||
|
||||
而热启动是在加电的情况下启动,又叫软件启动,比如重启,这种启动方式在启动之前和启动之后电没断过,内存等存储部件里面的值不会改变,但毕竟是启动过程,操作系统会对其进行初始化
|
||||
|
||||
不论是哪种启动,都会向 CPU 发送启动的信号,然后开始启动。同第一篇文章,我们分五个大的步骤讲述启动,BIOS -> MBR -> Bootloader -> OS -> Multiprocessor
|
||||
|
||||
系统 BIOS 所在的 ROM 是被设计成 CPU 可直接寻址的,而且地址范围也是固定的,从 0xF0000H 至 0xFFFFFH 共 64 KB。PC 按通电源后,电源设备开始向主板和其他设备供电,此时电压还不太稳定,主板上的控制芯片组会向 CPU 发出并保持一个 RESET(重置)信号,让 CPU 内部自动恢复到初始状态,但 CPU 在此刻不会马上执行指令。当芯片组检测到电源已经开始稳定供电了(当然从不稳定到稳定的过程只是一瞬间的事情),它便撤去 RESET 信号(如果是手工按下计算机面板上的 Reset 按钮来重启机器,那么松开该按钮时芯片组就会撤去 RESET 信号)CPU 进行重置,IP 寄存器的值设成 0,CS寄存器的值设成 0xFFFF。也就是说 CPU 马上从地址 0xFFFF0H 处开始执行指令,这个地址在系统 BIOS 空间的地址范围内,CPU 就是从这个固定的地址开始执行 BIOS 程序的。
|
||||
|
||||
各厂家的 BIOS 程序不尽相同,但基本都是完成 POST 自检及本地设备的枚举和初始化,包括对硬件执行一系列的测试,用来检测现在都有什么设备以及这些设备是否能正常工作,在这个阶段中,会显示一些信息,例如 BIOS 版本号等;初始化硬件设备,这个阶段在现代基于 PCI 的体系结构中相当重要,因为它可以保证所有的硬件设备操作不会引起 IRQ 线与 I/O 端口的冲突,在本阶段的最后,会显示系统中所安装的所有 PCI 设备的一个列表等。
|
||||
|
||||
BIOS 自检和初始化完成后,开始执行 BIOS 引导程序。由于系统 BIOS 空间只有 64KB 大小,把 Linux 内核放在这个空间里让 BIOS 引导程序直接引导是不可能的,只能把内核放在硬盘里(或其他设备,如 USB 或网络上, BIOS 根据启动顺序的设置依次查找),然后再从硬盘里引导 Linux 内核。但是,这时系统还处于实模式中,寻址能力只有 1MB,没有硬盘上的文件系统等信息,不会直接的引导整个 Linux 内核,而是通过先载入一个引导装入程序,然后由这个引导装入程序来引导 Linux 内核。
|
||||
|
||||
引导装入程序通常放在第一块硬盘(或其他设备)的第一个扇区里,这个扇区就是主引导扇区,包括硬盘主引导记录 MBR(Master Boot Record)、分区表DPT(Disk Partition Table)及主引导扇区标志 “55AA”,共 512 个字节。系统 BIOS 引导程序的唯一任务就是把存放在 MBR 中的引导装入程序载入内存的 0x7C00 位置(可以通过 BIOS 中断方式 INT 13h 读取磁盘指定扇区的内容),然后 CPU 跳转到这个地址,把控制权交给引导装入程序继续引导系统。GRUB(GRand Unified Bootloader)就是这样的一个引导程序。
|
||||
|
||||
# BIOS
|
||||
启动的瞬间会将寄存器 CS 和 IP 初始化:CS = 0xf000, IP = 0xfff0。
|
||||
|
||||
刚启动的时候正处于实模式,实模式下地址总线只用了 20 位,只有 2^20 = 1M 的寻址空间,也就是只用到的内存的低 1M ,这个时候分页机制还没有建立起来,CPU 运行时的地址都是实际的物理地址。
|
||||
|
||||
但实模式下寄存器只用到了 16 位寄存器,如何使用寄存器来寻址 20 位的地址空间?Intel 采用分段的机制来访问内存,也就是采用 段基址 :段偏移,
|
||||
"地址 = 段基址 + 偏移量"的方式来访问,但是实模式下的寄存器只能使用 16 位,所以规定实模式下 "地址 = 段基址 X 16 + 偏移量" 。
|
||||
因此根据 CS = 0xf000, IP = 0xfff0,得到的 address = 0xf000 << 4 + 0xfff0 = 0xffff0 。
|
||||
|
||||
这个地址是啥? 来看内存低 1M 的内存布局:
|
||||
|
||||
| 起始 | 结束 | 大小 | 用途 |
|
||||
| --- | --- | --- | --- |
|
||||
| FFFF0 | FFFFF | 16B | BIOS 入口地址,此地址也属于 BIOS 代码,同样属于顶部的 640 KB 字节,只是为了强调 其入口地址才单独贴出来。此处 16 字节的内容时跳转指令 jmp f000:e05b |
|
||||
| F0000 | FFFEF | 64KB-16B | 系统 BIOS 范围是 F0000~FFFFF 共 640KB,为了说明入口地址,将最上面的 16 字节从此处去掉了,所以此处的终止地址是 0xFFFEF |
|
||||
| C8000 | EFFFF | 160KB | 映射硬件适配器的 ROM 或内存映射模式 I/O |
|
||||
| C0000 | C7FFF | 32KB | 显示适配器 BIOS |
|
||||
| B8000 | BFFFF | 32KB | 用于文本模式显示适配器 |
|
||||
| B0000 | B7FFF | 32KB | 用于黑白显示适配器 |
|
||||
| A0000 | AFFFF | 64KB | 用于彩色显示适配器 |
|
||||
| 9FC00 | 9FFFF | 1KB | EBDA (Extended BIOS Data Area) 扩展 BIOS 数据区 |
|
||||
| 7E00 | 9FBFF | 622080B 约 608KB | 可用区域 |
|
||||
| 7C00 | 7DFF | 512B | MBR 被 BIOS 加载到此处,共 512 字节 |
|
||||
| 500 | 7BFF | 30464B 约 30KB | 可用区域 |
|
||||
| 400 | 4FF | 256B | BIOS Data Area( BIOS 数据区 ) |
|
||||
| 000 | 3FF | 1KB | Interrupt Vector Table ( 中断向量表 ) |
|
||||
|
||||
看最上面两行,可以知道 0xffff0 地址上存放的是一个跳转指令,CPU 执行这个命令然后跳转到 BIOS 代码的主体部分,BIOS 主要做一下几件事:
|
||||
|
||||
* 自检,然后对一些硬件设备做简单的初始化
|
||||
* 构建中断向量表加载中断服务程序
|
||||
* 将硬盘(通常引导设备就是硬盘)最开始那个扇区 MBR 加载到
|
||||
|
||||
# MBR
|
||||
关于 MBR(Master Boot Record),我在捋一捋磁盘及分区一文讲的比较详细了,这里不赘述,简单再说一下 MBR 的结构:
|
||||
|
||||
1. 引导程序和一些参数,446 字节
|
||||
2. 分区表 DPT,64字节
|
||||
3. 结尾标记签名,0x55 和 0xaa,两字节
|
||||
|
||||
MBR 的代码在分区表中寻找可以引导存在操作系统的分区,也就是寻找标记为 0x80 的活动分区,然后加载该活动分区的引导块,再执行其中的操作系统引导程序 Bootloader。
|
||||
|
||||
# Bootloader
|
||||
Bootloader,操作系统引导程序,操作系统加载器,不论怎么叫,它的主要作用就是将操作系统加载到内存里面。操作系统也是一个程序,需要加载到内存里面才能运行。平常正在运行的计算机我们可以使用 exec 族函数来加载运行一个程序,同样的要加载运行操作系统这个程序就使用 Bootloader。
|
||||
|
||||
在 Bootloader 里面还做了一些其他事情,比如进入保护模式,开启分页机制,建立内存的映射等等。像 GRUB,U-Boot 等都属于 Bootloader,只是功能更多更强大。
|
||||
|
||||
# GRUB引导过程
|
||||
|
||||
GRUB(GRand Unified Bootloader)是一个多重启动管理器。它可以在多个操作系统共存时选择启动哪个系统,可以启动的操作系统包括Linux, FreeBSD, Solaris, NetBSD, BeOS, OS/2, Windows 95/98 /NT /2000。它可以载入操作系统的内核和初始化操作系统(如Linux, FreeBSD),或者把启动权交给操作系统(如Windows 98)来完成启动。
|
||||
|
||||
GRUB 的实质是一个 mini os,它拥有 shell,支持 script,支持特定文件系统等。GRUB 由 stage1,stage1_5,stage2 以及 /boot/grub 目录下的诸多文件(包括Grub的配置文件与相关文件系统定义文件等)组成。
|
||||
|
||||
stage1 被编译成了一个 512 字节的 img,写在硬盘的 0 面 0 道第 1 扇,它所做的唯一的事情就是装载第二引导装载程序 stage2。
|
||||
|
||||
stage1_5 写进了 MBR 后的 15 个扇区中(因为 e2fs_stage1_5 大小为 7.5k)。硬盘上第一个文件系统分区的开始扇区最小也只能从 0 柱面,1 磁头,1 扇区开始。就是说 MBR 所在 0 磁头就只用到了 1 个扇区而已(其它扇区都是未用的,不属于任何分区),按照现在硬盘的规格来说,一般一个柱面磁头都有 60+ 个扇区,所有将 stage1_5 写进 MBR 以后的扇区中,不会影响正常的文件系统分区。stage1_5 就是文件系统的解释代码,根据 /boot分区(或/boot所在分区)的具体文件系统类型而异,如:ext3 分区的话就是 e2fs_stage1_5。在 stage1_5 没有被加载以前,系统无法识别任何文件系统(但是可以通过 BIOS 中断方式 INT 13h 读取磁盘指定扇区的内容), 加载 stage1_5 以后就可以识别 /boot所在分区的文件系统了,从而为加载 stage2 作好了准备。
|
||||
|
||||
stage2 是 grub 最核心的部分有 100 多KB,所以只能放在文件系统中,放在 /boot 分区里,放在这里的通常还有 Linux 内核映像文件。加载 stage2 后 grub 会根据 menulist 或用户输入加载 Linux 内核映像文件,即将内核映像装入地址 0x90000 的内存中,将内核入口装入到地址 0x90200 的内存中,然后跳转到内核入口处开始启动内核。
|
||||
|
||||
# OS
|
||||
操作系统内核加载到内存之后,就做一些初始化工作建立好工作环境,比如各个硬件的初始化,重新设置 GDT,IDT 等等初始的操作。初始化启动其他处理器(如果有多个处理器的话)。这里不细说,也不好叙述,等下面直接看实例 xv6 做了哪些事,怎么做的。
|
||||
|
||||
# Multiprocessor
|
||||
上述的启动过程是单处理情况下的启动过程,多处理器的情况下有些不同,用一句话先来简单概括多处理器情况下的启动:先启动一个 CPU,用它作为基础启动其他的处理器。
|
||||
|
||||
先启动的这个 CPU 称作 BSP(BootStrap Processor),其他处理器叫做 AP(Application Processor)。BSP 是由系统硬件或者 BIOS 动态选择决定的。
|
||||
|
||||
多处理器启动过程大致分为以下几个大步骤:
|
||||
|
||||
1. BIOS 启动 BSP,流程与上述讲的 BIOS-MBR-bootloader-OS 差不多
|
||||
2. BSP 从 MP Configuration Table 中获取多处理器的的配置信息
|
||||
3. BSP 启动 APs,通过发送 INIT-SIPI-SIPI 消息给 APs
|
||||
4. APs 启动,各个 APs 处理器要像 BSP 一样建立自己的一些机制,比如保护模式,分页,中断等等
|
||||
|
||||
这里我们主要关注第二点,获取多处理器的配置信息
|
||||
|
||||
# BSP启动详解
|
||||
|
||||
1. 在 BIOS POST 阶段,BSP 创建了 ACPI 表并添加它的 initial APIC ID。
|
||||
2. 进到 OS 后,内核最开始的代码还是由 BSP 执行,初始化后进入正式的 SMP Boot 流程。
|
||||
3. 在 BSP 执行后,将 processor 设置为 CPU 0 并广播一条 SIPI 消息给其他 AP,SIPI 消息包含了 BIOS AP 初始化的代码地址。
|
||||
4. 第一个获得 SIPI 消息的 AP 获取 BIOS 初始化信号量,执行初始化代码,添加 APIC ID 并将 processor 加1,初始化结束后,AP 执行 CLI (Clear Interrupt Flag) 指令并 halt 自己。
|
||||
5. 所有的 AP 都执行完初始化后,BSP 通过系统总线获取 processors 数量后,开始执行 OS boot-strap code、start-up code。AP 现在只能对 INITs, NMIs, and SMIs 响应,当然也响应 STPCLK# 引脚的 snoops、assertions
|
||||
|
||||
用一句话来概括多处理器情况下的启动:先启动一个 CPU,再以它为基础启动其他的处理器。
|
||||
|
||||
先启动的这个 CPU 称作 BSP(BootStrap Processor),其他处理器叫做 AP(Application Processor)。硬件会动态选择系统总线上的一个 processor 作为 BSP,其余的为 AP。在计算机上电或者重置系统时,每个 CPU 都先执行处理器自检(BIST),自检通过的CPU就拥有了称为 BSP 的资格,那么此时选谁呢?
|
||||
|
||||
选择的方式为上电后所有的 CPU 都执行 NOP 指令,看看哪个 CPU 先发送了 NOP,就会成为 BSP,BSP 选出来之后,它会将 IA32_APIC_BASE MSR 里面的 BSP flag 设置为1,标识该处理器是 BSP,其他的APs进入 wait for SIPI 的状态,等待 BSP 的发号施令。
|
||||
|
||||
在 BIOS 中,BSP 首先要收集所有的 AP 信息,将所有 AP 信息登记下来,这个登记表称为 MP Configuration Table,它首先把自己加进去(CPU 0),然后让 APs 自己在登记表上登记。Processors 之间传递消息靠的是一种叫 Inter-Processor Interrupt(IPI)的机制,而通知登记在它们的语言里就是 SIPI(Start-up IPI ),当然 SIPI 只能由 BSP 来说才管用。
|
||||
|
||||
通常BSP的初始化顺序为:
|
||||
|
||||
1. 初始化内存。
|
||||
2. 加载microcode
|
||||
3. 初始化MTRRs
|
||||
4. 初始化Cache
|
||||
5. 加载 AP start-up code 到 1Mbyte 以下的 4K 内存中。
|
||||
6. Enable APIC (SVR bit8)
|
||||
7. Program ICR寄存器,把AP start-up code地址写到该寄存器
|
||||
8. 在AP start-up code里,每个AP将会增加一个COUNT变量表示AP已经起来了
|
||||
9. 广播INIT-SIPI-SIPI IPI sequence to the Aps,这时所有的AP才会真正被唤醒起来执行
|
||||
|
||||
https://zhuanlan.zhihu.com/p/598552628
|
||||
https://peterhu.github.io/posts/2020/08/19/CPU%E5%A4%9A%E6%A0%B8%E5%88%9D%E5%A7%8B%E5%8C%96.html
|
||||
|
||||
# UP
|
||||
UP(Uni-Processor):系统只有一个处理器单元,即单核CPU系统。
|
||||
|
||||
# SMP
|
||||
对称多处理器结构 , 英文名称为 " Symmetrical Multi-Processing " , 简称 SMP 。
|
||||
SMP 又称为 UMA , 全称 " Uniform Memory Access " , 中文名称 " 统一内存访问架构 " 。
|
||||
在 " 对称多处理器结构 " 的 系统中 , 所有的处理器单元的地位都是平等的 , 一般指的是服务器设备上 , 运行的 多个 CPU , 没有 主次/从属 关系,都是平等的。
|
||||
这些处理器 共享 所有的设备资源 , 所有的资源对处理器单元具有相同的可访问性 , 如 : 磁盘 , 内存 , 总线等 ,多个CPU处理器共享相同的物理内存 , 每个 CPU 访问相同的物理地址 , 所消耗的时间是相同的 ;
|
||||
要注意,这里提到的“处理器单元”是指“logic CPU”,而不是“physical CPU”。举个例子,如果一个“physical CPU”包含2个core,并且一个core包含2个hardware thread。则一个“处理器单元”就是一个hardware thread。
|
||||
|
||||
# 内核针对多处理器 CPU 下的调度
|
||||
BIOS 调入执行启动引导区程序后,这段程序录入 Linux 操作系统的启动部分,解压缩 Linux 内核核心映像,然后转入 start_kernel 函数开始执行。在这以前,系统没有对 AP 做任何处理。在 start_kernel 函数中,主要处理例如 cache、内存等初始化工作,最后要调用 smp_init 函数,在这个函数里,具体实现 SMP 系统各 CPU 的初始处理机制, 我们来分析 smp_init 函数
|
||||
在 [linux/init/main.c] 中
|
||||
|
||||
~~~c
|
||||
static void __init smp_init(void)
|
||||
{
|
||||
smp_boot_cpus();
|
||||
smp_threads_ready=1;
|
||||
smp_commence();
|
||||
}
|
||||
~~~
|
||||
|
||||
在函数 smp_boot_cpus 中,要建立并初始化各 AP,关键代码如下:
|
||||
在 [linux/arch/i386/kernel/smpboot.c] 中
|
||||
~~~C
|
||||
void __init smp_boot_cpus(void)
|
||||
{
|
||||
……
|
||||
for (apicid = 0; apicid < NR_CPUS; apicid++) {
|
||||
if (apicid == boot_cpu_id)
|
||||
continue; // 是BP,因为上面已经初始化完毕,就不再需要初始化
|
||||
|
||||
if (!(phys_cpu_present_map & (1 << apicid)))
|
||||
continue; // 如果CPU不存在,不需要初始化
|
||||
|
||||
if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
|
||||
continue; //如果超过最大支持范围,不需要初始化
|
||||
|
||||
do_boot_cpu(apicid);// 对每个AP调用do_boot_cpu函数
|
||||
……
|
||||
}
|
||||
……
|
||||
}
|
||||
~~~
|
||||
|
||||
下面我们看一下do_boot_cpu中做了什么工作:
|
||||
在[linux/arch/i386/kernel/smpboot.c]中
|
||||
~~~c
|
||||
static void __init do_boot_cpu (int apicid)
|
||||
{
|
||||
struct task_struct *idle; // 空闲进程结构
|
||||
……
|
||||
if (fork_by_hand() < 0) //在每个cpu上建立0号进程,这些进程共享内存
|
||||
……
|
||||
idle->thread.eip = (unsigned long) start_secondary;
|
||||
// 将空闲进程结构的eip设置为 start_secondary 函数的入口处
|
||||
……
|
||||
start_eip = setup_trampoline(); // 得到trampoline.S代码的入口地址
|
||||
stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle);
|
||||
……
|
||||
*((volatile unsigned short *) phys_to_virt(0x469)) = start_eip >> 4;
|
||||
Dprintk("2.\n");
|
||||
*((volatile unsigned short *) phys_to_virt(0x467)) = start_eip & 0xf;
|
||||
Dprintk("3.\n");
|
||||
// 将trampoline.S的入口地址写入热启动的中断向量(warm reset vector)40:67
|
||||
……
|
||||
apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
|
||||
// 确定发送对象
|
||||
apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
|
||||
// 发送INIT IPI
|
||||
……
|
||||
apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
|
||||
//确定发送对象
|
||||
apic_write_around(APIC_ICR, APIC_DM_STARTUP | (start_eip >> 12));
|
||||
//发送STARTUP IPI
|
||||
……
|
||||
}
|
||||
~~~
|
||||
|
||||
现在对上面初始设置做如下概括 [1]:
|
||||
BSP 将 AP 在一开始被唤醒后需要执行的代码(trampoline.S)的首地址写入热启动向量(warm reset vector
|
||||
),即从40:67开始的两个字。这样,当 BSP 对 AP 发送 IPI 时,AP 响应中断,自动跳入这个 trampoline.S 代码
|
||||
部分继续执行。为了 AP 有足够的时间响应中断,BSP 在发送中断请求后要延迟一段时间,。
|
||||
在这以后,事实上 AP 已经在工作了,我们跟随 AP,看它在做什么。AP 响应中断直接跳转至 trampoline.S 的
|
||||
入口处,trampoline.S 在载入符号表 (gdt) 和局部符号表 (ldt) 之后进入保护模式并跳至 head.S 的入口处:
|
||||
在 [linux/arch/i386/kernel/trampoline.S] 中
|
||||
~~~C
|
||||
……
|
||||
inc %ax #protected mode (PE) bit
|
||||
lmsw %ax # 进入保护模式
|
||||
jmp flush_instr
|
||||
flush_instr:
|
||||
ljmpl $__KERNEL_CS, $0x00100000
|
||||
# 一个长跳转,0x10:0x00100000是内核被解压后的起始地址,即 head.S 的 startup_32[7]
|
||||
……
|
||||
~~~
|
||||
|
||||
AP 转入 head.S 继续执行,但是执行的代码与 BSP 所执行的并不完全一致:
|
||||
在 [linux/arch/i386/kernel/head.S] 中
|
||||
~~~C
|
||||
ENTRY(stext)
|
||||
ENTRY(_stext)
|
||||
startup_32:
|
||||
……
|
||||
incb ready # 该段代码每执行一次,ready 值加 1,BSP 执行时 ready 的值从 0 变为 1
|
||||
……
|
||||
movb ready, %cl
|
||||
cmpb $1,%cl
|
||||
je 1f # 当执行 CPU 为 BSP 时,ready 的值为 1
|
||||
call SYMBOL_NAME(initialize_secondary) # 执行 initialize_secondary 函数
|
||||
jmp L6
|
||||
1:
|
||||
call SYMBOL_NAME(start_kernel) # 执行 start_kernel() 函数
|
||||
L6:
|
||||
jmp L6
|
||||
ready: .byte 0 # ready 为字节变量,初始值为 0
|
||||
~~~
|
||||
|
||||
AP 执行 head.S 的过程是当执行到上述代码的时候,由于 ready 的值被改变,不再等于 1,所以就继续向前执行
|
||||
,调用 initialize_secondary 函数,而不是像 BSP 一样执行标号 1 处的代码(调用start_kernel函数)。
|
||||
initialize_secondary 函数里面的代码很简单:
|
||||
在 [linux/arch/i386/kernel/smpboot.c] 中
|
||||
~~~c
|
||||
void __init initialize_secondary(void)
|
||||
{
|
||||
asm volatile(
|
||||
"movl %0,%%esp\n\t"
|
||||
"jmp *%1"
|
||||
:
|
||||
:"r" (current->thread.esp),"r" (current->thread.eip));
|
||||
}
|
||||
~~~
|
||||
|
||||
这是一段内嵌汇编程序,将程序跳转至 current->thread.esp(即前面的idle->thread.esp)处 [8]。CPU执
|
||||
行 start_secondary 函数,进入空闲状态。
|
||||
在 [linux/arch/i386/kernel/smpboot.c] 中
|
||||
~~~c
|
||||
int __init start_secondary(void *unused)
|
||||
{
|
||||
cpu_init();
|
||||
smp_callin();
|
||||
while (!atomic_read(&smp_commenced))
|
||||
rep_nop();
|
||||
local_flush_tlb();
|
||||
return cpu_idle(); // 进入空闲进程
|
||||
}
|
||||
~~~
|
||||
|
||||
至此,一个 AP 的初始化过程就完成了。
|
||||
|
||||
总结
|
||||
下面简要的再把Linux的SMP启动过程做一总结。
|
||||
在 SMP 中,首先要对各个处理器进行初始化。然后 BSP 工作,而其它的 CPU(AP)则停留在一个初始化好的
|
||||
中断屏蔽状态休眠。BSP 继续进行启动过程,在执行到操作系统的 start_kernel 之前,BSP 所进行的工作与单
|
||||
处理器系统所做的工作是相同的。在 start_kernel 中,BSP 通过 smp_init 对每个 AP 进行初始化。初始化的
|
||||
方式是通过 APIC 发送 IPI。当 BSP 初始化完毕所有的 AP 之后,就继续执行 start_kernel 中的其余部分代码。
|
||||
而 AP 在接收到 IPI 之后,跳转到事先设置好的地址处执行 trampoline.S 和 head.S。在执行 head.S 的过程中
|
||||
直接跳入事先创建好的空闲进程,进入空闲状态,等待以后的系统调度。
|
||||
|
||||
内核调度
|
||||
在 [kernel/sched.c] 中, 内核为每一颗 CPU 分配了一个 runqueue ,我们的线程驱动就是每个 CPU 调用此队列的任务进行执行驱动
|
||||
|
||||
# 内核是怎么知道各个硬件的信息的?
|
||||
答案就是通过 SMBios 表,此表由 UEFI 或者 Legacy BIOS 提供的, 从 SMBIOS 的 spec 中可以看到,对于基于 Legacy BIOS 的系统而言,系统软件可以通过在物理内存范围 000F0000h ~ 000FFFFFh 内搜索制定的字符串来定位到 SMBIOS 表的入口点。对于SMBIOS 2.1 而言,这个字符串是 "_SM_",对于 SMBIOS 3.0 而言,这个字符串为 "_SM3_"。
|
||||
|
||||
而对于基于 UEFI 的系统而言,EFI configuration table (EFI_CONFIGURATION_TABLE) 包含了指向 SMBIOS table 的指针。
|
||||
|
||||
|
||||
每个硬件方法不同。比如说内存,内存条上有一个 smbus 总线的 eeprom,记录内存条的信息。usb 总线的总线协议就规定了设备类型,如存储设备,输入设备等。pcie 总线有 vendor id, device id. 板上一些无法通过枚举过程识别的,可能会硬编码在 BIOS 里,因为每个主板都要研发一次 BIOS。BIOS 和内核传递信息有多种标准。acpi, device tree 之类的。有些设备内核还会自己枚举,不用 BIOS 告诉他。
|
||||
|
||||
|
||||
# 内核线程的实现
|
||||
https://segmentfault.com/a/1190000040253849
|
||||
|
||||
# 锁的实现
|
||||
特别注意锁的悬停 ( mutex 的实现原理 )
|
||||
所有的锁的机制都是类似于“自旋锁”的机制,mutex 也不例外,当然会阻塞,是因为加锁失败,会把当前线程加入等待队列,把当前线程加入等待队列,等待下一轮的锁的抢占,抢占到锁,线程继续执行,否则还得继续等待,而对应的 CPU 线程,可没闲着继续驱动内核线程执行,对于用户层来说,仿佛多个线程在不停的执行。
|
||||
https://segmentfault.com/a/1190000040360086
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user