So geben Sie chinesische Zeichen im Linux-Kernel aus

So geben Sie chinesische Zeichen im Linux-Kernel aus

Sie können problemlos Chinesisch eingeben und im SSH-Terminal von Linux, wenn Sie sich unter Windows/MacOS angemeldet haben, eine chinesische Ausgabe erhalten, wie etwa die folgende:

Bildbeschreibung hier einfügen

Es ist jedoch fast unmöglich, Chinesisch auf Linux‘ eigenem virtuellen Terminal anzuzeigen:

[root@localhost Schriftart]# echo leather shoes>/dev/tty2 

Bildbeschreibung hier einfügen

Es werden zwei Fragezeichen angezeigt und es ist offensichtlich, dass der Linux-Kernel kein Chinesisch erkennen kann.

Warum sagen Sie, dass der Linux-Kernel kein Chinesisch erkennen kann? Es besteht ein Zusammenhang, der hier geklärt werden muss:

  • Ihre Eingabe und Anzeigeausgabe auf dem Remote-SSH-Terminal werden alle vom Hostcomputer des SSH-Terminals, beispielsweise Windows oder MacOS, ausgeführt und haben nichts mit Linux zu tun.
  • Ihr Eingabe- und Anzeigeausgabeverhalten auf dem lokalen virtuellen Linux-Terminal, beispielsweise /dev/tty1, wird vom Linux-Kernel selbst gehandhabt.

Beispielsweise habe ich iTerm SSH unter MacOS verwendet, um eine Verbindung zu einem entfernten CentOS Linux herzustellen. Alle Tastatureingaben und Anzeigeausgaben unter iTerm wurden vom MacOS-Hostcomputer von iTerm ausgeführt.

Wenn Sie im Gegenteil direkt auf dem virtuellen Terminal dieses CentOS Linux Eingaben vornehmen und versuchen, Ausgaben zu erhalten, müssen diese Eingaben und Ausgaben vom Linux-Kernel selbst gehandhabt werden.

Das ist im Wesentlichen alles. Um herauszufinden, warum der Linux-Kernel kein Chinesisch unterstützt, müssen Sie die Logik verstehen, wie der Linux-Kernel Unicode bei der Verarbeitung von Ein- und Ausgaben im virtuellen Terminal behandelt. Dies erfordert viel theoretisches Wissen und ist sehr ärgerlich.

Wie auch immer, ich kann hier einfach kein Chinesisch ausgeben und ich mache das nicht. Offensichtlich ist dies keine Arbeitsaufgabe, die erledigt werden muss, also spiele ich nur herum.

Das Ziel dieses Artikels besteht darin, das virtuelle Terminal von Linux für die Ausgabe von Chinesisch zu aktivieren.

Geben Sie nur Chinesisch aus, auch wenn es nur ein chinesisches Zeichen ist. Genauer gesagt, wenn ich das Zeichen „A“ auf der Tastatur eingebe, wird auf dem Monitor ein chinesisches Schriftzeichen angezeigt.

Daher ist in diesem Artikel nicht beabsichtigt , den Linux-Kernel in großem Umfang vollständig auf Chinesisch umzustellen . Viele Leute und Communities haben dies bereits getan, aber die Spielbarkeit ist nicht hoch. Schließlich kann man so etwas als Privatjob machen, um Geld zu verdienen. Solange es ein Job ist, mit dem man Geld verdient, ist die Spielbarkeit nicht hoch, weil es schnell gehen muss.

Sie müssen weder die langwierige und langweilige Unicode-Kodierung noch langweilige Schriftformate verstehen. Probieren Sie einfach aus, wie es geht.

Lassen Sie uns zunächst den Effekt zeigen. Hier ist ein 8 × Beispiel für eine 168\times 168×16-Punktmatrix:

Bildbeschreibung hier einfügen

Es sah nicht gut aus, also habe ich Folgendes gemacht 28 × 1628\mal 1628×16 Punktmatrix:

Bildbeschreibung hier einfügen

So wird das erreicht:

Von dem Moment an, in dem Sie eine Taste auf der Tastatur drücken, bis zu dem Moment, in dem ein Zeichen schließlich auf dem Monitor des virtuellen Terminals angezeigt wird, gibt es eigentlich zwei Zuordnungen:

Tastatur- und Zeichensatzzuordnung

Wandeln Sie ein Tastenereignis in einen Code in einem Zeichensatz um. Wenn beispielsweise die Taste „A“ gedrückt wird, ordnen Sie es 0x41 zu.

