code:
===================================
Command Line Options for Linux/m68k
===================================

Last Update: 2 May 1999

Linux/m68k version: 2.2.6

Author: Roman.Hodek@informatik.uni-erlangen.de (Roman Hodek)

Update: jds@kom.auc.dk (Jes Sorensen) and faq@linux-m68k.org (Chris Lawrence)

0) Introduction
===============

Often I've been asked which command line options the Linux/m68k
kernel understands, or how the exact syntax for the ... option is, or
... about the option ... . I hope, this document supplies all the
answers...

Note that some options might be outdated, their descriptions being
incomplete or missing. Please update the information and send in the
patches.

1) Overview of the Kernel's Option Processing
=============================================

The kernel knows three kinds of options on its command line:

  1) kernel options
  2) environment settings
  3) arguments for init

To which of these classes an argument belongs is determined as
follows: If the option is known to the kernel itself, i.e. if the name
(the part before the '=') or, in some cases, the whole argument string
is known to the kernel, it belongs to class 1. Otherwise, if the
argument contains an '=', it is of class 2, and the definition is put
into init's environment. All other arguments are passed to init as
command line options.

This document describes the valid kernel options for Linux/m68k in
the version mentioned at the start of this file. Later revisions may
add new such options, and some may be missing in older versions.

In general, the value (the part after the '=') of an option is a
list of values separated by commas. The interpretation of these values
is up to the driver that "owns" the option. This association of
options with drivers is also the reason that some are further
subdivided.

2) General Kernel Options
=========================

2.1) root=
----------

:Syntax: root=/dev/<device>
:or:     root=<hex_number>

This tells the kernel which device it should mount as the root
filesystem. The device must be a block device with a valid filesystem
on it.

The first syntax gives the device by name. These names are converted
into a major/minor number internally in the kernel in an unusual way.
Normally, this "conversion" is done by the device files in /dev, but
this isn't possible here, because the root filesystem (with /dev)
isn't mounted yet... So the kernel parses the name itself, with some
hardcoded name to number mappings. The name must always be a
combination of two or three letters, followed by a decimal number.
Valid names are::

  /dev/ram: -> 0x0100 (initial ramdisk)
  /dev/hda: -> 0x0300 (first IDE disk)
  /dev/hdb: -> 0x0340 (second IDE disk)
  /dev/sda: -> 0x0800 (first SCSI disk)
  /dev/sdb: -> 0x0810 (second SCSI disk)
  /dev/sdc: -> 0x0820 (third SCSI disk)
  /dev/sdd: -> 0x0830 (forth SCSI disk)
  /dev/sde: -> 0x0840 (fifth SCSI disk)
  /dev/fd : -> 0x0200 (floppy disk)

The name must be followed by a decimal number, that stands for the
partition number. Internally, the value of the number is just
added to the device number mentioned in the table above. The
exceptions are /dev/ram and /dev/fd, where /dev/ram refers to an
initial ramdisk loaded by your bootstrap program (please consult the
instructions for your bootstrap program to find out how to load an
initial ramdisk). As of kernel version 2.0.18 you must specify
/dev/ram as the root device if you want to boot from an initial
ramdisk. For the floppy devices, /dev/fd, the number stands for the
floppy drive number (there are no partitions on floppy disks). I.e.,
/dev/fd0 stands for the first drive, /dev/fd1 for the second, and so
on. Since the number is just added, you can also force the disk format
by adding a number greater than 3. If you look into your /dev
directory, use can see the /dev/fd0D720 has major 2 and minor 16. You
can specify this device for the root FS by writing "root=/dev/fd16" on
the kernel command line.

[Strange and maybe uninteresting stuff ON]

This unusual translation of device names has some strange
consequences: If, for example, you have a symbolic link from /dev/fd
to /dev/fd0D720 as an abbreviation for floppy driver #0 in DD format,
you cannot use this name for specifying the root device, because the
kernel cannot see this symlink before mounting the root FS and it
isn't in the table above. If you use it, the root device will not be
set at all, without an error message. Another example: You cannot use a
partition on e.g. the sixth SCSI disk as the root filesystem, if you
want to specify it by name. This is, because only the devices up to
/dev/sde are in the table above, but not /dev/sdf. Although, you can
use the sixth SCSI disk for the root FS, but you have to specify the
device by number... (see below). Or, even more strange, you can use the
fact that there is no range checking of the partition number, and your
knowledge that each disk uses 16 minors, and write "root=/dev/sde17"
(for /dev/sdf1).

[Strange and maybe uninteresting stuff OFF]

If the device containing your root partition isn't in the table
above, you can also specify it by major and minor numbers. These are
written in hex, with no prefix and no separator between. E.g., if you
have a CD with contents appropriate as a root filesystem in the first
SCSI CD-ROM drive, you boot from it by "root=0b00". Here, hex "0b" =
decimal 11 is the major of SCSI CD-ROMs, and the minor 0 stands for
the first of these. You can find out all valid major numbers by
looking into include/linux/major.h.

In addition to major and minor numbers, if the device containing your
root partition uses a partition table format with unique partition
identifiers, then you may use them.  For instance,
"root=PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF".  It is also
possible to reference another partition on the same device using a
known partition UUID as the starting point.  For example,
if partition 5 of the device has the UUID of
00112233-4455-6677-8899-AABBCCDDEEFF then partition 3 may be found as
follows:

  PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF/PARTNROFF=-2

Authoritative information can be found in
"Documentation/admin-guide/kernel-parameters.rst".

2.2) ro, rw
-----------

:Syntax: ro
:or:     rw

These two options tell the kernel whether it should mount the root
filesystem read-only or read-write. The default is read-only, except
for ramdisks, which default to read-write.

2.3) debug
----------

:Syntax: debug

This raises the kernel log level to 10 (the default is 7). This is the
same level as set by the "dmesg" command, just that the maximum level
selectable by dmesg is 8.

2.4) debug=
-----------

:Syntax: debug=<device>

This option causes certain kernel messages be printed to the selected
debugging device. This can aid debugging the kernel, since the
messages can be captured and analyzed on some other machine. Which
devices are possible depends on the machine type. There are no checks
for the validity of the device name. If the device isn't implemented,
nothing happens.

Messages logged this way are in general stack dumps after kernel
memory faults or bad kernel traps, and kernel panics. To be exact: all
messages of level 0 (panic messages) and all messages printed while
the log level is 8 or more (their level doesn't matter). Before stack
dumps, the kernel sets the log level to 10 automatically. A level of
at least 8 can also be set by the "debug" command line option (see
2.3) and at run time with "dmesg -n 8".

Devices possible for Amiga:

 - "ser":
	  built-in serial port; parameters: 9600bps, 8N1
 - "mem":
	  Save the messages to a reserved area in chip mem. After
          rebooting, they can be read under AmigaOS with the tool
          'dmesg'.

Devices possible for Atari:

 - "ser1":
	   ST-MFP serial port ("Modem1"); parameters: 9600bps, 8N1
 - "ser2":
	   SCC channel B serial port ("Modem2"); parameters: 9600bps, 8N1
 - "ser" :
	   default serial port
           This is "ser2" for a Falcon, and "ser1" for any other machine
 - "midi":
	   The MIDI port; parameters: 31250bps, 8N1
 - "par" :
	   parallel port

           The printing routine for this implements a timeout for the
           case there's no printer connected (else the kernel would
           lock up). The timeout is not exact, but usually a few
           seconds.

