読者です 読者をやめる 読者になる 読者になる

alpaca2unix blog

UNIXやGnu/Linuxの勉強と備忘録です。

キーボードを分解。そして洗う。

わたしが使用しているパソコンはデスクトップタイプなんです。なので、ノートブックタイプだと、いまからお話しすることは保証できません。

さて、わたしのキーボードちゃんの「A」ボタンが反応が悪くなってしまったのです。以前、オレンジジュースをこぼしてしまった記憶が蘇ります。

粘り気があるというか、ポンポン反応しないというか。

それで、最初のうちはキーボーを水を含ませたティッシュで拭いてみたりしたのですが、まったく意味なし。

ネバネバしている「A」キーボードをなんとかさせたくて、カッターで「A」ボタンの四角いまわりをなぞってみたり。それでも良くならなかったです。

予備のキーボードは一応、あったので、分解してみるかという気になりました。

f:id:alpaca2unix:20170327205148j:plain

キーボードの上面を取ると下側はこんな風になっていました。興味津々。ふにゃふにゃした材質の白いシリコン(?)の中には回路が通っていました。ここは傷をつけてはいけないですし、水洗いしてはいけなさそうですね。

そして、キーボードの上側を丸洗い。特に問題になっている「A」ボタン周辺をお湯で洗いました。

f:id:alpaca2unix:20170327205419j:plain

とんでもなく原始的な方法ですが、そして、乾かす。

f:id:alpaca2unix:20170327205444j:plain

時々、裏側にして、乾かす。

昼に乾かしはじめて夕方にはすっかり乾きました。そしてネジを締めて、このキーボードをパソコンにつなぎトライ! 無事、反応よくキーボードが使えるようになりました。

 

kayo .〜*

BeOS後継のHaikuが激速で凄い!

f:id:alpaca2unix:20170324160721p:plain

日頃、Linuxを使用していると何と重たいことか。わたしのLinuxには3つの環境が入っていまして、

  1.  Gnome3 激重いけど、最先端
  2.  Mate 中途半端な感じもするけど、gnome2の後継としては良い
  3.  Enlightenment 速いけれど、たまに落ちる。ゲーム時に使用。

すこし昔、Freebsdをメインにしていた時にblackboxというのを使っていました。あれは良かった。blackboxをいまの環境に加えてみようかな。ただし、もうメンテされてないというのが不安。そこで、Flaxboxという選択肢が出てくるわけだけど、blackboxの方が好きなのよね・・・

HaikuはVMware上でメモリ1GBとしか振ってなかったのに、激速で動いてくれました。ちょっと楽しそうなOSなので、使ってみることにします。

 

kayo .~*

OS開発にゴールはないのかもしれない

下記のページの「ld」をアレンジしたら、無事、コンパイルが通りました。ld --helpも見ていたら、概要も分かってきました。^ ^*

# ld --architecture=x86_64 -r -o AlpacaOS.bin boot.o kernel.o

softwaretechnique.jp

これで、自前のbootloaderとkernelがくっついた状態になりました。ブートストラップでkernelを読んでくれます。ですが、今度は、bootloder→Grub2→kernelという具合にしてみたです。

 

kayo .~*

リンカの仕方、Makefileの書き方が分からないんです。

f:id:alpaca2unix:20170324090156p:plain

 

boot.S

    //    Declare constants for the multiboot header.
    .set ALIGN,         1<<0                    # align loaded modules on page boundaries
    .set MEMINFO,        1<<1                    # provide memory map
    .set FLAGS,            ALIGN | MEMINFO            # this is the multiboot 'flag' field
    .set MAGIC,            0x1BADB002                # 'magic number' lets bootloader find the header
    .set CHECKSUM,        -(MAGIC + FLAGS)        # checksum of above, to prove we are multiboot

   /*
    *    Declare a multiboot header that marks the program as a kernel.
    *    These are mafic Values that are documented in the multiboot standerd.
    *    The bootloader will search for this signature in the first 8KiB of the Kernel file, aligned at a 32-bit boundary.
    *    The signature is in its own section so the header can be forced to be within the first 8KiB of the Kernel file.
    */

    .section         .multiboot
    .align            4
    .long            MAGIC
    .long            FLAGS
    .long            CHECKSUM

   /*
    *    The multiboot standard does not define the value of the stack pointer register (esp)
    *    and it is up to the kernel to provide a stack.
    *    This allocates room for a small stack by creating a symbol at the bottom of it,
    *    then allocating 16384bytes for it, and finaly creating a symbol at the top.
    *    The stack grows downwards on x86.
    *    The stack is its own section so it can be marked nobits,
    *    which means the kernel file is smaller because it does not contain an uninitialized stack.
    *    The stack on x86 must be 16-byte aligned according to the System V ABI and de-facto extentions.
    *    The compiler will assume the stack is properly aligned and failure to align the stack will result in undefined behavior.
    */

    .section     .bss
    .align        16
stack_bottom:
    .skip        16384            # 16 KiB
