咸菜

啃咸菜 品生活

slax正确显示中文sb模块

寻觅一款小型Linux做维护用

曾用CDLinux破解WIFI密码,万幸成功取得密码^_^,那时意外发现电脑里有一款Linux很实用。更了解Windows的我自然更关注能共存,能读写ntfs,最重要能显示中文的小巧Linux,。
CDLinux具有我看中的所有优点(也许先入为主,我的理想型就是以它为蓝本吧),但是可惜多年未更新了。后来我用tinyCore能完成基本的文件操作,极大的问题是不支持ntfs,只在非常老旧工控机上用还行。再后来比较相中slitaz,据说能支持中文,但也许是我使用时无网络、不加载模块的缘故,并不能显示中文。嗯,也许是我并没有深入捣鼓,配置的不对吧,但是单从持续更新这一条来讲,我也推荐slax。
slax曾基于slackware,但是现已基于debian,能够直接使用apt包管理工具安装软件,这种方便让人无法拒绝,同时,它还是有“模块”的,可以在原镜像基础上加载modeules。还有,在与windows共存之外,在slax中进行的修改是默认保存下来的,改动被记录到/slax/changes/下,通过其专有工具savechanges还可以将所有改动保存成.sb模块文件。

grub4dos启动slax造成键盘布局错误?

嗯。正如小标题尾的问号,我也不确定。我自己遇到的情况是这样。slax设计的是安装syslinux启动引导程序,在windows中运行/slax/boot/bootinst.bat或在Linux中执行/slax/boot/bootinst.sh可以安装。查看路径可以看到,在/slax/boot/下有一个440字节的mbr.bin二进制mbr文件(正好接上我上篇把玩古董Maxtor机械硬盘的日志)。

如题,我已经有grub4dos了。我只是复制了slax到硬盘,没有按部就班的典型安装,我在grubmenu.lst中自己添加了slax,但是启动到slax后发现键盘总是布局不符,无法正常使用键盘按键,应该是传给vmlinuz的参数不规范导致的。修改为仅留perch参数后键盘正常,默认保存改动也正常:

kernel /slax/boot/vmlinuz slax.flags=perch
initrd /slax/boot/initrfs.img
boot

让slax正确显示中文

我非常受益于glaumar写的日志Slax的安装和基本配置,按照他的日志操作顺利达成我的slax汉化目的。总结就是安装了noto字体库和fcitx拼音输入法。
问题是,我按照其日子操作了apt update && apt upgrade -y,虽然升级了系统软件,但是/slax/changes/下产生了高达1.7G的改动记录文件。。。
我不能抛弃小巧化的追求,于是在我的U盘里,我重新布置了/slax/,apt安装了noto字体,也没有安装输入法,能够正确显示中文已经达到我的基本要求。
slax支持中文sb模块
然后我savechanges henoto.sb将改动保存成了sb模块文件。看了下,增加的/slax/modeules/henoto.sb大小约90M,/slax/整体约355M,还算小巧,比较满意,共享在网盘(提取码:5ky6)供参考
我导出的henoto.sb所改动之处有:

把玩古董Maxtor机械硬盘

折戟沉沙鐵未銷,自將磨洗認前朝。
20G迈拓机械硬盘

LBA(Logical Block Addressing)

LBA编址就是依CHS以从小到大顺序给扇区编号。是将CHS这种三维寻址通过#lba=(#c*H+#h)*S+#s-1(H:heads per cylinder, S:sectors per track)规则转换为一维线性寻址。化繁为简。

MBR(Master Boot Record)

MBR之“主”是相对于PBR(Partition Boot Record,也称VBR卷引导记录)来说的,每个分区都有自己的PBR,但整块硬盘盘只有一个MBR。BIOS从硬盘加载MBR,MBR中“引导代码”加载PBR,PBR中的“引导代码”能启动特定程序,而后程序再启动操作系统,这个过程叫“链式加载”。
PBR开始于partition(分区)的第一个扇区,如同MBR开始于整个硬盘的第一个扇区,类似于MBR关联DPT(disk partition table,分区表),PBR关联file system(文件系统)以及特定操作系统。

通常用MBR指代整个扇区,其实MBR严格讲只是扇区前446Bytes内容,其后紧接着4个16Bytes的DPT,在扇区最后偏移地址0x01fe和0x01ff分别存储0x55和0xaa,这个0x55aa是record(记录)有效标志,总共446+64+2=512Bytes写满第一扇区。