2.6) ramdisk_size=
------------------

:Syntax: ramdisk_size=<size>

This option instructs the kernel to set up a ramdisk of the given
size in KBytes. Do not use this option if the ramdisk contents are
passed by bootstrap! In this case, the size is selected automatically
and should not be overwritten.

The only application is for root filesystems on floppy disks, that
should be loaded into memory. To do that, select the corresponding
size of the disk as ramdisk size, and set the root device to the disk
drive (with "root=").

2.7) swap=

  I can't find any sign of this option in 2.2.6.

2.8) buff=
-----------

  I can't find any sign of this option in 2.2.6.

3) General Device Options (Amiga and Atari)
===========================================

3.1) ether=
-----------

:Syntax: ether=[<irq>[,<base_addr>[,<mem_start>[,<mem_end>]]]],<dev-name>

<dev-name> is the name of a net driver, as specified in
drivers/net/Space.c in the Linux source. Most prominent are eth0, ...
eth3, sl0, ... sl3, ppp0, ..., ppp3, dummy, and lo.

The non-ethernet drivers (sl, ppp, dummy, lo) obviously ignore the
settings by this options. Also, the existing ethernet drivers for
Linux/m68k (ariadne, a2065, hydra) don't use them because Zorro boards
are really Plug-'n-Play, so the "ether=" option is useless altogether
for Linux/m68k.

3.2) hd=
--------

:Syntax: hd=<cylinders>,<heads>,<sectors>

This option sets the disk geometry of an IDE disk. The first hd=
option is for the first IDE disk, the second for the second one.
(I.e., you can give this option twice.) In most cases, you won't have
to use this option, since the kernel can obtain the geometry data
itself. It exists just for the case that this fails for one of your
disks.

3.3) max_scsi_luns=
-------------------

:Syntax: max_scsi_luns=<n>

Sets the maximum number of LUNs (logical units) of SCSI devices to
be scanned. Valid values for <n> are between 1 and 8. Default is 8 if
"Probe all LUNs on each SCSI device" was selected during the kernel
configuration, else 1.

3.4) st=
--------

:Syntax: st=<buffer_size>,[<write_thres>,[<max_buffers>]]

Sets several parameters of the SCSI tape driver. <buffer_size> is
the number of 512-byte buffers reserved for tape operations for each
device. <write_thres> sets the number of blocks which must be filled
to start an actual write operation to the tape. Maximum value is the
total number of buffers. <max_buffer> limits the total number of
buffers allocated for all tape devices.

3.5) dmasound=
--------------

:Syntax: dmasound=[<buffers>,<buffer-size>[,<catch-radius>]]

This option controls some configurations of the Linux/m68k DMA sound
driver (Amiga and Atari): <buffers> is the number of buffers you want
to use (minimum 4, default 4), <buffer-size> is the size of each
buffer in kilobytes (minimum 4, default 32) and <catch-radius> says
how much percent of error will be tolerated when setting a frequency
(maximum 10, default 0). For example with 3% you can play 8000Hz
AU-Files on the Falcon with its hardware frequency of 8195Hz and thus
don't need to expand the sound.

4) Options for Atari Only
=========================

4.1) video=
-----------

:Syntax: video=<fbname>:<sub-options...>

The <fbname> parameter specifies the name of the frame buffer,
eg. most atari users will want to specify `atafb` here. The
<sub-options> is a comma-separated list of the sub-options listed
below.

NB:
    Please notice that this option was renamed from `atavideo` to
    `video` during the development of the 1.3.x kernels, thus you
    might need to update your boot-scripts if upgrading to 2.x from
    an 1.2.x kernel.

NBB:
    The behavior of video= was changed in 2.1.57 so the recommended
    option is to specify the name of the frame buffer.

4.1.1) Video Mode
-----------------

This sub-option may be any of the predefined video modes, as listed
in atari/atafb.c in the Linux/m68k source tree. The kernel will
activate the given video mode at boot time and make it the default
mode, if the hardware allows. Currently defined names are:

 - stlow           : 320x200x4
 - stmid, default5 : 640x200x2
 - sthigh, default4: 640x400x1
 - ttlow           : 320x480x8, TT only
 - ttmid, default1 : 640x480x4, TT only
 - tthigh, default2: 1280x960x1, TT only
 - vga2            : 640x480x1, Falcon only
 - vga4            : 640x480x2, Falcon only
 - vga16, default3 : 640x480x4, Falcon only
 - vga256          : 640x480x8, Falcon only
 - falh2           : 896x608x1, Falcon only
 - falh16          : 896x608x4, Falcon only

If no video mode is given on the command line, the kernel tries the
modes names "default<n>" in turn, until one is possible with the
hardware in use.

A video mode setting doesn't make sense, if the external driver is
activated by a "external:" sub-option.

4.1.2) inverse
--------------

Invert the display. This affects only text consoles.
Usually, the background is chosen to be black. With this
option, you can make the background white.

4.1.3) font
-----------

:Syntax: font:<fontname>

Specify the font to use in text modes. Currently you can choose only
between `VGA8x8`, `VGA8x16` and `PEARL8x8`. `VGA8x8` is default, if the
vertical size of the display is less than 400 pixel rows. Otherwise, the
`VGA8x16` font is the default.

4.1.4) `hwscroll_`
------------------

:Syntax: `hwscroll_<n>`

The number of additional lines of video memory to reserve for
speeding up the scrolling ("hardware scrolling"). Hardware scrolling
is possible only if the kernel can set the video base address in steps
fine enough. This is true for STE, MegaSTE, TT, and Falcon. It is not
possible with plain STs and graphics cards (The former because the
base address must be on a 256 byte boundary there, the latter because
the kernel doesn't know how to set the base address at all.)

By default, <n> is set to the number of visible text lines on the
display. Thus, the amount of video memory is doubled, compared to no
hardware scrolling. You can turn off the hardware scrolling altogether
by setting <n> to 0.

4.1.5) internal:
----------------

:Syntax: internal:<xres>;<yres>[;<xres_max>;<yres_max>;<offset>]

This option specifies the capabilities of some extended internal video
hardware, like e.g. OverScan. <xres> and <yres> give the (extended)
dimensions of the screen.

If your OverScan needs a black border, you have to write the last
three arguments of the "internal:". <xres_max> is the maximum line
length the hardware allows, <yres_max> the maximum number of lines.
<offset> is the offset of the visible part of the screen memory to its
physical start, in bytes.

Often, extended interval video hardware has to be activated somehow.
For this, see the "sw_*" options below.

4.1.6) external:
----------------

:Syntax:
  external:<xres>;<yres>;<depth>;<org>;<scrmem>[;<scrlen>[;<vgabase>
  [;<colw>[;<coltype>[;<xres_virtual>]]]]]

.. I had to break this line...

This is probably the most complicated parameter... It specifies that
you have some external video hardware (a graphics board), and how to
use it under Linux/m68k. The kernel cannot know more about the hardware
than you tell it here! The kernel also is unable to set or change any
video modes, since it doesn't know about any board internal. So, you
have to switch to that video mode before you start Linux, and cannot
switch to another mode once Linux has started.