stack_top:

   /*
    *    The linker scripts specifies _start as the entry point to the kernel and
    *    the bootloader will jump to this position once the kernel has been loaded.
    *    It desen't make sense to return from this function as the bootloader is gone.
    */

    .section    .text
    .global        _start
    .type        _start, @function
    _start:

   /*
    *    The bootloader has loaded us int 32-bit protected mode on a x86 machine.
    *    Interrupts ar disabled. Paging is disabled/
    *    The processor state is as defined in the multiboot standard.
    *    The kernel has full contorl of the CPU.
    *    The kernel can only make use of hardware features
    *    and any code it provides as part of itself.
    *    There's no printf function,
    *    unless the kernel provides its own <stdio.h> header and a printf implementation.
    *    There are no security restricions, no safeguards, no debugging mechanism,
    *    only what the kernel provides itself.
    *    It has absolute and complete power over the machine.
    *
    *    To set up a stack, we set the esp register to point to the top of our stack
    *    (as it grows downwards on x86 systems).
    *    This is necessarily done in assembly as languages such as C cannot function without a stack.
    */

    mov        $stack_top, %esp

   /*
    *    This is a good place to initialize crucial processor state before the high-level kernel is entered.
    *    It's best to minimize the earily environment where crucial features are offline.
    *    Note that the processor is not fully initialized set extensions are not initialized yet:
    *    Features such as floating point instructions and instruction set extensions are not initialized yet.
    *    The GDT should be loaded here.
    *    Paging should be enabled here.
    *    C++ features such as global constructors and exceptions will require runtime support to work as well.
    */
    
   /*
    *    Enter the high-level kernel. The ABI requires the stack is 16-byte
    *    aligned at the time of call instruction (which afterwards pushes the return pointer of size 4 bytes).
    *    The stack was originally 16-byte aligned above and we've since pushed a multiple of 16 bytes to the stack since
    *    (pushed 0 bytes so far) and the alignment is thus preserved and the call is well defined.
    */
    
    call kernel_main
    
   /*
    *    If the system has nothing more to do,
    *    put the computer into an infinite loop. to that:
    *    1) Disable interrupts with cli (clear interrupt enable in eflags)/
    *       They are already disabled by the bootloader, so this is not needed.    
    *       Mind that you might later enable interrupts and return from kernel_main (which is sort of nonsensical to do).
    *    2) Wait for the next interrupt to arrive with hlt (hlt instruction).
    *       Since they are disabled, this will lock up the computer.
    *    3) Jump to the hlt instruction if it ever wakes up due to a non-maskable interrupt occurring
    *       or due to system management mode.
    */
    
    cli
1:    hlt
    jmp        1b
    
//    Set the size of the _start symbol to the current location '.' minus its start.
//    This is useful when debugging or when you implement call tracing
    
.size     _start, . - _start

# as boot.s -o boot.o

これで、boot.oをゲット!

kernel.c

/* Surely you will remove the processor conditionals and this comment
   appropriately depending on whethre or not you use C++. */
#if    !defined(__cplusplus)
#include <stdbool.h>    /* C doesm't booleans by default. */
#endif
#include <stddef.h>
#include <stdint.h>

/* Check if the compiler thinks we are targeting the wrong operating system    */
#if defined(__linux__)
/* error "You are not using a cross-compiler, you will most certainly run into trouble" */
#endif

/* This tutorial will only work for the 32-bit ix86 targets. */
#if !defined(__i386__)
/* error "This tutorial needs to be compiled with a ix86-elf compiler" */
#endif

/* Hardware text mode color constants */
enum vga_color {
    VGA_COLOR_BLACK = 0,
    VGA_COLOR_BLUE = 1,
    VGA_COLOR_GREEN = 2,
    VGA_COLOR_CYAN = 3,
    VGA_COLOR_RED = 4,
    VGA_COLOR_MAGENTA = 5,
    VGA_COLOR_BROWN = 6,
    VGA_COLOR_LIGHT_GREY = 7,
    VGA_COLOR_DARK_GREY = 8,
    VGA_COLOR_LIGHT_BLUE = 9,
    VGA_COLOR_LIGHT_GREEN = 10,
    VGA_COLOR_LIGHT_CYAN = 11,
    VGA_COLOR_LIGHT_RED = 12,
    VGA_COLOR_LIGHT_MAGENTA = 13,
    VGA_COLOR_LIGHT_BROWN = 14,
    VGA_COLOR_WHITE = 15,
};

static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) {
    return fg | bg << 4;
}

static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
    return (uint16_t) uc | (uint16_t) color << 8;
}

size_t strlen(const char* str) {
    size_t len = 0;    
    while (str[len])
        len++;
    return len;
}

static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;

size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;

void terminal_initialize(void) {
    terminal_row = 0;
    terminal_column = 0;
    terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
    terminal_buffer = (uint16_t*) 0xB8000;
    for (size_t y = 0; y < VGA_HEIGHT; y++) {
        for (size_t x = 0; x < VGA_WIDTH; x++) {
            const size_t index = y * VGA_WIDTH + x;
            terminal_buffer[index] = vga_entry(' ', terminal_color);
        }
    }
}
 
