默认的启动方式, unraid启动ssh后无法开启X11的转发,即使配置对也无无法开启。因为X11压根就没有启动。 启动的时候,必须选择gui方式启动后,然后sshd_config中打开x11转发才能使用。
标签: emacs
win10 精简版安装windows defender
我之前将我的电脑使用精简版的win10安装了,一直以为自带杀毒软件了。不经意间,发现没有安全中心,打开 安全中心后,发现竟然没有杀毒软件,这就玩大发了。于是,想尽办法把自带的杀毒软件找回来了。
-
管理员权限打开powershell, 使用以下命令修复
sfc /SCANNOW Dism /Online /Cleanup-Image /ScanHealth Dism /Online /Cleanup-Image /CheckHealth DISM /Online /Cleanup-image /RestoreHealth
然后,重启, 更新。如果简化版不是做的太好的话,安全中心和杀毒软件应该就回来了。启动即可。 但我用的版本做的太好了。在系统盘的目录中可以看到已经有软件了,但就是启动不了。
-
如果启动不了,那就改注册表, 改策略
修改注册表位置:
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender
这里面有个DisableAntiSpyware的项, 修改为1。然后重启 然后安全中心中的defender就可以正常启动了。 如果安全中心的病毒检测部分的实时监控打不开,则需要修改策略:Win+r 然后输入gpedit.msc, 修改为以下内容
- 为什么不用第三方软件 在我这边第三方软件影响运行速度。。。占资源,我的win10运行在虚拟机中,只分配了4G的内存资源
杂事二三件
昨天做了几件事,主要是前天晚上的一些思路,成了几件,败了几件。
-
obs推流到抖音
无奈我的号是无粉丝的,然后使用tcpdump在网关抓包,抓推流地址,obs通过docker部署,最后推流成功。 但抖音这边会在软件里不断的检测心跳,于是主播暂时离开了。我主要是想试试在unraid中是否可以,算是成了, 无奈硬件不给力,推流的帧率只有几,作罢。其他软件只能在windows上,无法无人职守,不喜欢。
-
seaf客户端docker化
没啥特殊的,开干,基于ubuntu,一切顺利
-
org文件导出时自动替换某些内容为制定的字符
自己✍🏻️的内容还要对自己各种过滤,实在是对自己太残忍了。使用了个宏来帮自己哔掉。
#+MACRO: hidden $2
使用时,想要替换的字符可以这样✍🏻️:
真的{{{hidden(fuck,*)}}}鬼了
发布的时候,就会变成:
真的*鬼了
-
org组织代码结构
真的很无聊的想法,我想用org来组织整个项目。。。代码啥的都写到org中,然后编译的时候, 直接执行键入的编译的代码,将整个org按照org中书写的指定内容,生成指定的文件或者文件夹, 然后再编译整个项目。
简单的流程就是比如makefile内容写在org中,然后编译这个org,生成真正的makefile, 接着执行这个makefile,项目中的其他文件也是如此。
于是,理所当然的失败了。我对org-babel还是一无所知
-
emacs-lisp的语法树
我想找emacs-lisp的范式,不过没有找到。算了
unraid通过docker使用emacs
我没有在unraid的软件中找到emacs的包,对于unraid而言,emacs还是过于庞大。但我对系统自带的vi和通过插件安装的vim都不满意。 系统自带的vi是个精简版本的。两个vim每次编辑都创建临时文件。更何况,我还需要编辑各类文件。于是,有了通过docker来运行emacs 的想法。
docker构建emacs倒是很简单,但运行之后,发现了unraid引起的坑,与上一次尝试相同,最大的坑是文件读写的效率问题。不过,这次 我有了充分的解决方式。
我的cache主要由三块固态硬盘组成,分别是120G+120G+240G,本来没有240G,通过raid0组合,速度是很快,后来看着240G的固态放在 那里浪费,就加上了,然后为了最大的可用性,就恢复成默认的方式,这样可以充分利用磁盘空间。但这种方式有个问题,就是数据的读写, 每次读写都需要unraid磁盘程序的处理,需要判断是哪个硬盘,然后加载的小文件多的话,速度就爆慢了。以我最终的emacs(spacemacs)为例,如果 我将启动相关的配置,放置在cache上的话,从启动到能使用大约需要130秒左右,启动后啥也不做,仅仅打开home目录,这个目录使用的 也是cache磁盘,大概10秒多才能出来吧。
我还有另外一块机械硬盘在做cache, 主要是为了一些不太重要的文件,比如docker运行的容器,下载的镜像,从网上下载下来的一些电影 或者视频之类的,这块数据对我而言丢了无所谓的,做成cache处理也是为了不将其放入阵列中,使用方便而已。但如果将启动的配置, 放到这个硬盘中的话,启动只需要5秒钟,打开目录也是瞬间打开,效率相差近百倍了,已经几乎比我ubuntu主机上的要快了。
我本来使用的是ubuntu做的emacs,但最后折腾的实在太大,就改成alpine了,最终镜像229MB,相比于windows的压缩包87MB,虽然是 大了,但压缩包解完压缩也差不多150MB了吧,更何况,我在镜像中加入了rime输入法的支持,emoji字体的支持,还有git等常用工具, 已经很令我满意了。
付dockerfile文件及构建运行的docker-compose文件
FROM alpine:edge ADD install.alpine /install.sh RUN /install.sh
docker-compose文件, 通过配置DISPLAY来支持gui界面,LANG为了显示中文
version: '2' services: emacs: build: context: . dockerfile: alpine.Dockerfile environment: - DISPLAY=192.168.199.171:0.0 - LANG=zh_CN.UTF-8 working_dir: ${PWD} tty: true privileged: true volumes: - ../root:/root - .:${PWD}
安装脚本, 这样做是为了减少docker的层级
#!/bin/sh set -x op=${1:-all} function install_app () { sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories echo 'https://mirrors.aliyun.com/alpine/edge/testing' >> /etc/apk/repositories apk add --no-cache bash \ sudo \ dbus-x11 \ git \ curl \ emacs-x11 \ openssh-client \ librime \ wget \ wqy-zenhei \ gzip \ fontconfig \ font-noto-emoji \ unzip \ tar } function install_source_code() { set -euo pipefail I1FS=$'\n\t' mkdir -p /tmp/adodefont cd /tmp/adodefont wget -q --show-progress -O source-code-pro.zip https://github.com/adobe-fonts/source-code-pro/archive/2.030R-ro/1.050R-it.zip unzip -q source-code-pro.zip -d source-code-pro mkdir -p ~/.fonts cp -v source-code-pro/*/OTF/*.otf ~/.fonts/ fc-cache -f rm -rf source-code-pro{,.zip} } function clean_all() { rm -rf /var/cache/* /tmp/* /var/log/* ~/.cache && mkdir -p /var/cache/apk } function all() { install_app #install_source_code clean_all } $op
<30天自治操作系统>(day 2) 读后感
这两天无聊,随便找个写代码的练手。就就开始读这本书了。
day.2代码部分使用intel的汇编格式,nasm 的编译器。我在想如何将它尽可能的用C来写。
考虑到我只有linux下的gcc编译器,又不想装太多,所以就在linux下来试试吧。
编译的脚本流程:
gcc -fno-pie -m16 --static -c day2.c -o day2.o ld -f elf32 -m elf_i386 -fno-pie --script=boot.ld -shared --map --static day2.o -o day2
这里必须指定编译为16位的,这样才能在实模式下正确运行,如果是32位模式的话,调用call会出现call飞到其他位置,为了这个内容,我调试了一下午。
正常编译的可执行文件包含了很多其他用不到的内容,比如PE格式之类,对于loader而言,这些都是无法执行的,因此需要定制编译的脚本, 下面是脚本的内容:
ENTRY(_entry) OUTPUT_FORMAT(binary) SECTIONS { . = 0x7c00; . = ALIGN(4); .text : { *(.text) *(.text.*) } . = ALIGN(4); .data : { *(.data) *(.data.*) } . = ALIGN(4); .rodata : { *(.rodata) *(.rodata.*) } . = ALIGN(4); .sdata : { *(.sdata) *(.sdata.*) } . = ALIGN(4); .scommon : { *(.scommon) *(.scommon.*) } . = .; . = ALIGN(16); __got_start = .; .got : { *(.got) } __got_end = .; . = ALIGN(4); .sbss : { *(.sbss) *(.sbss.*) } .bss : { *(.bss) *(.bss.*) } . = ALIGN(16); .rel.dyn : { *(.rel.dyn) } .dynamic :{ *(.dynamic)} .interp : { *(.interp) } .dynstr : { *(.dynstr) KEEP(*(.dynstr))} .dynsym : { *(.dynsym) KEEP(*(.dynsym))} .bootflag1 0x1FE+0x7C00 : {*(.bootflag1)} }
其实大部分都没啥用,主要是定义入口函数为_entry, 输出格式为binary而非elf格式,代码的起始位置为0x7c00.
默认的nasm程序和gcc编译器生成的二进制文件,在制作启动盘的时候,都缺少启动磁盘和启动分区的标志。使用脚本的话,就方便很多了,可以直接将启动的标记写入到指定位置去。 也就是上面的bootflag1 和 bootflag2。因为day2中的数据非常的少,所以不考虑加载更多内容,因此将data的数据放到标记之前,这样启动的时候读取一个分区的数据就将要用到的 data放入到第一个分区中了,也因此, 这部分的代码+数据不能超过512-4个字节
下面是helloworld bootloader的c代码版本:
void _init(); void _fin(); __attribute__ ((naked)) void _entry() { __asm("jmp *%0": :"r"(_init)); } char msg[] = "\n\nhello, world\n"; void show_char(char c) { __asm("mov %0, %%al": :"r"(c)); __asm("mov $0x0e, %ah"); __asm("mov $15, %bx"); __asm("int $0x10"); } void _init() { int i =0; while(i<sizeof(msg)) { show_char(msg[i]); i++; } _fin(); } void _fin() { __asm("hlt"); } unsigned char __attribute__((section (".bootflag1"))) bootflag1[] __attribute__ ((aligned (1))) = {0x55,0xaa};//0xfff0aa55;
系统起始部分其实啥也没有,所以不可避免的还是要使用汇编相关的代码,只是使用C来组织下而已, 注意的是,这里的入口函数是_entry, 而非一般c语言的main函数,这在编译的自定义脚本中声明了。函数的naked属性声明,在没有使用变量的情况下,不会生成栈相关的处理。