The first 3 parameters of this sub-option should be obvious: <xres>,
<yres> and <depth> give the dimensions of the screen and the number of
planes (depth). The depth is the logarithm to base 2 of the number
of colors possible. (Or, the other way round: The number of colors is
2^depth).

You have to tell the kernel furthermore how the video memory is
organized. This is done by a letter as <org> parameter:

 'n':
      "normal planes", i.e. one whole plane after another
 'i':
      "interleaved planes", i.e. 16 bit of the first plane, than 16 bit
      of the next, and so on... This mode is used only with the
      built-in Atari video modes, I think there is no card that
      supports this mode.
 'p':
      "packed pixels", i.e. <depth> consecutive bits stand for all
      planes of one pixel; this is the most common mode for 8 planes
      (256 colors) on graphic cards
 't':
      "true color" (more or less packed pixels, but without a color
      lookup table); usually depth is 24

For monochrome modes (i.e., <depth> is 1), the <org> letter has a
different meaning:

 'n':
      normal colors, i.e. 0=white, 1=black
 'i':
      inverted colors, i.e. 0=black, 1=white

The next important information about the video hardware is the base
address of the video memory. That is given in the <scrmem> parameter,
as a hexadecimal number with a "0x" prefix. You have to find out this
address in the documentation of your hardware.

The next parameter, <scrlen>, tells the kernel about the size of the
video memory. If it's missing, the size is calculated from <xres>,
<yres>, and <depth>. For now, it is not useful to write a value here.
It would be used only for hardware scrolling (which isn't possible
with the external driver, because the kernel cannot set the video base
address), or for virtual resolutions under X (which the X server
doesn't support yet). So, it's currently best to leave this field
empty, either by ending the "external:" after the video address or by
writing two consecutive semicolons, if you want to give a <vgabase>
(it is allowed to leave this parameter empty).

The <vgabase> parameter is optional. If it is not given, the kernel
cannot read or write any color registers of the video hardware, and
thus you have to set appropriate colors before you start Linux. But if
your card is somehow VGA compatible, you can tell the kernel the base
address of the VGA register set, so it can change the color lookup
table. You have to look up this address in your board's documentation.
To avoid misunderstandings: <vgabase> is the _base_ address, i.e. a 4k
aligned address. For read/writing the color registers, the kernel
uses the addresses vgabase+0x3c7...vgabase+0x3c9. The <vgabase>
parameter is written in hexadecimal with a "0x" prefix, just as
<scrmem>.

<colw> is meaningful only if <vgabase> is specified. It tells the
kernel how wide each of the color register is, i.e. the number of bits
per single color (red/green/blue). Default is 6, another quite usual
value is 8.

Also <coltype> is used together with <vgabase>. It tells the kernel
about the color register model of your gfx board. Currently, the types
"vga" (which is also the default) and "mv300" (SANG MV300) are
implemented.

Parameter <xres_virtual> is required for ProMST or ET4000 cards where
the physical linelength differs from the visible length. With ProMST,
xres_virtual must be set to 2048. For ET4000, xres_virtual depends on the
initialisation of the video-card.
If you're missing a corresponding yres_virtual: the external part is legacy,
therefore we don't support hardware-dependent functions like hardware-scroll,
panning or blanking.

4.1.7) eclock:
--------------

The external pixel clock attached to the Falcon VIDEL shifter. This
currently works only with the ScreenWonder!

4.1.8) monitorcap:
-------------------

:Syntax: monitorcap:<vmin>;<vmax>;<hmin>;<hmax>

This describes the capabilities of a multisync monitor. Don't use it
with a fixed-frequency monitor! For now, only the Falcon frame buffer
uses the settings of "monitorcap:".

<vmin> and <vmax> are the minimum and maximum, resp., vertical frequencies
your monitor can work with, in Hz. <hmin> and <hmax> are the same for
the horizontal frequency, in kHz.

  The defaults are 58;62;31;32 (VGA compatible).

  The defaults for TV/SC1224/SC1435 cover both PAL and NTSC standards.

4.1.9) keep
------------

If this option is given, the framebuffer device doesn't do any video
mode calculations and settings on its own. The only Atari fb device
that does this currently is the Falcon.

What you reach with this: Settings for unknown video extensions
aren't overridden by the driver, so you can still use the mode found
when booting, when the driver doesn't know to set this mode itself.
But this also means, that you can't switch video modes anymore...

An example where you may want to use "keep" is the ScreenBlaster for
the Falcon.

4.2) atamouse=
--------------

:Syntax: atamouse=<x-threshold>,[<y-threshold>]

With this option, you can set the mouse movement reporting threshold.
This is the number of pixels of mouse movement that have to accumulate
before the IKBD sends a new mouse packet to the kernel. Higher values
reduce the mouse interrupt load and thus reduce the chance of keyboard
overruns. Lower values give a slightly faster mouse responses and
slightly better mouse tracking.

You can set the threshold in x and y separately, but usually this is
of little practical use. If there's just one number in the option, it
is used for both dimensions. The default value is 2 for both
thresholds.

4.3) ataflop=
-------------

:Syntax: ataflop=<drive type>[,<trackbuffering>[,<steprateA>[,<steprateB>]]]

   The drive type may be 0, 1, or 2, for DD, HD, and ED, resp. This
   setting affects how many buffers are reserved and which formats are
   probed (see also below). The default is 1 (HD). Only one drive type
   can be selected. If you have two disk drives, select the "better"
   type.

   The second parameter <trackbuffer> tells the kernel whether to use
   track buffering (1) or not (0). The default is machine-dependent:
   no for the Medusa and yes for all others.

   With the two following parameters, you can change the default
   steprate used for drive A and B, resp.

4.4) atascsi=
-------------

:Syntax: atascsi=<can_queue>[,<cmd_per_lun>[,<scat-gat>[,<host-id>[,<tagged>]]]]

