> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/ask/flat/chapter-13-freebsd-system-updates/di-13.3-jie-shi-yong-pkgbase-geng-xin-ji-ben-xi-tong.md).

# 13.3 Updating the Base System with PkgBase

The design goal of PkgBase is to enable stable, current, and release (including BETA, RC, etc.) branches to all use a unified binary tool for updates. Previously, the stable and current branches could only be updated by compiling source code.

> **Note**
>
> Only FreeBSD 14.0-RELEASE and later can be directly converted to PkgBase. Older versions still need to be updated via `freebsd-update` (running pkgbasify will display `Unsupported FreeBSD version`, meaning the FreeBSD version is not supported).

> **Warning**
>
> **This carries risks and may result in the loss of all system data! It is recommended to make a backup before proceeding.**

* Lock the pkg package in the **/mnt/upgrade** environment to prevent upgrades or modifications:

```sh
# pkg -c /mnt/upgrade lock pkg  # Lock the pkg package in the /mnt/upgrade environment
pkg-2.4.2_1: lock this package? [y/N]: y # Enter y and press Enter to confirm locking pkg
Locking pkg-2.4.2_1
```

* Download the PkgBase conversion script

```sh
# fetch -o /mnt/upgrade https://raw.githubusercontent.com/FreeBSDFoundation/pkgbasify/main/pkgbasify.lua  # Download the PkgBase conversion script
```

* Convert using pkgbasify

> **Warning**
>
> After confirming the `Do you accept this risk and wish to continue? (y/n)` risk prompt, there is no second confirmation step!

```sh
# chroot /mnt/upgrade /usr/libexec/flua pkgbasify.lua  # Convert using pkgbasify
Running this tool will irreversibly modify your system to use pkgbase.
This tool and pkgbase are experimental and may result in a broken system.
It is highly recommended to backup your system before proceeding.
Do you accept this risk and wish to continue? (y/n) y # Risk prompt; confirm to continue
Updating FreeBSD repository catalogue...

……Omitted here……

The following 370 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        FreeBSD-acct: 14.3p6 [FreeBSD-base]
        FreeBSD-acct-man: 14.3p6 [FreeBSD-base]
        FreeBSD-acpi: 14.3p6 [FreeBSD-base]
        FreeBSD-acpi-man: 14.3p6 [FreeBSD-base]

……Omitted here……

Conversion finished.

Please verify that the contents of the following critical files are as expected:
/etc/master.passwd
/etc/group
/etc/ssh/sshd_config

After verifying those files, restart the system.
```

* Check the system version in the boot environment 15.0-RELEASE

```sh
# chroot /mnt/upgrade freebsd-version -kru
14.3-RELEASE-p6
14.3-RELEASE
14.3-RELEASE-p6
```

## Using PkgBase to Update the System Version in the Boot Environment to 15.0-RELEASE

After converting to PkgBase, you can use the pkg package manager to upgrade the system. Below we configure the PkgBase source and perform the upgrade.

Software source structure:

```sh
/usr/local/etc/pkg/
└── repos/ # pkg repository configuration directory
    └── FreeBSD-base.conf # PkgBase source configuration file
```

* Create the PkgBase software source directory

```sh
# mkdir -p /mnt/upgrade/usr/local/etc/pkg/repos/  # Create the PkgBase software source directory
```

* Edit the **/mnt/upgrade/usr/local/etc/pkg/repos/FreeBSD-base.conf** file and add the PkgBase source

```ini
FreeBSD-base {
    url: "pkg+https://pkg.FreeBSD.org/${ABI}/base_release_${VERSION_MINOR}",
    mirror_type: "srv",
    signature_type: "fingerprints",
    fingerprints: "/usr/share/keys/pkgbase-${VERSION_MAJOR}",
    enabled: yes
}
```

> **Warning**
>
> Please check the contents of `FreeBSD-base.conf`, especially that you should **not** manually hardcode any specific version in it (such as `base_release_3`).
>
> Since FreeBSD 15.0 uses a new signing key, when upgrading from 14.x to 15.0, the `fingerprints` path must be changed from the pkgbasify default `/usr/share/keys/pkg` to `/usr/share/keys/pkgbase-${VERSION_MAJOR}`, and ensure that the pkgbase-15 key is installed (which can be installed via `pkg add -f https://pkg.freebsd.org/FreeBSD:15:$(uname -p)/base_release_0/FreeBSD-pkg-bootstrap-15.0.pkg`).

> **Tip**
>
> Users who need to switch software sources can change the `url` line to `url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/base_release_${VERSION_MINOR}",`. Readers concerned with security should keep the default settings.

* Refresh the software source

```sh
# pkg -c /mnt/upgrade update -r FreeBSD-base  # Refresh the software source
```

* Use PkgBase to update from 14.3-RELEASE to 15.0-RELEASE (i.e., specify the ABI as 15)

