勇闖新世界︰ 《 Kernel 4.X 》之整裝蓄勢‧事件驅動‧三下

假使我們換個觀點來看『事件驅動』,Kernel 4.1.Y 的發布就是一個『事件』,『驅動』著新一輪的『驗證』與『測試』。但是有時候即使早已經新舊規範準備汰換了,然而卻因為大量舊規範軟體存在以及現實使用考慮,因此不得不雙規並行很長的時間。這種情況從派生二和派生三的發展史中可以清楚的見到。再加上軟體的『自動更新』,由於『測試』與『驗證』自動化之困難,實務上仍舊是個『大麻煩』,或許『活補之術』正是因此而生。雖說 Kernel 4.X 裡也開始支援此法,

1.2. Live patching

This release introduces “livepatch”, a feature for live patching the kernel code, aimed primarily at systems who want to get security updates without needing to reboot. This feature has been born as result of merging kgraft and kpatch, two attempts by SuSE and Red Hat that where started to replace the now propietary ksplice. It’s relatively simple and minimalistic, as it’s making use of existing kernel infrastructure (namely ftrace) as much as possible. It’s also self-contained and it doesn’t hook itself in any other kernel subsystems.

In this release livepatch is not feature complete, yet it provides a basic infrastructure for function “live patching” (i.e. code redirection), including API for kernel modules containing the actual patches, and API/ABI for userspace to be able to operate on the patches (look up what patches are applied, enable/disable them, etc). Most CVEs should be safe to apply this way. Only the x86 architecture is supported in this release, others will follow.

For more details see the merge commit

Sample live patching module: commit

Code commit

,然而在樹莓派上之用法如何?作者不知尚待研究。

由是觀之,未來所謂『智慧型物聯網』終究必須面對這一課題,或將取法大自然的生物『蛻變之法』,破繭而出蝶化而飛的耶!

於是就可以明白實務上『裝置樹』也需要一個變遷過程,此處僅以『DS18B20』數位環境溫度感測器為範例,追跡相關檔案在何處?以祈加快讀者的理解腳步。因為必將及於『驅動程式』的原始碼,先介紹 notro 先生的 rpi-source 網頁︰

/rpi-source

Issue #13: Currently a workaround is necessary on the latest kernels. Run sudo modprobe configs before rpi-source.

As of April 2015 PeterOGB has offered to maintain this code.

Pi1 and Pi2 Kernels are now supported.

rpi-source installs the kernel source used to build rpi-update kernels and the kernel on the Raspian image.
This makes it possible to build loadable kernel modules.
It is not possible to build modules that depend on missing parts that need to be built into the kernel proper (bool in Kconfig).

The script uses sudo internally when self-updating and when making the links /lib/modules/(uname -r)/{build,source}</em></span>  <span style="color: #666699;">Note: rpi-source is supported from Linux version 3.10.37 (when Module.symvers appeared in the repo)</span>  <span style="color: #666699;"><a href="https://github.com/notro/rpi-source/wiki/Examples-on-how-to-build-various-modules"><span style="color: #666699;">Examples on how to build various modules</span></a></span>  <span style="color: #666699;">Install</span> <pre class="lang:sh decode:true ">sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update</pre> <span style="color: #666699;">Run</span>  <span style="color: #ff9900;"><code>sudo modprobe configs</code></span>  <span style="color: #ff9900;">rpi-source --skip-gcc</span>  <span style="color: #ff0000;">※ 取得 rpi-update  Kernel 版本之原始碼。</span>  ───  </div> 此處特以 Kernel 4.0.9 為例,展示這些檔案間的關聯性︰  <span style="color: #808080;"><strong>【組構檔 /boot/config.txt 】 裝置樹設定處</strong></span>  <span style="color: #808080;">dtoverlay=w1-gpio</span>  <span style="color: #808080;"><strong>【裝置參數說明檔位置】</strong></span>  <span style="color: #808080;">系統檔案位置 /boot/overlays/README</span>  <span style="color: #808080;">來源檔位置 ~/linux-□□□/arch/arm/boot/dts/overlays/README</span>  《<span style="color: #808080;">w1-gpio 參數內容</span>》 <span style="color: #ff0000;">※ 注意參數名稱</span> <pre class="lang:sh decode:true">Name:   w1-gpio Info:   Configures the w1-gpio Onewire interface module.         Use this overlay if you *don't* need a GPIO to drive an external pullup. Load:   dtoverlay=w1-gpio,<param>=<val> Params: gpiopin                  GPIO for I/O (default "4")           pullup                   Non-zero, "on", or "y" to enable the parasitic                                  power (2-wire, power-on-data) feature     Name:   w1-gpio-pullup Info:   Configures the w1-gpio Onewire interface module.         Use this overlay if you *do* need a GPIO to drive an external pullup. Load:   dtoverlay=w1-gpio-pullup,<param>=<val>,... Params: gpiopin                  GPIO for I/O (default "4")           pullup                   Non-zero, "on", or "y" to enable the parasitic                                  power (2-wire, power-on-data) feature           extpullup                GPIO for external pullup (default "5") </pre>    <span style="color: #808080;"><strong>【驅動程式資訊】</strong></span> <span style="color: #ff0000;">※ 注意參數名稱<span style="color: #ff0000;">之匹配</span></span> <pre class="lang:sh decode:true">pi@raspberrypi ~ modinfo w1-gpio

