---
# System prepended metadata

title: Linux Kernel Quick Question
tags: [linuxKernel, Interview]

---

# Linux Kernel Quick Question
###### tags: `Interview` `linuxKernel` `EMBEDDED_C


1. hello world moudle 怎寫
```clike=
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>



MODULE_LICENSE("Dual BSD/GPL");

static int __init device_tree_init(void)
{
    /* 
        a pointer point to a device_node struct
    */
    printk("  ---------------------------------\n");
    struct device_node *np;
    printk("device tree start checking the node\n");
    /* Disable SMP boot unless both CPUs are listed in DT and !disabled */
    np = of_find_node_by_name(NULL, "uart1");
    pr_info("start checking the node with np of ptr\n");
    if (np =! NULL){
        pr_info("%s find node in dts\n",__func__);
    }
    else{
        pr_err("%s error: cannot find the the node in dts\n",__func__);
    }
    return 0;
}


static void __exit device_tree_exit(void)
{
    printk("end of the module\n");
    printk("--------------------------------------------------------------------------\n");
}
/*                                                                                                                                                                                     
 *  load a Linux driver
 */
module_init(device_tree_init);
/*
 * unload the Linux driver
 */
module_exit(device_tree_exit);


```
### 2. Entry Point / Exit Point of the Kernel Module
```clike=
module_init(*_init_module);
module_exit(*_exit_module);
```
* #### What does it mean `__init`?
* #### What does it mean `__exit`?
### 4. character device driverv .read .write 怎寫

* `struct file_opertion` 

```clike=
const struct file_operations my_fops = {
    .owner = THIS_MODULE,
    .open = my_open,
    .read = my_read,
    .write = my_write,
    .release = my_release,
    .unlocked_ioctl = my_ioctl
};
```
* Read
```clike=
static int my_read(struct file *file, char __user *user_buffer,
                   size_t size, loff_t *offset)
{
    struct my_device_data *my_data = (struct my_device_data *) file->private_data;
    ssize_t len = min(my_data->size - *offset, size);

    if (len <= 0)
        return 0;

    /* read data from my_data->buffer to user buffer */
    if (copy_to_user(user_buffer, my_data->buffer + *offset, len))
        return -EFAULT;

    *offset += len;
    return len;
}
```
* Write
```clike=
static int my_read(struct file *file, char __user *user_buffer,
                   size_t size, loff_t *offset)
{
    struct my_device_data *my_data = (struct my_device_data *) file->private_data;
    ssize_t len = min(my_data->size - *offset, size);

    if (len <= 0)
        return 0;

    /* read data from my_data->buffer to user buffer */
    if (copy_to_user(user_buffer, my_data->buffer + *offset, len))
        return -EFAULT;

    *offset += len;
    return len;
}

```
### 6. kconfig怎加
* `Make Menuconfig`加入後
### 7. config 放哪,如何更改
* `make menuconfig` 生成新的config file 

### 8. build完Kernel後會產生幾種類型的檔以及格式的差異-[Refefrence](https://www.cnblogs.com/lemaden/p/10438499.html)
* **`vmlinux`**:
    * directory:`/arh/arm/boot/compressed`
    * vm代表Virtual Memory,
    * File Format(using `file` command to check)
        * #### ELF 
        *  statically linked,ELF 32-bit LSB executable
* **`dtb`**:
    * directory:`/arch/arm/boot/dts`
    * File Format
        * imx6ul-panzer.dtb: Device Tree Blob version 17, size=36467, boot CPU=0, string block size=2587, **DT structure** block size=33824
* **`zImage`**:
    * directory: `arch/arm/boot/compressed/vmlinux`
    * **壓縮過後的vmlinux**, 
    它是由vmlinux經過objcopy，objcopy實現由vmlinux的elf文件複製成純binary file並由gzip壓縮分解而成
    * File Format: 
        * Linux kernel ARM boot executable zImage (little-endian)

### 9. build完產物放哪
* dtb-> `/arch/arm/boot/dts`
* zImage->


---

### 10. dts怎改




---

### 11. image格式差異 ??
###
### 12. external ko怎build
* Refernece 編譯過得source code
* `Makefile`, `.c`
* `export ARCH = `
* `export Cross_Compile`
* `Make`
* Insert Module
    * `modprobe`
    * `insertmode`


---

### 13. Makefile怎寫
```script=
obj-m   :=smnt_falt.o                                                                                                                                                              
KDIR    :=/home/paul/Panzer/linux-imx_4_9MYCC        =/home/paul/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
# The KDIR must have to assign a ./direction
modules:
    $(MAKE) ARCH=arm CROSS_COMPILE=$(MYCC) -C $(KDIR) SUBDIRS=$(shell pwd) modules
clean:
    rm -f modules.order Module.symvers  *.o *.ko *.mod.c

```
### 語法整理

#### **`:=`** 
`:=`注意到，make 會將整個 Makefile 展開後，再決定變數的值。也就是說，變數的值將會是整個 Mackfile 中最後被指定的值。