This option sets some parameters for the Atari native SCSI driver.
Generally, any number of arguments can be omitted from the end. And
for each of the numbers, a negative value means "use default". The
defaults depend on whether TT-style or Falcon-style SCSI is used.
Below, defaults are noted as n/m, where the first value refers to
TT-SCSI and the latter to Falcon-SCSI. If an illegal value is given
for one parameter, an error message is printed and that one setting is
ignored (others aren't affected).

  <can_queue>:
    This is the maximum number of SCSI commands queued internally to the
    Atari SCSI driver. A value of 1 effectively turns off the driver
    internal multitasking (if it causes problems). Legal values are >=
    1. <can_queue> can be as high as you like, but values greater than
    <cmd_per_lun> times the number of SCSI targets (LUNs) you have
    don't make sense. Default: 16/8.

  <cmd_per_lun>:
    Maximum number of SCSI commands issued to the driver for one
    logical unit (LUN, usually one SCSI target). Legal values start
    from 1. If tagged queuing (see below) is not used, values greater
    than 2 don't make sense, but waste memory. Otherwise, the maximum
    is the number of command tags available to the driver (currently
    32). Default: 8/1. (Note: Values > 1 seem to cause problems on a
    Falcon, cause not yet known.)

    The <cmd_per_lun> value at a great part determines the amount of
    memory SCSI reserves for itself. The formula is rather
    complicated, but I can give you some hints:

      no scatter-gather:
	cmd_per_lun * 232 bytes
      full scatter-gather:
	cmd_per_lun * approx. 17 Kbytes

  <scat-gat>:
    Size of the scatter-gather table, i.e. the number of requests
    consecutive on the disk that can be merged into one SCSI command.
    Legal values are between 0 and 255. Default: 255/0. Note: This
    value is forced to 0 on a Falcon, since scatter-gather isn't
    possible with the ST-DMA. Not using scatter-gather hurts
    performance significantly.

  <host-id>:
    The SCSI ID to be used by the initiator (your Atari). This is
    usually 7, the highest possible ID. Every ID on the SCSI bus must
    be unique. Default: determined at run time: If the NV-RAM checksum
    is valid, and bit 7 in byte 30 of the NV-RAM is set, the lower 3
    bits of this byte are used as the host ID. (This method is defined
    by Atari and also used by some TOS HD drivers.) If the above
    isn't given, the default ID is 7. (both, TT and Falcon).

  <tagged>:
    0 means turn off tagged queuing support, all other values > 0 mean
    use tagged queuing for targets that support it. Default: currently
    off, but this may change when tagged queuing handling has been
    proved to be reliable.

    Tagged queuing means that more than one command can be issued to
    one LUN, and the SCSI device itself orders the requests so they
    can be performed in optimal order. Not all SCSI devices support
    tagged queuing (:-().

4.5 switches=
-------------

:Syntax: switches=<list of switches>

With this option you can switch some hardware lines that are often
used to enable/disable certain hardware extensions. Examples are
OverScan, overclocking, ...

The <list of switches> is a comma-separated list of the following
items:

  ikbd:
	set RTS of the keyboard ACIA high
  midi:
	set RTS of the MIDI ACIA high
  snd6:
	set bit 6 of the PSG port A
  snd7:
	set bit 6 of the PSG port A

It doesn't make sense to mention a switch more than once (no
difference to only once), but you can give as many switches as you
want to enable different features. The switch lines are set as early
as possible during kernel initialization (even before determining the
present hardware.)

All of the items can also be prefixed with `ov_`, i.e. `ov_ikbd`,
`ov_midi`, ... These options are meant for switching on an OverScan
video extension. The difference to the bare option is that the
switch-on is done after video initialization, and somehow synchronized
to the HBLANK. A speciality is that ov_ikbd and ov_midi are switched
off before rebooting, so that OverScan is disabled and TOS boots
correctly.

If you give an option both, with and without the `ov_` prefix, the
earlier initialization (`ov_`-less) takes precedence. But the
switching-off on reset still happens in this case.

5) Options for Amiga Only:
==========================

5.1) video=
-----------

:Syntax: video=<fbname>:<sub-options...>

The <fbname> parameter specifies the name of the frame buffer, valid
options are `amifb`, `cyber`, 'virge', `retz3` and `clgen`, provided
that the respective frame buffer devices have been compiled into the
kernel (or compiled as loadable modules). The behavior of the <fbname>
option was changed in 2.1.57 so it is now recommended to specify this
option.

The <sub-options> is a comma-separated list of the sub-options listed
below. This option is organized similar to the Atari version of the
"video"-option (4.1), but knows fewer sub-options.

5.1.1) video mode
-----------------

Again, similar to the video mode for the Atari (see 4.1.1). Predefined
modes depend on the used frame buffer device.

OCS, ECS and AGA machines all use the color frame buffer. The following
predefined video modes are available:

NTSC modes:
 - ntsc            : 640x200, 15 kHz, 60 Hz
 - ntsc-lace       : 640x400, 15 kHz, 60 Hz interlaced

PAL modes:
 - pal             : 640x256, 15 kHz, 50 Hz
 - pal-lace        : 640x512, 15 kHz, 50 Hz interlaced

ECS modes:
 - multiscan       : 640x480, 29 kHz, 57 Hz
 - multiscan-lace  : 640x960, 29 kHz, 57 Hz interlaced
 - euro36          : 640x200, 15 kHz, 72 Hz
 - euro36-lace     : 640x400, 15 kHz, 72 Hz interlaced
 - euro72          : 640x400, 29 kHz, 68 Hz
 - euro72-lace     : 640x800, 29 kHz, 68 Hz interlaced
 - super72         : 800x300, 23 kHz, 70 Hz
 - super72-lace    : 800x600, 23 kHz, 70 Hz interlaced
 - dblntsc-ff      : 640x400, 27 kHz, 57 Hz
 - dblntsc-lace    : 640x800, 27 kHz, 57 Hz interlaced
 - dblpal-ff       : 640x512, 27 kHz, 47 Hz
 - dblpal-lace     : 640x1024, 27 kHz, 47 Hz interlaced
 - dblntsc         : 640x200, 27 kHz, 57 Hz doublescan
 - dblpal          : 640x256, 27 kHz, 47 Hz doublescan

VGA modes:
 - vga             : 640x480, 31 kHz, 60 Hz
 - vga70           : 640x400, 31 kHz, 70 Hz

Please notice that the ECS and VGA modes require either an ECS or AGA
chipset, and that these modes are limited to 2-bit color for the ECS
chipset and 8-bit color for the AGA chipset.

5.1.2) depth
------------

:Syntax: depth:<nr. of bit-planes>

Specify the number of bit-planes for the selected video-mode.

5.1.3) inverse
--------------

Use inverted display (black on white). Functionally the same as the
"inverse" sub-option for the Atari.

5.1.4) font
-----------

:Syntax: font:<fontname>

Specify the font to use in text modes. Functionally the same as the
"font" sub-option for the Atari, except that `PEARL8x8` is used instead
of `VGA8x8` if the vertical size of the display is less than 400 pixel
rows.

5.1.5) monitorcap:
-------------------

:Syntax: monitorcap:<vmin>;<vmax>;<hmin>;<hmax>

This describes the capabilities of a multisync monitor. For now, only
the color frame buffer uses the settings of "monitorcap:".

<vmin> and <vmax> are the minimum and maximum, resp., vertical frequencies
your monitor can work with, in Hz. <hmin> and <hmax> are the same for
the horizontal frequency, in kHz.

The defaults are 50;90;15;38 (Generic Amiga multisync monitor).

5.2) fd_def_df0=
----------------

:Syntax: fd_def_df0=<value>

Sets the df0 value for "silent" floppy drives. The value should be in
hexadecimal with "0x" prefix.

5.3) wd33c93=
-------------

:Syntax: wd33c93=<sub-options...>

These options affect the A590/A2091, A3000 and GVP Series II SCSI
controllers.

The <sub-options> is a comma-separated list of the sub-options listed
below.

5.3.1) nosync
-------------

:Syntax: nosync:bitmask

bitmask is a byte where the 1st 7 bits correspond with the 7
possible SCSI devices. Set a bit to prevent sync negotiation on that
device. To maintain backwards compatibility, a command-line such as
"wd33c93=255" will be automatically translated to
"wd33c93=nosync:0xff". The default is to disable sync negotiation for
all devices, eg. nosync:0xff.

5.3.2) period
-------------

:Syntax: period:ns

`ns` is the minimum # of nanoseconds in a SCSI data transfer
period. Default is 500; acceptable values are 250 - 1000.

5.3.3) disconnect
-----------------

:Syntax: disconnect:x

Specify x = 0 to never allow disconnects, 2 to always allow them.
x = 1 does 'adaptive' disconnects, which is the default and generally
the best choice.

5.3.4) debug
------------

