U盘Linux系统在任何PC上启动

将系统安装在U盘中随身携带使用已经很容易了,比如 Windows 就有 Windows To Go。将系统装在U盘上需要一个寿命长久的U盘,而且随机读写性能要强。

Linux 发行版都提供 Live ISO 镜像,也可以将系统直接装载 U盘上,但很多时候安装后的U盘可以在安装的 PC 上启动,换一个 PC 就无法启动了。这篇文章就讲述如何解决其他 PC 上启动的问题。

这里只考虑 UEFI 模式的启动,毕竟都2020年了。

安装后无法在其他 PC 上正常启动的原因,是 UEFI 启动的文件一般都会安装在 PC 的内部硬盘上,而不是目标U盘上。

解决方法:

  1. 安装前,在U盘上新建一个大于300MB的FAT32格式的 ESP 分区。
  2. 启动 Linux 发行版,安装系统到 U盘上。推荐根 / 和 主目录 /home 分别挂载在不同的U盘分区。
  3. 安装后进入PC主系统,如果是windows,推荐使用 DiskGenus 打开PC硬盘的 ESP 分区,拷贝 EFI\xxx\ 目录(xxx 一般为发行版名称,Debian 为 debian,Ubuntu 为 ubuntu),复制到 U盘的 ESP 分区 EFI 目录下(没有则新建),并重命名 xxx 为 boot。主系统非 Linux 可以使用 PE 启动盘操作。
  4. 重命名 U盘 ESP 分区下 EFI\boot 目录的 grubx64.efi 文件为 bootx64.efi 。

完成以上步骤后,将U盘插在其他PC上,在 UEFI 模式下,手动选择启动盘为U盘,则可以顺利进入U盘Linux系统。

如果想在U盘上安装多个系统,可以考虑使用 refind 来代替 grub 进行启动管理,即将 refind 拷贝到U盘 ESP 分区下 EFI\boot 目录下,并重命名 refind_x64.efi 文件为 bootx64.efi。refind 会在启动时搜索所有可启动的 EFI 系统,提供用户选择。

(完)

一个基于 libev 的 ntripcaster 简单实现

Ntripcaster 是测绘领域GNSS相关的服务器软件,服务于差分GNSS测量、RTK测量等高精度测量测绘。

这里开源一个基于 libev,用 C 实现的简单 ntripcaster 服务器。

Ntripcaster 是基于 Ntrip协议 的 broker 程序,给 Ntrip Client 传输所请求的 GNSS 差分数据,接受来自 Ntrip Server 产生的差分数据来源。网络图例如下:

1
2
3
4
|--------|          |--------|         |--------|
| Ntrip  | <------> | Ntrip  | <------ | Ntrip  |
| Client |          | Caster |         | Source |
|--------|          |--------|         |--------|

libev 是一个 C 实现的跨平台事件库,支持 IO、定时器、文件状态监控等等,特别适合用来写网络服务程序,其接口也简洁好用。

简单实现的 Ntripcaster 源码: https://github.com/lazytinker/ntripcaster

预编译的二进制可执行文件(linux/windows):https://github.com/lazytinker/ntripcaster_bin

目前支持的功能:

  1. 支持 Ntrip 1.0 协议,支持动态源列表(source tables)。
  2. 支持 linux 和 windows(MinGW 编译)。
  3. 支持用户名密码验证,支持多用户、多源单独密码管控。
  4. 至此后同用户客户端多连接。

目前不支持的功能:

  1. VRS虚拟站。
  2. 根据客户端GGA提供最近站差分数据。
  3. 动态用户名密码增减支持。

除了 VRS,其他功能添加也比较简单,只不过暂时没有什么动力去完善,编写这个程序主要还是为了 libev 的练手。有什么问题,可以与我联系。

(完)

交叉编译 LCM 库

LCM (Lightweight Communications and Marshalling)是一个 基于 UDP 网络的消息传递库,适合高带宽和低延迟的通信需求,模式为发布/订阅。

本文讲述如何交叉编译 LCM 库到 arm linux上。

LCM 依赖 glib 2.0 库,glib 又依赖 zlib/libffi,所以需要依次编译依赖的库。如果目标平台 rootfs 中已有这些库,那么则可以直接最终的 LCM。

需要的源码包

根据目标 arm 平台不同,需要修改后面脚本命令中的 HOST 变量定义,用来指定交叉编译器:

  • armel: arm-linux-gnueabi
  • armhf: arm-linux-gnueabihf
  • aarch64(arm64): aarch64-linux-gnu

交叉编译器编译器可以通过 apt-get install crossbuild-essential-??? 来安装,具体后缀与目标 arm 平台一致。

0. 环境变量配置

以下为编译环境配置,需要在终端中执行,并且之后的编译命令也需要在该终端中执行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
export HOST=arm-linux-gnueabihf      # 不同平台需要修改变量
export ROOTFS="~/dev_rootfs/${HOST}" # 指定编译文件存放根目录
export CFLAGS="-L${ROOTFS}/usr/local/lib -I${ROOTFS}/usr/local/include"
export CC=${HOST}-gcc
export AR=${HOST}-ar
export NM=${HOST}-nm
export LD=${HOST}-ld
export STRIP=${HOST}-strip
export RANLIB=${HOST}-ranlib
export PREFIX=${ROOTFS}/usr/local

1. 编译 zlib/libffi

以下为编译 zlib 和 libffi 的命令,使用配置过环境变量的终端进入源码目录执行。

1
2
3
4
5
6
7
# 注意:
# 编译 zlib  不需要 --host 参数
# 编译 libffi 需要 --host 参数
./configure --prefix=${PREFIX} --host=${HOST}

make 
make install 

这里需要注意 libffi 的头文件会安装到 ${ROOTFS}/usr/local/lib 目录中,需要手动移动到 ${ROOTFS}/usr/local/include 目录里,否则编译 glib 时会提示找不到头文件。

2. 编译 glib

编译 glib 2.0,如果本机架构不是 x86_64,则需要修改 --build 参数项。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
MN=nm ./configure --prefix=${PREFIX} \
   --build=x86_64-linux \
   --host=${HOST} \
   glib_cv_stack_grows=no \
   glib_cv_uscore=no \
   ac_cv_func_posix_getpwuid_r=yes \
   ac_cv_func_posix_getgrgid_r=yes \
   ac_cv_lib_rt_clock_gettime=no \
   glib_cv_monotonic_clock=yes \
   --enable-libmount=no \
   --with-pcre=internal

make 
make install

3. 编译 LCM

编译 LCM,需要使用 cmake 工具。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
cmake .. -DCMAKE_CROSSCOMPILING=true \
         -DCMAKE_C_COMPILER=${HOST}-gcc \
         -DCMAKE_CXX_COMPILER=${HOST}-g++ \
         -DCMAKE_FIND_ROOT_PATH=${ROOTFS}/usr/local/ \
         -DCMAKE_INSTALL_PREFIX:PATH=${ROOTFS}/usr/local/ \
         -DLCM_ENABLE_TESTS=OFF \
         -DCMAKE_BUILD_TYPE=Release

make
make install

备注:编译 LCM 也可以使用 cmake toolchain 文件,这样更简洁方便。

编译完成后将头文件/库文件保存到交叉编译rootfs中,即可用来交叉编译应用程序,将动态库文件复制到目标 arm 板子上的 /usr/lib 或 /usr/local/lib 中(需要使用 ldconfig 命令刷新动态库缓存),即可用来运行程序。