Commit 1ed17e94b1aea32a988b4ca0f9213519de557bee

Authored by 김태훈
1 parent 05acf2c258
Exists in master

전주기 시연용 응용 프로그램 추가

go/src/fullcycle/analog-kernel/input-sample
@@ -0,0 +1,294 @@ @@ -0,0 +1,294 @@
  1 +[ 0.000000] Booting Linux on physical CPU 0x0
  2 +[ 0.000000] Linux version 4.9.80-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #1098 SMP Fri Mar 9 19:11:42 GMT 2018
  3 +[ 0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d
  4 +[ 0.000000] CPU: div instructions available: patching division code
  5 +[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
  6 +[ 0.000000] OF: fdt:Machine model: Raspberry Pi 3 Model B Rev 1.2
  7 +[ 0.000000] cma: Reserved 8 MiB at 0x3ac00000
  8 +[ 0.000000] Memory policy: Data cache writealloc
  9 +[ 0.000000] percpu: Embedded 14 pages/cpu @ba35b000 s25600 r8192 d23552 u57344
  10 +[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 240555
  11 +[ 0.000000] Kernel command line: 8250.nr_uarts=1 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 dwc_otg.lpm_enable=0 console=ttyS0,115200 console=tty1 root=PARTUUID=c80dc558-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
  12 +[ 0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)
  13 +[ 0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
  14 +[ 0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
  15 +[ 0.000000] Memory: 940364K/970752K available (7168K kernel code, 487K rwdata, 2032K rodata, 1024K init, 770K bss, 22196K reserved, 8192K cma-reserved)
  16 +[ 0.000000] Virtual kernel memory layout:
  17 +[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
  18 +[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
  19 +[ 0.000000] vmalloc : 0xbb800000 - 0xff800000 (1088 MB)
  20 +[ 0.000000] lowmem : 0x80000000 - 0xbb400000 ( 948 MB)
  21 +[ 0.000000] modules : 0x7f000000 - 0x80000000 ( 16 MB)
  22 +[ 0.000000] .text : 0x80008000 - 0x80800000 (8160 kB)
  23 +[ 0.000000] .init : 0x80b00000 - 0x80c00000 (1024 kB)
  24 +[ 0.000000] .data : 0x80c00000 - 0x80c79cbc ( 488 kB)
  25 +[ 0.000000] .bss : 0x80c7b000 - 0x80d3b9e4 ( 771 kB)
  26 +[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
  27 +[ 0.000000] Hierarchical RCU implementation.
  28 +[ 0.000000] Build-time adjustment of leaf fanout to 32.
  29 +[ 0.000000] NR_IRQS:16 nr_irqs:16 16
  30 +[ 0.000000] arm_arch_timer: Architected cp15 timer(s) running at 19.20MHz (phys).
  31 +[ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns
  32 +[ 0.000007] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps every 4398046511078ns
  33 +[ 0.000022] Switching to timer-based delay loop, resolution 52ns
  34 +[ 0.000301] Console: colour dummy device 80x30
  35 +[ 0.001189] console [tty1] enabled
  36 +[ 0.001237] Calibrating delay loop (skipped), value calculated using timer frequency.. 38.40 BogoMIPS (lpj=192000)
  37 +[ 0.001304] pid_max: default: 32768 minimum: 301
  38 +[ 0.001640] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes)
  39 +[ 0.001682] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes)
  40 +[ 0.002721] Disabling memory control group subsystem
  41 +[ 0.002825] CPU: Testing write buffer coherency: ok
  42 +[ 0.002889] ftrace: allocating 22627 entries in 67 pages
  43 +[ 0.050538] CPU0: update cpu_capacity 1024
  44 +[ 0.050590] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
  45 +[ 0.050651] Setting up static identity map for 0x100000 - 0x100034
  46 +[ 0.052502] CPU1: update cpu_capacity 1024
  47 +[ 0.052509] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
  48 +[ 0.053151] CPU2: update cpu_capacity 1024
  49 +[ 0.053158] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
  50 +[ 0.053782] CPU3: update cpu_capacity 1024
  51 +[ 0.053788] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
  52 +[ 0.053876] Brought up 4 CPUs
  53 +[ 0.054049] SMP: Total of 4 processors activated (153.60 BogoMIPS).
  54 +[ 0.054078] CPU: All CPU(s) started in HYP mode.
  55 +[ 0.054105] CPU: Virtualization extensions available.
  56 +[ 0.054925] devtmpfs: initialized
  57 +[ 0.066064] VFP support v0.3: implementor 41 architecture 3 part 40 variant 3 rev 4
  58 +[ 0.066387] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
  59 +[ 0.066447] futex hash table entries: 1024 (order: 4, 65536 bytes)
  60 +[ 0.067005] pinctrl core: initialized pinctrl subsystem
  61 +[ 0.067938] NET: Registered protocol family 16
  62 +[ 0.070178] DMA: preallocated 1024 KiB pool for atomic coherent allocations
  63 +[ 0.078975] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.
  64 +[ 0.079024] hw-breakpoint: maximum watchpoint size is 8 bytes.
  65 +[ 0.079206] Serial: AMBA PL011 UART driver
  66 +[ 0.081108] bcm2835-mbox 3f00b880.mailbox: mailbox enabled
  67 +[ 0.081656] uart-pl011 3f201000.serial: could not find pctldev for node /soc/gpio@7e200000/uart0_pins, deferring probe
  68 +[ 0.082020] irq: no irq domain found for /soc/aux@0x7e215000 !
  69 +[ 0.151380] bcm2835-dma 3f007000.dma: DMA legacy API manager at bb80d000, dmachans=0x1
  70 +[ 0.153246] SCSI subsystem initialized
  71 +[ 0.153569] usbcore: registered new interface driver usbfs
  72 +[ 0.153679] usbcore: registered new interface driver hub
  73 +[ 0.153796] usbcore: registered new device driver usb
  74 +[ 0.160347] raspberrypi-firmware soc:firmware: Attached to firmware from 2018-03-13 18:45
  75 +[ 0.161752] clocksource: Switched to clocksource arch_sys_counter
  76 +[ 0.209297] VFS: Disk quotas dquot_6.6.0
  77 +[ 0.209409] VFS: Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
  78 +[ 0.209638] FS-Cache: Loaded
  79 +[ 0.209906] CacheFiles: Loaded
  80 +[ 0.222053] NET: Registered protocol family 2
  81 +[ 0.222946] TCP established hash table entries: 8192 (order: 3, 32768 bytes)
  82 +[ 0.223084] TCP bind hash table entries: 8192 (order: 4, 65536 bytes)
  83 +[ 0.223295] TCP: Hash tables configured (established 8192 bind 8192)
  84 +[ 0.223407] UDP hash table entries: 512 (order: 2, 16384 bytes)
  85 +[ 0.223474] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
  86 +[ 0.223706] NET: Registered protocol family 1
  87 +[ 0.224139] RPC: Registered named UNIX socket transport module.
  88 +[ 0.224171] RPC: Registered udp transport module.
  89 +[ 0.224199] RPC: Registered tcp transport module.
  90 +[ 0.224226] RPC: Registered tcp NFSv4.1 backchannel transport module.
  91 +[ 0.225201] hw perfevents: enabled with armv7_cortex_a7 PMU driver, 7 counters available
  92 +[ 0.227516] workingset: timestamp_bits=14 max_order=18 bucket_order=4
  93 +[ 0.243575] FS-Cache: Netfs 'nfs' registered for caching
  94 +[ 0.244570] NFS: Registering the id_resolver key type
  95 +[ 0.244620] Key type id_resolver registered
  96 +[ 0.244648] Key type id_legacy registered
  97 +[ 0.247075] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
  98 +[ 0.247226] io scheduler noop registered
  99 +[ 0.247256] io scheduler deadline registered (default)
  100 +[ 0.247542] io scheduler cfq registered
  101 +[ 0.253205] BCM2708FB: allocated DMA memory fad10000
  102 +[ 0.253258] BCM2708FB: allocated DMA channel 0 @ bb80d000
  103 +[ 0.261949] Console: switching to colour frame buffer device 82x26
  104 +[ 0.269369] Serial: 8250/16550 driver, 1 ports, IRQ sharing enabled
  105 +[ 0.273301] bcm2835-rng 3f104000.rng: hwrng registered
  106 +[ 0.275682] vc-mem: phys_addr:0x00000000 mem_base=0x3ec00000 mem_size:0x40000000(1024 MiB)
  107 +[ 0.280940] vc-sm: Videocore shared memory driver
  108 +[ 0.298295] brd: module loaded
  109 +[ 0.309480] loop: module loaded
  110 +[ 0.311864] Loading iSCSI transport class v2.0-870.
  111 +[ 0.314857] libphy: Fixed MDIO Bus: probed
  112 +[ 0.317213] usbcore: registered new interface driver lan78xx
  113 +[ 0.319579] usbcore: registered new interface driver smsc95xx
  114 +[ 0.321831] dwc_otg: version 3.00a 10-AUG-2012 (platform bus)
  115 +[ 0.552154] Core Release: 2.80a
  116 +[ 0.554363] Setting default values for core params
  117 +[ 0.556552] Finished setting default values for core params
  118 +[ 0.759140] Using Buffer DMA mode
  119 +[ 0.761337] Periodic Transfer Interrupt Enhancement - disabled
  120 +[ 0.763656] Multiprocessor Interrupt Enhancement - disabled
  121 +[ 0.765971] OTG VER PARAM: 0, OTG VER FLAG: 0
  122 +[ 0.768319] Dedicated Tx FIFOs mode
  123 +[ 0.770929] WARN::dwc_otg_hcd_init:1032: FIQ DMA bounce buffers: virt = 0xbad04000 dma = 0xfad04000 len=9024
  124 +[ 0.775666] FIQ FSM acceleration enabled for :
  125 +[ 0.775666] Non-periodic Split Transactions
  126 +[ 0.775666] Periodic Split Transactions
  127 +[ 0.775666] High-Speed Isochronous Endpoints
  128 +[ 0.775666] Interrupt/Control Split Transaction hack enabled
  129 +[ 0.786746] WARN::hcd_init_fiq:459: FIQ on core 1 at 0x8059b380
  130 +[ 0.789026] WARN::hcd_init_fiq:460: FIQ ASM at 0x8059b6f0 length 36
  131 +[ 0.791285] WARN::hcd_init_fiq:486: MPHI regs_base at 0xbb878000
  132 +[ 0.793550] dwc_otg 3f980000.usb: DWC OTG Controller
  133 +[ 0.795866] dwc_otg 3f980000.usb: new USB bus registered, assigned bus number 1
  134 +[ 0.798224] dwc_otg 3f980000.usb: irq 62, io mem 0x00000000
  135 +[ 0.800538] Init: Port Power? op_state=1
  136 +[ 0.802811] Init: Power Port (0)
  137 +[ 0.805198] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
  138 +[ 0.807508] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
  139 +[ 0.809802] usb usb1: Product: DWC OTG Controller
  140 +[ 0.812061] usb usb1: Manufacturer: Linux 4.9.80-v7+ dwc_otg_hcd
  141 +[ 0.814327] usb usb1: SerialNumber: 3f980000.usb
  142 +[ 0.817410] hub 1-0:1.0: USB hub found
  143 +[ 0.819607] hub 1-0:1.0: 1 port detected
  144 +[ 0.822544] usbcore: registered new interface driver usb-storage
  145 +[ 0.824871] mousedev: PS/2 mouse device common for all mice
  146 +[ 0.827965] bcm2835-wdt 3f100000.watchdog: Broadcom BCM2835 watchdog timer
  147 +[ 0.830488] bcm2835-cpufreq: min=600000 max=1200000
  148 +[ 0.833165] sdhci: Secure Digital Host Controller Interface driver
  149 +[ 0.835478] sdhci: Copyright(c) Pierre Ossman
  150 +[ 0.838000] sdhost-bcm2835 3f202000.sdhost: could not get clk, deferring probe
  151 +[ 0.842594] mmc-bcm2835 3f300000.mmc: could not get clk, deferring probe
  152 +[ 0.845137] sdhci-pltfm: SDHCI platform and OF driver helper
  153 +[ 0.849016] ledtrig-cpu: registered to indicate activity on CPUs
  154 +[ 0.851668] hidraw: raw HID events driver (C) Jiri Kosina
  155 +[ 0.854366] usbcore: registered new interface driver usbhid
  156 +[ 0.856826] usbhid: USB HID core driver
  157 +[ 0.860069] vchiq: vchiq_init_state: slot_zero = 0xbad80000, is_master = 0
  158 +[ 0.863954] [vc_sm_connected_init]: start
  159 +[ 0.872620] [vc_sm_connected_init]: end - returning 0
  160 +[ 0.875442] Initializing XFRM netlink socket
  161 +[ 0.877894] NET: Registered protocol family 17
  162 +[ 0.880431] Key type dns_resolver registered
  163 +[ 0.883248] Registering SWP/SWPB emulation handler
  164 +[ 0.886437] registered taskstats version 1
  165 +[ 0.895220] uart-pl011 3f201000.serial: cts_event_workaround enabled
  166 +[ 0.897794] 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 87, base_baud = 0) is a PL011 rev2
  167 +[ 0.904299] console [ttyS0] disabled
  168 +[ 0.906753] 3f215040.serial: ttyS0 at MMIO 0x0 (irq = 220, base_baud = 31250000) is a 16550
  169 +[ 1.899569] console [ttyS0] enabled
  170 +[ 1.906298] sdhost: log_buf @ bad07000 (fad07000)
  171 +[ 1.991780] mmc0: sdhost-bcm2835 loaded - DMA enabled (>1)
  172 +[ 2.001958] mmc-bcm2835 3f300000.mmc: mmc_debug:0 mmc_debug2:0
  173 +[ 2.010292] mmc-bcm2835 3f300000.mmc: DMA channel allocated
  174 +[ 2.039017] Indeed it is in host mode hprt0 = 00021501
  175 +[ 2.131876] of_cfs_init
  176 +[ 2.133893] random: fast init done
  177 +[ 2.142450] of_cfs_init: OK
  178 +[ 2.147979] Waiting for root device PARTUUID=c80dc558-02...
  179 +[ 2.151869] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
  180 +[ 2.153435] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
  181 +[ 2.155002] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
  182 +[ 2.157820] mmc1: queuing unknown CIS tuple 0x80 (7 bytes)
  183 +[ 2.213728] mmc0: host does not support reading read-only switch, assuming write-enable
  184 +[ 2.232871] mmc0: new high speed SDHC card at address aaaa
  185 +[ 2.241224] mmcblk0: mmc0:aaaa SC16G 14.8 GiB
  186 +[ 2.247801] usb 1-1: new high-speed USB device number 2 using dwc_otg
  187 +[ 2.256822] Indeed it is in host mode hprt0 = 00001101
  188 +[ 2.329935] mmcblk0: p1 p2
  189 +[ 2.357583] mmc1: new high speed SDIO card at address 0001
  190 +[ 2.427039] EXT4-fs (mmcblk0p2): INFO: recovery required on readonly filesystem
  191 +[ 2.436690] EXT4-fs (mmcblk0p2): write access will be enabled during recovery
  192 +[ 2.458484] EXT4-fs (mmcblk0p2): recovery complete
  193 +[ 2.467210] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
  194 +[ 2.479804] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
  195 +[ 2.492049] usb 1-1: New USB device found, idVendor=0424, idProduct=9514
  196 +[ 2.500151] devtmpfs: mounted
  197 +[ 2.506664] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
  198 +[ 2.518166] Freeing unused kernel memory: 1024K
  199 +[ 2.526223] hub 1-1:1.0: USB hub found
  200 +[ 2.532766] hub 1-1:1.0: 5 ports detected
  201 +[ 2.851799] usb 1-1.1: new high-speed USB device number 3 using dwc_otg
  202 +[ 2.960961] systemd[1]: System time before build time, advancing clock.
  203 +[ 2.982100] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00
  204 +[ 2.991832] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
  205 +[ 3.004854] smsc95xx v1.0.5
  206 +[ 3.081379] NET: Registered protocol family 10
  207 +[ 3.102250] ip_tables: (C) 2000-2006 Netfilter Core Team
  208 +[ 3.105781] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-3f980000.usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:d1:b3:bf
  209 +[ 3.152858] systemd[1]: systemd 232 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
  210 +[ 3.180405] systemd[1]: Detected architecture arm.
  211 +[ 3.204807] systemd[1]: Set hostname to <raspberrypi>.
  212 +[ 3.655243] systemd[1]: Listening on udev Kernel Socket.
  213 +[ 3.666913] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
  214 +[ 3.683625] systemd[1]: Listening on Journal Socket.
  215 +[ 3.694815] systemd[1]: Listening on Syslog Socket.
  216 +[ 3.706356] systemd[1]: Created slice System Slice.
  217 +[ 3.719823] systemd[1]: Mounting RPC Pipe File System...
  218 +[ 3.735831] systemd[1]: Starting Restore / save the current clock...
  219 +[ OK ] Started Show Plymouth Boot Screen.
  220 +[ OK ] Reached target Encrypted Volumes.
  221 +[ OK ] Reached target Paths.
  222 +[ OK ] Started Forward Password Requests to Plymouth Directory Watch.
  223 +[ OK ] Started File System Check on /dev/disk/by-partuuid/c80dc558-01.
  224 + Mounting /boot...
  225 +[ OK ] Mounted /boot.
  226 +[ OK ] Reached target Local File Systems.
  227 + Starting Set console font and keymap...
  228 + Starting Tell Plymouth To Write Out Runtime Data...
  229 + Starting Raise network interfaces...
  230 + Starting Preprocess NFS configuration...
  231 + Starting Create Volatile Files and Directories...
  232 +[ OK ] Started Tell Plymouth To Write Out Runtime Data.
  233 +[ OK ] Started Preprocess NFS configuration.
  234 +[ OK ] Reached target NFS client services.
  235 +[ OK ] Reached target Remote File Systems (Pre).
  236 +[ OK ] Reached target Remote File Systems.
  237 +[ OK ] Started Create Volatile Files and Directories.
  238 + Starting Network Time Synchronization...
  239 + Starting Update UTMP about System Boot/Shutdown...
  240 +[ OK ] Started Update UTMP about System Boot/Shutdown.
  241 +[ OK ] Started Network Time Synchronization.
  242 +[ OK ] Reached target System Initialization.
  243 +[ OK ] Listening on triggerhappy.socket.
  244 +[ OK ] Listening on Avahi mDNS/DNS-SD Stack Activation Socket.
  245 +[ OK ] Listening on D-Bus System Message Bus Socket.
  246 +[ OK ] Reached target Sockets.
  247 +[ OK ] Reached target Basic System.
  248 + Starting LSB: Switch to ondemand cpu…or (unless shift key is pressed)...
  249 + Starting System Logging Service...
  250 + Starting LSB: Autogenerate and use a swap file...
  251 +[ OK ] Started Regular background program processing daemon.
  252 + Starting dhcpcd on all interfaces...
  253 + Starting triggerhappy global hotkey daemon...
  254 + Starting Save/Restore Sound Card State...
  255 + Starting Configure Bluetooth Modems connected by UART...
  256 + Starting Avahi mDNS/DNS-SD Stack...
  257 +[ OK ] Started D-Bus System Message Bus.
  258 +[ OK ] Started Avahi mDNS/DNS-SD Stack.
  259 + Starting Disable WiFi if country not set...
  260 +[ OK ] Started Daily Cleanup of Temporary Directories.
  261 + Starting Login Service...
  262 +[ OK ] Reached target System Time Synchronized.
  263 +[ OK ] Started Daily apt download activities.
  264 +[ OK ] Started Daily apt upgrade and clean activities.
  265 +[ OK ] Reached target Timers.
  266 +[ OK ] Started triggerhappy global hotkey daemon.
  267 +[ OK ] Started System Logging Service.
  268 +[ OK ] Started Save/Restore Sound Card State.
  269 +[ OK ] Started Disable WiFi if country not set.
  270 + Starting Load/Save RF Kill Switch Status...
  271 +[ OK ] Started Login Service.
  272 +[ OK ] Started Raise network interfaces.
  273 +[ OK ] Started LSB: Switch to ondemand cpu …rnor (unless shift key is pressed).
  274 +[ OK ] Started Load/Save RF Kill Switch Status.
  275 +[ OK ] Started LSB: Autogenerate and use a swap file.
  276 +[ OK ] Started Configure Bluetooth Modems connected by UART.
  277 + Starting Bluetooth service...
  278 +[ OK ] Started Bluetooth service.
  279 +[ OK ] Reached target Bluetooth.
  280 + Starting Hostname Service...
  281 +[ OK ] Started Hostname Service.
  282 +[ OK ] Started Set console font and keymap.
  283 +[ OK ] Started dhcpcd on all interfaces.
  284 +[ OK ] Reached target Network.
  285 + Starting /etc/rc.local Compatibility...
  286 + Starting Permit User Sessions...
  287 +[ OK ] Started /etc/rc.local Compatibility.
  288 +[ OK ] Started Permit User Sessions.
  289 + Starting Terminate Plymouth Boot Screen...
  290 + Starting Hold until boot process finishes up...
  291 +
  292 +Raspbian GNU/Linux 9 raspberrypi ttyS0
  293 +raspberrypi login:
  294 +end of kernel
go/src/fullcycle/analog-kernel/main.go
@@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
  1 +package main
  2 +
  3 +import (
  4 + "bufio"
  5 + "encoding/json"
  6 + "fmt"
  7 + "io/ioutil"
  8 + "log"
  9 + "os"
  10 +
  11 + "fullcycle/analog-kernel/parser"
  12 +)
  13 +
  14 +const defaultResult = `
  15 +{
  16 + "result": {
  17 + "cpu" : {
  18 + "name": "ARMv7 Processor",
  19 + "id": "410fd034",
  20 + "revision": "4",
  21 + "arch": "ARMv7",
  22 + "cr": "10c5383d"
  23 + },
  24 +
  25 + "model" : {
  26 + "model": "Raspberry Pi 3 Model B Rev 1.2"
  27 + }
  28 + },
  29 +
  30 + "report": {
  31 + "log_id": "012-3233-4423",
  32 + "date": "2018/04/18",
  33 +
  34 + "target": "raspberry pi3",
  35 + "hardware": [
  36 + {
  37 + "title": "CPU",
  38 + "result": "PASS"
  39 + },
  40 + {
  41 + "title": "Memory",
  42 + "result": "FAIL",
  43 + "message": "Not found in booting log messages"
  44 + }
  45 + ],
  46 +
  47 + "os": [
  48 + ],
  49 +
  50 + "device": [
  51 + ]
  52 + }
  53 +}
  54 +`
  55 +
  56 +func check(err error) {
  57 + if err != nil {
  58 + log.Fatal(err)
  59 + }
  60 +}
  61 +
  62 +var uuid string
  63 +
  64 +func init() {
  65 + if len(os.Args) == 1 {
  66 + fmt.Fprintf(os.Stderr, "Usage: %v <UUID>\n", os.Args[0])
  67 + os.Exit(1)
  68 + }
  69 +
  70 + uuid = os.Args[1]
  71 +}
  72 +
  73 +func main() {
  74 + var r parser.Request
  75 +
  76 + // Read the sheet.
  77 + fname := fmt.Sprintf("sheet-%v.json", uuid)
  78 + b, err := ioutil.ReadFile(fname)
  79 + check(err)
  80 +
  81 + err = json.Unmarshal(b, &r.Sheet)
  82 + check(err)
  83 +
  84 + // Read stdin.
  85 + s := bufio.NewScanner(os.Stdin)
  86 + for s.Scan() {
  87 + if l := s.Text(); l == "end of kernel" {
  88 + break
  89 + } else {
  90 + r.Log = append(r.Log, l)
  91 + }
  92 + }
  93 +
  94 + // Parse.
  95 + p := parser.New()
  96 + result := p.Parse(&r)
  97 +
  98 + // Print.
  99 + fmt.Print(result)
  100 +}
go/src/fullcycle/analog-kernel/parser/device.go
@@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
  1 +package parser
  2 +
  3 +import "regexp"
  4 +
  5 +type deviceTableElement struct {
  6 + name string
  7 + reString string
  8 + re *regexp.Regexp
  9 +}
  10 +
  11 +var deviceTable = []deviceTableElement{
  12 + {"AMBA PL011 UART Device", "Serial: AMBA PL011 UART driver", nil},
  13 + {"BCM2835 Mailbox", "bcm2835-mbox[[:print:]]+mailbox enabled", nil},
  14 + {"BCM2835 DMA", "bcm2835-dma[[:print:]]+DMA legacy API manager", nil},
  15 + {"RaspberryPi Firmware", "raspberrypi-firmware soc:firmware: Attached to firmware", nil},
  16 + {"BCM2708FB", "BCM2708FB: allocated DMA memory", nil},
  17 + {"BCM2835 RNG", "bcm2835-rng[[:print:]]+hwrng registered", nil},
  18 + {"Videocore Memory", "vc-mem: phys_addr:", nil},
  19 + {"Videocore Shared Memory", "vc-sm: Videocore shared memory driver", nil},
  20 + {"Microchip LAN78XX Based USB Ethernet Adapter", "new interface driver lan78xx", nil},
  21 + {"SMSC LAN95XX Based USB 2.0 10/100 Ethernet Device", "new interface driver smsc95xx", nil},
  22 + {"DesignWare OTG", "dwc_otg: version ", nil},
  23 + {"USB Mass Storage", "new interface driver usb-storage", nil},
  24 + {"BCM2835 Watchdog Timer", "bcm2835-wdt[[:print:]]+Broadcom BCM2835 watchdog timer", nil},
  25 + {"BCM2835 CPU Frequency Scaler", "bcm2835-cpufreq: min=", nil},
  26 + {"Secure Digital Host Controller Interface", "sdhci: Secure Digital Host Controller Interface driver", nil},
  27 + {"8250/16550 Serial Device", "Serial: 8250/16550 driver", nil},
  28 + {"SDHC Card", "new high speed SDHC card", nil},
  29 + {"SDIO Card", "new high speed SDIO card", nil},
  30 + {"S3C Power Management", "S3C Power Management, Copyright 2004 Simtec Electronics", nil},
  31 + {"SCSI subsystem", "SCSI subsystem initialized", nil},
  32 + {"ARM Mali", "Mali: Mali device driver loaded", nil},
  33 + {"Generic vibrator", "vibrator_init: vibrator", nil},
  34 + {"Broadcom Dongle Host Driver", "dhd_module_init in", nil},
  35 + {"Intel® Performance Counter Monitor", "intel_pmu_driver [[:print:]]+: after pmu initialization", nil},
  36 + {"Generic Wi-Fi", "found wifi platform device wlan", nil},
  37 + {"Broadcom SDIO", "bcmsdh_sdmmc: bcmsdh_sdmmc_probe Enter", nil},
  38 + {"s3c64xx SPI", "s3c64xx-spi 13920000.spi: spi bus clock parent not specified, using clock at index 0 as parent", nil},
  39 + {"NLS-HR22", "hid-generic [0-9]+:1EAB:1A03.[0-9]+: input,hidraw[0-9]+: USB HID v1.00 Keyboard", nil},
  40 + {"CP210X", "cp210x [0-9]+-[0-9]+.[0-9]+:[0-9]+.[0-9]+: cp210x converter detected", nil},
  41 + {"NetWinder Floating Point Emulator", "NetWinder Floating Point Emulator", nil},
  42 + {"Block layer SCSI generic", "Block layer SCSI generic \\(bsg\\) driver", nil},
  43 + {"SCSI Media Changer", "SCSI Media Changer driver", nil},
  44 + {"Nuvoton NUC970 EHCI Host Controller", "Nuvoton NUC970 EHCI Host Controller", nil},
  45 + {"Nuvoton NUC970 OHCI Host Controller", "Nuvoton NUC970 OHCI Host Controller", nil},
  46 + {"Wireless RNDIS USB", "new interface driver rndis_wlan", nil},
  47 + {"ASIX AX88xxx Based USB 2.0 Ethernet Adapters", "new interface driver asix", nil},
  48 + {"ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet", "new interface driver ax88179_178a", nil},
  49 + {"CDC Ethernet", "new interface driver cdc_ether", nil},
  50 + {"CDC EEM", "new interface driver cdc_eem", nil},
  51 + {"NetChip 1080 based cables (Laplink, ...)", "new interface driver net1080", nil},
  52 + {"Host for RNDIS and ActiveSync devices", "new interface driver rndis_host", nil},
  53 + {"Simple USB Network Links (CDC Ethernet subset)", "new interface driver cdc_subset", nil},
  54 + {"Sharp Zaurus (stock ROMs) and compatible", "new interface driver zaurus", nil},
  55 + {"CDC NCM", "new interface driver cdc_ncm", nil},
  56 + {"CDC MBIM", "new interface driver cdc_mbim", nil},
  57 + {"I2C EEPROM", "at24 .* EEPROM", nil},
  58 +}
  59 +
  60 +func init() {
  61 + for i, e := range deviceTable {
  62 + deviceTable[i].re = regexp.MustCompile(e.reString)
  63 + }
  64 +}
go/src/fullcycle/analog-kernel/parser/parse.go
@@ -0,0 +1,586 @@ @@ -0,0 +1,586 @@
  1 +package parser
  2 +
  3 +import (
  4 + "regexp"
  5 + "strconv"
  6 + "strings"
  7 +)
  8 +
  9 +var parseFuncList = []func(chan string, chan jsonObject){
  10 + parseMemory,
  11 + parseMemoryLayout,
  12 + parseTimestamps,
  13 + parseStatus,
  14 + parseHashTables,
  15 + parseLinux,
  16 + parseCpu,
  17 + parseModel,
  18 + parseDeviceFound,
  19 + parseKernelCommandLine,
  20 + parseCma,
  21 + parseSlub,
  22 + parsePidMax,
  23 + parseWorkingset,
  24 +}
  25 +
  26 +var reTimestamp = regexp.MustCompile(`^\[[[:blank:]]*[[:digit:]]+\.[[:digit:]]+[[:blank:]]*\]`)
  27 +var reAddress = regexp.MustCompile(`0x[[:xdigit:]]+`)
  28 +
  29 +func parseMemory(lines chan string, chanOutput chan jsonObject) {
  30 + m := make(jsonObject)
  31 + m["type"] = "memory"
  32 +
  33 + rLine := regexp.MustCompile("Memory: [[:ascii:]]+ available")
  34 + rBytes := regexp.MustCompile("[[:digit:]]+[Kk]")
  35 + for line := range lines {
  36 + if found := rLine.FindString(line); found != "" {
  37 + r := rBytes.FindAllString(line, 2)
  38 + m["available"] = r[0]
  39 + m["total"] = r[1]
  40 + chanOutput <- m
  41 + return
  42 + }
  43 + }
  44 +
  45 + m["available"] = ""
  46 + m["total"] = ""
  47 +
  48 + chanOutput <- m
  49 +}
  50 +
  51 +func parseMemoryLayout(lines chan string, chanOutput chan jsonObject) {
  52 + rHeaderArm := regexp.MustCompile("Virtual kernel memory layout:")
  53 + rHeaderX86 := regexp.MustCompile("Zone ranges:")
  54 + for line := range lines {
  55 + if rHeaderArm.MatchString(line) {
  56 + parseMemoryLayoutArm(lines, chanOutput)
  57 + return
  58 + }
  59 +
  60 + if rHeaderX86.MatchString(line) {
  61 + parseMemoryLayoutX86(lines, chanOutput)
  62 + return
  63 + }
  64 + }
  65 +
  66 + m := make(jsonObject)
  67 + m["type"] = "memory_layout"
  68 + m["layout"] = make([]jsonObject, 0)
  69 +
  70 + chanOutput <- m
  71 +}
  72 +
  73 +func parseMemoryLayoutArm(lines chan string, chanOutput chan jsonObject) {
  74 + m := make(jsonObject)
  75 + m["type"] = "memory_layout"
  76 + m["layout"] = make([]jsonObject, 0)
  77 +
  78 + rLine := regexp.MustCompile(`[[:print:]]+:[[:blank:]]*0x[[:xdigit:]]+[[:blank:]]*-[[:blank:]]*0x[[:xdigit:]]+`)
  79 + rLabel := regexp.MustCompile(`[[:graph:]]+`)
  80 +
  81 + for line := range lines {
  82 + line = removeTimestamp(line)
  83 + if rLine.MatchString(line) {
  84 + item := make(jsonObject)
  85 + item["label"] = rLabel.FindString(line)
  86 +
  87 + r := reAddress.FindAllString(line, 2)
  88 + item["from"] = r[0]
  89 + item["to"] = r[1]
  90 +
  91 + m["layout"] = append(m["layout"].([]jsonObject), item)
  92 + } else {
  93 + break
  94 + }
  95 + }
  96 +
  97 + chanOutput <- m
  98 +}
  99 +
  100 +func parseMemoryLayoutX86(lines chan string, chanOutput chan jsonObject) {
  101 + m := make(jsonObject)
  102 + m["type"] = "memory_layout"
  103 + m["layout"] = make([]jsonObject, 0)
  104 +
  105 + rLine := regexp.MustCompile(`[[:print:]]+\[mem[[:blank:]]+0x[[:xdigit:]]+-0x[[:xdigit:]]+\]`)
  106 + rLabel := regexp.MustCompile(`[[:graph:]]+`)
  107 +
  108 + for line := range lines {
  109 + line = removeTimestamp(line)
  110 + if rLine.MatchString(line) {
  111 + item := make(jsonObject)
  112 + item["label"] = rLabel.FindString(line)
  113 +
  114 + r := reAddress.FindAllString(line, 2)
  115 + item["from"] = r[0]
  116 + item["to"] = r[1]
  117 +
  118 + m["layout"] = append(m["layout"].([]jsonObject), item)
  119 + } else {
  120 + break
  121 + }
  122 + }
  123 +
  124 + chanOutput <- m
  125 +}
  126 +
  127 +func parseTimestamps(lines chan string, chanOutput chan jsonObject) {
  128 + rVal := regexp.MustCompile(`[[:digit:]]+\.[[:digit:]]+`)
  129 +
  130 + list := make(jsonArray, 0)
  131 + for line := range lines {
  132 + if reTimestamp.MatchString(line) {
  133 + t := reTimestamp.FindString(line)
  134 + v := rVal.FindString(t)
  135 + f, _ := strconv.ParseFloat(v, 64)
  136 + list = append(list, f)
  137 + }
  138 + }
  139 +
  140 + m := make(jsonObject)
  141 + m["type"] = "timestamps"
  142 + m["timestamps"] = list
  143 +
  144 + chanOutput <- m
  145 +}
  146 +
  147 +func parseStatus(lines chan string, chanOutput chan jsonObject) {
  148 + rLine := regexp.MustCompile(`^\[[[:blank:]]*(OK|FAIL)[[:blank:]]*\][[:blank:]]+`)
  149 + rOk := regexp.MustCompile(`^\[[[:blank:]]*OK[[:blank:]]*\]`)
  150 +
  151 + list := make([]jsonObject, 0)
  152 + for line := range lines {
  153 + if rLine.MatchString(line) {
  154 + item := make(jsonObject)
  155 + if rOk.MatchString(line) {
  156 + item["status"] = "ok"
  157 + } else {
  158 + item["status"] = "fail"
  159 + }
  160 +
  161 + prefix := rLine.FindString(line)
  162 + label := strings.TrimPrefix(line, prefix)
  163 + item["label"] = label
  164 +
  165 + list = append(list, item)
  166 + }
  167 + }
  168 +
  169 + m := make(jsonObject)
  170 + m["type"] = "status"
  171 + m["list"] = list
  172 +
  173 + chanOutput <- m
  174 +}
  175 +
  176 +func parseHashTables(lines chan string, chanOutput chan jsonObject) {
  177 + rLine := regexp.MustCompile(`[[:graph:]]+ hash table entries:`)
  178 +
  179 + list := make([]jsonObject, 0)
  180 + for line := range lines {
  181 + if rLine.MatchString(line) {
  182 + line = removeTimestamp(line)
  183 +
  184 + item := make(jsonObject)
  185 +
  186 + label := regexp.MustCompile(`[[:print:]]+ hash table entries:`).FindString(line)
  187 +
  188 + item["label"] = strings.TrimSuffix(label, " hash table entries:")
  189 +
  190 + entries := regexp.MustCompile(`hash table entries: [[:digit:]]+`).FindString(line)
  191 + entries = strings.TrimPrefix(entries, "hash table entries: ")
  192 +
  193 + item["entries"], _ = strconv.ParseInt(entries, 10, 64)
  194 +
  195 + order := regexp.MustCompile(`order:? [[:digit:]-]+`).FindString(line)
  196 + orderPrefix := regexp.MustCompile(`order:? `).FindString(order)
  197 + order = strings.TrimPrefix(order, orderPrefix)
  198 +
  199 + item["order"], _ = strconv.ParseInt(order, 10, 64)
  200 +
  201 + size := regexp.MustCompile(`[[:digit:]]+ bytes`).FindString(line)
  202 + size = strings.TrimSuffix(size, " bytes")
  203 +
  204 + item["size"], _ = strconv.ParseInt(size, 10, 64)
  205 +
  206 + list = append(list, item)
  207 + }
  208 + }
  209 +
  210 + m := make(jsonObject)
  211 + m["type"] = "hash_tables"
  212 + m["list"] = list
  213 +
  214 + chanOutput <- m
  215 +}
  216 +
  217 +func parseLinux(lines chan string, chanOutput chan jsonObject) {
  218 + m := make(jsonObject)
  219 + m["type"] = "linux"
  220 + m["version"] = ""
  221 + m["builder"] = ""
  222 + m["toolchain"] = ""
  223 + m["label"] = ""
  224 +
  225 + rLine := regexp.MustCompile(`Linux version[[:blank:]]+[[:graph:]]+[[:blank:]]+([[:print:]]+)[[:blank:]]+([[:print:]]+)[[:blank:]]+#[[:print:]]+`)
  226 + for line := range lines {
  227 + if rLine.MatchString(line) {
  228 + line = rLine.FindString(line)
  229 + line = strings.TrimPrefix(line, "Linux version ")
  230 +
  231 + m["version"] = regexp.MustCompile(`[[:graph:]]+`).FindString(line)
  232 + m["os"] = "linux"
  233 +
  234 + bracketed := regexp.MustCompile(`\([[:print:]]+?\)`).FindAllString(line, 2)
  235 + for i, s := range bracketed {
  236 + switch i {
  237 + case 0:
  238 + m["builder"] = removeBrackets(s)
  239 + case 1:
  240 + m["toolchain"] = removeBrackets(s)
  241 + }
  242 + }
  243 +
  244 + m["label"] = regexp.MustCompile(`#[[:print:]]+`).FindString(line)
  245 +
  246 + break
  247 + }
  248 + }
  249 +
  250 + chanOutput <- m
  251 +}
  252 +
  253 +func parseCpu(lines chan string, chanOutput chan jsonObject) {
  254 + m := make(jsonObject)
  255 + m["type"] = "cpu"
  256 + m["name"] = ""
  257 + m["id"] = ""
  258 + m["revision"] = ""
  259 + m["arch"] = ""
  260 + m["cr"] = ""
  261 + m["data_cache"] = ""
  262 + m["instruction_cache"] = ""
  263 +
  264 + rLine1 := regexp.MustCompile(`CPU:[[:blank:]]+[[:print:]]+[[:blank:]]+\[[[:xdigit:]]+\][[:blank:]]+revision[[:blank:]]+[[:digit:]][[:blank:]]+\([[:print:]]+\), cr=[[:xdigit:]]+`)
  265 + rLine2 := regexp.MustCompile(`CPU:[[:blank:]]+[[:print:]]+[[:blank:]]+data cache,[[:blank:]]+[[:print:]]+[[:blank:]]+instruction cache`)
  266 + for line := range lines {
  267 + if rLine1.MatchString(line) {
  268 + line = rLine1.FindString(line)
  269 + line = strings.TrimPrefix(line, "CPU: ")
  270 +
  271 + name := regexp.MustCompile(`[[:print:]]+\[`).FindString(line)
  272 + name = strings.TrimSuffix(name, "[")
  273 + name = strings.TrimSpace(name)
  274 +
  275 + m["name"] = name
  276 +
  277 + id := regexp.MustCompile(`\[[[:xdigit:]]+\]`).FindString(line)
  278 + id = strings.TrimPrefix(id, "[")
  279 + id = strings.TrimSuffix(id, "]")
  280 +
  281 + m["id"] = id
  282 +
  283 + revision := regexp.MustCompile(`revision[[:blank:]]+[[:digit:]]+`).FindString(line)
  284 + revision = strings.TrimPrefix(revision, "revision")
  285 + revision = strings.TrimSpace(revision)
  286 +
  287 + m["revision"] = revision
  288 +
  289 + arch := regexp.MustCompile(`\([[:print:]]+\)`).FindString(line)
  290 + arch = strings.TrimPrefix(arch, "(")
  291 + arch = strings.TrimSuffix(arch, ")")
  292 + arch = strings.TrimSpace(arch)
  293 +
  294 + m["arch"] = arch
  295 +
  296 + cr := regexp.MustCompile(`cr=[[:xdigit:]]+`).FindString(line)
  297 + cr = strings.TrimPrefix(cr, "cr=")
  298 +
  299 + m["cr"] = cr
  300 + } else if rLine2.MatchString(line) {
  301 + line = rLine2.FindString(line)
  302 + line = strings.TrimPrefix(line, `CPU: `)
  303 +
  304 + dataCache := regexp.MustCompile(`[[:print:]]+data cache`).FindString(line)
  305 + dataCache = strings.TrimSuffix(dataCache, "data cache")
  306 + dataCache = strings.TrimSpace(dataCache)
  307 +
  308 + m["data_cache"] = dataCache
  309 +
  310 + instructionCache := regexp.MustCompile(`,[[:print:]]+instruction cache`).FindString(line)
  311 + instructionCache = strings.TrimPrefix(instructionCache, ",")
  312 + instructionCache = strings.TrimSuffix(instructionCache, "instruction cache")
  313 + instructionCache = strings.TrimSpace(instructionCache)
  314 +
  315 + m["instruction_cache"] = instructionCache
  316 + }
  317 + }
  318 +
  319 + chanOutput <- m
  320 +}
  321 +
  322 +func parseModel(lines chan string, chanOutput chan jsonObject) {
  323 + m := make(jsonObject)
  324 + m["type"] = "model"
  325 + m["model"] = ""
  326 +
  327 + rLine := regexp.MustCompile(`(Machine model: [[:print:]]+)|(Machine: [[:print:]]+)`)
  328 + rLineEdison := regexp.MustCompile(`Linux version[[:print:]]+edison`)
  329 + rLineARTIK := regexp.MustCompile(`CPU EXYNOS3250`)
  330 + for line := range lines {
  331 + if rLine.MatchString(line) {
  332 + line = rLine.FindString(line)
  333 + line = strings.TrimPrefix(line, "Machine model: ")
  334 + line = strings.TrimPrefix(line, "Machine: ")
  335 +
  336 + m["model"] = strings.TrimSpace(line)
  337 +
  338 + break
  339 + } else if rLineEdison.MatchString(line) {
  340 + m["model"] = "Intel Edison"
  341 +
  342 + break
  343 + } else if rLineARTIK.MatchString(line) {
  344 + m["model"] = "SAMSUNG ARTIK5"
  345 +
  346 + break
  347 + }
  348 + }
  349 +
  350 + chanOutput <- m
  351 +}
  352 +
  353 +func parseDeviceFound(lines chan string, chanOutput chan jsonObject) {
  354 + list := make([]string, 0)
  355 + for line := range lines {
  356 + for _, e := range deviceTable {
  357 + if e.re.MatchString(line) {
  358 + list = append(list, e.name)
  359 + }
  360 + }
  361 + }
  362 +
  363 + m := make(jsonObject)
  364 + m["type"] = "device_found"
  365 + m["list"] = list
  366 +
  367 + chanOutput <- m
  368 +}
  369 +
  370 +func parseKernelCommandLine(lines chan string, chanOutput chan jsonObject) {
  371 + m := make(jsonObject)
  372 + m["type"] = "kernel_command_line"
  373 + m["kernel_command_line"] = ""
  374 +
  375 + rLine := regexp.MustCompile("Kernel command line: [[:print:]]+")
  376 + for line := range lines {
  377 + if rLine.MatchString(line) {
  378 + line = rLine.FindString(line)
  379 +
  380 + cmdline := strings.TrimPrefix(line, "Kernel command line: ")
  381 + cmdline = strings.TrimSpace(cmdline)
  382 + if strings.HasPrefix(cmdline, `"`) && strings.HasSuffix(cmdline, `"`) {
  383 + cmdline = strings.TrimPrefix(cmdline, `"`)
  384 + cmdline = strings.TrimSuffix(cmdline, `"`)
  385 + }
  386 +
  387 + m["kernel_command_line"] = cmdline
  388 +
  389 + break
  390 + }
  391 + }
  392 +
  393 + chanOutput <- m
  394 +}
  395 +
  396 +func parseCma(lines chan string, chanOutput chan jsonObject) {
  397 + m := make(jsonObject)
  398 + m["type"] = "cma"
  399 + m["size"] = ""
  400 + m["address"] = ""
  401 +
  402 + rLine := regexp.MustCompile("cma: Reserved [[:print:]]+ at [[:print:]]+")
  403 + for line := range lines {
  404 + if rLine.MatchString(line) {
  405 + line = rLine.FindString(line)
  406 + line = strings.TrimPrefix(line, "cma: Reserved ")
  407 +
  408 + size := regexp.MustCompile(`[[:print:]]+ at`).FindString(line)
  409 + size = strings.TrimSuffix(size, "at")
  410 + size = strings.TrimSpace(size)
  411 +
  412 + m["size"] = size
  413 +
  414 + address := regexp.MustCompile(`at [[:print:]]+`).FindString(line)
  415 + address = strings.TrimPrefix(address, "at")
  416 + address = strings.TrimSpace(address)
  417 +
  418 + m["address"] = address
  419 +
  420 + break
  421 + }
  422 + }
  423 +
  424 + chanOutput <- m
  425 +}
  426 +
  427 +func parseSlub(lines chan string, chanOutput chan jsonObject) {
  428 + m := make(jsonObject)
  429 + m["type"] = "slub"
  430 + m["hw_align"] = ""
  431 + m["order"] = ""
  432 + m["min_objects"] = ""
  433 + m["cpus"] = ""
  434 + m["nodes"] = ""
  435 +
  436 + rLine := regexp.MustCompile("SLUB: HWalign=[[:digit:]]+, Order=[[:digit:]]+-[[:digit:]]+, MinObjects=[[:digit:]]+, CPUs=[[:digit:]]+, Nodes=[[:digit:]]+")
  437 + for line := range lines {
  438 + if rLine.MatchString(line) {
  439 + line = rLine.FindString(line)
  440 +
  441 + hwAlign := regexp.MustCompile(`HWalign=[[:digit:]]+`).FindString(line)
  442 + hwAlign = strings.TrimPrefix(hwAlign, `HWalign=`)
  443 +
  444 + m["hw_align"] = hwAlign
  445 +
  446 + order := regexp.MustCompile(`Order=[[:digit:]]+-[[:digit:]]+`).FindString(line)
  447 + order = strings.TrimPrefix(order, `Order=`)
  448 +
  449 + m["order"] = order
  450 +
  451 + minObjects := regexp.MustCompile(`MinObjects=[[:digit:]]+`).FindString(line)
  452 + minObjects = strings.TrimPrefix(minObjects, `MinObjects=`)
  453 +
  454 + m["min_objects"] = minObjects
  455 +
  456 + cpus := regexp.MustCompile(`CPUs=[[:digit:]]+`).FindString(line)
  457 + cpus = strings.TrimPrefix(cpus, `CPUs=`)
  458 +
  459 + m["cpus"] = cpus
  460 +
  461 + nodes := regexp.MustCompile(`Nodes=[[:digit:]]+`).FindString(line)
  462 + nodes = strings.TrimPrefix(nodes, `Nodes=`)
  463 +
  464 + m["nodes"] = nodes
  465 +
  466 + break
  467 + }
  468 + }
  469 +
  470 + chanOutput <- m
  471 +}
  472 +
  473 +func parsePidMax(lines chan string, chanOutput chan jsonObject) {
  474 + m := make(jsonObject)
  475 + m["type"] = "pid_max"
  476 + m["default"] = ""
  477 + m["min"] = ""
  478 +
  479 + rLine := regexp.MustCompile("pid_max:[[:blank:]]+default:[[:blank:]]*[[:digit:]]+[[:blank:]]+minimum:[[:blank:]]*[[:digit:]]+")
  480 + for line := range lines {
  481 + if rLine.MatchString(line) {
  482 + line = rLine.FindString(line)
  483 +
  484 + m["default"] = extract(line,
  485 + `default:[[:blank:]]*[[:digit:]]+`,
  486 + `default:[[:blank:]]*`,
  487 + ``)
  488 +
  489 + m["min"] = extract(line,
  490 + `minimum:[[:blank:]]*[[:digit:]]+`,
  491 + `minimum:[[:blank:]]*`,
  492 + ``)
  493 +
  494 + break
  495 + }
  496 + }
  497 +
  498 + chanOutput <- m
  499 +}
  500 +
  501 +func parseWorkingset(lines chan string, chanOutput chan jsonObject) {
  502 + m := make(jsonObject)
  503 + m["type"] = "workingset"
  504 + m["timestamp bits"] = ""
  505 + m["max_order"] = ""
  506 + m["bucket_order"] = ""
  507 +
  508 + rLine := regexp.MustCompile("workingset: timestamp_bits=[[:digit:]]+ max_order=[[:digit:]]+ bucket_order=[[:digit:]]+")
  509 + for line := range lines {
  510 + if rLine.MatchString(line) {
  511 + line = rLine.FindString(line)
  512 +
  513 + m["timestamp_bits"] = extract(line,
  514 + `timestamp_bits=[[:digit:]]+`,
  515 + `timestamp_bits=`,
  516 + ``)
  517 +
  518 + m["max_order"] = extract(line,
  519 + `max_order=[[:digit:]]+`,
  520 + `max_order=`,
  521 + ``)
  522 +
  523 + m["bucket_order"] = extract(line,
  524 + `bucket_order=[[:digit:]]+`,
  525 + `bucket_order=`,
  526 + ``)
  527 +
  528 + break
  529 + }
  530 + }
  531 +
  532 + chanOutput <- m
  533 +}
  534 +
  535 +func removeBrackets(s string) string {
  536 + for strings.HasPrefix(s, "(") && strings.HasSuffix(s, ")") {
  537 + openCount := strings.Count(s, "(")
  538 + closeCount := strings.Count(s, ")")
  539 +
  540 + if openCount > closeCount {
  541 + s = strings.TrimPrefix(s, "(")
  542 + } else if openCount < closeCount {
  543 + s = strings.TrimSuffix(s, ")")
  544 + } else {
  545 + s = strings.TrimPrefix(s, "(")
  546 + s = strings.TrimSuffix(s, ")")
  547 + }
  548 + }
  549 +
  550 + return s
  551 +}
  552 +
  553 +func removeTimestamp(s string) string {
  554 + if reTimestamp.MatchString(s) {
  555 + t := reTimestamp.FindString(s)
  556 + s = strings.TrimPrefix(s, t)
  557 + }
  558 + return strings.TrimSpace(s)
  559 +}
  560 +
  561 +func extract(from string, chunk, prefix, suffix string) string {
  562 + reChunk, err := regexp.Compile(chunk)
  563 + if err != nil {
  564 + return ""
  565 + }
  566 +
  567 + rePrefix, err := regexp.Compile(prefix)
  568 + if err != nil {
  569 + return ""
  570 + }
  571 +
  572 + reSuffix, err := regexp.Compile(suffix)
  573 + if err != nil {
  574 + return ""
  575 + }
  576 +
  577 + b := reChunk.FindString(from)
  578 +
  579 + p := rePrefix.FindString(b)
  580 + b = strings.TrimPrefix(b, p)
  581 +
  582 + s := reSuffix.FindString(b)
  583 + b = strings.TrimSuffix(b, s)
  584 +
  585 + return b
  586 +}
go/src/fullcycle/analog-kernel/parser/parser.go
@@ -0,0 +1,250 @@ @@ -0,0 +1,250 @@
  1 +package parser
  2 +
  3 +import (
  4 + "encoding/json"
  5 + "fmt"
  6 + "io/ioutil"
  7 + "strings"
  8 +)
  9 +
  10 +type jsonObject map[string]interface{}
  11 +type jsonArray []interface{}
  12 +
  13 +type Request struct {
  14 + Log []string `json:"log"`
  15 + Sheet Sheet `json:"sheet"`
  16 +}
  17 +
  18 +type Sheet struct {
  19 + LogID string `json:"log_id"`
  20 + Date string `json:"date"`
  21 + Target string `json:"target"`
  22 + Memory string `json:"memory"`
  23 + StartLine string `json:"start_line"`
  24 +
  25 + Hardware []SheetEntry `json:"hardware"`
  26 + OS []SheetEntry `json:"os"`
  27 + Device []SheetEntry `json:"device"`
  28 +}
  29 +
  30 +type SheetEntry struct {
  31 + Title string `json:"title"`
  32 + Check [][]string `json:"check"`
  33 + ErrorMessage []string `json:"error_message"`
  34 +}
  35 +
  36 +type Parser struct {
  37 + InChan chan string
  38 + OutChan chan jsonObject
  39 +}
  40 +
  41 +func New() *Parser {
  42 + parser := &Parser{}
  43 + return parser
  44 +}
  45 +
  46 +func (p *Parser) Parse(request *Request) string {
  47 + p.start()
  48 + for _, line := range request.Log {
  49 + p.InChan <- line
  50 + }
  51 + p.stop()
  52 +
  53 + return p.makeResult(request.Sheet)
  54 +}
  55 +
  56 +func (p *Parser) start() {
  57 + p.InChan = make(chan string, 100)
  58 + p.OutChan = make(chan jsonObject, 1)
  59 +
  60 + // Go parse functions
  61 + inputChanList := make([]chan string, len(parseFuncList))
  62 + outputChanList := make([]chan jsonObject, len(parseFuncList))
  63 + for i, parseFunc := range parseFuncList {
  64 + f := parseFunc
  65 +
  66 + inputChan := make(chan string, 10)
  67 + outputChan := make(chan jsonObject, 1)
  68 +
  69 + inputChanList[i] = inputChan
  70 + outputChanList[i] = outputChan
  71 +
  72 + go func() {
  73 + defer func() {
  74 + if r := recover(); r != nil {
  75 + //p.Fatal("Internal Error", r, string(debug.Stack()))
  76 + }
  77 + for range inputChan {
  78 + }
  79 + close(outputChan)
  80 + }()
  81 + f(inputChan, outputChan)
  82 + }()
  83 + }
  84 +
  85 + // Broadcast input
  86 + go func() {
  87 + for input := range p.InChan {
  88 + for _, inputChan := range inputChanList {
  89 + inputChan <- input
  90 + }
  91 + }
  92 +
  93 + for _, inputChan := range inputChanList {
  94 + close(inputChan)
  95 + }
  96 + }()
  97 +
  98 + // Merge output
  99 + go func() {
  100 + output := make(jsonObject)
  101 +
  102 + for _, outputChan := range outputChanList {
  103 + for parsed := range outputChan {
  104 + output[parsed["type"].(string)] = parsed
  105 + }
  106 + }
  107 +
  108 + p.OutChan <- output
  109 + close(p.OutChan)
  110 + }()
  111 +}
  112 +
  113 +func (p *Parser) stop() {
  114 + close(p.InChan)
  115 +}
  116 +
  117 +func (p *Parser) makeReport(result jsonObject, checklist []SheetEntry) ([]jsonObject, bool) {
  118 + var report []jsonObject
  119 +
  120 + totalPass := true
  121 +
  122 + for _, entry := range checklist {
  123 + reportEntry := make(jsonObject)
  124 + reportEntry["title"] = entry.Title
  125 +
  126 + pass := true
  127 + for _, c := range entry.Check {
  128 + o, ok := result[c[0]].(jsonObject)
  129 + if !ok {
  130 + reportEntry["result"] = "FAIL"
  131 + reportEntry["message"] = entry.ErrorMessage[0]
  132 + pass = false
  133 + break
  134 + }
  135 + switch o[c[1]].(type) {
  136 + case string:
  137 + if len(c[2]) > 0 {
  138 + v, ok := o[c[1]].(string)
  139 + if !ok {
  140 + reportEntry["result"] = "FAIL"
  141 + reportEntry["message"] = entry.ErrorMessage[0]
  142 + pass = false
  143 + break
  144 + }
  145 + if strings.Compare(v, c[2]) != 0 {
  146 + reportEntry["result"] = "FAIL"
  147 + reportEntry["message"] = entry.ErrorMessage[0]
  148 + pass = false
  149 + break
  150 + }
  151 + }
  152 + case []string:
  153 + if len(c[2]) > 0 {
  154 + l, ok := o[c[1]].([]string)
  155 + if !ok {
  156 + reportEntry["result"] = "FAIL"
  157 + reportEntry["message"] = entry.ErrorMessage[0]
  158 + pass = false
  159 + break
  160 + }
  161 +
  162 + found := false
  163 + for _, v := range l {
  164 + if strings.Compare(v, c[2]) == 0 {
  165 + found = true
  166 + }
  167 + }
  168 + if !found {
  169 + reportEntry["result"] = "FAIL"
  170 + reportEntry["message"] = entry.ErrorMessage[0]
  171 + pass = false
  172 + break
  173 + }
  174 + }
  175 + case []jsonObject:
  176 + if len(c[2]) > 0 {
  177 + list, ok := o[c[1]].([]jsonObject)
  178 + if !ok {
  179 + reportEntry["result"] = "FAIL"
  180 + reportEntry["message"] = entry.ErrorMessage[0]
  181 + pass = false
  182 + break
  183 + }
  184 +
  185 + found := false
  186 + for _, v := range list {
  187 + label := v["label"].(string)
  188 + if strings.Compare(label, c[2]) == 0 {
  189 + found = true
  190 + }
  191 + }
  192 + if !found {
  193 + reportEntry["result"] = "FAIL"
  194 + reportEntry["message"] = entry.ErrorMessage[0]
  195 + pass = false
  196 + break
  197 + }
  198 + }
  199 + default:
  200 + fmt.Printf("%v fail (type: %T)\n", c[1], o[c[1]])
  201 + reportEntry["result"] = "FAIL"
  202 + pass = false
  203 + }
  204 + }
  205 + if pass {
  206 + reportEntry["result"] = "PASS"
  207 + } else {
  208 + totalPass = false
  209 + }
  210 + report = append(report, reportEntry)
  211 + }
  212 +
  213 + return report, totalPass
  214 +}
  215 +
  216 +func (p *Parser) makeResult(sheet Sheet) string {
  217 + output := make(jsonObject)
  218 +
  219 + result := <-p.OutChan
  220 + report := make(jsonObject)
  221 +
  222 + pass := true
  223 + totalPass := true
  224 +
  225 + result["memory_size"] = sheet.Memory
  226 +
  227 + report["log_id"] = sheet.LogID
  228 + report["date"] = sheet.Date
  229 + report["target"] = sheet.Target
  230 +
  231 + report["hardware"], pass = p.makeReport(result, sheet.Hardware)
  232 + totalPass = totalPass && pass
  233 + report["os"], pass = p.makeReport(result, sheet.OS)
  234 + totalPass = totalPass && pass
  235 + report["device"], pass = p.makeReport(result, sheet.Device)
  236 + totalPass = totalPass && pass
  237 +
  238 + if totalPass {
  239 + report["pass"] = "PASS"
  240 + }
  241 +
  242 + output["result"] = result
  243 + output["report"] = report
  244 +
  245 + b, err := json.MarshalIndent(output, "", " ")
  246 + if err == nil {
  247 + ioutil.WriteFile("anal-kernel-response.json", b, 0644)
  248 + }
  249 + return string(b)
  250 +}
go/src/fullcycle/analog-kernel/sheet-sample.json
@@ -0,0 +1,203 @@ @@ -0,0 +1,203 @@
  1 +{
  2 + "log_id": "012-3233-4423",
  3 + "date": "2018/04/18",
  4 +
  5 + "target": "raspberry pi3",
  6 + "hardware": [
  7 + {
  8 + "title": "Check the CPU type",
  9 + "check": [
  10 + ["cpu", "name", "ARMv7 Processor"]
  11 + ],
  12 + "error_message": [
  13 + "Not found in booting log messages"
  14 + ]
  15 + },
  16 + {
  17 + "title": "Check memory size",
  18 + "check": [
  19 + ["memory", "total", "970752K"]
  20 + ],
  21 + "error_message": [
  22 + "Not found in booting log messages",
  23 + "Wrong size"
  24 + ]
  25 + },
  26 + {
  27 + "title": "Check board model type",
  28 + "check": [
  29 + ["model", "model", "Raspberry Pi 3 Model B Rev 1.2"]
  30 + ],
  31 + "error_message": [
  32 + "Not found in booting log messages",
  33 + "Wrong model"
  34 + ]
  35 + },
  36 + {
  37 + "title": "Check CMA",
  38 + "check": [
  39 + ["cma", "size", ""]
  40 + ],
  41 + "error_message": [
  42 + "Not found in booting log messages"
  43 + ]
  44 + }
  45 + ],
  46 + "os": [
  47 + {
  48 + "title": "Check OS type (Linux)",
  49 + "check": [
  50 + ["linux", "type", "linux"]
  51 + ],
  52 + "error_message": [
  53 + "Not found in booting log messages"
  54 + ]
  55 + },
  56 + {
  57 + "title": "Check kernel memory layout",
  58 + "check": [
  59 + ["memory_layout", "layout", "vector"],
  60 + ["memory_layout", "layout", "fixmap"],
  61 + ["memory_layout", "layout", "vmalloc"],
  62 + ["memory_layout", "layout", "lowmem"],
  63 + ["memory_layout", "layout", "modules"],
  64 + ["memory_layout", "layout", ".text"],
  65 + ["memory_layout", "layout", ".init"],
  66 + ["memory_layout", "layout", ".data"],
  67 + ["memory_layout", "layout", ".bss"]
  68 + ],
  69 + "error_message": [
  70 + "Not found in booting log messages"
  71 + ]
  72 + },
  73 + {
  74 + "title": "Check kernel hash tables",
  75 + "check": [
  76 + ["hash_tables", "list", "PID"],
  77 + ["hash_tables", "list", "Dentry cache"],
  78 + ["hash_tables", "list", "Inode-cache"],
  79 + ["hash_tables", "list", "Mount-cache"],
  80 + ["hash_tables", "list", "Mountpoint-cache"],
  81 + ["hash_tables", "list", "futex"],
  82 + ["hash_tables", "list", "VFS: Dquot-cache"],
  83 + ["hash_tables", "list", "TCP established"],
  84 + ["hash_tables", "list", "TCP bind"],
  85 + ["hash_tables", "list", "UDP"],
  86 + ["hash_tables", "list", "UDP-Lite"]
  87 + ],
  88 + "error_message": [
  89 + "Not found in booting log messages"
  90 + ]
  91 + }
  92 + ],
  93 + "device": [
  94 + {
  95 + "title": "Check driver existance (UART)",
  96 + "check": [
  97 + ["device_found", "list", "AMBA PL011 UART Device"]
  98 + ],
  99 + "error_message": [
  100 + "Not found in booting log messages"
  101 + ]
  102 + },
  103 + {
  104 + "title": "Check driver existance (Mailbox)",
  105 + "check": [
  106 + ["device_found", "list", "BCM2835 Mailbox"]
  107 + ],
  108 + "error_message": [
  109 + "Not found in booting log messages"
  110 + ]
  111 + },
  112 + {
  113 + "title": "Check driver existance (DMA)",
  114 + "check": [
  115 + ["device_found", "list", "BCM2835 DMA"]
  116 + ],
  117 + "error_message": [
  118 + "Not found in booting log messages"
  119 + ]
  120 + },
  121 + {
  122 + "title": "Check driver existance (SCSI)",
  123 + "check": [
  124 + ["device_found", "list", "SCSI subsystem"]
  125 + ],
  126 + "error_message": [
  127 + "Not found in booting log messages"
  128 + ]
  129 + },
  130 + {
  131 + "title": "Check driver existance (Ethernet)",
  132 + "check": [
  133 + ["device_found", "list", "SMSC LAN95XX Based USB 2.0 10/100 Ethernet Device"]
  134 + ],
  135 + "error_message": [
  136 + "Not found in booting log messages"
  137 + ]
  138 + },
  139 + {
  140 + "title": "Check driver existance (Watchdog Timer)",
  141 + "check": [
  142 + ["device_found", "list", "BCM2835 Watchdog Timer"]
  143 + ],
  144 + "error_message": [
  145 + "Not found in booting log messages"
  146 + ]
  147 + },
  148 + {
  149 + "title": "Check driver existance (USB Mass Storage)",
  150 + "check": [
  151 + ["device_found", "list", "USB Mass Storage"]
  152 + ],
  153 + "error_message": [
  154 + "Not found in booting log messages"
  155 + ]
  156 + },
  157 + {
  158 + "title": "Check driver existance (BCM FrameBuffer)",
  159 + "check": [
  160 + ["device_found", "list", "BCM2708FB"]
  161 + ],
  162 + "error_message": [
  163 + "Not found in booting log messages"
  164 + ]
  165 + },
  166 + {
  167 + "title": "Check driver existance (Random Generator)",
  168 + "check": [
  169 + ["device_found", "list", "BCM2835 RNG"]
  170 + ],
  171 + "error_message": [
  172 + "Not found in booting log messages"
  173 + ]
  174 + },
  175 + {
  176 + "title": "Check driver existance (SDHCI)",
  177 + "check": [
  178 + ["device_found", "list", "Secure Digital Host Controller Interface"]
  179 + ],
  180 + "error_message": [
  181 + "Not found in booting log messages"
  182 + ]
  183 + },
  184 + {
  185 + "title": "Check driver existance (MMC:SDHC)",
  186 + "check": [
  187 + ["device_found", "list", "SDHC Card"]
  188 + ],
  189 + "error_message": [
  190 + "Not found in booting log messages"
  191 + ]
  192 + },
  193 + {
  194 + "title": "Check driver existance (MMC:SDIO)",
  195 + "check": [
  196 + ["device_found", "list", "SDIO Card"]
  197 + ],
  198 + "error_message": [
  199 + "Not found in booting log messages"
  200 + ]
  201 + }
  202 + ]
  203 +}
go/src/fullcycle/analog-kernel/test.sh
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +#!/bin/sh
  2 +
  3 +cat input-sample | ./analog-kernel sample
go/src/fullcycle/do-iperf/main.go
@@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
  1 +package main
  2 +
  3 +import (
  4 + "bufio"
  5 + "fmt"
  6 + "io"
  7 + "log"
  8 + "os"
  9 + "os/exec"
  10 +)
  11 +
  12 +func main() {
  13 + var host string
  14 + var out io.Writer
  15 +
  16 + if l := len(os.Args); l == 1 {
  17 + host = "172.30.0.1"
  18 + out = os.Stdout
  19 + } else if l == 2 {
  20 + host = os.Args[1]
  21 + out = os.Stdout
  22 + } else {
  23 + f, err := os.OpenFile(os.Args[2], os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
  24 + if err != nil {
  25 + log.Fatal(err)
  26 + }
  27 + defer f.Close()
  28 +
  29 + host = os.Args[1]
  30 + out = f
  31 + }
  32 +
  33 + test("hw-wifi", host, out)
  34 +}
  35 +
  36 +func test(code, host string, out io.Writer) {
  37 + c := exec.Command("iperf", "-c", host, "-i", "1", "-t", "10")
  38 + stdout, err := c.StdoutPipe()
  39 +
  40 + err = c.Start()
  41 + if err != nil {
  42 + log.Fatal(err)
  43 + }
  44 +
  45 + state := 0
  46 +
  47 + s := bufio.NewScanner(stdout)
  48 + for s.Scan() {
  49 + fmt.Fprintf(out, "{\"code\": \"%v\", \"state\": %v, \"data\": \"%v\", \"timeout\": 10}\n", code, state, s.Text())
  50 + if state < 90 {
  51 + state += 10
  52 + }
  53 + }
  54 +
  55 + fmt.Fprintf(out, "{\"code\": \"%v\", \"state\": 100, \"data\": \"\", \"timeout\": 10}\n", code)
  56 +}