:Syntax: debug:x

If `DEBUGGING_ON` is defined, x is a bit mask that causes various
types of debug output to printed - see the DB_xxx defines in
wd33c93.h.

5.3.5) clock
------------

:Syntax: clock:x

x = clock input in MHz for WD33c93 chip. Normal values would be from
8 through 20. The default value depends on your hostadapter(s),
default for the A3000 internal controller is 14, for the A2091 it's 8
and for the GVP hostadapters it's either 8 or 14, depending on the
hostadapter and the SCSI-clock jumper present on some GVP
hostadapters.

5.3.6) next
-----------

No argument. Used to separate blocks of keywords when there's more
than one wd33c93-based host adapter in the system.

5.3.7) nodma
------------

:Syntax: nodma:x

If x is 1 (or if the option is just written as "nodma"), the WD33c93
controller will not use DMA (= direct memory access) to access the
Amiga's memory.  This is useful for some systems (like A3000's and
A4000's with the A3640 accelerator, revision 3.0) that have problems
using DMA to chip memory.  The default is 0, i.e. to use DMA if
possible.

5.4) gvp11=
-----------

:Syntax: gvp11=<addr-mask>

The earlier versions of the GVP driver did not handle DMA
address-mask settings correctly which made it necessary for some
people to use this option, in order to get their GVP controller
running under Linux. These problems have hopefully been solved and the
use of this option is now highly unrecommended!

Incorrect use can lead to unpredictable behavior, so please only use
this option if you *know* what you are doing and have a reason to do
so. In any case if you experience problems and need to use this
option, please inform us about it by mailing to the Linux/68k kernel
mailing list.

The address mask set by this option specifies which addresses are
valid for DMA with the GVP Series II SCSI controller. An address is
valid, if no bits are set except the bits that are set in the mask,
too.

Some versions of the GVP can only DMA into a 24 bit address range,
some can address a 25 bit address range while others can use the whole
32 bit address range for DMA. The correct setting depends on your
controller and should be autodetected by the driver. An example is the
24 bit region which is specified by a mask of 0x00fffffe.


code:
.. _configuregit:

Configure Git
=============

This chapter describes maintainer level git configuration.

Tagged branches used in :ref:`Documentation/maintainer/pull-requests.rst
<pullrequests>` should be signed with the developers public GPG key. Signed
tags can be created by passing the ``-u`` flag to ``git tag``. However,
since you would *usually* use the same key for the same project, you can
set it once with
::

	git config user.signingkey "keyname"

Alternatively, edit your ``.git/config`` or ``~/.gitconfig`` file by hand:
::

	[user]
		name = Jane Developer
		email = jd@domain.org
		signingkey = jd@domain.org

You may need to tell ``git`` to use ``gpg2``
::

	[gpg]
		program = /path/to/gpg2

You may also like to tell ``gpg`` which ``tty`` to use (add to your shell rc file)
::

	export GPG_TTY=$(tty)

Creating commit links to lore.kernel.org
----------------------------------------

The web site http://lore.kernel.org is meant as a grand archive of all mail
list traffic concerning or influencing the kernel development. Storing archives
of patches here is a recommended practice, and when a maintainer applies a
patch to a subsystem tree, it is a good idea to provide a Link: tag with a
reference back to the lore archive so that people that browse the commit
history can find related discussions and rationale behind a certain change.
The link tag will look like this:

    Link: https://lore.kernel.org/r/<message-id>

This can be configured to happen automatically any time you issue ``git am``
by adding the following hook into your git:

.. code-block:: none

	$ git config am.messageid true
	$ cat >.git/hooks/applypatch-msg <<'EOF'
	#!/bin/sh
	. git-sh-setup
	perl -pi -e 's|^Message-Id:\s*<?([^>]+)>?$|Link: https://lore.kernel.org/r/$1|g;' "$1"
	test -x "$GIT_DIR/hooks/commit-msg" &&
		exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
	:
	EOF
	$ chmod a+x .git/hooks/applypatch-msg

repo_name: angery/linux


code:
==========================
Kernel Maintainer Handbook
==========================

This document is the humble beginning of a manual for kernel maintainers.
There is a lot yet to go here!  Please feel free to propose (and write)
additions to this manual.

.. toctree::
   :maxdepth: 2

   configure-git
   rebasing-and-merging
   pull-requests
   messy-diffstat
   maintainer-entry-profile
   modifying-patches


code:
.. _maintainerentryprofile:

Maintainer Entry Profile
========================

The Maintainer Entry Profile supplements the top-level process documents
(submitting-patches, submitting drivers...) with
subsystem/device-driver-local customs as well as details about the patch
submission life-cycle. A contributor uses this document to level set
their expectations and avoid common mistakes; maintainers may use these
profiles to look across subsystems for opportunities to converge on
common practices.

Overview
--------
Provide an introduction to how the subsystem operates. While MAINTAINERS
tells the contributor where to send patches for which files, it does not
convey other subsystem-local infrastructure and mechanisms that aid
development.

Example questions to consider:

- Are there notifications when patches are applied to the local tree, or
  merged upstream?
- Does the subsystem have a patchwork instance? Are patchwork state
  changes notified?
- Any bots or CI infrastructure that watches the list, or automated
  testing feedback that the subsystem uses to gate acceptance?
- Git branches that are pulled into -next?
- What branch should contributors submit against?
- Links to any other Maintainer Entry Profiles? For example a
  device-driver may point to an entry for its parent subsystem. This makes
  the contributor aware of obligations a maintainer may have for
  other maintainers in the submission chain.

Submit Checklist Addendum
-------------------------
List mandatory and advisory criteria, beyond the common "submit-checklist",
for a patch to be considered healthy enough for maintainer attention.
For example: "pass checkpatch.pl with no errors, or warning. Pass the
unit test detailed at $URI".

The Submit Checklist Addendum can also include details about the status
of related hardware specifications. For example, does the subsystem
require published specifications at a certain revision before patches
will be considered.

Key Cycle Dates
---------------
One of the common misunderstandings of submitters is that patches can be
sent at any time before the merge window closes and can still be
considered for the next -rc1. The reality is that most patches need to
be settled in soaking in linux-next in advance of the merge window
opening. Clarify for the submitter the key dates (in terms of -rc release
week) that patches might be considered for merging and when patches need to
wait for the next -rc. At a minimum:

- Last -rc for new feature submissions:
  New feature submissions targeting the next merge window should have
  their first posting for consideration before this point. Patches that
  are submitted after this point should be clear that they are targeting
  the NEXT+1 merge window, or should come with sufficient justification
  why they should be considered on an expedited schedule. A general
  guideline is to set expectation with contributors that new feature
  submissions should appear before -rc5.

- Last -rc to merge features: Deadline for merge decisions
  Indicate to contributors the point at which an as yet un-applied patch
  set will need to wait for the NEXT+1 merge window. Of course there is no
  obligation to ever accept any given patchset, but if the review has not
  concluded by this point the expectation is the contributor should wait and
  resubmit for the following merge window.

Optional:

- First -rc at which the development baseline branch, listed in the
  overview section, should be considered ready for new submissions.

Review Cadence
--------------
One of the largest sources of contributor angst is how soon to ping
after a patchset has been posted without receiving any feedback. In
addition to specifying how long to wait before a resubmission this
section can also indicate a preferred style of update like, resend the
full series, or privately send a reminder email. This section might also
list how review works for this code area and methods to get feedback
that are not directly from the maintainer.

