(备忘录) – 系统相关

使用 DISM 处理 Windows 安装镜像

Windows 使用了 Wim 来压缩安装镜像,这个镜像中包含了展开到目标系统盘中的镜像。所以可以通过 DISM 脱机处理安装镜像。以下是一些常用的命令。还可以添加预安装的应用(UWP)和开始屏幕指定等等,这些可以参看引用1

  • 展开镜像到目标目录 Dism /Mount-Image /ImageFile:wim文件 /index:目标的系统版本的索引 /MountDir:展开的目录
  • 添加驱动程序 Dism /Image:展开的目录 /Add-Driver /Driver:驱动的目录或者inf文件 /Recurse注意使用了 Recure 开关可以递归地将若干个驱动文件加入到展开的镜像中,但是这会增大 install.wim 的大小(包含不同的 inf 但是由共享相同的驱动文件)
  • 为镜像添加更新(仅 msu 和 cab 支持)Dism /Image:展开的目录 /Add-Package /PackagePath:MSU或者CAB的路径
  • 启用某种功能(以启用 .Net Framework 3.5 为例)Dism /Image:展开的目录 /Enable-Feature /FeatureName:NetFx3 /ALL /Source:指定的组件目录(可以是光盘的 sources\sxs)

进行完所有的操作后,可以进行提交(commit)或放弃(discard)。如果需要提价请确保展开源 wim 文件还存在。例如:Dism /Unmount-Wim /MountDir:展开的目录 /Commit 就会将修改后的镜像更新到源 wim 文件对应的镜像位置(相应的索引)。

Linux 编译 CSAPP 用的 Y86-64 模拟器(GUI)

由于官网提供的 Y86-64 模拟器只能使用 Tcl/tk 8.5, 而最新的 Fedora 27 自带的是 Tcl 8.6,所以需要手动编译 Tcl 和 Tk。

  1. 编译 Tcl/Tk 8.5 最后一个 8.5 版本的Tcl 8.5.19Tk 8.5.19。在使用 Makefile 编译之前需要安装 libX11-devel 和 libXpm-devel。然后 makemake install 进行编译、安装。默认的目录在 /usr/local 下,includelib 也在 /usr 对应的目录下。
  2. 编译模拟器,安装 flex、flex-devel、bison 和 bison-devel,将下载的模拟器文件 sim.tar 解压,打开其中的 Makefile,修改一下的参数,指定对应的 Tcl/Tk 路径。Compile parameters然后 make clean & make 编译。
  3. 检验 ,切换到 pipe 目录, 运行 ./psim -t -g ../y86-code/asum.yo。会出现如下的界面:GUI

可能的错误:

  • ./psim: error while loading shared libraries: libtk8.5.so: cannot open shared object file: No such file or directory 错误,那就是需要添加动态链接库的目录到 /etc/ld.so.conf 中,例如:Add library dir最后使用 ldconfig 生成缓存,检查是否有链接库的信息。Check library

扩充:Windows 环境下编译

现在对网上的各种博客无感,很多文章要么是 N年前的内容或者是谬误。所有选哟自己动手实践!

虚拟 LINUX 环境

我是用的是 MSYS2,这个环境使用的 pacman 管理包,可以支持多语言。可以支持 MINGW32 和 MINGW64。在 Windows 情况下,使用的 Win32 的某些库文件所以生成的程序是 exe。另外,包管理可以避免去编译某些程序的依赖库(Y86 模拟器需要 flex 和 bison,而 GNU 只提供 Win32 版本,而编译器是64位的环境)。注意路径不要有空格

安装就不介绍了。需要设置下安装源:

  • /etc/pacman.d/mirrorlist.mingw32 : 开头添加 Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686
  • /etc/pacman.d/mirrorlist.mingw64 : 开头添加 Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64
  • /etc/pacman.d/mirrorlist.msys : 开头添加 Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/msys/$arch
  • 使用命令 pacman -Sypacman -Syu 刷新源和更新程序

接下来安装编译链工具、依赖库:pacman -S mingw-w64-x86_64-toolchain libraries development compression VCS sys-utils net-utils msys2-devel base-devel base。可能会提示替换警告,可以继续。这样安装后,vim 可能无法使用了,先卸载(-R) git (vim 的依赖项),再重新安装。

修改文件

打开下载好的源码,找到 Makefile 文件,修改一下的内容。(网上传说不能用 tk8.6 及以上。其实 tk8.6 是可以的)

修改makefile 的内容