但,有些复杂MBR的引导代码量超过446Bytes(比如grub4dos)会占用16个扇区或更多,但是DPT的位置不能改变,所以备份MBR时只备份446Bytes可能并不够,而备份一个或几个扇区则连带分区表也备份了,还原时不同硬盘极可能不通用,要十分注意。 #dd bs=1 count=446 if=/dev/sda of=mbr446b.bin只适用非常简单的MBR,如果想备份16个扇区,则#dd bs=1b count=16 if=/dev/sda of=mbr16s.bin 注意dd程序bs参数默认单位就是Byte字节,当加suffix后缀时是倍乘关系,1b即1*512=512Bytes,1k即1*1024=1024Bytes。那么还原时得分两段,DPT前的446Bytes是第一段,跳过DPT的64Bytes后面的是第二段。

#dd bs=1 count=446 if=mbr16s.bin of=/dev/sda
#dd bs=1b seek=1 skip=1 count=15 if=/mbr16s.bin of=/dev/sda

DPT(Disk Partition Table)

前辈们扣扣索索的把MBR和DPT捏吧捏吧都挤进首扇区(好吧,要理解当初存储容量很宝贵),DPT总共只有64Bytes,而16Bytes描述一个分区项信息,故一块硬盘最多只能划分4个分区项(4个primary partition主分区或3个主分区+1个extended partition扩展分区)。
扩展分区像链式指针,跳转到其他扇区继续读取分区信息,春节假期也就几天,关于扩展分区就不去了解那么多了。

我Maxtor这块盘的DPT把玩记录:

#dd bs=1 skip=446 count=66 if=/dev/sda | hexdump
66+0 records in
66+0 records out
66 bytes (66B) copied, 0.000090 seconds, 716.1KB/s
0000000 4180 0001 3f06 0abf 0fff 0000 f54b 007f
0000010 4000 0a81 fe06 ffff 054a 0080 f54b 007f
0000020 fe00 ffff fe83 ffff 0000 0100 f800 009f
0000030 fe00 ffff fe0f ffff ffc1 019f 6fbf 00c2
0000040 aa55
0000042

看输出有点奇怪,DPT第一字节,表示活动分区的0x80显示在0x41后面,并且MBR记录有效标志0x55,0xaa也显示成了aa55H。这应该是hexdump程序输出显示采用了big endian(BE,大端字节序,高位字节在前)的缘故(关于big endian我在日志VIM转换文本文件字符编码中GB18030段落中有提到)
别扭是别扭点,自己把每两字节对换下前后看就行了,也不影响啥。而且我发现用hexdump -C使其带ASCII字符显示时又正常的little endian(LE,小端字节序,低位字节在前)了,想方便一点可以带参“-C“。

分析第一分区项:0x80表活动分区,从此分区启动引导;0x41表分区开始于65heads;0x01,0x00表分区开始于1sector0cylinder;0x06表此分区使用FAT16 file system;0x3f表分区结束于63heads;0xbf,0x0a表此分区结束于63===(0xbf &0b111111)sectors522===(((0xbf &0b11000000) <<2) |0x0a)cylinders (此处数大一眼看不出,借助javascript计算,1Byte是8bits,用位运算);0xff 0x0f 0x00 0x00表头前4095===0xfff个sectors保留;0x4b 0xf5 0x7f 0x00表分区总共8385867===0x7ff54b个sectors。
用fdisk直观的比对一下

#fdisk /dev/sda
command: p
Dvice  Boot StartCHS EndCHS      StrartLBA   EndLBA  Sectors Size  Id Type
/dev/sda1 * 0,65,1   522,63,63        4095  8389961  8385867 4094M  6 Fat16
Partition 1 does not end on cylinder boundary
/dev/sda2  522,64,1 1023,254,63    8389962 16775828  8385867 4094M  6 Fat16
/dev/sda3 1023,254,63 1023,254,63 16777216 27260927 10483712 5119M 83 Linux
/dev/sda4 1023,254,63 1023,254,63 27262913 40005503 12742591 6221M  f Win95 Ext't (LBA)
/dev/sda5 1023,254,63 1023,254,63 27262976 29360127  2097152 1024M 82 Linux swap
/dev/sda6 1023,254,63 1023,254,63 29362176 40005503 10643328 5196M  c Win95 FAT32 (LBA)

fdisk的交互命令可以带领着一步步改动DPT,比如d删除某分区,n新建一分区,改动后p打印可以看到修改后效果,要注意的是只有w写入后才真正修改DPT了。