Existing profiles
-----------------

For now, existing maintainer profiles are listed here; we will likely want
to do something different in the near future.

.. toctree::
   :maxdepth: 1

   ../doc-guide/maintainer-profile
   ../nvdimm/maintainer-entry-profile
   ../riscv/patch-acceptance
   ../driver-api/media/maintainer-entry-profile
   ../driver-api/vfio-pci-device-specific-driver-acceptance


code:
.. SPDX-License-Identifier: GPL-2.0

=====================================
Handling messy pull-request diffstats
=====================================

Subsystem maintainers routinely use ``git request-pull`` as part of the
process of sending work upstream.  Normally, the result includes a nice
diffstat that shows which files will be touched and how much of each will
be changed.  Occasionally, though, a repository with a relatively
complicated development history will yield a massive diffstat containing a
great deal of unrelated work.  The result looks ugly and obscures what the
pull request is actually doing.  This document describes what is happening
and how to fix things up; it is derived from The Wisdom of Linus Torvalds,
found in Linus1_ and Linus2_.

.. _Linus1: https://lore.kernel.org/lkml/CAHk-=wg3wXH2JNxkQi+eLZkpuxqV+wPiHhw_Jf7ViH33Sw7PHA@mail.gmail.com/
.. _Linus2: https://lore.kernel.org/lkml/CAHk-=wgXbSa8yq8Dht8at+gxb_idnJ7X5qWZQWRBN4_CUPr=eQ@mail.gmail.com/

A Git development history proceeds as a series of commits.  In a simplified
manner, mainline kernel development looks like this::

  ... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN

If one wants to see what has changed between two points, a command like
this will do the job::

  $ git diff --stat --summary vN-rc2..vN-rc3

Here, there are two clear points in the history; Git will essentially
"subtract" the beginning point from the end point and display the resulting
differences.  The requested operation is unambiguous and easy enough to
understand.

When a subsystem maintainer creates a branch and commits changes to it, the
result in the simplest case is a history that looks like::

  ... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN
                          |
                          +-- c1 --- c2 --- ... --- cN