```sh
# env ABI=FreeBSD:15:amd64 pkg-static -c /mnt/upgrade upgrade -r FreeBSD-base  # Upgrade FreeBSD base system packages in the /mnt/upgrade environment using the specified ABI
pkg-static: Setting ABI requires setting OSVERSION, guessing the OSVERSION as: 1500000
pkg-static: Warning: Major OS version upgrade detected.  Running "pkg bootstrap -f" recommended
Updating FreeBSD-base repository catalogue...
pkg-static: Repository FreeBSD-base has a wrong packagesite, need to re-create database
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01
Fetching data.pkg: 100%   80 KiB  81.6kB/s    00:01
Processing entries:   0%
Newer FreeBSD version for package FreeBSD-zlib-dbg:
To ignore this error set IGNORE_OSVERSION=yes
- package: 1500068
- running userland: 1500000
Ignore the mismatch and continue? [y/N]: y # Enter y and press Enter to continue
Processing entries: 100%
FreeBSD-base repository update completed. 496 packages processed.
FreeBSD-base is up to date.
Checking for upgrades (230 candidates): 100%
Processing candidates (230 candidates): 100%
The following 290 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        FreeBSD-atf: 15.0 [FreeBSD-base]
        FreeBSD-atf-dev: 15.0 [FreeBSD-base]
        FreeBSD-atf-lib: 15.0 [FreeBSD-base]

        ……Some entries omitted here……

        FreeBSD-zoneinfo: 14.3p6 -> 15.0 [FreeBSD-base]

Number of packages to be installed: 61
Number of packages to be upgraded: 229

The operation will free 100 MiB.
473 MiB to be downloaded.

Proceed with this action? [y/N]: y # Enter y and press Enter to continue
```

> **Tip**
>
> If no updates are detected, please confirm whether the system has been successfully converted to PkgBase and check whether the software source configuration is correct.

* Check the system version in the boot environment 15.0-RELEASE

```sh
# chroot /mnt/upgrade freebsd-version -kru
15.0-RELEASE
14.3-RELEASE
15.0-RELEASE
```

The `r` showing 14.3-RELEASE is not abnormal; it indicates that the currently running system is still 14.3-RELEASE. Combined with other parameters, it can be seen that the switch to 15.0-RELEASE will only occur after a reboot.

* Unlock pkg

```sh
# chroot /mnt/upgrade pkg unlock pkg  # Unlock pkg
pkg: Warning: Major OS version upgrade detected.  Running "pkg bootstrap -f" recommended
pkg-2.4.2_1: unlock this package? [y/N]: y
Unlocking pkg-2.4.2_1
```

* Update the ABI of all third-party packages to FreeBSD 15.0

```sh
# chroot /mnt/upgrade pkg upgrade  # Update the ABI of all third-party packages to FreeBSD 15.0
```

The update process requires multiple confirmations to complete.

## Appendix: Switching Software Sources for the pkgbasify Script (Using USTC)

For users in restricted network environments, it may be necessary to configure a domestic mirror source for the pkgbasify script to improve download speeds. Below describes how to modify the source address in the script.

The University of Science and Technology of China (USTC) provides FreeBSD mirror services. You can modify the pkgbasify script to use this mirror source. For other open-source mirror sites, see the software source chapter. First, you need to find the relevant function in the script.

Find the `create_base_repo_conf` function in the Lua script:

```lua
local function base_repo_url()
	local major, minor, branch = freebsd_version()
	if math.tointeger(major) < 14 then
		fatal("Unsupported FreeBSD version: " .. raw)
	end
	if branch == "RELEASE" or branch:match("^BETA") or branch:match("^RC") then
		return "pkg+https://pkg.FreeBSD.org/${ABI}/base_release_" .. minor
	elseif branch == "CURRENT" or
		branch == "STABLE" or
		branch == "PRERELEASE" or
		branch:match("^ALPHA")
	then
		return "pkg+https://pkg.FreeBSD.org/${ABI}/base_latest"
	else
		fatal("Unsupported FreeBSD version: " .. raw)
	end
end
```

Modify this function as follows, where the mirror site is specified in the `return` section:

```lua
local function base_repo_url()
	local major, minor, branch = freebsd_version()
	if math.tointeger(major) < 14 then
		fatal("Unsupported FreeBSD version: " .. raw)
	end
	if branch == "RELEASE" or branch:match("^BETA") or branch:match("^RC") then
		return "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/base_release_" .. minor
	elseif branch == "CURRENT" or
		branch == "STABLE" or
		branch == "PRERELEASE" or
		branch:match("^ALPHA")
	then
		return "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/base_latest"
	else
		fatal("Unsupported FreeBSD version: " .. raw)
	end
end
```

> **Warning**
>
> Please remove `pkg+` from the `return "pkg+https://"` line, otherwise an error will occur.

Then find the following function `create_base_repo_conf`

```lua
local function create_base_repo_conf(path)
	assert(os.execute("mkdir -p " .. path:match(".*/")))
	local f <close> = assert(io.open(path, "w"))
	if math.tointeger(freebsd_version()) >= 15 then
		assert(f:write(string.format([[
%s: {
  enabled: yes
}
]], options.repo_name)))
	else
		assert(f:write(string.format([[
%s: {
  url: "%s",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
]], options.repo_name, base_repo_url())))
	end
end
```

Modify as follows (removed the srv-related lines):

```lua
local function create_base_repo_conf(path)
	assert(os.execute("mkdir -p " .. path:match(".*/")))
	local f <close> = assert(io.open(path, "w"))
	if math.tointeger(freebsd_version()) >= 15 then
		assert(f:write(string.format([[
%s: {
  enabled: yes
}
]], options.repo_name)))
	else
		assert(f:write(string.format([[
%s: {
  url: "%s",
  enabled: yes
}
]], options.repo_name, base_repo_url())))
	end
end
```

> **Tip**
>
> Readers concerned with security should keep the default settings.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/ask/flat/chapter-13-freebsd-system-updates/di-13.3-jie-shi-yong-pkgbase-geng-xin-ji-ben-xi-tong.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