Zeichensatz- und Schriftartzuordnung

Ordnen Sie die Codewörter eines Zeichensatzes zur Anzeige einer Punktmatrix zu. Beispielsweise wird 0x41 einem Zeichen zugeordnet, das als „A“ angesehen werden kann. 8 × 168\mal 168×16 Punktmatrix.

Die Linux-Konsole kann keine Zeichensatzcodes über 0x00ff erkennen und kann daher keine Unicode-Codes über 0x00ff verarbeiten. Wenn Sie dies möchten, müssen Sie den Kernel-Code ändern.

Wie ich bereits sagte, ist die Änderung des Kernelcodes zur umfassenden Unterstützung von Chinesisch ein lukratives Geschäft. Es ist jedoch nicht nur langweilig, sondern auch, dass niemand es weitergeben möchte.

Daher habe ich versucht, die beiden obigen Zuordnungen zu ändern, um das Problem zu lösen. Da es nur zur Anzeige dient, werde ich die Zuordnung zwischen Tastatur und Zeichensatz nicht ändern, da dann immer noch das Problem der Verarbeitung von Zeichensatz-Codewörtern größer als 0x00ff bestehen würde.

Dies bedeutet, dass Ihnen zur Anzeige von Chinesisch nur eine Möglichkeit bleibt: Sie müssen die Zuordnung der Zeichensätze und Schriftarten ändern!

Diese Zuordnung muss irgendwo im Kernelspeicher oder im Dateisystem gespeichert werden. In der Konfigurationsdatei des aktuellen Kernels finde ich folgende Informationen:

[root@localhost Schriftart]# cat /boot/config-3.10.0-862.11.6.el7.x86_64 |grep FONT
# CONFIG_FONTS ist nicht festgelegt
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y

Sehen wir uns an, was in /proc/kallsyms steht:

[root@localhost Schriftart]# cat /proc/kallsyms |grep Schriftart.*8x
ffffffffb006a3e0 R Schriftart_VGA_8x8
ffffffffb006a420 r fontdata_8x8
ffffffffb006ac20 R Schriftart_VGA_8x16
ffffffffb006ac60 r Fontdata_8x16
ffffffffb0307a10 r __ksymtab_font_vga_8x16
ffffffffb03234b8 r __kcrctab_font_vga_8x16
ffffffffb034246e r __kstrtab_font_vga_8x16

Nun, dies ist die im Kernel gespeicherte Schriftart:

[root@localhost rh]# ll ./drivers/video/console/font_8x*
-rw-r--r--. 1 root root 95976 17. September 2018 ./drivers/video/console/font_8x16.c
-rw-r--r--. 1 root root 50858 17. September 2018 ./drivers/video/console/font_8x8.c

Diese beiden Dateien werden hier nicht analysiert. Dies bestätigt lediglich die Tatsache, dass der Kernel bei der Initialisierung seine eigene Schriftart verwendet . Schließlich gibt es zu diesem Zeitpunkt nichts außer dem Kernel selbst.

Das Problem ist, dass im Benutzermodus die Schriftart geändert und ansprechender gestaltet werden kann. Diese Schriftarten können nicht mit nur zwei 8x8- und 8x16-Schriftarten verarbeitet werden ...

Jetzt müssen wir die Schriftartdatei finden, die wir in der Distribution installiert haben. Wir müssen es finden, dann die Form einer bestimmten Schriftart darin ändern und es ins Chinesische umwandeln! So einfach ist das.

Sie müssen nicht suchen, wo die Schriftdatei installiert und gespeichert ist. Sie können sie finden, indem Sie den Befehl strace setfont ausführen.