# filename 指出位置
filename: /lib/modules/4.0.9-v7+/kernel/drivers/w1/masters/w1-gpio.ko
license: GPL
author: Ville Syrjala <syrjala@sci.fi>
description: GPIO w1 bus master driver
srcversion: 8F7F6F07E57EDD4CD8E19FB
alias: of:N*T*Cw1-gpio*
depends: wire
intree: Y
vermagic: 4.0.9-v7+ SMP preempt mod_unload modversions ARMv7

# 參數名稱
parm: pullup:Enable parasitic power (power on data) mode (int)
parm: extpullup:GPIO external pullup pin number (int)
parm: gpiopin:GPIO pin number (int)

 

【w1-gpio-overlay.dts】※ 注意檔案名稱與模組名稱差異

來源檔位置 linux-4d317a835a7b6354e41c2678507f2a894fdceb26
/arch/arm/boot/dts/overlays

目的檔位置 /boot/overlays/w1-gpio-overlay.dtb

// Definitions for w1-gpio module (without external pullup)
/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";

        fragment@0 {
                target-path = "/";
                __overlay__ {

                        w1: onewire@0 {
                                compatible = "w1-gpio";
                                pinctrl-names = "default";
                                pinctrl-0 = <&w1_pins>;
                                gpios = <&gpio 4 0>;
                                rpi,parasitic-power = <0>;
                                status = "okay";
                        };
                };
        };

        fragment@1 {
                target = <&gpio>;
                __overlay__ {
                        w1_pins: w1_pins {
                                brcm,pins = <4>;
                                brcm,function = <0>; // in (initially)
                                brcm,pull = <0>; // off
                        };
                };
        };

        __overrides__ {
                gpiopin =       <&w1>,"gpios:4",
                                <&w1_pins>,"brcm,pins:0";
                pullup =        <&w1>,"rpi,parasitic-power:0";
        };
};

 

【對比相關 w1-gpio-pullup-pullup-overlay.dts】

來源檔位置 linux-4d317a835a7b6354e41c2678507f2a894fdceb26
/arch/arm/boot/dts/overlays

目的檔位置 /boot/overlays/w1-gpio-pullup-overlay.dtb

// Definitions for w1-gpio module (with external pullup)
/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";

        fragment@0 {
                target-path = "/";
                __overlay__ {

                        w1: onewire@0 {
                                compatible = "w1-gpio";
                                pinctrl-names = "default";
                                pinctrl-0 = <&w1_pins>;
                                gpios = <&gpio 4 0>, <&gpio 5 1>;
                                rpi,parasitic-power = <0>;
                                status = "okay";
                        };
                };
        };

        fragment@1 {
                target = <&gpio>;
                __overlay__ {
                        w1_pins: w1_pins {
                                brcm,pins = <4 5>;
                                brcm,function = <0 1>; // in out
                                brcm,pull = <0 0>; // off off
                        };
                };
        };

        __overrides__ {
                gpiopin =       <&w1>,"gpios:4",
                                <&w1_pins>,"brcm,pins:0";
                extpullup =     <&w1>,"gpios:16",
                                <&w1_pins>,"brcm,pins:4";
                pullup =        <&w1>,"rpi,parasitic-power:0";
        };
};

 

【w1-gpio.c】驅動程式 ※ 注意 MODULE_PARM_DESC 之描述

來源檔位置 linux-4d317a835a7b6354e41c2678507f2a894fdceb26
/drivers/w1/masters

目的檔位置 /lib/modules/4.0.9-v7+/kernel/drivers/w1/masters/w1-gpio.ko

/*
 * w1-gpio - GPIO w1 bus master driver
 *
 * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/w1-gpio.h>
#include <linux/gpio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/delay.h>

#include "../w1.h"
#include "../w1_int.h"

static int w1_gpio_pullup = 0;
static int w1_gpio_pullup_orig = 0;
module_param_named(pullup, w1_gpio_pullup, int, 0);
MODULE_PARM_DESC(pullup, "Enable parasitic power (power on data) mode");
static int w1_gpio_pullup_pin = -1;
static int w1_gpio_pullup_pin_orig = -1;
module_param_named(extpullup, w1_gpio_pullup_pin, int, 0);
MODULE_PARM_DESC(extpullup, "GPIO external pullup pin number");
static int w1_gpio_pin = -1;
static int w1_gpio_pin_orig = -1;
module_param_named(gpiopin, w1_gpio_pin, int, 0);
MODULE_PARM_DESC(gpiopin, "GPIO pin number");
………

 

 

※ 註記︰ Kernel 4.1.5 已經發行。