If that maintainer now uses ``git diff`` to see what has changed between
the mainline branch (let's call it "linus") and cN, there are still two
clear endpoints, and the result is as expected.  So a pull request
generated with ``git request-pull`` will also be as expected.  But now
consider a slightly more complex development history::

  ... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN
                |         |
                |         +-- c1 --- c2 --- ... --- cN
                |                   /
                +-- x1 --- x2 --- x3

Our maintainer has created one branch at vN-rc1 and another at vN-rc2; the
two were then subsequently merged into c2.  Now a pull request generated
for cN may end up being messy indeed, and developers often end up wondering
why.

What is happening here is that there are no longer two clear end points for
the ``git diff`` operation to use.  The development culminating in cN
started in two different places; to generate the diffstat, ``git diff``
ends up having pick one of them and hoping for the best.  If the diffstat
starts at vN-rc1, it may end up including all of the changes between there
and the second origin end point (vN-rc2), which is certainly not what our
maintainer had in mind.  With all of that extra junk in the diffstat, it
may be impossible to tell what actually happened in the changes leading up
to cN.

Maintainers often try to resolve this problem by, for example, rebasing the
branch or performing another merge with the linus branch, then recreating
the pull request.  This approach tends not to lead to joy at the receiving
end of that pull request; rebasing and/or merging just before pushing
upstream is a well-known way to get a grumpy response.

So what is to be done?  The best response when confronted with this
situation is to indeed to do a merge with the branch you intend your work
to be pulled into, but to do it privately, as if it were the source of
shame.  Create a new, throwaway branch and do the merge there::

  ... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN
                |         |                                      |
                |         +-- c1 --- c2 --- ... --- cN           |
                |                   /               |            |
                +-- x1 --- x2 --- x3                +------------+-- TEMP

The merge operation resolves all of the complications resulting from the
multiple beginning points, yielding a coherent result that contains only
the differences from the mainline branch.  Now it will be possible to
generate a diffstat with the desired information::

  $ git diff -C --stat --summary linus..TEMP

Save the output from this command, then simply delete the TEMP branch;
definitely do not expose it to the outside world.  Take the saved diffstat
output and edit it into the messy pull request, yielding a result that
shows what is really going on.  That request can then be sent upstream.


code:
.. _modifyingpatches:

Modifying Patches
=================

If you are a subsystem or branch maintainer, sometimes you need to slightly
modify patches you receive in order to merge them, because the code is not
exactly the same in your tree and the submitters'. If you stick strictly to
rule (c) of the developers certificate of origin, you should ask the submitter
to rediff, but this is a totally counter-productive waste of time and energy.
Rule (b) allows you to adjust the code, but then it is very impolite to change
one submitters code and make him endorse your bugs. To solve this problem, it
is recommended that you add a line between the last Signed-off-by header and
yours, indicating the nature of your changes. While there is nothing mandatory
about this, it seems like prepending the description with your mail and/or
name, all enclosed in square brackets, is noticeable enough to make it obvious
that you are responsible for last-minute changes. Example::

       Signed-off-by: Random J Developer <random@developer.example.org>
       [lucky@maintainer.example.org: struct foo moved from foo.c to foo.h]
       Signed-off-by: Lucky K Maintainer <lucky@maintainer.example.org>

This practice is particularly helpful if you maintain a stable branch and
want at the same time to credit the author, track changes, merge the fix,
and protect the submitter from complaints. Note that under no circumstances
can you change the author's identity (the From header), as it is the one
which appears in the changelog.

Special note to back-porters: It seems to be a common and useful practice
to insert an indication of the origin of a patch at the top of the commit
message (just after the subject line) to facilitate tracking. For instance,
here's what we see in a 3.x-stable release::

  Date:   Tue Oct 7 07:26:38 2014 -0400

    libata: Un-break ATA blacklist

    commit 1c40279960bcd7d52dbdf1d466b20d24b99176c8 upstream.

And here's what might appear in an older kernel once a patch is backported::

    Date:   Tue May 13 22:12:27 2008 +0200

        wireless, airo: waitbusy() won't delay

        [backport of 2.6 commit b7acbdfbd1f277c1eb23f344f899cfa4cd0bf36a]

Whatever the format, this information provides a valuable help to people
tracking your trees, and to people trying to troubleshoot bugs in your
tree.


code:
.. _pullrequests:

Creating Pull Requests
======================

This chapter describes how maintainers can create and submit pull requests
to other maintainers. This is useful for transferring changes from one
maintainers tree to another maintainers tree.

This document was written by Tobin C. Harding (who at that time, was not an
experienced maintainer) primarily from comments made by Greg Kroah-Hartman
and Linus Torvalds on LKML. Suggestions and fixes by Jonathan Corbet and
Mauro Carvalho Chehab.  Misrepresentation was unintentional but inevitable,
please direct abuse to Tobin C. Harding <me@tobin.cc>.

Original email thread::

	https://lore.kernel.org/r/20171114110500.GA21175@kroah.com

Create Branch
-------------

To start with you will need to have all the changes you wish to include in
the pull request on a separate branch. Typically you will base this branch
off of a branch in the developers tree whom you intend to send the pull
request to.

In order to create the pull request you must first tag the branch that you
have just created. It is recommended that you choose a meaningful tag name,
in a way that you and others can understand, even after some time.  A good
practice is to include in the name an indicator of the subsystem of origin
and the target kernel version.

Greg offers the following. A pull request with miscellaneous stuff for
drivers/char, to be applied at the Kernel version 4.15-rc1 could be named
as ``char-misc-4.15-rc1``. If such tag would be produced from a branch
named ``char-misc-next``, you would be using the following command::

        git tag -s char-misc-4.15-rc1 char-misc-next

that will create a signed tag called ``char-misc-4.15-rc1`` based on the
last commit in the ``char-misc-next`` branch, and sign it with your gpg key
(see :ref:`Documentation/maintainer/configure-git.rst <configuregit>`).

Linus will only accept pull requests based on a signed tag. Other
maintainers may differ.

When you run the above command ``git`` will drop you into an editor and ask
you to describe the tag.  In this case, you are describing a pull request,
so outline what is contained here, why it should be merged, and what, if
any, testing has been done.  All of this information will end up in the tag
itself, and then in the merge commit that the maintainer makes if/when they
merge the pull request. So write it up well, as it will be in the kernel
tree for forever.

As said by Linus::

	Anyway, at least to me, the important part is the *message*. I want
	to understand what I'm pulling, and why I should pull it. I also
	want to use that message as the message for the merge, so it should
	not just make sense to me, but make sense as a historical record
	too.

	Note that if there is something odd about the pull request, that
	should very much be in the explanation. If you're touching files
	that you don't maintain, explain _why_. I will see it in the
	diffstat anyway, and if you didn't mention it, I'll just be extra
	suspicious.  And when you send me new stuff after the merge window
	(or even bug-fixes, but ones that look scary), explain not just
	what they do and why they do it, but explain the _timing_. What
	happened that this didn't go through the merge window..

	I will take both what you write in the email pull request _and_ in
	the signed tag, so depending on your workflow, you can either
	describe your work in the signed tag (which will also automatically
	make it into the pull request email), or you can make the signed
	tag just a placeholder with nothing interesting in it, and describe
	the work later when you actually send me the pull request.

	And yes, I will edit the message. Partly because I tend to do just
	trivial formatting (the whole indentation and quoting etc), but
	partly because part of the message may make sense for me at pull
	time (describing the conflicts and your personal issues for sending
	it right now), but may not make sense in the context of a merge
	commit message, so I will try to make it all make sense. I will
	also fix any speeling mistaeks and bad grammar I notice,
	particularly for non-native speakers (but also for native ones
	;^). But I may miss some, or even add some.

			Linus

Greg gives, as an example pull request::

	Char/Misc patches for 4.15-rc1

	Here is the big char/misc patch set for the 4.15-rc1 merge window.
	Contained in here is the normal set of new functions added to all
	of these crazy drivers, as well as the following brand new
	subsystems:
		- time_travel_controller: Finally a set of drivers for the
		  latest time travel bus architecture that provides i/o to
		  the CPU before it asked for it, allowing uninterrupted
		  processing
		- relativity_shifters: due to the affect that the
		  time_travel_controllers have on the overall system, there
		  was a need for a new set of relativity shifter drivers to
		  accommodate the newly formed black holes that would
		  threaten to suck CPUs into them.  This subsystem handles
		  this in a way to successfully neutralize the problems.
		  There is a Kconfig option to force these to be enabled
		  when needed, so problems should not occur.

	All of these patches have been successfully tested in the latest
	linux-next releases, and the original problems that it found have
	all been resolved (apologies to anyone living near Canberra for the
	lack of the Kconfig options in the earlier versions of the
	linux-next tree creations.)

	Signed-off-by: Your-name-here <your_email@domain>

The tag message format is just like a git commit id.  One line at the top
for a "summary subject" and be sure to sign-off at the bottom.

Now that you have a local signed tag, you need to push it up to where it
can be retrieved::

	git push origin char-misc-4.15-rc1

Create Pull Request
-------------------

The last thing to do is create the pull request message.  ``git`` handily
will do this for you with the ``git request-pull`` command, but it needs a
bit of help determining what you want to pull, and on what to base the pull
against (to show the correct changes to be pulled and the diffstat). The
following command(s) will generate a pull request::

	git request-pull master git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/ char-misc-4.15-rc1

Quoting Greg::

	This is asking git to compare the difference from the
	'char-misc-4.15-rc1' tag location, to the head of the 'master'
	branch (which in my case points to the last location in Linus's
	tree that I diverged from, usually a -rc release) and to use the
	git:// protocol to pull from.  If you wish to use https://, that
	can be used here instead as well (but note that some people behind
	firewalls will have problems with https git pulls).

	If the char-misc-4.15-rc1 tag is not present in the repo that I am
	asking to be pulled from, git will complain saying it is not there,
	a handy way to remember to actually push it to a public location.

	The output of 'git request-pull' will contain the location of the
	git tree and specific tag to pull from, and the full text
	description of that tag (which is why you need to provide good
	information in that tag).  It will also create a diffstat of the
	pull request, and a shortlog of the individual commits that the
	pull request will provide.

Linus responded that he tends to prefer the ``git://`` protocol. Other
maintainers may have different preferences. Also, note that if you are
creating pull requests without a signed tag then ``https://`` may be a
better choice. Please see the original thread for the full discussion.

Submit Pull Request
-------------------

A pull request is submitted in the same way as an ordinary patch. Send as
inline email to the maintainer and CC LKML and any sub-system specific
lists if required. Pull requests to Linus typically have a subject line
something like::

	[GIT PULL] <subsystem> changes for v4.15-rc1


code:
.. SPDX-License-Identifier: GPL-2.0

====================
Rebasing and merging
====================

Maintaining a subsystem, as a general rule, requires a familiarity with the
Git source-code management system.  Git is a powerful tool with a lot of
features; as is often the case with such tools, there are right and wrong
ways to use those features.  This document looks in particular at the use
of rebasing and merging.  Maintainers often get in trouble when they use
those tools incorrectly, but avoiding problems is not actually all that
hard.

One thing to be aware of in general is that, unlike many other projects,
the kernel community is not scared by seeing merge commits in its
development history.  Indeed, given the scale of the project, avoiding
merges would be nearly impossible.  Some problems encountered by
maintainers result from a desire to avoid merges, while others come from
merging a little too often.

Rebasing
========

"Rebasing" is the process of changing the history of a series of commits
within a repository.  There are two different types of operations that are
referred to as rebasing since both are done with the ``git rebase``
command, but there are significant differences between them:

 - Changing the parent (starting) commit upon which a series of patches is
   built.  For example, a rebase operation could take a patch set built on
   the previous kernel release and base it, instead, on the current
   release.  We'll call this operation "reparenting" in the discussion
   below.

 - Changing the history of a set of patches by fixing (or deleting) broken
   commits, adding patches, adding tags to commit changelogs, or changing
   the order in which commits are applied.  In the following text, this
   type of operation will be referred to as "history modification"

The term "rebasing" will be used to refer to both of the above operations.
Used properly, rebasing can yield a cleaner and clearer development
history; used improperly, it can obscure that history and introduce bugs.

There are a few rules of thumb that can help developers to avoid the worst
perils of rebasing:

 - History that has been exposed to the world beyond your private system
   should usually not be changed.  Others may have pulled a copy of your
   tree and built on it; modifying your tree will create pain for them.  If
   work is in need of rebasing, that is usually a sign that it is not yet
   ready to be committed to a public repository.

   That said, there are always exceptions.  Some trees (linux-next being
   a significant example) are frequently rebased by their nature, and
   developers know not to base work on them.  Developers will sometimes
   expose an unstable branch for others to test with or for automated
   testing services.  If you do expose a branch that may be unstable in
   this way, be sure that prospective users know not to base work on it.

 - Do not rebase a branch that contains history created by others.  If you
   have pulled changes from another developer's repository, you are now a
   custodian of their history.  You should not change it.  With few
   exceptions, for example, a broken commit in a tree like this should be
   explicitly reverted rather than disappeared via history modification.

 - Do not reparent a tree without a good reason to do so.  Just being on a
   newer base or avoiding a merge with an upstream repository is not
   generally a good reason.

 - If you must reparent a repository, do not pick some random kernel commit
   as the new base.  The kernel is often in a relatively unstable state
   between release points; basing development on one of those points
   increases the chances of running into surprising bugs.  When a patch
   series must move to a new base, pick a stable point (such as one of
   the -rc releases) to move to.

 - Realize that reparenting a patch series (or making significant history
   modifications) changes the environment in which it was developed and,
   likely, invalidates much of the testing that was done.  A reparented
   patch series should, as a general rule, be treated like new code and
   retested from the beginning.

A frequent cause of merge-window trouble is when Linus is presented with a
patch series that has clearly been reparented, often to a random commit,
shortly before the pull request was sent.  The chances of such a series
having been adequately tested are relatively low - as are the chances of
the pull request being acted upon.

If, instead, rebasing is limited to private trees, commits are based on a
well-known starting point, and they are well tested, the potential for
trouble is low.

Merging
=======

Merging is a common operation in the kernel development process; the 5.1
development cycle included 1,126 merge commits - nearly 9% of the total.
Kernel work is accumulated in over 100 different subsystem trees, each of
which may contain multiple topic branches; each branch is usually developed
independently of the others.  So naturally, at least one merge will be
required before any given branch finds its way into an upstream repository.

Many projects require that branches in pull requests be based on the
current trunk so that no merge commits appear in the history.  The kernel
is not such a project; any rebasing of branches to avoid merges will, most
likely, lead to trouble.

Subsystem maintainers find themselves having to do two types of merges:
from lower-level subsystem trees and from others, either sibling trees or
the mainline.  The best practices to follow differ in those two situations.

Merging from lower-level trees
------------------------------

Larger subsystems tend to have multiple levels of maintainers, with the
lower-level maintainers sending pull requests to the higher levels.  Acting
on such a pull request will almost certainly generate a merge commit; that
is as it should be.  In fact, subsystem maintainers may want to use
the --no-ff flag to force the addition of a merge commit in the rare cases
where one would not normally be created so that the reasons for the merge
can be recorded.  The changelog for the merge should, for any kind of
merge, say *why* the merge is being done.  For a lower-level tree, "why" is
usually a summary of the changes that will come with that pull.

Maintainers at all levels should be using signed tags on their pull
requests, and upstream maintainers should verify the tags when pulling
branches.  Failure to do so threatens the security of the development
process as a whole.

As per the rules outlined above, once you have merged somebody else's
history into your tree, you cannot rebase that branch, even if you
otherwise would be able to.

Merging from sibling or upstream trees
--------------------------------------

While merges from downstream are common and unremarkable, merges from other
trees tend to be a red flag when it comes time to push a branch upstream.
Such merges need to be carefully thought about and well justified, or
there's a good chance that a subsequent pull request will be rejected.

It is natural to want to merge the master branch into a repository; this
type of merge is often called a "back merge".  Back merges can help to make
sure that there are no conflicts with parallel development and generally
gives a warm, fuzzy feeling of being up-to-date.  But this temptation
should be avoided almost all of the time.

Why is that?  Back merges will muddy the development history of your own
branch.  They will significantly increase your chances of encountering bugs
from elsewhere in the community and make it hard to ensure that the work
you are managing is stable and ready for upstream.  Frequent merges can
also obscure problems with the development process in your tree; they can
hide interactions with other trees that should not be happening (often) in
a well-managed branch.

That said, back merges are occasionally required; when that happens, be
sure to document *why* it was required in the commit message.  As always,
merge to a well-known stable point, rather than to some random commit.
Even then, you should not back merge a tree above your immediate upstream
tree; if a higher-level back merge is really required, the upstream tree
should do it first.

One of the most frequent causes of merge-related trouble is when a
maintainer merges with the upstream in order to resolve merge conflicts
before sending a pull request.  Again, this temptation is easy enough to
understand, but it should absolutely be avoided.  This is especially true
for the final pull request: Linus is adamant that he would much rather see
merge conflicts than unnecessary back merges.  Seeing the conflicts lets
him know where potential problem areas are.  He does a lot of merges (382
in the 5.1 development cycle) and has gotten quite good at conflict
resolution - often better than the developers involved.

So what should a maintainer do when there is a conflict between their
subsystem branch and the mainline?  The most important step is to warn
Linus in the pull request that the conflict will happen; if nothing else,
that demonstrates an awareness of how your branch fits into the whole.  For
especially difficult conflicts, create and push a *separate* branch to show
how you would resolve things.  Mention that branch in your pull request,
but the pull request itself should be for the unmerged branch.

Even in the absence of known conflicts, doing a test merge before sending a
pull request is a good idea.  It may alert you to problems that you somehow
didn't see from linux-next and helps to understand exactly what you are
asking upstream to do.

Another reason for doing merges of upstream or another subsystem tree is to
resolve dependencies.  These dependency issues do happen at times, and
sometimes a cross-merge with another tree is the best way to resolve them;
as always, in such situations, the merge commit should explain why the
merge has been done.  Take a moment to do it right; people will read those
changelogs.

Often, though, dependency issues indicate that a change of approach is
needed.  Merging another subsystem tree to resolve a dependency risks
bringing in other bugs and should almost never be done.  If that subsystem
tree fails to be pulled upstream, whatever problems it had will block the
merging of your tree as well.  Preferable alternatives include agreeing
with the maintainer to carry both sets of changes in one of the trees or
creating a topic branch dedicated to the prerequisite commits that can be
merged into both trees.  If the dependency is related to major
infrastructural changes, the right solution might be to hold the dependent
commits for one development cycle so that those changes have time to
stabilize in the mainline.

Finally
=======

It is relatively common to merge with the mainline toward the beginning of
the development cycle in order to pick up changes and fixes done elsewhere
in the tree.  As always, such a merge should pick a well-known release
point rather than some random spot.  If your upstream-bound branch has
emptied entirely into the mainline during the merge window, you can pull it
forward with a command like::

  git merge v5.2-rc1^0

The "^0" will cause Git to do a fast-forward merge (which should be
possible in this situation), thus avoiding the addition of a spurious merge
commit.

The guidelines laid out above are just that: guidelines.  There will always
be situations that call out for a different solution, and these guidelines
should not prevent developers from doing the right thing when the need
arises.  But one should always think about whether the need has truly
arisen and be prepared to explain why something abnormal needs to be done.