What is the difference in RISCV between JAL and JALR?
JAL saves the next address (program counter +4) to the destination register, adds the immediate value encoded in the instruction to the program counter, and jumps to that address.
JALR saves the next address (program counter +4) to the destination register, adds the immediate value encoded in the instruction to the source register, and jumps to that (even) address.
In other words, while JAL jumps to an address relative to the current instruction, JALR jumps to an even address relative to one stored in a register.
The detailed parts from the technical documentation are these:

Unconditional Jumps
The jump and link (JAL) instruction uses the J-type format, where the J-immediate encodes a
signed offset in multiples of 2 bytes. The offset is sign-extended and added to the pc to form the
jump target address. Jumps can therefore target a ±1 MiB range. JAL stores the address of the
instruction following the jump (pc+4) into register rd. The standard software calling convention
uses x1 as the return address register and x5 as an alternate link register. Plain unconditional jumps (assembler pseudo-op J) are encoded as a JAL with rd=x0.


The indirect jump instruction JALR (jump and link register) uses the I-type encoding. The target
address is obtained by adding the 12-bit signed I-immediate to the register rs1, then setting the
least-significant bit of the result to zero. The address of the instruction following the jump (pc+4)
is written to register rd. Register x0 can be used as the destination if the result is not required.