#### **`?=`**
`?=`是一個簡化的語法：若變數未定義，則替它指定新的值。
否則，採用原有的值。
    * e.g：`Foo?=`

#### **`+=`**
若變數未定義，則替它指定新的值。否則，採用原有的值。
    * e.g:``
    
---

### 14. compiler怎指定???
`export ARCH=arm`
`export CROSS_COMPILE=/gcc-arm */bin/arm-none-eabi-`
### 15. kernel版本怎看
* 透過板子
    * `uname -a`
    * `cat /proc/version`
* 參考Makfile
    * Makefile一開始就會寫出
```clike=
# SPDX-License-Identifier: GPL-2.0                                                                                                       
VERSION = 4
PATCHLEVEL = 14
SUBLEVEL = 78
EXTRAVERSION =
NAME = Petit Gorille
```
### 16. 反組譯看dump???
### 17. 板子上常用指令
#### **`cat proc interrupt`**
* e.g:
    ```
    CPU0               CPU1  CPU2  CPU3
      0: 3710374484      0     0     0  IO-APIC-edge  timer
      1:         20      0     0     0  IO-APIC-edge  i8042
      6:          5      0     0     0  IO-APIC-edge  floppy
      7:          0      0     0     0  IO-APIC-edge  parport0
      8:          0      0     0     0  IO-APIC-edge  rtc
      9:          0      0     0     0  IO-APIC-level  acpi
     12:        240      0     0     0  IO-APIC-edge  i8042
     14:   11200026      0     0     0  IO-APIC-edge  ide0
     51:   61281329      0     0     0  IO-APIC-level  ioc0
     59:          1      0     0     0  IO-APIC-level  vmci
     67:   19386473      0     0     0  IO-APIC-level  eth0
     75:   94595340      0     0     0  IO-APIC-level  eth1
    NMI:          0      0     0     0
    LOC: 3737150067 3737142382 3737145101 3737144204
    ERR:          0
    MIS:          0
    ```

* IRQ 
    > IRQ0 — system timer (cannot be changed);
    > IRQ1 — keyboard controller (cannot be changed)
    > IRQ3 — serial port controller for serial port 2 (shared with serial port 4, if present);
    > IRQ 4 — serial port controller for serial port 1 (shared with serial port 3, if present);
    > IRQ 5 — parallel port 2 and 3 or sound card;
    > IRQ 6 — floppy disk controller;
    > IRQ 7 — parallel port 1. It is used for printers or for any parallel port if a printer is not present.
#### **`cat proc vmalloc`**
#### **`cat proc meminfo`**
> The ‘/proc/meminfo‘ is used by to report the amount of free and used memory (both physical and swap) on the system as well as the shared memory and buffers used by the kernel.
```
MemTotal:        1882064 kB
MemFree:         1376380 kB
MemAvailable:    1535676 kB
Buffers:            2088 kB
Cached:           292324 kB
SwapCached:            0 kB
Active:           152944 kB
Inactive:         252628 kB
Active(anon):     111328 kB
Inactive(anon):    16508 kB
Active(file):      41616 kB
Inactive(file):   236120 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       2097148 kB
SwapFree:        2097148 kB
Dirty:                40 kB
Writeback:             0 kB
AnonPages:        111180 kB
Mapped:            56396 kB
Shmem:             16676 kB
Slab:              54508 kB
SReclaimable:      25456 kB
SUnreclaim:        29052 kB
KernelStack:        2608 kB
PageTables:         5056 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     3038180 kB
Committed_AS:     577664 kB
VmallocTotal:   34359738367 kB
VmallocUsed:       14664 kB
VmallocChunk:   34359717628 kB
HardwareCorrupted:     0 kB
AnonHugePages:     24576 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       69632 kB
DirectMap2M:     2027520 kB
```
* #### Module 
    * Add Module
        * `insmod`
        * `modprobe`
    * Display the current moad module
        * `lsmod`
    * Remove the module
        * `rmmod`
    * Get Information of the module 
        * `modinfo`

* log level Set Up
19. What's`device tree`
* #### Hardware description file 
>Device Tree is a document to tell us about the Hardware's architecture, for example we would know how many of hardware chips in this hardware.
* #### properties and nodes
>where devices are represented by nodes
with their properties.

* #### What's  the purpose of it and which Kernel Version start to have ? 


### 18. driver 怎麼拿到device tree裡面東西?
> 透過of_node_系列的API
* `of_find_node_by_name`
```clike=
//of_find_node_by_name
struct device_node *np1 = NULL;

printk("decalre a pointer np1 point to the struct of device_node\n");
np1 = of_find_node_by_name(NULL, "uart1");
```
* `of_machine_is_compatible`
```clike=

   if (of_machine_is_compatible("fsl,imx8qm"))
        imx8qm_get_mac_from_fuse(idx, mac,
                     &imx8_fuse_mapping[IMX8QM_FUSE]);
    else if (of_machine_is_compatible("fsl,imx8qxp"))
        imx8qm_get_mac_from_fuse(idx, mac,
                     &imx8_fuse_mapping[IMX8QXP_FUSE]);

```