然后使用 make 命令编译程序。有几个注意:

  • C:/Programs/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lfl : 修改 misc 下的 Makefile,指定 flex 库的路径:
  • C:\Programs\msys64\tmp\ccv14H5r.o:ssim.c:(.data+0x0): undefined reference to matherr : 找到提示的文件(这里是 ssim.c ),找到 matherr 的声明(一般是一个函数的声明),改为 _matherr。

然后运行(一定要在终端)之前提到的测试例子:

参考

  1. (Baidu)MSYS2 配置
  2. (Cnblogs)windows搭建gcc开发环境(msys2)
  3. (Douban)pacman 常用命令

编译 ffmpeg 以及解码器

编译各种解码器

  1. yasm 汇编工具 使用 yum install yasm-devel yasm 直接安装对应版本系统的二进制文件
  2. x264 这个是提供 H264 编码的库,下载源码。然后使用./configure --prefix=/usr/local/ffmpeg --enable-shared --enable-static --enable-yasm。在这里为了省事,直接把编译好的动态链接可以放入待会会安装的 ffmpeg 的目录中。注意一定要使用开启--enanble-shared 这个选项否则就会在 ffmpeg 编译的过程中发生链接错误(can not be used when making a shared object; recompile with -fPIC)!
  3. x265 下载1.9版本的 h265 源码 注意 x265 使用的 cmake 所以需要安装好 cmake。进入目录 build/linux 运行 PATH="/usr/local/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="/usr/local/ffmpeg" -DENABLE_SHARED:bool=off ../../source 就可以编译好动态链接库版本的 x265 编码器。
  4. libvpx 这个提供 WebM 的编码器,下载源码 然后进入目录,PATH="/usr/local/bin:$PATH" ./configure --prefix="/usr/local/ffmpeg" --disable-examples --disable-unit-tests 进行编译和安装。
  5. fdk-acc ACC 编码,下载源码, 不要使用 0.1.4 的版本。首先安装 automake, automake-devel 和 libtool。然后运行 autoreconf -fiv;./configure --prefix="/usr/local/ffmpeg" --enable-shared
  6. 这些编码仅仅是用来处理视频的,声音还要另外安装。这里就不多说了。现在编译 ffmpeg。。configure 使用如下的一些参数:--enable-gpl:使用 GPL 协议;--pkg-config-flags: pkgconfig(Makefile 的一个帮助工具,用于保存第三方引用链接的信息);--enable-xxx:编译 xxx 编码器。总的来说就是./configure --prefix=/usr/local/ffmpeg --pkg-config-flags="--static" --enable-shared --enable-yasm --enable-libx264 --enable-gpl --enable-pthreads --bindir="/usr/local/bin" --enable-libfdk-aac --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree。为了编译为动态链接库的版本,还需要使用 make CFLAGS='-fPIC'。最后安装即可,生成的可执行文件在/usr/bin 下(--bindir 指定)。

注意事项

  • 编译 ffmpeg 的时候找不到 x265 的 pkgconfig ,则需要因把 /usr/local/ffmpeg/lib/pkgconfig 添加到变量 PKG_CONFIG_PATH 中,例如:/usr/local/x264/lib/pkgconfig:/usr/local/ffmpeg/lib/pkgconfig:/usr/lib64/pkgconfig,然后 export 到 shell 中。
  • 找不到链接库,同上一篇文章,把 /usr/local/ffmpeg/lib 添加到 ld.so.conf 中,然后 sudo ldconfig。
  • 编译的时候找不到头文件:(有 x264 是因为之前 x264 并没有编译到 ffmpeg 中)
C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/ffmpeg/include:/usr/local/x264/include
CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/ffmpeg/include:/usr/local/x264/include
export C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/x264/lib:/usr/local/ffmpeg/lib
export LD_LIBRARY_PATH

题外话:虚拟机中的 ffmpeg 输出流到实体机

在 Linux 下可以借助 ffserver 响应用户的请求。

ffserver 原理

为了能够使主机与虚拟机相互 ping 通,可以使用虚拟机的桥接模式将虚拟机和主机放置在一个子网之中。

