Light Display Manager 是一个轻量级的跨桌面环境的 Display Manager, 可以支持多种显示技术,如 X11, Mir, Wayland.

Build

Dependencies

  • 开发包依赖

    • libpam0g-dev
    • libgcrypt20-dev
    • libglib2.0-dev
    • libxklavier-dev
  • 构建工具依赖

    • intltool
    • yelp-tools
    • gtk-doc-tools
  • 安装

Lightdm 可执行程序路径 /usr/sbin/lightdm, 日志默认路径 /var/log/lightdm/lightdm.log. 所以构建时可以使用

  • --prefix 指定安装路径 (默认 /usr/local)
  • --localstatedir 指定日志路径 (默认 $prefix/var/log/lightdm)
  • --sysconfdir 指定 lightdm.conf 路径 (默认 $prefix/etc/lightdm)
1
2
3
./autogen.sh --prefix=/usr --localstatedir=/var --sysconfdir=/etc --disable-tests
make -j $JOBS
sudo make install

Graphics Boot-up

flowchart TD
    A["systemd"]
    B["/usr/sbin/lightdm"]
    C["`[Seat:*]
        # Dump core
        xserver-command=X -core`"]
    D["`X
        Symbolic link to Xorg`"]

    A -- lightdm.service --> B -- /usr/share/lightdm/lightdm.conf.d/50-xserver-command.conf --> C --> D

P.S. lightdm --show-config 可以显示与 lightdm 相关的配置

《程序员的自我修养–链接,装载与库》这本书是在读研时才看的,印象很深,现在想想这本书讲的都是程序员,尤其是从事系统编程的必备素养。这里我将平时使用的跟编译,链接和构建应用程序及库相关的知识记录下来,希望以后能温故知新。

Read more »

Glossary

  • PoC: Proof of Concept, 概念验证
  • Chisel: tExtended on Scala
  • GDSII: 版图
  • RTL: Register-Transfer Level, RTL 语言包括 SystemVerilog, Verilog, VHDL等
  • FIRRTL: Chisel 的“翻译器”, Chisel -> Verilog
  • shift left: 把验证和调试放在 tape in 阶段
  • GEM5: C Simulator for GPU
  • PPA: Power, Performance, Area, used in deciding how to optimize semiconductor designs
Read more »

LLVM & llvm-project

LLVM 是 Low-Level Virtual Machine 的简写,但事实上它与虚拟机关系不大。我们更熟悉它是一套工具链,包括 clang /'klæŋ/, lld, lldb 等等。接触 LLVM 是因为 Mesa llvmpipe 使用 LLVM, 还有 AMDGPU 和 Radeon 的编译器后端都使用 LLVM IR,所以要编译 Mesa 的 -Dgallium-drivers=llvmpipe,radeonsi 都依赖于 LLVM 的诸多组件, 构建 Linux 内核的 eBPF 程序也依赖 LLVM, 构建 perfetto 也依赖 LLVM。这里主要记录 LLVM 的构建和使用的一些问题。

Read more »

Regular Expressions

GNU Extensions

Shorthand Classes

shorthand equivalence
\w [[:alnum:]_]
\W [^[:alnum:]_]
\s [[:space:]]
\S [^[:space:]]

Word Boundaries

shorthand matches
\b position at a word boundary
\B position not at a word boundary
\< position at the start of a word
\> position at the end of a word
\` (backtick) position at the start of subject string
\' (single quote) position at the end of subject string

Perl Compatiable Regular Expression (PCRE)

grep multiline mode

  • -P: 使用 Perl 正则表达式扩展
  • -z: 让 grep 把输入的行看成是一个多个行的集合,一个整体
  • .*?: 后面的 ? 表示 .*non-greedy 模式匹配,也就是尽可能少(短)的匹配
  • (?s): 让 . 匹配包括 \n 在内的任意字符,也就是所谓的 dot all flag.

rg multiline mode

  • -U, --multiline 使能多行匹配,允许正则表达式里包含 \n (普通模式下不允许),但 -U 并不会改变 . 的语义,所以你仍然需要显式地给 . 指定 (?s) flag

    • rg -U 'struct file_operations .*? = ?\{(?s).*?\.mmap = (?s).*?\};' -tc drivers/gpu
      这个例子找出内核 GPU 驱动中所有重写了 mmap file operation 方法的c文件

Lookarounds: Lookahead, Lookbehind

语法 名称 含义
(?=foo) 正向先行断言 Positive Lookahead 向前(右) 字符串里必须有 foo
(?!foo) 负向先行断言 Negative Lookahead 向前(右) 字符串里不能有 foo
(?<=foo) 正向后行断言 Positive Lookbehind 向后(左) 字符串里必须有 foo
(?<!foo) 负向后行断言 Negative Lookbehind 向后(左) 字符串里不能有 foo
  • 它们只是检查是否匹配,不作为最终匹配结果的一部分,即所谓"断言"
  • 它们可以解决 Non greedy 匹配有时解决不了的问题
  • rg (ripgrep) 默认不支持 lookahead, lookbehind, 需要加 -P--pcre2 选项

基础知识 - 变量和函数

Linux 下的 Shell 有很多, sh, bash, csh, zsh 等, 这里主要记录一下 bash 和 zsh 的一些不同之处

Parameter Expansion

Use an alternate value

1
2
${var:+WORD}
${var+WORD}

如果 var 没有设置或为空,则这个变量展开为 Nothing (注意:不是空 empty, 是 nothing), 如果被设置了(不包括被设置成空),它展开为 + 后面的 WORD.

如果冒号被省略,则 var 即使被设置为空,它也展开为 + 后面的 WORD

Indirect

1
${!var}

如果 var 的值是 MESA_DEBUG, 那么这个形式展开后是变量 MESA_DEBUG 的值,例如 export MESA_DEBUG=1, var=MESA_DEBUG, 则最后的展开结果是 1

Quoted

1
${var@Q}

@Q 指变量展开后的值被单引号引起来,例如 export ABC=abc, echo "ABC=${ABC@Q}" 的结果是 ABC='abc'

反斜杠 backslash \

\ 在 shell 中是用来转义字符的,就是说 echo "\\\\" 显示的实际只有一个 \, 而且 while read var 时要注意加 -r 选项,读入原始字串

经典命令

exec

exec 命令有 2 个特点:

  • 直接覆盖当前进程,就是说进程 PID 不变,但执行的代码被更换了
  • 原来的 shell 环境被销毁,这样当前的代码结束后,也就不会返回原 shell(没得返回), 直接退出, 所以循环中慎用 exec
  • 可以把它想像成系统调用 execve()

下面是 linux kernel 安装 bzImage 的一段代码,其中就使用了 exec, 保证列出的 4 个安装脚本中,只执行第 1 个存在的,不会重复安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# User/arch may have a custom install script
for file in "${HOME}/bin/${INSTALLKERNEL}" \
"/sbin/${INSTALLKERNEL}" \
"${srctree}/arch/${SRCARCH}/install.sh" \
"${srctree}/arch/${SRCARCH}/boot/install.sh"
do
if [ ! -x "${file}" ]; then
continue
fi

# installkernel(8) says the parameters are like follows:
#
# installkernel version zImage System.map [directory]
exec "${file}" "${KERNELRELEASE}" "${KBUILD_IMAGE}" System.map "${INSTALL_PATH}"
done

timeout

timeout 命令用来给一个 COMMAND 设定一个 DURATION, 这在自动化中很有用,比如

1
for i in `fd --type x`; do timeout -k 0.1 10 ./$i; done

假如当前在 VulkanExamples 的 bin 目录下,上面的命令表示让每个 demo 执行 10s 后结束(timeout 给它发 TERM 信号), 如果发了 TERM 信号后,又经过 0.1s (-k 0.1),这个 demo 还未能退出,就再发 KILL 信号,强制结束它

tree

tree 像一个简单的文件浏览器,但它并不是 shell 内置的命令,apt install treepacman -S tree 都可以安装。有时一个目录中包含太多的文件,tree 的默认输出就不太好浏览,这时可以只打印目录,并限制搜索深度

1
tree -L 2 -d

crontab

crontab -e (添加定时任务), 不光可以添加周期性的定时任务,也可以添加开机时一次性任务

1
@reboot /home/luc/mystart.sh

crontab 是每用户的, 就是说当前用户设定的任务,只有当前用户的权限,所以如果有些情况下任务执行需要 root 权限,就需要切换到 root 用户后 crontab -e

文本处理 - awk, sed, grep(rg) 三剑客

Linux 下的文本处理三剑客: grep, sed, awk, 除了它们其实还有一些小巧的命令,如 tr, cut 也可以帮助我们快速处理和格式化文本。
下面以一个例子为例。

awk

1
awk 'program' inputfile1 inputfile2 ...

awk 的调用形式就是上面这样的,而其中的 program 由若干条 rules 组成,而一条 rule 由一个 pattern 和一个 action 组成

1
2
3
pattern { action }
pattern { action }
...

sed

sed 和 awk 一样,都是按行处理文本的。

  • sed -n '2 {s/^/#/; p; q}' file
    • sed 默认会将每一行都打印出来, -n 取消这一行为
    • sed 可以在操作的前面指定位置和范围, 如
      • 行号
      • 正则表达式 /^foo/
      • 两个正则表达式锁定范围 /^foo/, /bar$/
    • 如果 -n 后,完全都不打印了,但如果又想将处理后的行打印出来,使用 p 命令
    • q 命令的作用是立即退出,sed 的默认行为是对第2行处理完后,虽然后面的行都不需要处理,但 sed 仍然会继续将后面的每行往模式空间加载。

grep(rg)

在 Linux 内核源码目录下,搜索 drivers/gpu/drm 下所有的 DRIVER_NAME 定义,并排序后格式化输出

命令如下:

1
2
3
4
rg '#define DRIVER_NAME' drivers/gpu/drm --no-heading \
| tr -s '\t' | tr '\t' ' ' | tr -s ' ' \
| awk -F':' '{printf("%-52s%-40s\n",$1,$2)}' \
| sort -k4
  • rg (ripgrep) 比 grep 更快,更强大
  • tr 在不带任何选项时,默认执行替换,例子是中将 tab 替换成 空格, -s 表示 squeeze-repeats, 就是去掉重复的字符,例如多个空格只保留一个
  • awk 天生支持 C-Style printf

引号

当混合使用 awk 和 sed 时,比较便利地处理引号的方法是定义 awk 变量 -v Q="'"

  • awk 的 printf() 函数第一个参数必须使用双引号 printf("%s: %s%d%s\n", $1, Q, $2, Q)
    • awk 中的用户自定义变量和内置变量,使用时都不需要加 $, 如 NR, NF
  • awk 和 sed 的命令字串必须用引号括起来,当用 awk 生成 sed 命令时,将单引号定义为 awk 变量尤其方便,可读性也强

行范围 (Line range)

sed, awk 都支持行范围,如 sed -n '3,5p', awk 'NR >= 3 && NR <= 5',它们的效果是一样的,都是只打印给定文件的 3 到 5 行, 除了行号, sed, awk 还支持通过正则匹配来指定行位置

1
sed -n '/foo/,$p'
  • $ 表示最后一行
  • p 是 sed print 命令的缩写
1
awk '/foo/ {f=1} f'
  • awk 实现行范围的方式与 sed 稍有不同,它在满足匹配 foo 这个条件时,将布尔变量 f 设置为 1,相当于从这一行开始,开启 print 打印这个默认操作
  • awk 的一条 rule 里,可以省略 pattern, 或者省略 action, 但不能同时两个都省略;如果省略 pattern, 则对每个输入行都执行 action, 如果省略 action, 则对每个匹配行执行 print action。这个例子里面, awk 的 program 包括两条 rules
    • /foo/ {f=1} 这条 rule 什么都没有省略
    • f 这条 rule 省略了 action, 所以对每个输入行执行 print action

它们两个的效果也是一样的,都是从第一个匹配 foo 的行开始,一直打印到文件结束。

正则匹配 (Regex match)

awk 中一个 rule 中的 pattern 部分可以只是一条 / 括起来的正则表达式,默认这个正则表达式的匹配对象是 $0, 也就是整行, 如

1
awk '/foo/'

它实际上是

1
awk '$0~/foo/ {print $0}'

它意思是只要当前行里包含 foo 这个字串,就打印这一行。所以 awk 的正则 pattern, 准确来说是用来搜索

默认情况下是 $0~/foo/, 那么不默认情况下,可以指定哪个 field 去“匹配”, 如

1
awk '$1~/foo/ && $3!~/bar/ {print}'

它意思是当前这条记录,如果第1个字段包含 foo 第3个字段不包含 bar, 那么就打印整条记录

0%