void terminal_setcolor(uint8_t color) {
    terminal_color = color;
}
 
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) {
    const size_t index = y * VGA_WIDTH + x;
    terminal_buffer[index] = vga_entry(c, color);
}
 
void terminal_putchar(char c) {
    terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
    if (++terminal_column == VGA_WIDTH) {
        terminal_column = 0;
        if (++terminal_row == VGA_HEIGHT)
            terminal_row = 0;
    }
}
 
void terminal_write(const char* data, size_t size) {
    for (size_t i = 0; i < size; i++)
        terminal_putchar(data[i]);
}
 
void terminal_writestring(const char* data) {
    terminal_write(data, strlen(data));
}
 
#if defined(__cplusplus)
extern "C" /* Use C linkage for kernel_main. */
#endif
void kernel_main(void) {
    /* Initialize terminal interface */
    terminal_initialize();
 
    /* Newline support is left as an exercise. */
    terminal_writestring("Hello, kernel World!\n");
}

# gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
これで、kernel.oをゲット!

boot.oとkernel.oをリンクして、AlpacaOS.imgを作ることができると、qemuで起動できるのですが、ソースは書けてもリンク方法が分からないでいます。いま調べているところなのですが、Makefileの勉強はやっぱりした方がいいですね。これから先、プログラミングをしていく上で確実に必要な感じ。あと、ちょっとなのになー。早く、qemuでMy_kernelの起動を見たいのですが・・・ちなみにこのカーネルは「OS自作入門」のkernelとは異なります。

kayo .~*

骨髄球2.0% 我が帝国総動員玉砕戦線発令、手前。

2~3ヶ月に一度、採血しなくてはならないお薬を服用しているので、いつものように採血結果の紙をもらいました。毎度のことながら、謎の高さを見せている白血球(16.6千/ul)を見て、しんぱーいって思っています。いや、30万/ulとかになってなきゃ急性白血病とかではないと思うのですが、問題は!!!

 

白血球数  16.6 千/ul  ⇧ やじるしがちょっとでかい

赤血球数  453 万/ul

血小版数  29.0万/ul

血液像(白血球分類)

好中球   59.5%

幼若球   2.0% ↑

(kayo軍司令官が小学生兵隊をオーダー。つまり、人員足りてないってこと。)

骨髄球   2.0% ↑

(さらに、kayo軍司令官が赤ちゃん兵隊見習いをオーダー。ヲイ!司令官。まだロクロク歩けない赤ちゃん兵隊見習いをオーダーするほど足りてないの??)

骨髄芽球  none
(kayo軍の兵隊。といっても卵。まだ徴兵されてない。ハンプティダンプティさえオーダーするようだと専門家に行かないといけないみたい。)

好酸球   3.0%

好塩基球  1.0%

リンパ球  28.0%  リンパ球は大丈夫みたい。

単球    6.5%

<<血液像は鏡検法による検査結果です>>

中性脂肪の値とかは載せなくてよ。- -;;

 

今回、初登場のキャラクター。骨髄球2.0% ↑

 

先生も、あまり出てきて欲しくないね。と言ってました。ただ、ジャンルの違う病院なので、専門外だから詳しくはないんだーと。

好中球はいわゆる白血球の門番というか、わたしの体の中にいる自衛隊みたいな存在らしいです。

ところが、何をとち狂っているのか自衛隊の司令官が骨髄球も骨髄から出てくるように、2.0%でオーダーだ!と言うのです。

 

骨髄球   2.0% ↑

骨随球は好中球の赤ちゃんです。大きくなって好中球になり、骨髄から飛び出し、自衛隊に入るわけですが、司令官は赤ちゃんをオーダーしているというわけです。人員不足の戦が起こっているのか、何かエラーがあるには違いなさそう。ちなみに白血球は1~2年前までは、12 千/ulで推移していましたが、このところ、16 千/ulで推移し始めました。

 

幼若球   2.0% ↑

のとおり小学生の兵隊も徴兵されています。徴兵率2.0% これも普通は出てこない数値のようです。

 

先生によると、骨髄球は、はじめて出てきたものだし、様子見かなと言ってました。心配なら病院を紹介すると。

で!!

「骨髄芽球」が出てきた場合は話が違うぞと言います。骨髄芽球はいわば、卵てきな存在。赤ちゃんレベルにもなってない芽なんです。

これを司令官が2.0%でオーダーだと言ってきたら、人員不足甚だしいというわけ。

何か、大きな戦が起こっている可能性大。

使い物になりそうにない、白血球の卵みたいなのを戦場に送ることになると言うことになってしまいます。

いわば、我が帝国総動員玉砕戦線発令という・・・

ああ・・・

とにかく、2~3ヶ月に一回は、採血をするので気になる白血球成分を載せていきたいと思います。^ ^;;

 

最後に、ねーセンセ。骨髄検査って痛いの?って聞いたら、痛いかもしれないと・・・麻酔は? する。といってました・・・やーだー・・・やーだーー。泣

 

kayo .~*