将虚拟机与主机放置在一个子网中:

  1. 添加一个环回网卡。在计算机管理MMC中,点击操作然后添加红框中的网络适配器设备添加网卡
  2. 管理员打开 VMware 的虚拟网络编辑器(这是一个例子),找到 VMnet 0,在桥接模式的下拉列表中选择刚刚那个网卡并确定。
  3. 打开那个网卡的 IPv4 的设置,输入一个指定的主机 IP地址、网关和子网掩码:Windows IP 设置
  4. 这样主机的 IP 地址为 192.168.100.101,网关是 192.168.100.100(用来指定将数据发送到那个网卡上)。同样需要设置虚拟机的 IP 地址,保持子网掩码和网关与主机一直,IP 地址只要在 192.168.100. 子网内就可以了:Linux 虚拟机 IP 设置
  5. 主机和虚拟机的 IP 分别为 192.168.100.101 和 192.168.100.102。但是如果需要访问各自的服务,一个不好的方法是关闭二者都有的防火墙。Fedora:
systemctl stop firewalld.service
systemctl disable firewalld.service

这样就可以 ping 通:ping 通

搭建 ffserver

ffserver 广播

ffserver 默认的配置文件在 /etc/ffserver.conf,通过开关 -f 也可以指定其他的。ffserver 需要:

  • 绑定一个监听的端口这样可以监听远程的访问
  • 添加一个输出配置,用于指定广播流的格式
  • 指定本地由 ffmepg 传送到的 ffm 的定义以及关联的(feed)输出配置/etc/ffserver.conf:
HTTPPort 8090                      # Port to bind the server to
HTTPBindAddress 0.0.0.0
MaxHTTPConnections 2000
MaxClients 1000
MaxBandwidth 10000             # Maximum bandwidth per client
                               # set this high enough to exceed stream bitrate
CustomLog -
NoDaemon                       # Remove this if you want FFserver to daemonize after start
<Feed feed1.ffm>               # This is the input feed where FFmpeg will send
   File /tmp/feed1.ffm            # video stream.
   FileMaxSize 64M              # Maximum file size for buffering video
   ACL allow 127.0.0.1         # Allowed IPs
</Feed>
<Stream test.webm>              # Output stream URL definition
   Feed feed1.ffm              # Feed from which to receive video
   Format webm
   # Audio settings
   #AudioCodec vorbis
   #AudioBitRate 64             # Audio bitrate
   # Video settings
   VideoCodec libvpx
   VideoSize 320x240           # Video resolution
   VideoFrameRate 30           # Video FPS
   AVOptionVideo flags +global_header  # Parameters passed to encoder
                                       # (same as ffmpeg command-line parameters)
   AVOptionVideo cpu-used 0
   AVOptionVideo qmin 10
   AVOptionVideo qmax 42
   AVOptionVideo quality good
   NoAudio
   #PreRoll 15
   #StartSendOnKey
   VideoBitRate 128          # Video bitrate
</Stream>
<Stream status.html>            # Server status URL
   Format status
   # Only allow local people to get the status
   ACL allow localhost
   ACL allow 192.168.0.0 192.168.255.255
</Stream>
<Redirect index.html>    # Just an URL redirect for index
   # Redirect index.html to the appropriate site
   URL http://www.ffmpeg.org/
</Redirect>

由于不需要传输声音所以我没有指定声音的编码。定义了一下的信息

  • 客户通过:http://ip:8090/status.html 可以获得当前 ffserver 的运行信息ffserver 信息
  • 输入源输出到本地的广播源:http://127.0.0.1/feed1.ffm
  • 客户可以通过:http://ip:8090/test.webm 访问这个流。

ffmpeg 命令行输出到广播源

  • 输出一段视频:ffmpeg -i ~/ai.mp4 -r 30 http://127.0.0.1:8090/feed1.ffm
  • 输出摄像头(虚拟机不能使用):ffmpeg -f video4linux2 -s 320x240 -r 30 -i /dev/video0 http://127.0.0.1:8090/feed1.ffm输出的视频

使用 ffmpeg 对流进行处理

  • 保存为本地的视频文件:ffmpeg -i http://192.168.100.102:8090/test.webm save.mp4

内网穿透

因为最近在学校的服务器上开启了一个虚拟机,但是虚拟机的网络是处于在学校的内网之中。而寝室的宽带网络独立于学校的内网,所以需要使用内网穿透绕过路由将某些端口暴露到外网中。