[root@localhost ~]# strace -F -e trace=open setfont
...
strace: Prozess 6276 angehängt
[pid 6276] öffnen("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4
...
[pid 6276] öffnen("/lib/kbd/consolefonts/default8x16.psfu.gz", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 4
[pid 6276] +++ beendet mit 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=6276, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
+++ beendet mit 0 +++

Das ist es, /lib/kbd/consolefonts/default8x16.psfu.gz

Im PSFU-Format müssen Sie nicht nach dem Format der Schriftart suchen, Sie können bestimmte Zeichen durch Mustererkennung finden.

Ich habe vor, zuerst ‚A‘ zu finden und dann das ‚B‘ und ‚C‘ dahinter in meine Namen „Zhao“ und „Ya“ zu ändern.

Zuerst muss ich aus den Zeichen „赵“ und „亚“ eine Punktmatrix bilden. Das Folgende ist meine Arbeit „Zhao“:

00000000
00000000
00100000
11111000
00100101 
00100101
11111010
00100011 
00111010 
01100101 
01100000
10011000
10000111
00000000
00000000
00000000 

Bildbeschreibung hier einfügen

Als Nächstes verwenden wir diese Punktmatrix, um die Punktmatrix von „B“ zu ersetzen, und erstellen gleichzeitig ein „亚“-Zeichen, um die Punktmatrix von „C“ zu ersetzen.

Das entsprechende Punktmatrixdiagramm der Standardschriftart finden Sie auf der folgenden Site:
https://www.zap.org.au/software/fonts/console-fonts-distributed/psftx-centos-7.5/default8x16.psfu.large.pdf

Bildbeschreibung hier einfügen

Wir können das Punktmatrix-Array des Zeichens „A“ abrufen und dieses Array dann in der Datei default8x16.psfu abgleichen. Der Code lautet wie folgt:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <string.h>

unsigned char zhaoya[32] = {
			// Die erste Zeile ist „Zhao“
			0x00, 0x00, 0x20, 0xf8, 0x25, 0x25, 0xfa, 0x23, 0x3a, 0x65, 0x60, 0x98, 0x87, 0x00, 0x00, 0x00,
			// Die zweite Zeile ist 0x00, 0x00, 0x00, 0x7e, 0x24, 0x24, 0x24, 0xa5, 0xa5, 0x66, 0x24, 0x24, 0x7e, 0x00, 0x00, 0x00
};


int main(int argc, char **argv)
{
	}
	unsigned char Puffer[16];
	off_t-Offset = 0;
	Int s = 0;

	int fd = öffnen("default8x16.psfu", O_RDWR);
	i = pread(fd, Puffer, 8, Offset);
	während (1) {
		i = pread(fd, Puffer, 16, Offset);
		if (s == 2) { // Ersetze 'C'
			memcpy (buf, &zhaoya[16], 16);
			i = pwrite(fd, Puffer, 16, Offset);
			brechen;
		}
		if (s == 1) { // Ersetze 'B'
			memcpy (buf, &zhaoya[0], 16);
			pwrite(fd, Puffer, 16, Offset);
			s = 2;
		}
		// Einfache Methode zur Identifizierung von 'A'
		wenn (buf[0] == 0x00 && buf[1] == 0x00 &&
			buf[2] == 0x10 && buf[3] == 0x38) {
			printf("A gefunden bei %d !\n", Offset);
			s = 1;
		}
		Versatz += 16;
	}
}

Direkt kompilieren und ausführen und dann dies default8x16.psfu als Parameter für den Kernel festlegen:

[root@localhost Schriftart]# setfont ./default8x16.psfu

Rufen Sie nun das virtuelle Linux-Terminal tty2 auf. Wenn Sie den Großbuchstaben „B“ auf der Tastatur eingeben, erscheint das Wort „Zhao“.

Obwohl 16 × 816\mal 816×8 gerade 8 × 88\mal 88×8 kann auch eine komplexe chinesische Punktmatrix erzeugen, ist aber zu hässlich.

Also werde ich eine Schriftart mit höherer Auflösung finden. Ich habe ein hochauflösendes auf Ubuntu gefunden 28 × 1628\mal 1628×16 Punktmatrix Arabic-VGA28x16.psf.gz . Die Änderungsmethode ist genau die gleiche wie bei der vorherigen und die Bitmap sieht wie folgt aus:
https://www.zap.org.au/software/fonts/console-fonts-distributed/psftx-debian-9.4/Lat7-VGA28x16.psf.pdf

Ich muss es nicht selbst machen 28 × 1628\mal 1628×16-Punktmatrix, ich muss nur die vorgefertigte von GNU uifont verwenden. Sie können die Punktmatrix direkt gemäß den Unicode-Codewörtern „赵“ und „亚“ in unifont_sample-12.1.01.hex indizieren. Zur Abfrage von Unicode-Codewörtern beliebiger Zeichen siehe:
https://graphemica.com/

Der Code zum Ersetzen der Schriftart lautet wie folgt:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include "zhao"

#definiere L 28*2
int fd;

int main(int argc, char **argv)
{
	unsigned char Puffer[L];
	off_t-Offset = 0;
	// Dieser 0x0e60 ist der durch Mustervergleich erhaltene Offset.
	Versatz += 0x0e60;

	fd = öffnen("Lat7-VGA28x16.psf", O_RDWR);
	pread(fd, Puffer, L, Offset);
	memset(buf, 0, L);
	memcpy(buf+8, &code[0], 32);
	pwrite(fd, Puffer, L, Offset);

	Versatz += L;
	pread(fd, Puffer, L, Offset);
	memset(buf, 0, L);
	memcpy(buf+8, &code[32], 32);
	pwrite(fd, Puffer, L, Offset);

	Versatz += L;
	pread(fd, Puffer, L, Offset);
	memset(buf, 0, L);
	memcpy(buf+8, &code[64], 32);
	pwrite(fd, Puffer, L, Offset);
}

Dann ist die Wirkung:

Bildbeschreibung hier einfügen

nicht schlecht.

Tatsächlich ist der Inhalt dieses Artikels lediglich:

  1. Machen Sie eine beschissene Punktmatrix;
  2. Die Zuordnungsbeziehung zwischen Tastatur, ASCII/Unicode und Schriftart;
  3. Wie man Probleme lokalisiert und analysiert, ohne irgendwelche Details zu kennen;
  4. Je einfacher, desto besser, je komplizierter, desto schlechter.

Nun, eigentlich sind der dritte und vierte Punkt die wichtigsten.

Wenn Sie schließlich wissen möchten, welche Schriftarten Ihr aktuelles virtuelles Terminal unterstützt, geben Sie Folgendes ein:

[root@localhost Schriftart]# showconsolefont

Es wird angezeigt:

Bildbeschreibung hier einfügen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Eine kurze Analyse der Schwachstellen im Linux-Kernel
  • Implementierungsprozess der verknüpften Liste im Linux-Kernel
  • Eine kurze Erläuterung des gesamten Vorgangs zum Erstellen eines neuen Prozesses im Linux-Kernel
  • Methode zur Anpassung der Linux-Kernel-Parameter
  • Implementierung und Analyse des Linux-Kernel- und Benutzerbereichs
  • Ein kurzer Vortrag über Linux-Kernel-Timer
  • Ein Bild, das das Funktionsprinzip des Linux-Kernels zeigt
  • Detaillierte Erklärung der Bootparameter des Linux-Kernels
  • Detaillierte Implementierung des Rot-Schwarz-Baum-Algorithmus im Linux-Kernel
  • Detaillierte Erläuterung der Kernelkompilierung des Linux-Betriebssystems
  • Schreiben von Linux-Kernelmodulen und -Treibern

<<:  Vue implementiert Klick-Feedback-Anweisungen für den Wasserwelleneffekt

>>:  Grafisches Tutorial zur Installation und Konfiguration der Dekomprimierungsversion von MySQL 8.0.13

Artikel empfehlen

Wissen Sie, wie viele Verbindungen ein Linux-Server verarbeiten kann?

Vorwort Sehen wir uns zunächst an, wie eine TCP-V...

Designbeispiele für Dropdown-Menüs und Schiebemenüs

Ich habe viele Websites gefunden, die Dropdown- od...

Detaillierte Erklärung der Kartenüberlagerung in OpenLayers6

1. Overlay-Übersicht Overlay bedeutet Überlagerun...

SQL-Implementierung von LeetCode (196. Doppelte Postfächer löschen)

[LeetCode] 196.Doppelte E-Mails löschen Schreiben...

17 hervorragende Webdesigns, sorgfältig von Startups entwickelt

Startups überraschen uns oft mit ihren unkonventi...

Implementierungsbeispiel für den Linux-Befehl „tac“

1. Befehlseinführung Der Befehl tac (umgekehrte R...

In der HTML-Tabelle wird nur der äußere Rand der Tabelle angezeigt

Ich möchte eine Frage stellen. Ich habe in Dreamw...

Ausführliche Erläuterung der InnoDB-Sperren in der MySQL-Technologie

Inhaltsverzeichnis Vorwort 1. Was ist ein Schloss...

Ubuntu 18.04 erhält Root-Berechtigungen und meldet sich als Root-Benutzer an

Vorab geschrieben: In den folgenden Schritten müs...

Der Unterschied zwischen JS-Pre-Parsing und Variablen-Promotion im Web-Interview

Inhaltsverzeichnis Was ist eine Voranalyse? Der U...

So konfigurieren Sie die MySQL-Master-Slave-Synchronisierung in Ubuntu 16.04

Vorbereitung 1. Die Master- und Slave-Datenbankve...