dd不仅可以做备份还原用,直接“定点手术“也没毛病,比如echo -en "\x00" | dd bs=1 seek=446 of=/dev/sda将第一主分区的active标志0x80替换成了0x00,这块硬盘将不再启动引导;echo -en "\x00\x00" | dd bs=1 seek=510 of=/dev/sda擦掉记录有效标志,MBR变为无效;echo -en "\x55\xaa" seek=510 of=/dev/sda恢复有效标志。

zero-fill

我与我的迈拓注定渐行渐远,所谓“是非成败转头空”:

#fdisk -l | head -n 3
Disk /dev/sda: 19GB, 20490559488 bytes, 40020624 sectors
2491 cylinders, 255 heads, 63 sectors/track
Units: cylinders of 16065 * 512 = 8225280 bytes
#dd bs=8225280 count=2491 conv=fsync if=/dev/zero of=/dev/sda &
#watch -n 99 pkill -USR1 ^dd$
85+0 records in
85+0 records out
690923520 bytes (658.9MB) copied, 2.629941 seconds, 250.5MB/s

用后缀&使dd后台运行,再watch周期打断dd得到进度信息,注意dd不使用conv=fsync参数的话最后一些setors可能不能真的写上0以致硬盘没有擦干净。同terminal终端这样watch,进度信息是一条“刷新”的,发现dd不使用&后缀而是再开一个terminal来watch的话,原terminal的dd的进度输出是多条一直累加下去显示的。 zero-fill的场面应该很壮观:“谈笑间,樯橹灰飞烟灭。”

vim转换文本文件字符编码

用VLCplayer手机上看电影,发现.srt的字幕文件总是显示乱码,类似于将feb鹹菜de漢字幕乱码成febûy²Ëde<9d>h×ÖÄ»,尝试更改过编码选项也无济于事,干脆直接选项定位为utf8,然后想从文本文件下手转换编码,于是又了解到一点新知识,遂记录在此。

vim转换文本文件编码

未设置.vimrc的vim,打开字幕那个.srt依然显示乱码,这时是没法转换的,需要先能够正确显示文本内容才行,也就是需找到文本是采用的那种编码。:edit ++encoding=gbk后文本正常,确定是gbk编码,此时具备转换条件,转换文件也很简单::write ++encoding=utf8

复习一下vim几个关于编码的设置

还想再记几个参数,直接放上.vimrc吧

set nocompatible
set encoding=utf-8
set fileencoding=utf-8
set fileencodings=ucs-bom,utf-8,gb18030,latin1
set fileformat=unix
set fileformats=unix,dos
set nonumber
set showcmd
set autoindent
set ruler
set showmatch
set t_Co=256
set tabstop=2
set shiftwidth=2
filetype indent on
syntax on

不得不再了解一下code page

在转换字幕.srt文件时,如前述:set ++encoding=gbk后,文本可以正确显示,再:set encoding却返回encoding=cp936,这个cp936就是code page。

code page就是针对一定范围字符的编码页表。其可内置于操作系统(包括bios)来显示文字(包括非英文字母),不同操作系统间code page并不一定一致。code page编号以区别,有OEM用的、Windows用的,也有两者通用、共用的,比如cp936(简体gbk)。但发现vim却不把gb18030显示为cp54936,不明所以。

GB18030

7bit编码表ascii显示不了汉字,1980年设计了用于简体的gb2312和用于繁体的big5。gb2312用两组数,第一组数“区”,第二组数“位”,就是区位码。其与ascii编码冲突,作为code page时,在区位码高低字节上分别+0xa0(比如“啊”区位码1601即0x10,0x01,code page码b0a1,即0xb0,0xa1),存储格式big endian(BE,大端字节序,高位字节在前)。gb2312字符少,1995年gbk(汉字扩展规范)扩充了字符,2000年gb18030取代gbk,不仅收录汉字,还包括少数民族文字。

从ascii、gb2312、gbk到gb18030,字符编码是向前兼容的,同一个字符总是保持相同的编码(so,用错code page时汉字都乱码而大部分英文字母幸存),所以用gb18030可以正确解读以gbk编码的文本。gb集都是DBCS(双字节字符集),高字节最高位为1(以区别于ascii)。因为gb集低字节最高位也可能为1,所以需避免拆开DBCS的双字节,解析DBCS字节流时,只要遇到最高位为1(就当是双字节高字节开始了),就将两个字节认为DBCS编码(而不在意低字节最高位为0为1)。