服务端配置

  • 一个已经备案的域名:
  • 服务端运行 sudo apt-get install build-essential golang mercurial git,应为 ngrok 是基于 Go 语言开发,可以直接生成机器码也可以跨平台地编译不同系统的版本。
  • 用于 ngrok 在编译的时候需要很多其他的源,所以需要下载其他人修改后的版本 git clone https://github.com/tutumcloud/ngrok.git ngrok,然后进入目录 ngrok。导出指定的域名:export NGROK_DOMAIN="ddayzzz.wang"
  • 由于我们的域名已经备案了,所以在编译的时候只需要指定证书和密钥就可以(我的域名是 Let's Encrypt,所以证书的、密钥目录在 /etc/letsencrypt/live/ddayzzz.wang):certs
cp /etc/letsencrypt/live/ddayzzz.wang/cert.pem assets/client/tls/ngrokroot.crt # 复制服务器证书,用于编译
cp /etc/letsencrypt/live/ddayzzz.wang/cert.pem cert.crt # 复制服务器证书,这个用于运行
cp /etc/letsencrypt/live/ddayzzz.wang/privkey1.pem privkey.pem  # 复制私钥证书
  • 指定了证书之后,以后 ngrok 都会按照证书进行数据的加密。使用 sudo make release-server release-client 编译 Linux 服务端和客户端。
  • 编译后会在 bin 目录下生成服务端 ngrokd 和客户端 ngrok。运行服务端:./bin/ngrokd -tlsKey="privkey.pem" -tlsCrt="cert.pem" -domain="$NGROK_DOMAIN" -httpAddr=":8000" -httpsAddr=":8001" -tunnelAddr=":4443"
参数 含义
tlsCrt 服务器证书
tlsKey 私钥证书
httpAddr http转发的端口号
httpsAddr https 转发的端口号
tunnelAddr ngrok 客户端连接的管理用途的端口
  • 注意,有些虚拟主机提供商会限制端口入方向,所以需要关闭端口的限制。

如果没有问题了,可以输入一些测试 https://ddayzzz.wang:8001,如果出现:测试服务就正常。

客户端配置

注意,由于ngrok 2.x 是闭源的所以,不要使用最新的而是使用 1.7 的版本。创建配置文件(ngrok 使用 yaml 配置文件格式,需要使用空格而不是制表来控制缩进):

server_addr: "ddayzzz.wang:4443"
trust_host_root_certs: true
tunnels:
  rmdp:
    remote_port: 8003
    proto:
      tcp: "3389"

这里转发了远程桌面服务,也就是我通过外网的域名的端口 8003 就可以访问内网的客户端上的 3389 端口了。注意要指定 trust_host_root_certs 让 ngrok 客户端信任其他认证机构签发的证书。否则服务端会提示 bad:certification,客户端一直 reconnecting。

运行截图:

ngrk running in client

ngrok Windows 版本客户端下载

服务端持久运行

  • 在后台一直运行:
apt install screen
screen keepngrok # 随便一个名字
# 运行了一个子 shell 环境
# 输入并运行之前的服务器启动命令 ...
# Ctrl+A+D 可以放到后台运行。
# 直接退出 shell

问题

  • 只能转发一个端口,如果需要做多端口转发就可以使用 VPN 转发。
  • FTP 服务即使转发了21端口也不能访问内网的 ftp 服务。

参考

  1. (CSDN) ngrok 后台运行的方法
  2. (imququ.com)搭建 ngrok 服务实现内网穿透
  3. (Github)self-hosted ngrokd - client fails with 'Certificate signed by unknown authority' on Mac OS X
  4. (ubock.com)CentOS 7 搭建ngrok服务器

引用&参考

  1. DISM 的使用
  2. (CSDN)CSAPP Y86 环境部署
  3. (Cnblogs) Linux找不到动态链接库
  4. (ffserver wiki)ffserver 文档
  5. (Cnblogs)Linux 下 WebM 直播搭建
  6. (CSDN)ffmpeg+ffserver搭建流媒体服务器
  7. (Linuxidc) Fedora 18/19 以上关闭防火墙
  8. (baidu) 构建虚拟机PC连接
  9. (CSDN) linux 下编译 x256
  10. (Cnblogs) linux 下 找不到 pkgconfig 路径 
  11. (Cnblogs) linux下编译支持librtmp、libx264、libfaac的ffmpeg
  12. (Cnblogs)Linux---centos编译安装ffmpeg
  13. (Cnblogs) Compile with fpic
  14. (CSDN) PKG_CONFIG_PATH 路径设置
  15. (内存溢出)CentOS编译安装ffmpeg以及相关编码解码器
  16. (Chinaunix)Linux添加头文件路径—INCLUDE_PATH

3条评论

  • 2019年1月21日

    学学方兄搞个打赏按钮吧,我想打赏但是找不到二维🐎

    • shu

      2019年1月21日

      你啊 naive, 个人网站一律不得经商!

  • shu

    2019年8月21日

    吼啊! 😯