### 19. What's the three types of Device Driver:
* Character Device Module
* Block Device Module
* Network Interface Module

### 20. Linux Kernel可以被簡單分為以下幾個區塊:
* Process management
>Kernel負責創造銷毀Process，並且也handling their connection to the outside world (input and output)。與不同的Process溝通(signals、pipe、 interprocess communication primitives)是整個系統的基礎，也是由Kernel掌控。CPU的process排成也是歸類在這，Kernel可以在單CPU或多CPU上跑虛擬的多個process。
* Memory management
> 記憶體是重要資源，並且如何用它也成為效能關鍵。Kernel建了虛擬記憶體空間，並且所有processes都是在上面被控管資源的方式執行。所有kernel使用Memory management都是透過 malloc/free這組函數來與之互動的，複雜一點的函數裡面也是malloc/free。
* Filesystems
>Unix就是基於Filesystems的一個作業系統，幾乎所有東西在Unix裡面都能被當作一個檔案。Kernel會建 structured filesystem on top of unstructured hardware，這個抽象的檔案才會被系統用力的使用。Linux支援多種不同 filesystem類別，可以有不同方法來 organizing data on the physical medium。例如磁碟可以格式化成Linux-standard ext3 filesystem，或是 FAT filesystem等等的。
* Device control
> 幾乎所有 system operation都會最終map到硬體。除了 processor、 memory還有一些其他以外，所有device control operations都由一段 specific to the device being addressed的code來執行，這個code就是device driver。所有 peripheral想在掛在系統都要由kernel給他device driver，包括硬碟、鍵盤、磁碟。這部分就是本書重點。
* Networking
> Networking一定要透過 operating system管理，因為多數network都不是為了單一特定process。在process拿到 packets前， packets都會經過 collected, identified, and dispatched的程序。系統負責透過程式跟 network interfaces來傳packet，然後依據 network activity來控制程式的執行。此外，所有routing and address resolution issues都在kernel中實現。

### 21. Probe()怎麼去實做的

### 23. What's the Linux syscall? ans 
    * socket 
    * write
    * malloc
### 24. What script would you use to check that a file compiles with Linux Kernel Coding Style
### 25. What's the command to get kernel log?
* `demsg`
* `cat /log/....`

### 26. What is the file used to describe the hardware architecture of ARM platform when compileing the linux kernel?
> dts
### 27. What is the file used to describe the hardware architecture of ARM platform when compileing the linux kernel?
> dtb
### 28. What commmand is used to view systemed logs?
* What's `systemed` logs?
    * systemctl
    * Any text file will work
    * syslogctl
    * rsyslog
    * journalctl
### 29.Consider the ollowing mount output Which file system is read only?
![](https://i.imgur.com/OgiLgrs.png)


* securityfs
* devpts
* tmpfs
* systemd-1
* /dev/xvdb


### 30.Which command could you use to back up a disk device without mounting at first? 

### 31.What's the name of the document where you would find technical characteristics of a product,machine,component?

### 32.What's the name of the default distribution of yocto?


### 33.What's the name of the configuration file where the machine is genarlly defined?

### 34.What's the correct way to modify an exiting recipe?

### 35. [What's the booting process?](https://hackmd.io/pVjnSuIkTVaibWFUK4RfEw?both)-in Panzer


---

### 36. embedeed linux中tty的架構？


---

### 37. Big Endian && Little Endian
* Adress from low to high
* E.G: `0xFF00AB11`
    * **Big Endian**越前面放的越重要

        | Address | 0x4000 | 0x4001 |0x4002 |0x4003
        | -------- | -------- | -------- | --------| --------|
        | **Byte Order**     | byte0    |     byte 1|byte 2|byte 3
        | **Value**     | 0xFF    |     0x00|0xAB|0x11|
    * **Little Endian** ->相反
        | Address | 0x4000 | 0x4001 |0x4002 |0x4003 |
        | -------- | -------- | -------- | --------| --------|
        | **Byte Order**     | byte0    |     byte 1|byte 2|byte 3
        | **Value** | 0x11    |     0xAB|0x00|0xFF|
* #### Chck it with C programming
```clike=
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

union Endian{
    char c[64];
    uint64_t i;
};

// 1 Byte = 8 bit can be expressed 0xFF.
int main(void){

    union Endian Var;
    Var.i = (uint64_t)0x11223344;//0x11223344; //(4 + 4 + 4 +4) = 64 bit; 

    printf("sizeof is %ld\n",sizeof(Var.c[0]));
    printf("The adrees of %p and val is %x \n",&(Var.c[0]),Var.c[0]);
    printf("The adrees of %p and val is %x \n",&(Var.c[1]),Var.c[1]);
    printf("The adrees of %p and val is %x \n",&(Var.c[2]),Var.c[2]);
    printf("The adrees of %p and val is %x \n",&(Var.c[3]),Var.c[3]);


    if(Var.c[0] == 0x11)
        printf("Big Endian\n");
    else
        printf("Little Endian\n");
    return 0;
}

```
### 38. Where's the kernel entry point 
* `start_kernel`

