-
Notifications
You must be signed in to change notification settings - Fork 4
/
tutorial.lua
158 lines (131 loc) · 7.01 KB
/
tutorial.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
-- This is a short introduction to the autokernel lua API.
-- The static parts of this api (classes, globals) are defined in [api.lua](https://github.com/oddlama/autokernel/blob/main/src/script/api.lua),
-- which you may use as a reference.
--
-- This file intentionally contains errors to explain autokernel and should therefore _NOT_
-- be used as an actual script.
--###############################################################
-- Loading kconfig files
--###############################################################
-- First, it is a good idea to begin with loading the defconfig for your architecture.
-- This will be sane base configuration to build upon.
--
-- This is done unchecked (by calling the kernel's internal conf_read() function), as these
-- files tend to contain statements that break the strict assignment rules. It is unclear
-- at this point whether these are actual errors in the defconfig files, or if they are
-- technically acceptable due to assignment mechanics that autokernel is unaware of.
--
-- The global variable `kernel_dir` contains the kernel directory against which autokernel
-- is currently running.
load_kconfig_unchecked(kernel_dir .. "/arch/x86/configs/x86_64_defconfig")
-- A lot of distributions currently organize their kernel configuration into smaller config
-- files that are then merged together using `scripts/kconfig/merge_config.sh` which is provided
-- with the kernel sources.
--
-- If you have existing kconfig files that you want to apply with autokernel (including
-- all validity checks), you can do so without re-writing these files in lua by using
-- the global function `load_kconfig(path)`. Paths are relative to the current working
load_kconfig("/path/to/config/usb.config")
--###############################################################
-- Assigning symbol values
--###############################################################
-- All existing symbols in the kernel are automatically exposed as global variables.
-- These are instances of a special Symbol class, which you can use to get and set values.
--
-- We can now enable the CONFIG_ACPI symbol by calling the `Symbol:set(value)` function.
-- The global variables `y`, `m` and `n` are instances of the `Tristate` class.
CONFIG_ACPI:set(y)
-- For readability, it is supported and recommended to omit the `CONFIG_` prefix for all options.
-- Reassignments like this one will also cause warnings to be emitted, as typically symbols should
-- only be assigned once.
ACPI:set(y)
-- Instead of using the global tristate values you may also simply use a string representation.
-- This allows you to omit the parenthesis in lua.
ACPI:set "y"
-- Finally, as you will set a lot of values, symbols implement the call-operator to provide a
-- nice short-hand syntax to set values. When using string values to omit the parenthesis,
-- this syntax is very similar to the classic kconfig files.
ACPI(y) -- Using the global typed tristate symbol
ACPI "y" -- Using a string value
-- Depending on the symbol, it might be of a different type:
DEFAULT_HOSTNAME "my_hostname" -- <- A string symbol
PHYSICAL_ALIGN(0x11223344) -- <- A hex symbol
-- Invalid assignments will always cause errors, but errors are reported "late",
-- so evaluation continues even if an assignment failed. Most symbol assignments don't depend
-- on each other, so this allows autokernel to show you all errors at once.
ACPI "some string" -- <- invalid value
DEFAULT_HOSTNAME(y) -- <- invalid value
DOES_NOT_EXIST "y" -- <- invalid symbol name
WLAN_VENDOR_REALTEK "y" -- <- unmet dependencies
RTLWIFI_USB "n" -- <- cannot be set manually
--###############################################################
-- Conditionals
--###############################################################
-- Some symbols only exist in specific kernel versions, but you might want
-- to maintain compatiblity across several kernel versions.
--
-- The global variable `kernel_version` contains the current kernel version
-- wrapped in an instance of the `Version` class. Similarly, the `ver()` function
-- can be used to convert a version string to such a `Version` instance, which
-- can be compared to one another.
if kernel_version >= ver("5.6") then
USB4 "y"
else
THUNDERBOLT "y"
end
--###############################################################
-- Getting and comparing symbol values
--###############################################################
-- Symbol values can be read by using Symbol:value() or Symbol:v().
print("ACPI is currently set to " .. tostring(ACPI:value()))
print("USB4 is currently set to " .. tostring(USB4:v()))
-- To correctly compare symbol values, we need to be aware of the value type.
-- Instead of using type(...) to inspect the returned value type, the API provides
-- the Symbol:is(value) function to provide convenient value checking.
if USB4:is("y") then -- automatic conversion
print("USB4 is y")
elseif USB4:is("abc") then -- raises an error due to invalid symbol type comparison
print("Not reachable")
end
-- Comparisons between symbols are also possible
if USB:is(USB4) then
print("USB == USB4")
end
-- Roughly equivalent to USB4:is(ACPI:value()), but has even stricter requirements:
-- The two symbols must be of the same type.
if USB4:is(ACPI) then -- <- error: trying to compare Tristate to Boolean
print("Not reachable, invalid comparison")
end
--###############################################################
-- Automatically set symbols and dependencies
--###############################################################
-- Often you need to enable a symbol which depends on other symbols being set.
-- For example `RTLWIFI_USB` is needed to enable support for many WiFi USB modules.
--
--RTLWIFI_USB "y"
--
-- Trying to execute the above statement will most likely fail, because it's dependencies
-- (`USB=y`, `WLAN=y`, `RTL_CARDS=y`, ...) are still unmet. The error message would try
-- to guide you and explain that these symbols are missing:
-- USB "y"
-- NETDEVICES "y"
-- WLAN "y"
-- WLAN_VENDOR_REALTEK "y"
-- RTL_CARDS "y"
--
-- Now you can either copy all these assignments into your config,
-- or you can directly invoke the solver from lua:
RTLWIFI_USB:satisfy { y, recursive = true }
-- This will automatically calculate and assign the required values for the symbol
-- `RTLWIFI_USB` and its dependencies to be set to `y`.
-- Specifying `recursive = true` also includes transitive dependencies.
--
-- The returned solution will always be unambiguous with respect to the symbols that will be enabled.
-- If there is a choice involved somewhere in the dependency tree (e.g. SYMBOL_A==y || SYMBOL_B==y),
-- an error will be shown that explains which options you have. One of these must then
-- be set explicitly before calling satisfy.
-- If you prefer to use modules where possible, you can solve for `m` instead:
RTLWIFI_USB:satisfy { m, recursive = true }
-- Finally, you are of course able to use lua to it's full extent. Feel free to call
-- other programs, read/write files, make web requests or anything else that you
-- require to build the perfect kernel config.